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

Last change on this file since 912 was 841, checked in by Maciej Komosinski, 6 years ago

Updated #includes after splitting stl-util into util-stl, util-file and util-string

  • Property svn:eol-style set to native
File size: 5.3 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[732]2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]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>
[841]17#include <common/util-string.h>
[109]18
19///////////////////////////////////////////////////////////////////////////
20
[150]21GenoConvParam::GenoConvParam(GenoConvManager *g) :Param(0), gcm(g)
[109]22{
[150]23        updatetab();
[109]24}
25
26void GenoConvParam::freetab()
27{
[150]28        if (tab) free(tab);
29        tab = 0;
[109]30}
31
32const char *GenoConvParam::id(int i)
33{
[150]34        if (i >= gcm->converters.size()) return 0;
35        sprintf(tmp_id, "genkonw%d", i);
36        return tmp_id;
[109]37}
38
39void GenoConvParam::updatetab()
40{
[150]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;
[483]49        tab[0].flags = (paInt)ile;
[150]50        tab[0].name = "gkparam:";
51        gcnames.clear();
[783]52        gcnames.reserve(gcm->converters.size()); //avoid reallocations in the loop below, since we externally store pointers to objects saved in this vector
[150]53        for (i = 0, pe = tab + 1; gk = (GenoConverter *)gcm->converters(i); pe++, i++)
[109]54        {
[150]55                pe->id = "?";
56                pe->group = 0;
57                pe->flags = 0;
58                std::string descr = "f";
59                descr += gk->in_format;
[783]60                descr += " --> f";
[150]61                descr += gk->out_format;
[783]62                descr += "  :  ";
[150]63                descr += gk->name;
64                gcnames.push_back(descr);
[783]65                pe->name = gcnames.back().c_str(); //externally store a pointer to the object just saved in the vector
[150]66                pe->type = "d 0 1";
[109]67        }
[150]68        pe->id = 0;
[109]69}
70
71GenoConvParam::~GenoConvParam()
72{
[150]73        freetab();
[109]74}
75
76void *GenoConvParam::getTarget(int i)
77{
[150]78        GenoConverter *gk = (GenoConverter *)gcm->converters(i);
79        return &gk->enabled;
[109]80}
81
82GenoConvManager::GenoConvManager()
[732]83        :param(this)
[109]84{
85}
86
87GenoConvManager::~GenoConvManager()
88{
[150]89        FOREACH(GenoConverter*, gc, converters) delete gc;
[109]90}
91
92void GenoConvManager::addConverter(GenoConverter *gc)
93{
[150]94        converters += gc;
95        param.updatetab();
[109]96}
97void GenoConvManager::removeConverter(GenoConverter *gc)
98{
[150]99        converters -= gc;
100        param.updatetab();
[109]101}
102
[150]103GenoConverter *GenoConvManager::findConverters(SListTempl<GenoConverter*>* result, char in, char out, int enabled, char* name)
[109]104{
[150]105        GenoConverter *gk, *retval = 0;
106        int i = 0;
107        for (; gk = (GenoConverter*)converters(i); i++)
[109]108        {
[150]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);
[109]115        }
[150]116        return retval;
[109]117}
118
[150]119/// Writes path into 'path'.
[109]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
[150]125char *GenoConvManager::getPath(char in, char out, char *path, int maxlen, int *mapavailable)
[109]126{
[150]127        if (!maxlen) return 0;
128        GenoConverter *gk;
129        int i = 0;
130        for (; gk = (GenoConverter*)converters(i); i++)
[109]131        {
[150]132                if ((gk->enabled) && (gk->in_format == in))
[109]133                {
[150]134                        *path = (char)i;
135                        if (gk->out_format == out)
[109]136                        {
[150]137                                if (mapavailable)
138                                        *mapavailable = gk->mapsupport;
139                                return path;
[109]140                        }
[150]141                        else
[109]142                        {
[150]143                                int mapavail;
144                                char *ret = getPath(gk->out_format, out, path + 1, maxlen - 1, &mapavail);
145                                if (ret)
[109]146                                {
[150]147                                        if (mapavailable)
148                                                *mapavailable = gk->mapsupport && mapavail;
149                                        return ret;
[109]150                                }
151                        }
152                }
153        }
[150]154        return 0;
[109]155}
156
[150]157char *GenoConvManager::getFormatPath(char in, char out, char *path, int maxlen, int *mapavailable)
[109]158{
[150]159        char *ret = getPath(in, out, path, maxlen, mapavailable);
160        if (ret)
[109]161        {
[150]162                for (char*t = path; t <= ret; t++)
163                        *t = ((GenoConverter*)converters(*t))->out_format;
[109]164        }
[150]165        return ret;
[109]166}
167
[732]168Geno GenoConvManager::convert(Geno &in, char format, MultiMap *map, bool using_checkpoints, bool *converter_missing)
[109]169{
[150]170        if (in.getFormat() == format) { if (converter_missing) *converter_missing = false; return in; }
171        char path[10];
172        int dep;
173        char *ret;
174        if (in.isInvalid()) { if (converter_missing) *converter_missing = false; return Geno("", 0, "", "invalid genotype cannot be converted"); }
175        int mapavail;
176        for (dep = 1; dep < (int)sizeof(path); dep++) //iterative deepening
177                if (ret = getPath(in.getFormat(), format, path, dep, &mapavail)) break;
178        if (!ret) { if (converter_missing) *converter_missing = true; return Geno("", 0, "", "converter not found"); }
179        if (converter_missing) *converter_missing = false;
180        if (!map) mapavail = 0;
181        char *t = path;
182        SString tmp;
[534]183        tmp = in.getGenes();
[150]184        MultiMap lastmap, tmpmap;
185        int firstmap = 1;
186        for (; t <= ret; t++)
[109]187        {
[150]188                GenoConverter *gk = (GenoConverter*)converters(*t);
[732]189                tmp = gk->convert(tmp, mapavail ? &tmpmap : 0, using_checkpoints);
[150]190                if (!tmp.len())
[109]191                {
[732]192                        string t = ssprintf("f%c->f%c conversion failed (%s)", gk->in_format, gk->out_format, gk->name);
[180]193                        return Geno(0, 0, 0, t.c_str());
[109]194                }
[150]195                if (mapavail)
[109]196                {
[150]197                        if (firstmap)
[109]198                        {
[150]199                                lastmap = tmpmap;
200                                firstmap = 0;
[109]201                        }
[150]202                        else
[109]203                        {
[150]204                                MultiMap m;
205                                m.addCombined(lastmap, tmpmap);
206                                lastmap = m;
[109]207                        }
[150]208                        tmpmap.clear();
[109]209                }
210        }
[150]211        if (map)
212                *map = lastmap;
213        return Geno(tmp, format, in.getName(), in.getComment());
[109]214}
Note: See TracBrowser for help on using the repository browser.