Changeset 150 for cpp/frams/genetics


Ignore:
Timestamp:
03/01/14 22:05:02 (10 years ago)
Author:
sz
Message:

Warn against missing converter, convert() caller can differentiate between conversion failure and missing converter.

Location:
cpp/frams/genetics
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/genetics/geno.cpp

    r145 r150  
    88
    99SListTempl<GenoValidator*> Geno::validators;
    10 GenoConvManager *Geno::converters=NULL;
    11 
    12 void Geno::init(const SString& genstring,char genformat,const SString& genname,const SString& comment)
    13 {
    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)
     10GenoConvManager *Geno::converters = NULL;
     11
     12void Geno::init(const SString& genstring, char genformat, const SString& genname, const SString& comment)
     13{
     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)
    2222        { // unknown format
    23         genformat='1';
    24         if (genstring.charAt(0)=='/')
     23                genformat = '1';
     24                if (genstring.charAt(0) == '/')
    2525                {
    26                 int end;
    27                 SString newcomment;
    28                 switch(genstring.charAt(1))
     26                        int end;
     27                        SString newcomment;
     28                        switch (genstring.charAt(1))
    2929                        {
    3030                        case '/':
    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                                         }
     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                                }
    3838                                else
    39                                         {
    40                                         gencopy=0;
    41                                         mapinshift=genstring.len();
    42                                         }
     39                                {
     40                                        gencopy = 0;
     41                                        mapinshift = genstring.len();
     42                                }
    4343                                break;
    4444                        case '*':
    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                                         }
     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                                }
    5252                                else
    53                                         {
    54                                         gencopy=0;
    55                                         mapinshift=genstring.len();
    56                                         }
     53                                {
     54                                        gencopy = 0;
     55                                        mapinshift = genstring.len();
     56                                }
    5757                                break;
    5858                        }
    59                 if (newcomment.len()>0)
     59                        if (newcomment.len() > 0)
    6060                        {
    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                                 }
     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                                        }
    6969                        }
    7070                }
    7171        }
    7272
    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...?
     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...?
    7979}
    8080
    8181void Geno::freeF0()
    8282{
    83 if (f0gen) {delete f0gen; f0gen=0;}
    84 }
    85 
    86 Geno::Geno(const char *genstring,char genformat,const char *genname,const char *comment)
    87 {
    88 init(SString(genstring),genformat,SString(genname),SString(comment));
    89 }
    90 
    91 Geno::Geno(const SString& genstring,char genformat,const SString& genname,const SString& comment)
    92 {
    93 init(genstring,genformat,genname,comment);
     83        if (f0gen) { delete f0gen; f0gen = 0; }
     84}
     85
     86Geno::Geno(const char *genstring, char genformat, const char *genname, const char *comment)
     87{
     88        init(SString(genstring), genformat, SString(genname), SString(comment));
     89}
     90
     91Geno::Geno(const SString& genstring, char genformat, const SString& genname, const SString& comment)
     92{
     93        init(genstring, genformat, genname, comment);
    9494}
    9595
    9696Geno::Geno(const Geno& src)
    97         :gen(src.gen),name(src.name),format(src.format),txt(src.txt),isvalid(src.isvalid),
    98          f0gen(0),mapinshift(src.mapinshift),mapoutshift(src.mapinshift),
    99          multiline(src.multiline),owner(0)
    100 {f0gen=src.f0gen?new Geno(*src.f0gen):0; refcount=1;}
     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}
    101103
    102104void Geno::operator=(const Geno& src)
    103105{
    104 freeF0();
    105 gen=src.gen;
    106 name=src.name;
    107 format=src.format;
    108 txt=src.txt;
    109 isvalid=src.isvalid;
    110 mapinshift=src.mapinshift;
    111 mapoutshift=src.mapinshift;
    112 multiline=src.multiline;
    113 f0gen=src.f0gen?new Geno(*src.f0gen):0;
    114 owner=0;
     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;
    115117}
    116118
    117119Geno::Geno(const SString& src)
    118120{
    119 init(src,-1,SString::empty(),SString::empty());
    120 }
    121 
    122 void Geno::setGene(const SString& g,char newformat)
    123 {
    124 gen=g;
    125 isvalid=-1;
    126 freeF0();
    127 if (newformat>=0) format=newformat;
     121        init(src, -1, SString::empty(), SString::empty());
     122}
     123
     124void Geno::setGene(const SString& g, char newformat)
     125{
     126        gen = g;
     127        isvalid = -1;
     128        freeF0();
     129        if (newformat >= 0) format = newformat;
    128130}
    129131
    130132void Geno::setString(const SString& g)
    131133{
    132 freeF0();
    133 init(g,-1,SString::empty(),SString::empty());
     134        freeF0();
     135        init(g, -1, SString::empty(), SString::empty());
    134136}
    135137
    136138void Geno::setName(const SString& n)
    137139{
    138 name=n;
     140        name = n;
    139141}
    140142
    141143void Geno::setComment(const SString& c)
    142144{
    143 txt=c;
     145        txt = c;
    144146}
    145147
    146148SString Geno::toString(void) const
    147149{
    148 SString out;
    149 int comment=0;
    150 if ((format!='1')||(comment=(txt.len()||name.len())))
    151         {
    152         if (multiline)
    153                 out+="//";
     150        SString out;
     151        int comment = 0;
     152        if ((format != '1') || (comment = (txt.len() || name.len())))
     153        {
     154                if (multiline)
     155                        out += "//";
     156                else
     157                        out += "/*";
     158                out += format;
     159                if (comment)
     160                {
     161                        if (txt.len()) { out += ";"; out += txt; }
     162                        if (name.len()){ out += ";"; out += name; }
     163                }
     164                if (multiline)
     165                        out += "\n";
     166                else
     167                        out += "*/";
     168        }
     169        out += gen;
     170        return out;
     171}
     172
     173SString Geno::shortString(void) const
     174{
     175        SString out;
     176        if (format != '1')
     177        {
     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 += "*/";
     190        }
     191        out += gen;
     192        return out;
     193}
     194
     195int Geno::mapGenToString(int genpos) const
     196{
     197        if (genpos > gen.len()) return -2;
     198        if (genpos<0) return -1;
     199        return mapinshift + genpos;
     200}
     201
     202int Geno::mapStringToGen(int stringpos) const
     203{
     204        stringpos -= mapinshift;
     205        if (stringpos>gen.len()) return -2;
     206        if (stringpos < 0) return -1;
     207        return stringpos;
     208}
     209
     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; }
     214
     215int ModelGenoValidator::testGenoValidity(Geno& g)
     216{
     217        if (g.getFormat() == '0')
     218        {
     219                Model mod(g);
     220                return mod.isValid();
     221        }
    154222        else
    155                 out+="/*";
    156         out+=format;
    157         if (comment)
     223        {
     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();
     229        }
     230}
     231
     232void Geno::validate()
     233{
     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);
     241}
     242
     243bool Geno::isValid(void)
     244{
     245        if (isvalid<0) validate();
     246        return isvalid>0;
     247}
     248
     249Geno Geno::getConverted(char otherformat, MultiMap *m, bool *converter_missing)
     250{
     251        if (otherformat == getFormat()) { if (converter_missing) *converter_missing = false; return *this; }
     252#ifndef NO_GENOCONVMANAGER
     253        if (converters)
     254        {
     255                if ((otherformat == '0') && (!m))
    158256                {
    159                 if (txt.len()) {out+=";";out+=txt;}
    160                 if (name.len()){out+=";";out+=name;}
     257                        if (!f0gen)
     258                                f0gen = new Geno(converters->convert(*this, otherformat, NULL, converter_missing));
     259                        return *f0gen;
    161260                }
    162         if (multiline)
    163                 out+="\n";
    164         else
    165                 out+="*/";
    166         }
    167 out+=gen;
    168 return out;
    169 }
    170 
    171 SString Geno::shortString(void) const
    172 {
    173 SString out;
    174 if (format!='1')
    175         {
    176         if (multiline)
    177                 out+="//";
    178         else
    179                 out+="/*";
    180         if (format==0)
    181                 out+="invalid";
    182         else
    183                 out+=format;
    184         if (multiline)
    185                 out+="\n";
    186         else
    187                 out+="*/";
    188         }
    189 out+=gen;
    190 return out;
    191 }
    192 
    193 int Geno::mapGenToString(int genpos) const
    194 {
    195 if (genpos>gen.len()) return -2;
    196 if (genpos<0) return -1;
    197 return mapinshift+genpos;
    198 }
    199 
    200 int Geno::mapStringToGen(int stringpos) const
    201 {
    202 stringpos-=mapinshift;
    203 if (stringpos>gen.len()) return -2;
    204 if (stringpos<0) return -1;
    205 return stringpos;
    206 }
    207 
    208 SString Geno::getGene(void) const {return gen;}
    209 SString Geno::getName(void) const {return name;}
    210 char Geno::getFormat(void) const {return format;}
    211 SString Geno::getComment(void) const {return txt;}
    212 
    213 int ModelGenoValidator::testGenoValidity(Geno& g)
    214 {
    215 if (g.getFormat()=='0')
    216         {
    217         Model mod(g);
    218         return mod.isValid();
    219         }
    220 else
    221         {
    222         Geno f0geno=g.getConverted('0');
    223         return f0geno.isValid();
    224         }
    225 }
    226 
    227 void Geno::validate()
    228 {
    229 if (isvalid>=0) return;
    230 if (gen.len()==0) { isvalid=0; return; }
    231 FOREACH(GenoValidator*,v,validators)
    232         if ((isvalid=v->testGenoValidity(*this))>=0)
    233                 break;
    234 }
    235 
    236 bool Geno::isValid(void)
    237 {
    238 if (isvalid<0) validate();
    239 return isvalid>0;
    240 }
    241 
    242 Geno Geno::getConverted(char otherformat,MultiMap *m)
    243 {
    244 if (otherformat==getFormat()) return *this;
    245 #ifndef NO_GENOCONVMANAGER
    246 if (converters)
    247         {
    248         if ((otherformat=='0')&&(!m))
    249                 {
    250                 if (!f0gen)
    251                         f0gen=new Geno(converters->convert(*this,otherformat));
    252                 return *f0gen;
    253         }
    254         else
    255                 return converters->convert(*this,otherformat,m);
     261                else
     262                        return converters->convert(*this, otherformat, m, converter_missing);
    256263        }
    257264#endif
    258 return (otherformat==getFormat())?*this:Geno(0,0,0,"GenConvManager not available");
     265        if (converter_missing) *converter_missing = true;
     266        return (otherformat == getFormat()) ? *this : Geno(0, 0, 0, "GenConvManager not available");
    259267}
    260268
    261269Geno::~Geno()
    262270{
    263 if (f0gen) delete f0gen;
    264 }
     271        if (f0gen) delete f0gen;
     272}
  • cpp/frams/genetics/geno.h

    r145 r150  
    1515class GenoValidator
    1616{
    17   public:
    18 virtual int testGenoValidity(Geno& g)=0;/// -1=no information  0=invalid  1=valid
     17public:
     18        virtual int testGenoValidity(Geno& g) = 0;/// -1=no information  0=invalid  1=valid
    1919};
    2020
    21 /// basic GenoValidator that works by building a Model from any Geno (by converting to f0)
    22 /// validation fails when the model can't be built or the genotype can't be converted
    23 class ModelGenoValidator: public GenoValidator
     21/// Basic GenoValidator that works by building a Model from any Geno (by converting to f0).
     22/// Validation fails when the model can't be built or the genotype can't be converted.
     23class ModelGenoValidator : public GenoValidator
    2424{
    2525public:
     
    2828
    2929/// basic information about a single genotype.
    30 class Geno: public DestrBase
     30class Geno : public DestrBase
    3131{
    32 friend class Simulator;//needs to access validators directly
    33 SString gen;
    34 SString name;
    35 char format;
    36 SString txt;
    37 int isvalid; ///< <0 -> unknown   >=0 -> value for "isValid"
     32        friend class Simulator;//needs to access validators directly
     33        SString gen;
     34        SString name;
     35        char format;
     36        SString txt;
     37        int isvalid; ///< <0 -> unknown   >=0 -> value for "isValid"
    3838
    39 Geno *f0gen;
     39        Geno *f0gen;
    4040
    41 int mapinshift; /// # of characters in the initial comment
    42 int mapoutshift; /// # of characters in the output comment
    43 int multiline;
     41        int mapinshift; /// number of characters in the initial comment
     42        int mapoutshift; /// number of characters in the output comment
     43        int multiline;
    4444
    45 void init(const SString& genstring,char genformat,const SString& genname,const SString& comment);
    46 void validate(void);
     45        void init(const SString& genstring, char genformat, const SString& genname, const SString& comment);
     46        void validate(void);
    4747
    48 void freeF0();
     48        void freeF0();
    4949
    50 bool isInvalid() {return isvalid==0;}
     50        bool isInvalid() { return isvalid == 0; }
    5151
    52 friend class Model;
    53 friend class GenoConvManager;
    54        
     52        friend class Model;
     53        friend class GenoConvManager;
     54
    5555public:
    56 /// create a genotype object from primitives
    57 /// @param genstring pure genotype, without any comments
    58 /// @param genformat genotype format
    59 /// @param comment information about genotype (for genetic operators and "history")
    60 Geno(const char *genstring=0,char genformat=-1,const char *genname=0,const char *comment=0);
     56        /// create a genotype object from primitives
     57        /// @param genstring pure genotype, without any comments
     58        /// @param genformat genotype format
     59        /// @param comment information about genotype (for genetic operators and "history")
     60        Geno(const char *genstring = 0, char genformat = -1, const char *genname = 0, const char *comment = 0);
    6161
    62 /// create a genotype object from primitives
    63 /// @param genstring pure genotype, wihtout any comments
    64 /// @param genformat genotype format
    65 /// @param name genotype name, new name will generated if needed
    66 /// @param comment information about genotype (for genetic operators and "history")
    67 Geno(const SString& genstring,char genformat,const SString& genname,const SString& comment);
     62        /// create a genotype object from primitives
     63        /// @param genstring pure genotype, wihtout any comments
     64        /// @param genformat genotype format
     65        /// @param name genotype name, new name will generated if needed
     66        /// @param comment information about genotype (for genetic operators and "history")
     67        Geno(const SString& genstring, char genformat, const SString& genname, const SString& comment);
    6868
    69 /// create object from full string, containing optional format and comment information
    70 Geno(const SString & fullstring);
     69        /// create object from full string, containing optional format and comment information
     70        Geno(const SString & fullstring);
    7171
    72 /// clone
    73 Geno(const Geno& src);
     72        /// clone
     73        Geno(const Geno& src);
    7474
    75 void operator=(const Geno& src);
     75        void operator=(const Geno& src);
    7676
    77 ~Geno();
     77        ~Geno();
    7878
    79 void setValid(int v) {isvalid=v;}
    80 int getValid() {return isvalid;}
     79        void setValid(int v) { isvalid = v; }
     80        int getValid() { return isvalid; }
    8181
    82 /// return string representation, with format comment at the beginning
    83 SString toString(void) const;
    84 SString shortString(void) const;
     82        /// return string representation, with format comment at the beginning
     83        SString toString(void) const;
     84        SString shortString(void) const;
    8585
    86 void setString(const SString& genewithcomments);
     86        void setString(const SString& genewithcomments);
    8787
    88 /** @param newformat=-1 -> don't change */
    89 void setGene(const SString& g, char newformat=-1);
    90 SString getGene(void) const;
     88        /** @param newformat=-1 -> don't change */
     89        void setGene(const SString& g, char newformat = -1);
     90        SString getGene(void) const;
    9191
    92 SString getName(void) const;
    93 void setName(const SString&);
    94 char getFormat(void) const;
     92        SString getName(void) const;
     93        void setName(const SString&);
     94        char getFormat(void) const;
    9595
    96 SString getComment(void) const;
    97 void setComment(const SString&);
     96        SString getComment(void) const;
     97        void setComment(const SString&);
    9898
    99 /// invalid genotype cannot be used to build a creature
    100 bool isValid(void);
     99        /// invalid genotype cannot be used to build a creature
     100        bool isValid(void);
    101101
    102 /// make converted version of the genotype.
    103 Geno getConverted(char otherformat,MultiMap *m=0);
     102        /// make converted version of the genotype.
     103        /// @param converter_missing optional output parameter (ignored when NULL). Receives true if the conversion fails because of the lack of appropriate converter(s) (the returned Geno is always invalid in this case). Receives false if the genotype was converted by a converter or a converter chain (the returned Geno can be valid or invalid, depending on the converter's decision).
     104        Geno getConverted(char otherformat, MultiMap *m = 0, bool *converter_missing = NULL);
    104105
    105 /// @return -1 = before first char in the string
    106 /// @return -2 = after last char in the string
    107 int mapGenToString(int genpos) const;
    108 /// @return -1 = before first char in the genotype
    109 /// @return -2 = after last char in the genotype
    110 int mapStringToGen(int stringpos) const;
     106        /// @return -1 = before first char in the string
     107        /// @return -2 = after last char in the string
     108        int mapGenToString(int genpos) const;
     109        /// @return -1 = before first char in the genotype
     110        /// @return -2 = after last char in the genotype
     111        int mapStringToGen(int stringpos) const;
    111112
    112 int operator==(const Geno &g) {return (format==g.format)&&(gen==g.gen);}
     113        int operator==(const Geno &g) { return (format == g.format) && (gen == g.gen); }
    113114
    114 void* owner;
     115        void* owner;
    115116
    116 // managing global Geno-related objects (used for validation and conversion)
    117 static void addValidator(GenoValidator* gv) {validators+=gv;}
    118 static void removeValidator(GenoValidator* gv) {validators-=gv;}
    119 static void useConverters(GenoConvManager& gcm) {converters=&gcm;}
    120 static GenoConvManager &getConverters() {return *converters;}
    121   protected:
    122 static GenoConvManager *converters;
    123 static SListTempl<GenoValidator*> validators;
     117        // managing global Geno-related objects (used for validation and conversion)
     118        static void addValidator(GenoValidator* gv) { validators += gv; }
     119        static void removeValidator(GenoValidator* gv) { validators -= gv; }
     120        static void useConverters(GenoConvManager& gcm) { converters = &gcm; }
     121        static GenoConvManager &getConverters() { return *converters; }
     122protected:
     123        static GenoConvManager *converters;
     124        static SListTempl<GenoValidator*> validators;
    124125};
    125126
  • cpp/frams/genetics/genoconv.cpp

    r145 r150  
    1818///////////////////////////////////////////////////////////////////////////
    1919
    20 GenoConvParam::GenoConvParam(GenoConvManager *g):Param(0),gcm(g)
    21 {
    22 updatetab();
     20GenoConvParam::GenoConvParam(GenoConvManager *g) :Param(0), gcm(g)
     21{
     22        updatetab();
    2323}
    2424
    2525void GenoConvParam::freetab()
    2626{
    27 if (tab) free(tab);
    28 tab=0;
     27        if (tab) free(tab);
     28        tab = 0;
    2929}
    3030
    3131const char *GenoConvParam::id(int i)
    3232{
    33 if (i>=gcm->converters.size()) return 0;
    34 sprintf(tmp_id,"genkonw%d",i);
    35 return tmp_id;
     33        if (i >= gcm->converters.size()) return 0;
     34        sprintf(tmp_id, "genkonw%d", i);
     35        return tmp_id;
    3636}
    3737
    3838void GenoConvParam::updatetab()
    3939{
    40 int i;
    41 GenoConverter *gk;
    42 ParamEntry *pe;
    43 int ile=gcm->converters.size();
    44 freetab();
    45 tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
    46 tab[0].id="Genetics: Conversions";
    47 tab[0].group=1;
    48 tab[0].flags=(short)ile;
    49 tab[0].name="gkparam:";
    50 gcnames.clear();
    51 for (i=0,pe=tab+1;gk=(GenoConverter *)gcm->converters(i);pe++,i++)
    52         {
    53         pe->id="?";
    54         pe->group=0;
    55         pe->flags=0;
    56         std::string descr="f";
    57         descr+=gk->in_format;
    58         descr+=" -> f";
    59         descr+=gk->out_format;
    60         descr+=" : ";
    61         descr+=gk->name;
    62         gcnames.push_back(descr);
    63         pe->name=descr.c_str();
    64         pe->type="d 0 1";
    65         pe->help=gk->info;
    66         }
    67 pe->id=0;
     40        int i;
     41        GenoConverter *gk;
     42        ParamEntry *pe;
     43        int ile = gcm->converters.size();
     44        freetab();
     45        tab = (ParamEntry*)calloc(2 + ile, sizeof(ParamEntry));
     46        tab[0].id = "Genetics: Conversions";
     47        tab[0].group = 1;
     48        tab[0].flags = (short)ile;
     49        tab[0].name = "gkparam:";
     50        gcnames.clear();
     51        for (i = 0, pe = tab + 1; gk = (GenoConverter *)gcm->converters(i); pe++, i++)
     52        {
     53                pe->id = "?";
     54                pe->group = 0;
     55                pe->flags = 0;
     56                std::string descr = "f";
     57                descr += gk->in_format;
     58                descr += " -> f";
     59                descr += gk->out_format;
     60                descr += " : ";
     61                descr += gk->name;
     62                gcnames.push_back(descr);
     63                pe->name = descr.c_str();
     64                pe->type = "d 0 1";
     65                pe->help = gk->info;
     66        }
     67        pe->id = 0;
    6868}
    6969
    7070GenoConvParam::~GenoConvParam()
    7171{
    72 freetab();
     72        freetab();
    7373}
    7474
    7575void *GenoConvParam::getTarget(int i)
    7676{
    77 GenoConverter *gk=(GenoConverter *)gcm->converters(i);
    78 return &gk->enabled;
     77        GenoConverter *gk = (GenoConverter *)gcm->converters(i);
     78        return &gk->enabled;
    7979}
    8080
    8181GenoConvManager::GenoConvManager()
    82         :param(this)
     82:param(this)
    8383{
    8484}
     
    8686GenoConvManager::~GenoConvManager()
    8787{
    88 GenoConverter *gc;
    89 for (converters.start();gc=(GenoConverter*)converters();) delete gc;
     88        FOREACH(GenoConverter*, gc, converters) delete gc;
    9089}
    9190
    9291void GenoConvManager::addConverter(GenoConverter *gc)
    9392{
    94 converters+=gc;
    95 param.updatetab();
     93        converters += gc;
     94        param.updatetab();
    9695}
    9796void GenoConvManager::removeConverter(GenoConverter *gc)
    9897{
    99 converters-=gc;
    100 param.updatetab();
    101 }
    102 
    103 GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result,char in,char out,int enabled,char* name)
    104 {
    105 GenoConverter *gk,*retval=0;
    106 int i=0;
    107 for (;gk=(GenoConverter*)converters(i);i++)
    108         {
    109         if ((in!=-1)&&(in!=gk->in_format)) continue;
    110         if ((out!=-1)&&(out!=gk->out_format)) continue;
    111         if ((enabled!=-1)&&(enabled!=gk->enabled)) continue;
    112         if ((name)&&(strcmp(name,gk->name))) continue;
    113         if (!retval) {retval=gk; if (!result) break;}
    114         if (result) result->append(gk);
    115         }
    116 return retval;
    117 }
    118 
    119 /// write path into 'path'
     98        converters -= gc;
     99        param.updatetab();
     100}
     101
     102GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result, char in, char out, int enabled, char* name)
     103{
     104        GenoConverter *gk, *retval = 0;
     105        int i = 0;
     106        for (; gk = (GenoConverter*)converters(i); i++)
     107        {
     108                if ((in != -1) && (in != gk->in_format)) continue;
     109                if ((out != -1) && (out != gk->out_format)) continue;
     110                if ((enabled != -1) && (enabled != gk->enabled)) continue;
     111                if ((name) && (strcmp(name, gk->name))) continue;
     112                if (!retval) { retval = gk; if (!result) break; }
     113                if (result) result->append(gk);
     114        }
     115        return retval;
     116}
     117
     118/// Writes path into 'path'.
    120119/// return the last path element (return >= path)
    121120/// null -> path not found
     
    123122/// (can be NULL if you don't need this information)
    124123
    125 char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
    126 {
    127 if (!maxlen) return 0;
    128 GenoConverter *gk;
    129 int i=0;
    130 for (;gk=(GenoConverter*)converters(i);i++)
    131         {
    132         if ((gk->enabled)&&(gk->in_format == in))
     124char *GenoConvManager::getPath(char in, char out, char *path, int maxlen, int *mapavailable)
     125{
     126        if (!maxlen) return 0;
     127        GenoConverter *gk;
     128        int i = 0;
     129        for (; gk = (GenoConverter*)converters(i); i++)
     130        {
     131                if ((gk->enabled) && (gk->in_format == in))
    133132                {
    134                 *path=(char)i;
    135                 if (gk->out_format == out)
    136                         {
    137                         if (mapavailable)
    138                                 *mapavailable=gk->mapsupport;
    139                         return path;
    140                         }
    141                 else
    142                         {
    143                         int mapavail;
    144                         char *ret=getPath(gk->out_format,out,path+1,maxlen-1,&mapavail);
    145                         if (ret)
     133                        *path = (char)i;
     134                        if (gk->out_format == out)
     135                        {
     136                                if (mapavailable)
     137                                        *mapavailable = gk->mapsupport;
     138                                return path;
     139                        }
     140                        else
     141                        {
     142                                int mapavail;
     143                                char *ret = getPath(gk->out_format, out, path + 1, maxlen - 1, &mapavail);
     144                                if (ret)
    146145                                {
    147                                 if (mapavailable)
    148                                         *mapavailable=gk->mapsupport && mapavail;
    149                                 return ret;
     146                                        if (mapavailable)
     147                                                *mapavailable = gk->mapsupport && mapavail;
     148                                        return ret;
    150149                                }
    151150                        }
    152151                }
    153152        }
    154 return 0;
    155 }
    156 
    157 char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
    158 {
    159 char *ret=getPath(in,out,path,maxlen,mapavailable);
    160 if (ret)
    161         {
    162         for (char*t=path;t<=ret;t++)
    163                 *t=((GenoConverter*)converters(*t))->out_format;
    164         }
    165 return ret;
    166 }
    167 
    168 Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
    169 {
    170 if (in.getFormat()==format) return in;
    171 char path[10];
    172 int dep;
    173 char *ret;
    174 if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
    175 int mapavail;
    176 for (dep=1;dep<(int)sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
    177         if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
    178 if (!ret) { return Geno("",0,"","converter not found"); }
    179 if (!map) mapavail=0;
    180 char *t=path;
    181 SString tmp;
    182 tmp=in.getGene();
    183 MultiMap lastmap,tmpmap;
    184 int firstmap=1;
    185 for (;t<=ret;t++)
    186         {
    187         GenoConverter *gk=(GenoConverter*)converters(*t);
    188         tmp=gk->convert(tmp,mapavail?&tmpmap:0);
    189         if (!tmp.len())
     153        return 0;
     154}
     155
     156char *GenoConvManager::getFormatPath(char in, char out, char *path, int maxlen, int *mapavailable)
     157{
     158        char *ret = getPath(in, out, path, maxlen, mapavailable);
     159        if (ret)
     160        {
     161                for (char*t = path; t <= ret; t++)
     162                        *t = ((GenoConverter*)converters(*t))->out_format;
     163        }
     164        return ret;
     165}
     166
     167Geno GenoConvManager::convert(Geno &in, char format, MultiMap *map, bool *converter_missing)
     168{
     169        if (in.getFormat() == format) { if (converter_missing) *converter_missing = false; return in; }
     170        char path[10];
     171        int dep;
     172        char *ret;
     173        if (in.isInvalid()) { if (converter_missing) *converter_missing = false; return Geno("", 0, "", "invalid genotype cannot be converted"); }
     174        int mapavail;
     175        for (dep = 1; dep < (int)sizeof(path); dep++) //iterative deepening
     176                if (ret = getPath(in.getFormat(), format, path, dep, &mapavail)) break;
     177        if (!ret) { if (converter_missing) *converter_missing = true; return Geno("", 0, "", "converter not found"); }
     178        if (converter_missing) *converter_missing = false;
     179        if (!map) mapavail = 0;
     180        char *t = path;
     181        SString tmp;
     182        tmp = in.getGene();
     183        MultiMap lastmap, tmpmap;
     184        int firstmap = 1;
     185        for (; t <= ret; t++)
     186        {
     187                GenoConverter *gk = (GenoConverter*)converters(*t);
     188                tmp = gk->convert(tmp, mapavail ? &tmpmap : 0);
     189                if (!tmp.len())
    190190                {
    191                 char t[100];
    192                 sprintf(t,"f%c->f%c conversion failed (%s)",gk->in_format,gk->out_format,gk->name);
    193                 return Geno(0,0,0,t);
     191                        char t[100];
     192                        sprintf(t, "f%c->f%c conversion failed (%s)", gk->in_format, gk->out_format, gk->name);
     193                        return Geno(0, 0, 0, t);
    194194                }
    195         if (mapavail)
     195                if (mapavail)
    196196                {
    197                 if (firstmap)
    198                         {
    199                         lastmap=tmpmap;
    200                         firstmap=0;
    201                         }
    202                 else
    203                         {
    204                         MultiMap m;
    205                         m.addCombined(lastmap,tmpmap);
    206                         lastmap=m;
    207                         }
    208                 tmpmap.clear();
     197                        if (firstmap)
     198                        {
     199                                lastmap = tmpmap;
     200                                firstmap = 0;
     201                        }
     202                        else
     203                        {
     204                                MultiMap m;
     205                                m.addCombined(lastmap, tmpmap);
     206                                lastmap = m;
     207                        }
     208                        tmpmap.clear();
    209209                }
    210210        }
    211 if (map)
    212         *map=lastmap;
    213 return Geno(tmp, format, in.getName(), in.getComment());
    214 }
     211        if (map)
     212                *map = lastmap;
     213        return Geno(tmp, format, in.getName(), in.getComment());
     214}
  • cpp/frams/genetics/genoconv.h

    r145 r150  
    1717class GenoConvManager;
    1818
    19 class GenoConvParam: public Param
     19class GenoConvParam : public Param
    2020{
    21 GenoConvManager *gcm;
    22 std::vector<std::string> gcnames;
    23 char tmp_id[20];
    24 void freetab();
     21        GenoConvManager *gcm;
     22        std::vector<std::string> gcnames;
     23        char tmp_id[20];
     24        void freetab();
    2525public:
    26 GenoConvParam(GenoConvManager *g);
    27 ~GenoConvParam();
    28 void *getTarget(int);
    29 const char* id(int i);
    30 void updatetab();
     26        GenoConvParam(GenoConvManager *g);
     27        ~GenoConvParam();
     28        void *getTarget(int);
     29        const char* id(int i);
     30        void updatetab();
    3131};
    3232
     
    4242{
    4343public:
    44 const char *name;       //< converter name (short)
    45 char in_format,         //< input format, eg. '1'
    46         out_format;     //< output format, eg. '0'
    47 const char *info;       //< detailed info about converter, format or copyright
    48 long enabled;   //< don't touch this! (used by configuration module)
    49 long mapsupport; //< set to 1 if your converter supports genotype mapping
     44        const char *name;       //< converter name (short)
     45        char in_format,         //< input format, eg. '1'
     46                out_format;     //< output format, eg. '0'
     47        const char *info;       //< detailed info about converter, format or copyright
     48        long enabled;   //< don't touch this! (used by configuration module)
     49        long mapsupport; //< set to 1 if your converter supports genotype mapping
    5050
    51 /// You have to reimplement this method.
    52 /// If your converter cannot do its job, return empty string
    53 /// (return SString();), any other return value is assumed
    54 /// to be output genotype.
    55 /// @param map if not null, mapping informaton is requested, converter should add conversion map to this object
    56 virtual SString convert(SString &i,MultiMap *map) {return SString();}
     51        /// You have to reimplement this method.
     52        /// If your converter cannot do its job, return empty string
     53        /// (return SString();), any other return value is assumed
     54        /// to be output genotype.
     55        /// @param map if not null, mapping informaton is requested, converter should add conversion map to this object
     56        virtual SString convert(SString &i, MultiMap *map) { return SString(); }
    5757
    58 virtual ~GenoConverter() {}
    59 /// Don't forget to set public fields in your constructor
    60 GenoConverter():name(""),in_format(-1),out_format('0'),info(""),enabled(1),mapsupport(0) {}
     58        virtual ~GenoConverter() {}
     59        /// Don't forget to set public fields in your constructor
     60        GenoConverter() :name(""), in_format(-1), out_format('0'), info(""), enabled(1), mapsupport(0) {}
    6161};
    6262
     
    7171class GenoConvManager
    7272{
    73 friend class GenoConvParam;
    74 SList converters;
     73        friend class GenoConvParam;
     74        SList converters;
    7575public:
    76 GenoConvManager();
    77 ~GenoConvManager();
    78 class GenoConvParam param;
    79 /// make a genotype in other format. genotype will be invalid
    80 /// if GenoConvManager cannot convert it.
    81 Geno convert(Geno &in,char format,MultiMap *map=0);
    82 /// register GenoConverter, the added object will be automatically deleted when GenoConvManager is destructed (call removeConverter() if this is not desirable)
    83 void addConverter(GenoConverter *conv);
    84 /// unregister GenoConverter
    85 void removeConverter(GenoConverter *conv);
     76        GenoConvManager();
     77        ~GenoConvManager();
     78        class GenoConvParam param;
     79        /// make a genotype in other format. genotype will be invalid
     80        /// if GenoConvManager cannot convert it.
     81        Geno convert(Geno &in, char format, MultiMap *map = 0, bool *converter_missing = NULL);
     82        /// register GenoConverter, the added object will be automatically deleted when GenoConvManager is destructed (call removeConverter() if this is not desirable)
     83        void addConverter(GenoConverter *conv);
     84        /// unregister GenoConverter
     85        void removeConverter(GenoConverter *conv);
    8686
    87 char *getPath(char in,char out,char *path,int maxlen,int *mapavailable=0);
    88 char *getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable=0);
    89 /// returns the list of converters meeting the specified criteria
    90 /// pass result=0 if you only need one result (by return value)
    91 /// default criteria values mean "don't care", pass anything else to narrow your search
    92 GenoConverter *findConverters(SListTempl<GenoConverter*>* result=0,char in=-1,char out=-1,int enabled=-1,char* name=0);
     87        char *getPath(char in, char out, char *path, int maxlen, int *mapavailable = 0);
     88        char *getFormatPath(char in, char out, char *path, int maxlen, int *mapavailable = 0);
     89        /// returns the list of converters meeting the specified criteria
     90        /// pass result=0 if you only need one result (by return value)
     91        /// default criteria values mean "don't care", pass anything else to narrow your search
     92        GenoConverter *findConverters(SListTempl<GenoConverter*>* result = 0, char in = -1, char out = -1, int enabled = -1, char* name = 0);
    9393};
    9494
    9595#endif
    96 
    97 
Note: See TracChangeset for help on using the changeset viewer.