source: cpp/frams/_demos/genoconv_test.cpp @ 792

Last change on this file since 792 was 739, checked in by Maciej Komosinski, 7 years ago

Unlimited number of model Parts/Joints/Neurons? when displaying the genotype-to-phenotype mapping

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include <ctype.h>
6#include <frams/genetics/defgenoconv.h>
7#include <frams/model/model.h>
8#include <frams/util/multimap.h>
9#include <common/virtfile/stdiofile.h>
10#include "printconvmap.h"
11#include <common/loggers/loggertostdout.h>
12
13/**
14 @file
15 Sample code: Genotype converter class
16 */
17
18/// Sample Geno converter not using Model class.
19/// (This converter generates the same output for each input).
20/// Such a converter is responsible for doing valid f0 (or other format) output and storing temporary data.
21class GenoConv_Test : public GenoConverter
22{
23public:
24        GenoConv_Test()
25        {
26                name = "Test Converter";
27                in_format = 'x';
28        }
29        SString convert(SString &i, MultiMap *map, bool using_checkpoints) { return SString("after conversion..."); }
30        ~GenoConv_Test() {}
31};
32
33/// Sample Geno converter using Model class.
34/// (This converter generates the same output for each input).
35class GenoConv_Test2 : public GenoConverter
36{
37public:
38        GenoConv_Test2()
39        {
40                name = "Test Converter #2";
41                in_format = 'y';
42        }
43
44        SString convert(SString &i, MultiMap *map, bool using_checkpoints)
45        {
46                Model mod;
47                mod.open();
48                mod.addFromString(Model::PartType, "0,0,0");
49                mod.addFromString(Model::PartType, "0,0,-1");
50                mod.addFromString(Model::JointType, "0,1");
51                mod.getPart(1)->p.y += 0.2; //as an example, directly modify position of part #1
52                mod.close();
53                return mod.getF0Geno().getGenes();
54        }
55
56        ~GenoConv_Test2() {}
57};
58
59/// Sample Geno converter supporting conversion mapping.
60/// The conversion is very simple: any sequence of <digit><character>
61/// (but not inside neurons) is replaced by the repeated sequence of the character.
62class GenoConv_Test3 : public GenoConverter
63{
64public:
65        GenoConv_Test3()
66        {
67                name = "Test Converter #3";
68                in_format = 'z';
69                out_format = '1';
70                mapsupport = 1;
71        }
72        SString convert(SString &in, MultiMap *map, bool using_checkpoints);
73        ~GenoConv_Test3() {}
74};
75
76/** main converting routine - most important: direct conversion map example */
77SString GenoConv_Test3::convert(SString &in, MultiMap *map, bool using_checkpoints)
78{
79        SString dst;
80        const char* src = in.c_str();
81        const char* t;
82        int insideneuron = 0;
83        int n;
84        for (t = src; *t; t++)
85        {
86                if (insideneuron&&*t == ']') insideneuron = 0;
87                if (*t == '[') insideneuron = 1;
88                if ((!insideneuron) && isdigit(*t) && t[1])
89                { // special sequence detected!
90                        n = *t - '0';
91                        t++; // *t will be repeated 'n' times
92                        for (int i = 0; i < n; i++)
93                                dst += *t;
94                        if (map) // fill in the map only if requested
95                                map->add(t - src, t - src, dst.len() - n, dst.len() - 1);
96                        // meaning: source character (t-src) becomes (dst.len()-n ... dst.len()-1)
97                }
98                else
99                {
100                        dst += *t;
101                        if (map)
102                                map->add(t - src, t - src, dst.len() - 1, dst.len() - 1);
103                        // meaning: map single to single character: (t-src) into (dst.len()-1)
104                }
105        }
106        return dst;
107}
108
109
110///////////////////////////////////////////////
111
112void printGen(Geno &g)
113{
114        printf("Genotype:\n%s\nFormat: %c\nValid: %s\nComment: %s\n",
115                g.getGenes().c_str(), g.getFormat(), g.isValid() ? "yes" : "no", g.getComment().c_str());
116}
117
118static int goodWidthForFormat(int genotype_format)
119{
120        return genotype_format == '0' ? 45 : 15; // more space for long f0 lines
121}
122
123// arguments:
124//     genotype (or - meaning "read from stdin") [default: X]
125//     target format [default: 0]
126//     "checkpoints" (just write this exact word) [default: not using checkpoints]
127int main(int argc, char *argv[])
128{
129        LoggerToStdout messages_to_stdout(LoggerBase::Enable);
130
131        DefaultGenoConvManager gcm;
132        gcm.addDefaultConverters();
133        gcm.addConverter(new GenoConv_Test());
134        gcm.addConverter(new GenoConv_Test2());
135        gcm.addConverter(new GenoConv_Test3());
136        Geno::useConverters(&gcm);
137
138        Geno::Validators validators;
139        ModelGenoValidator model_validator;
140        validators += &model_validator;
141        Geno::useValidators(&validators);
142
143        SString src;
144        if (argc > 1)
145        {
146                src = argv[1];
147                if (src == "-")
148                {
149                        StdioFILEDontClose in(stdin);
150                        src = "";
151                        loadSString(&in, src, false);
152                }
153        }
154        else
155                src = "X";
156        char dst = (argc > 2) ? *argv[2] : '0';
157        bool using_checkpoints = (argc > 3) ? (strcmp(argv[3], "checkpoints") == 0) : false;
158
159        printf("*** Source genotype:\n");
160        Geno g1(src);
161        printGen(g1);
162        MultiMap m;
163        Geno g2 = g1.getConverted(dst, &m, using_checkpoints);
164        printf("*** Converted to f%c:\n", dst);
165        printGen(g2);
166
167        if (using_checkpoints)
168        { // using Model with checkpoints
169                Model m1(g2, false, true);//true=using_checkpoints
170                printf("\nModel built from the converted f%c genotype has %d checkpoints\n", g2.getFormat(), m1.getCheckpointCount());
171                Model m2(g1, false, true);//true=using_checkpoints
172                printf("Model built from the source f%c genotype has %d checkpoints\n", g1.getFormat(), m2.getCheckpointCount());
173                // accessing individual checkpoint models (if available)
174                if (m1.getCheckpointCount() > 0)
175                {
176                        int c = m1.getCheckpointCount() / 2;
177                        Model *cm = m1.getCheckpoint(c);
178                        printf("Checkpoint #%d (%d parts, %d joint, %d neurons)\n%s", c, cm->getPartCount(), cm->getJointCount(), cm->getNeuroCount(), cm->getF0Geno().getGenesAndFormat().c_str());
179                }
180        }
181        else
182        { // there is no mapping for checkpoints so it's nothing interesting to see here in the checkpoints mode
183                if (m.isEmpty())
184                        printf("(conversion map not available)\n");
185                else
186                {
187                        printf("Conversion map:\n");
188                        m.print();
189                        printConvMap(g1.getGenes(), g2.getGenes(), m, goodWidthForFormat(g1.getFormat()));
190                        printf("Reverse conversion map:\n");
191                        MultiMap rm;
192                        rm.addReversed(m);
193                        rm.print();
194                        printConvMap(g2.getGenes(), g1.getGenes(), rm, goodWidthForFormat(g2.getFormat()));
195                }
196
197                Model mod1(g1, 1);
198                printf("\nModel map for f%c genotype:\n", g1.getFormat());
199                ModelDisplayMap dm1(mod1);
200                dm1.print(goodWidthForFormat(g1.getFormat()));
201                MultiMap mod1combined;
202                mod1combined.addCombined(mod1.getMap(), dm1.getMap());
203                mod1combined.print();
204                Model mod2(g2, 1);
205                printf("\nModel map for f%c genotype:\n", g2.getFormat());
206                ModelDisplayMap dm2(mod2);
207                dm2.print(goodWidthForFormat(g2.getFormat()));
208                MultiMap mod2combined;
209                mod2combined.addCombined(mod2.getMap(), dm2.getMap());
210                mod2combined.print();
211        }
212        return 0;
213}
Note: See TracBrowser for help on using the repository browser.