1 | // This file is a part of the Framsticks GDK library.
|
---|
2 | // Copyright (C) 2002-2011 Szymon Ulatowski. See LICENSE.txt for details.
|
---|
3 | // Refer to http://www.framsticks.com/ for further information.
|
---|
4 |
|
---|
5 | #include "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 "multimap.h"
|
---|
17 |
|
---|
18 | ///////////////////////////////////////////////////////////////////////////
|
---|
19 |
|
---|
20 | GenoConvParam::GenoConvParam(GenoConvManager *g):Param(0),gcm(g)
|
---|
21 | {
|
---|
22 | updatetab();
|
---|
23 | }
|
---|
24 |
|
---|
25 | void GenoConvParam::freetab()
|
---|
26 | {
|
---|
27 | if (tab) free(tab);
|
---|
28 | tab=0;
|
---|
29 | }
|
---|
30 |
|
---|
31 | const char *GenoConvParam::id(int i)
|
---|
32 | {
|
---|
33 | if (i>=gcm->converters.size()) return 0;
|
---|
34 | static char t[20];
|
---|
35 | sprintf(t,"genkonw%d",i);
|
---|
36 | return t;
|
---|
37 | }
|
---|
38 |
|
---|
39 | void GenoConvParam::updatetab()
|
---|
40 | {
|
---|
41 | int i;
|
---|
42 | GenoConverter *gk;
|
---|
43 | ParamEntry *pe;
|
---|
44 | int ile=gcm->converters.size();
|
---|
45 | freetab();
|
---|
46 | tab=(ParamEntry*)calloc(2+ile,sizeof(ParamEntry));
|
---|
47 | tab[0].id="Genetics: Conversions";
|
---|
48 | tab[0].group=1;
|
---|
49 | tab[0].flags=ile;
|
---|
50 | tab[0].name="gkparam:";
|
---|
51 | gcnames.clear();
|
---|
52 | for (i=0,pe=tab+1;gk=(GenoConverter *)gcm->converters(i);pe++,i++)
|
---|
53 | {
|
---|
54 | pe->id="?";
|
---|
55 | pe->group=0;
|
---|
56 | pe->flags=0;
|
---|
57 | std::string descr="f";
|
---|
58 | descr+=gk->in_format;
|
---|
59 | descr+=" -> f";
|
---|
60 | descr+=gk->out_format;
|
---|
61 | descr+=" : ";
|
---|
62 | descr+=gk->name;
|
---|
63 | gcnames.push_back(descr);
|
---|
64 | pe->name=descr.c_str();
|
---|
65 | pe->type="d 0 1";
|
---|
66 | pe->help=gk->info;
|
---|
67 | }
|
---|
68 | pe->id=0;
|
---|
69 | }
|
---|
70 |
|
---|
71 | GenoConvParam::~GenoConvParam()
|
---|
72 | {
|
---|
73 | freetab();
|
---|
74 | }
|
---|
75 |
|
---|
76 | void *GenoConvParam::getTarget(int i)
|
---|
77 | {
|
---|
78 | GenoConverter *gk=(GenoConverter *)gcm->converters(i);
|
---|
79 | return &gk->enabled;
|
---|
80 | }
|
---|
81 |
|
---|
82 | GenoConvManager::GenoConvManager()
|
---|
83 | :param(this)
|
---|
84 | {
|
---|
85 | if (!globalobject) globalobject=this;
|
---|
86 | }
|
---|
87 |
|
---|
88 | GenoConvManager::~GenoConvManager()
|
---|
89 | {
|
---|
90 | GenoConverter *gc;
|
---|
91 | for (converters.start();gc=(GenoConverter*)converters();) delete gc;
|
---|
92 | if (globalobject==this) globalobject=0;
|
---|
93 | }
|
---|
94 |
|
---|
95 | GenoConvManager *GenoConvManager::globalobject=0;
|
---|
96 |
|
---|
97 | void GenoConvManager::addConverter(GenoConverter *gc)
|
---|
98 | {
|
---|
99 | converters+=gc;
|
---|
100 | param.updatetab();
|
---|
101 | }
|
---|
102 | void GenoConvManager::removeConverter(GenoConverter *gc)
|
---|
103 | {
|
---|
104 | converters-=gc;
|
---|
105 | param.updatetab();
|
---|
106 | }
|
---|
107 |
|
---|
108 | GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result,char in,char out,int enabled,char* name)
|
---|
109 | {
|
---|
110 | GenoConverter *gk,*retval=0;
|
---|
111 | int i=0;
|
---|
112 | for (;gk=(GenoConverter*)converters(i);i++)
|
---|
113 | {
|
---|
114 | if ((in!=-1)&&(in!=gk->in_format)) continue;
|
---|
115 | if ((out!=-1)&&(out!=gk->out_format)) continue;
|
---|
116 | if ((enabled!=-1)&&(enabled!=gk->enabled)) continue;
|
---|
117 | if ((name)&&(strcmp(name,gk->name))) continue;
|
---|
118 | if (!retval) {retval=gk; if (!result) break;}
|
---|
119 | if (result) result->append(gk);
|
---|
120 | }
|
---|
121 | return retval;
|
---|
122 | }
|
---|
123 |
|
---|
124 | /// write path into 'path'
|
---|
125 | /// return the last path element (return >= path)
|
---|
126 | /// null -> path not found
|
---|
127 | /// @param mapavailable will receive 1 if conversion map is supported by all converters in path
|
---|
128 | /// (can be NULL if you don't need this information)
|
---|
129 |
|
---|
130 | char *GenoConvManager::getPath(char in,char out,char *path,int maxlen,int *mapavailable)
|
---|
131 | {
|
---|
132 | if (!maxlen) return 0;
|
---|
133 | GenoConverter *gk;
|
---|
134 | int i=0;
|
---|
135 | for (;gk=(GenoConverter*)converters(i);i++)
|
---|
136 | {
|
---|
137 | if ((gk->enabled)&&(gk->in_format == in))
|
---|
138 | {
|
---|
139 | *path=i;
|
---|
140 | if (gk->out_format == out)
|
---|
141 | {
|
---|
142 | if (mapavailable)
|
---|
143 | *mapavailable=gk->mapsupport;
|
---|
144 | return path;
|
---|
145 | }
|
---|
146 | else
|
---|
147 | {
|
---|
148 | int mapavail;
|
---|
149 | char *ret=getPath(gk->out_format,out,path+1,maxlen-1,&mapavail);
|
---|
150 | if (ret)
|
---|
151 | {
|
---|
152 | if (mapavailable)
|
---|
153 | *mapavailable=gk->mapsupport && mapavail;
|
---|
154 | return ret;
|
---|
155 | }
|
---|
156 | }
|
---|
157 | }
|
---|
158 | }
|
---|
159 | return 0;
|
---|
160 | }
|
---|
161 |
|
---|
162 | char *GenoConvManager::getFormatPath(char in,char out,char *path,int maxlen,int *mapavailable)
|
---|
163 | {
|
---|
164 | char *ret=getPath(in,out,path,maxlen,mapavailable);
|
---|
165 | if (ret)
|
---|
166 | {
|
---|
167 | for (char*t=path;t<=ret;t++)
|
---|
168 | *t=((GenoConverter*)converters(*t))->out_format;
|
---|
169 | }
|
---|
170 | return ret;
|
---|
171 | }
|
---|
172 |
|
---|
173 | Geno GenoConvManager::convert(Geno &in,char format,MultiMap *map)
|
---|
174 | {
|
---|
175 | if (in.getFormat()==format) return in;
|
---|
176 | static char path[10];
|
---|
177 | int dep;
|
---|
178 | char *ret;
|
---|
179 | if (in.isInvalid()) { return Geno("",0,"","invalid genotype cannot be converted"); }
|
---|
180 | int mapavail;
|
---|
181 | for (dep=1;dep<sizeof(path);dep++) // sogenannte iteracyjne poglebianie...
|
---|
182 | if (ret=getPath(in.getFormat(),format,path,dep,&mapavail)) break;
|
---|
183 | if (!ret) { return Geno("",0,"","converter not found"); }
|
---|
184 | if (!map) mapavail=0;
|
---|
185 | char *t=path;
|
---|
186 | SString tmp;
|
---|
187 | tmp=in.getGene();
|
---|
188 | MultiMap lastmap,tmpmap;
|
---|
189 | int firstmap=1;
|
---|
190 | for (;t<=ret;t++)
|
---|
191 | {
|
---|
192 | GenoConverter *gk=(GenoConverter*)converters(*t);
|
---|
193 | tmp=gk->convert(tmp,mapavail?&tmpmap:0);
|
---|
194 | if (!tmp.len())
|
---|
195 | {
|
---|
196 | char t[100];
|
---|
197 | sprintf(t,"f%c->f%c conversion failed (%s)",gk->in_format,gk->out_format,gk->name);
|
---|
198 | return Geno(0,0,0,t);
|
---|
199 | }
|
---|
200 | if (mapavail)
|
---|
201 | {
|
---|
202 | if (firstmap)
|
---|
203 | {
|
---|
204 | lastmap=tmpmap;
|
---|
205 | firstmap=0;
|
---|
206 | }
|
---|
207 | else
|
---|
208 | {
|
---|
209 | MultiMap m;
|
---|
210 | m.addCombined(lastmap,tmpmap);
|
---|
211 | lastmap=m;
|
---|
212 | }
|
---|
213 | tmpmap.clear();
|
---|
214 | }
|
---|
215 | }
|
---|
216 | if (map)
|
---|
217 | *map=lastmap;
|
---|
218 | return Geno(tmp, format, in.getName(), in.getComment());
|
---|
219 | }
|
---|
220 |
|
---|
221 | Geno GenoConvManager::globalConvert(Geno &in,char format,MultiMap *map)
|
---|
222 | {
|
---|
223 | if (globalobject) return globalobject->convert(in,format,map);
|
---|
224 | if (format==in.getFormat()) return in;
|
---|
225 | return Geno(0,0,0,"GenConvManager not initialized");
|
---|
226 | }
|
---|
227 |
|
---|
228 | /////////////////////////////////
|
---|