source: cpp/frams/genetics/geno.cpp @ 197

Last change on this file since 197 was 197, checked in by Maciej Komosinski, 10 years ago

GDK used by developers since 1999, distributed on the web since 2002

  • Property svn:eol-style set to native
File size: 5.8 KB
RevLine 
[121]1// This file is a part of the Framsticks GDK.
[197]2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
[109]3// Refer to http://www.framsticks.com/ for further information.
4
5#include "geno.h"
[145]6#include "genoconv.h"
[109]7#include <frams/model/model.h>
8
9SListTempl<GenoValidator*> Geno::validators;
[150]10GenoConvManager *Geno::converters = NULL;
[109]11
[150]12void Geno::init(const SString& genstring, char genformat, const SString& genname, const SString& comment)
[109]13{
[150]14        refcount = 1;
15        owner = 0;
16        f0gen = 0;
17        mapinshift = 0;
18        mapoutshift = 0;
19        isvalid = -1;
20        SString gencopy(genstring);
21        if (genformat == -1)
[109]22        { // unknown format
[150]23                genformat = '1';
24                if (genstring.charAt(0) == '/')
[109]25                {
[150]26                        int end;
27                        SString newcomment;
28                        switch (genstring.charAt(1))
[109]29                        {
30                        case '/':
[150]31                                genformat = genstring.charAt(2);
32                                if ((end = genstring.indexOf('\n')) >= 0)
33                                {
34                                        newcomment = genstring.substr(2, end - 2);
35                                        gencopy = genstring.substr(end + 1);
36                                        mapinshift = end + 1;
37                                }
[109]38                                else
[150]39                                {
40                                        gencopy = 0;
41                                        mapinshift = genstring.len();
42                                }
[109]43                                break;
44                        case '*':
[150]45                                genformat = genstring.charAt(2);
46                                if ((end = genstring.indexOf("*/")) >= 0)
47                                {
48                                        newcomment = genstring.substr(2, end - 2);
49                                        gencopy = genstring.substr(end + 2);
50                                        mapinshift = end + 2;
51                                }
[109]52                                else
[150]53                                {
54                                        gencopy = 0;
55                                        mapinshift = genstring.len();
56                                }
[109]57                                break;
58                        }
[150]59                        if (newcomment.len() > 0)
[109]60                        {
[150]61                                SString token; int pos = 0;
62                                if (newcomment.getNextToken(pos, token, ';'))
63                                        if (newcomment.getNextToken(pos, token, ';'))
64                                        {
65                                                if (token.len()) txt = token;
66                                                if (newcomment.getNextToken(pos, token, ';'))
67                                                        if (token.len()) name = token;
68                                        }
[109]69                        }
70                }
71        }
72
[150]73        gen = gencopy;
74        format = genformat;
75        if (!name.len()) name = genname;
76        if (!txt.len()) txt = comment;
77        multiline = (strchr((const char*)gen, '\n') != 0);
78        // mapoutshift...?
[109]79}
80
81void Geno::freeF0()
82{
[150]83        if (f0gen) { delete f0gen; f0gen = 0; }
[109]84}
85
[150]86Geno::Geno(const char *genstring, char genformat, const char *genname, const char *comment)
[109]87{
[150]88        init(SString(genstring), genformat, SString(genname), SString(comment));
[109]89}
90
[150]91Geno::Geno(const SString& genstring, char genformat, const SString& genname, const SString& comment)
[109]92{
[150]93        init(genstring, genformat, genname, comment);
[109]94}
95
96Geno::Geno(const Geno& src)
[150]97:gen(src.gen), name(src.name), format(src.format), txt(src.txt), isvalid(src.isvalid),
98f0gen(0), mapinshift(src.mapinshift), mapoutshift(src.mapinshift),
99multiline(src.multiline), owner(0)
100{
101        f0gen = src.f0gen ? new Geno(*src.f0gen) : 0; refcount = 1;
102}
[109]103
104void Geno::operator=(const Geno& src)
105{
[150]106        freeF0();
107        gen = src.gen;
108        name = src.name;
109        format = src.format;
110        txt = src.txt;
111        isvalid = src.isvalid;
112        mapinshift = src.mapinshift;
113        mapoutshift = src.mapinshift;
114        multiline = src.multiline;
115        f0gen = src.f0gen ? new Geno(*src.f0gen) : 0;
116        owner = 0;
[109]117}
118
119Geno::Geno(const SString& src)
120{
[150]121        init(src, -1, SString::empty(), SString::empty());
[109]122}
123
[150]124void Geno::setGene(const SString& g, char newformat)
[109]125{
[150]126        gen = g;
127        isvalid = -1;
128        freeF0();
129        if (newformat >= 0) format = newformat;
[109]130}
131
132void Geno::setString(const SString& g)
133{
[150]134        freeF0();
135        init(g, -1, SString::empty(), SString::empty());
[109]136}
137
138void Geno::setName(const SString& n)
139{
[150]140        name = n;
[109]141}
142
143void Geno::setComment(const SString& c)
144{
[150]145        txt = c;
[109]146}
147
148SString Geno::toString(void) const
149{
[150]150        SString out;
151        int comment = 0;
152        if ((format != '1') || (comment = (txt.len() || name.len())))
[109]153        {
[150]154                if (multiline)
155                        out += "//";
156                else
157                        out += "/*";
158                out += format;
159                if (comment)
[109]160                {
[150]161                        if (txt.len()) { out += ";"; out += txt; }
162                        if (name.len()){ out += ";"; out += name; }
[109]163                }
[150]164                if (multiline)
165                        out += "\n";
166                else
167                        out += "*/";
[109]168        }
[150]169        out += gen;
170        return out;
[109]171}
172
173SString Geno::shortString(void) const
174{
[150]175        SString out;
176        if (format != '1')
[109]177        {
[150]178                if (multiline)
179                        out += "//";
180                else
181                        out += "/*";
182                if (format == 0)
183                        out += "invalid";
184                else
185                        out += format;
186                if (multiline)
187                        out += "\n";
188                else
189                        out += "*/";
[109]190        }
[150]191        out += gen;
192        return out;
[109]193}
194
195int Geno::mapGenToString(int genpos) const
196{
[150]197        if (genpos > gen.len()) return -2;
198        if (genpos<0) return -1;
199        return mapinshift + genpos;
[109]200}
201
202int Geno::mapStringToGen(int stringpos) const
203{
[150]204        stringpos -= mapinshift;
205        if (stringpos>gen.len()) return -2;
206        if (stringpos < 0) return -1;
207        return stringpos;
[109]208}
209
[150]210SString Geno::getGene(void) const { return gen; }
211SString Geno::getName(void) const { return name; }
212char Geno::getFormat(void) const { return format; }
213SString Geno::getComment(void) const { return txt; }
[109]214
215int ModelGenoValidator::testGenoValidity(Geno& g)
216{
[150]217        if (g.getFormat() == '0')
[109]218        {
[150]219                Model mod(g);
220                return mod.isValid();
[109]221        }
[150]222        else
[109]223        {
[150]224                bool converter_missing;
225                Geno f0geno = g.getConverted('0', NULL, &converter_missing);
226                if (converter_missing)
227                        return -1;//no result
228                return f0geno.isValid();
[109]229        }
230}
231
232void Geno::validate()
233{
[150]234        if (isvalid >= 0) return;
235        if (gen.len() == 0) { isvalid = 0; return; }
236        FOREACH(GenoValidator*, v, validators)
237                if ((isvalid = v->testGenoValidity(*this)) >= 0)
238                        return;
239        isvalid = 0;
240        FMprintf("Geno", "validate", FMLV_WARN, "Wrong configuration? No genotype validators defined for genetic format f%c.", format);
[109]241}
242
243bool Geno::isValid(void)
244{
[150]245        if (isvalid<0) validate();
246        return isvalid>0;
[109]247}
248
[150]249Geno Geno::getConverted(char otherformat, MultiMap *m, bool *converter_missing)
[109]250{
[150]251        if (otherformat == getFormat()) { if (converter_missing) *converter_missing = false; return *this; }
[109]252#ifndef NO_GENOCONVMANAGER
[150]253        if (converters)
[109]254        {
[150]255                if ((otherformat == '0') && (!m))
[145]256                {
[150]257                        if (!f0gen)
258                                f0gen = new Geno(converters->convert(*this, otherformat, NULL, converter_missing));
259                        return *f0gen;
260                }
261                else
262                        return converters->convert(*this, otherformat, m, converter_missing);
[109]263        }
[145]264#endif
[150]265        if (converter_missing) *converter_missing = true;
266        return (otherformat == getFormat()) ? *this : Geno(0, 0, 0, "GenConvManager not available");
[109]267}
268
269Geno::~Geno()
270{
[150]271        if (f0gen) delete f0gen;
[109]272}
Note: See TracBrowser for help on using the repository browser.