source: cpp/frams/genetics/genoconv.cpp @ 145

Last change on this file since 145 was 145, checked in by sz, 8 years ago

Genetics reorganization (affects ALL applications!):

  • Converters/Validators? are now configured/initialized in a more verbose but also less confusing way
  • At the same time, the PreconfiguredGenetics? object will help you avoid the increased complexity by creating the ready-to-use environment that is sufficient in 99% of cases (see the demos)
  • Format F genetics updated (work in progress)
  • Property svn:eol-style set to native
File size: 4.5 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include <common/nonstd.h>
6
7#include <stdlib.h>
8#include <math.h>
9#include <stdio.h>
10#include <string.h>
11#include <ctype.h>
12#include <time.h>
13#include <errno.h>
14
15#include "genoconv.h"
16#include <frams/util/multimap.h>
17
18///////////////////////////////////////////////////////////////////////////
19
20GenoConvParam::GenoConvParam(GenoConvManager *g):Param(0),gcm(g)
21{
22updatetab();
23}
24
25void GenoConvParam::freetab()
26{
27if (tab) free(tab);
28tab=0;
29}
30
31const char *GenoConvParam::id(int i)
32{
33if (i>=gcm->converters.size()) return 0;
34sprintf(tmp_id,"genkonw%d",i);
35return tmp_id;
36}
37
38void GenoConvParam::updatetab()
39{
40int i;
41GenoConverter *gk;
42ParamEntry *pe;
43int ile=gcm->converters.size();
44freetab();
45tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
46tab[0].id="Genetics: Conversions";
47tab[0].group=1;
48tab[0].flags=(short)ile;
49tab[0].name="gkparam:";
50gcnames.clear();
51for (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        }
67pe->id=0;
68}
69
70GenoConvParam::~GenoConvParam()
71{
72freetab();
73}
74
75void *GenoConvParam::getTarget(int i)
76{
77GenoConverter *gk=(GenoConverter *)gcm->converters(i);
78return &gk->enabled;
79}
80
81GenoConvManager::GenoConvManager()
82        :param(this)
83{
84}
85
86GenoConvManager::~GenoConvManager()
87{
88GenoConverter *gc;
89for (converters.start();gc=(GenoConverter*)converters();) delete gc;
90}
91
92void GenoConvManager::addConverter(GenoConverter *gc)
93{
94converters+=gc;
95param.updatetab();
96}
97void GenoConvManager::removeConverter(GenoConverter *gc)
98{
99converters-=gc;
100param.updatetab();
101}
102
103GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result,char in,char out,int enabled,char* name)
104{
105GenoConverter *gk,*retval=0;
106int i=0;
107for (;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        }
116return retval;
117}
118
119/// write path into 'path'
120/// return the last path element (return >= path)
121/// null -> path not found
122/// @param mapavailable will receive 1 if conversion map is supported by all converters in path
123/// (can be NULL if you don't need this information)
124
125char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
126{
127if (!maxlen) return 0;
128GenoConverter *gk;
129int i=0;
130for (;gk=(GenoConverter*)converters(i);i++)
131        {
132        if ((gk->enabled)&&(gk->in_format == in))
133                {
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)
146                                {
147                                if (mapavailable)
148                                        *mapavailable=gk->mapsupport && mapavail;
149                                return ret;
150                                }
151                        }
152                }
153        }
154return 0;
155}
156
157char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
158{
159char *ret=getPath(in,out,path,maxlen,mapavailable);
160if (ret)
161        {
162        for (char*t=path;t<=ret;t++)
163                *t=((GenoConverter*)converters(*t))->out_format;
164        }
165return ret;
166}
167
168Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
169{
170if (in.getFormat()==format) return in;
171char path[10];
172int dep;
173char *ret;
174if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
175int mapavail;
176for (dep=1;dep<(int)sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
177        if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
178if (!ret) { return Geno("",0,"","converter not found"); }
179if (!map) mapavail=0;
180char *t=path;
181SString tmp;
182tmp=in.getGene();
183MultiMap lastmap,tmpmap;
184int firstmap=1;
185for (;t<=ret;t++)
186        {
187        GenoConverter *gk=(GenoConverter*)converters(*t);
188        tmp=gk->convert(tmp,mapavail?&tmpmap:0);
189        if (!tmp.len())
190                {
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);
194                }
195        if (mapavail)
196                {
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();
209                }
210        }
211if (map)
212        *map=lastmap;
213return Geno(tmp, format, in.getName(), in.getComment());
214}
Note: See TracBrowser for help on using the repository browser.