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

Last change on this file since 1139 was 999, checked in by Maciej Komosinski, 4 years ago

More consistent usage of "shapetype" (vs. "shape")

  • Property svn:eol-style set to native
File size: 7.6 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[972]2// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[109]4
5#include <ctype.h>
[129]6#include <frams/genetics/defgenoconv.h>
[109]7#include <frams/model/model.h>
8#include <frams/util/multimap.h>
[527]9#include <common/virtfile/stdiofile.h>
[109]10#include "printconvmap.h"
[391]11#include <common/loggers/loggertostdout.h>
[109]12
13/**
14 @file
15 Sample code: Genotype converter class
[727]16 */
[109]17
[972]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.
[727]21class GenoConv_Test : public GenoConverter
[109]22{
23public:
[727]24        GenoConv_Test()
[109]25        {
[727]26                name = "Test Converter";
27                in_format = 'x';
[109]28        }
[732]29        SString convert(SString &i, MultiMap *map, bool using_checkpoints) { return SString("after conversion..."); }
[727]30        ~GenoConv_Test() {}
[109]31};
32
33/// Sample Geno converter using Model class.
[727]34/// (This converter generates the same output for each input).
35class GenoConv_Test2 : public GenoConverter
[109]36{
37public:
[727]38        GenoConv_Test2()
[109]39        {
[727]40                name = "Test Converter #2";
41                in_format = 'y';
[109]42        }
[727]43
[732]44        SString convert(SString &i, MultiMap *map, bool using_checkpoints)
[727]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        }
[732]55
[727]56        ~GenoConv_Test2() {}
[109]57};
58
59/// Sample Geno converter supporting conversion mapping.
[727]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
[109]63{
64public:
[727]65        GenoConv_Test3()
[109]66        {
[727]67                name = "Test Converter #3";
[955]68                in_format = "multiply";
[727]69                out_format = '1';
70                mapsupport = 1;
[109]71        }
[732]72        SString convert(SString &in, MultiMap *map, bool using_checkpoints);
[727]73        ~GenoConv_Test3() {}
[109]74};
75
76/** main converting routine - most important: direct conversion map example */
[732]77SString GenoConv_Test3::convert(SString &in, MultiMap *map, bool using_checkpoints)
[109]78{
[727]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++)
[109]85        {
[972]86                if (insideneuron && *t == ']') insideneuron = 0;
[727]87                if (*t == '[') insideneuron = 1;
88                if ((!insideneuron) && isdigit(*t) && t[1])
[109]89                { // special sequence detected!
[727]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
[972]95                                map->add(t - src, t - src, dst.length() - n, dst.length() - 1);
[727]96                        // meaning: source character (t-src) becomes (dst.len()-n ... dst.len()-1)
[109]97                }
[727]98                else
[109]99                {
[727]100                        dst += *t;
101                        if (map)
[972]102                                map->add(t - src, t - src, dst.length() - 1, dst.length() - 1);
[727]103                        // meaning: map single to single character: (t-src) into (dst.len()-1)
[109]104                }
105        }
[727]106        return dst;
[109]107}
108
[975]109/// Sample Geno converter producing "f0s" genotype from the textual list of shapes, eg. "/*shapes*/ball,cube,cube"
110class GenoConv_Test4 : public GenoConverter
111{
112public:
113        GenoConv_Test4()
114        {
115                name = "Test Converter #4";
116                in_format = "shapes";
117                out_format = "0s";
118                mapsupport = 1;
119        }
120        SString convert(SString &in, MultiMap *map, bool using_checkpoints);
121        ~GenoConv_Test4() {}
122};
[109]123
[975]124SString GenoConv_Test4::convert(SString &in, MultiMap *map, bool using_checkpoints)
125{
126        SString result;
127        int numparts=0;
128        int input_pos=0, prev_input_pos=0; SString word;
129        while(in.getNextToken(input_pos,word,','))
130                {
131                Part::Shape sh;
132                if (word=="cube")
133                        sh = Part::SHAPE_CUBOID;
134                else if (word=="ball")
135                        sh = Part::SHAPE_ELLIPSOID;
136                else if (word=="cylinder")
137                        sh = Part::SHAPE_CYLINDER;
138                else
139                        return "";
140                SString add;
141                add+=SString::sprintf("p:x=%g,sh=%d\n",numparts*2.0f,sh);
142                if (numparts>0)
143                        add+=SString::sprintf("j:p1=%d,p2=%d,sh=1\n",numparts-1,numparts);
144                if (map) // fill in the map only if requested
145                        map->add(prev_input_pos, prev_input_pos+word.length()-1, result.length(),result.length()+add.length()-1);
146                result+=add;
147                numparts++;
148                prev_input_pos = input_pos;
149                }
150        return result;
151}
152
153
[109]154///////////////////////////////////////////////
155
156void printGen(Geno &g)
157{
[955]158        printf("Genotype:\n%s\nFormat: %s\nValid: %s\nComment: %s\n",
[972]159                g.getGenes().c_str(), g.getFormat().c_str(), g.isValid() ? "yes" : "no", g.getComment().c_str());
[109]160}
161
[955]162static int goodWidthForFormat(const SString& genotype_format)
[739]163{
[975]164        return Geno::formatIsOneOf(genotype_format, Geno::F0_FORMAT_LIST) ? 45 : 15; // more space for long f0 lines
[739]165}
166
[732]167// arguments:
[994]168//     genotype (or - meaning "read from stdin") [default: X, but try "/*shapes*/ball,cube,cylinder,cube"]
[732]169//     target format [default: 0]
170//     "checkpoints" (just write this exact word) [default: not using checkpoints]
[727]171int main(int argc, char *argv[])
[109]172{
[727]173        LoggerToStdout messages_to_stdout(LoggerBase::Enable);
[145]174
[727]175        DefaultGenoConvManager gcm;
176        gcm.addDefaultConverters();
177        gcm.addConverter(new GenoConv_Test());
178        gcm.addConverter(new GenoConv_Test2());
179        gcm.addConverter(new GenoConv_Test3());
[975]180        gcm.addConverter(new GenoConv_Test4());
[727]181        Geno::useConverters(&gcm);
[109]182
[727]183        Geno::Validators validators;
184        ModelGenoValidator model_validator;
185        validators += &model_validator;
186        Geno::useValidators(&validators);
[145]187
[727]188        SString src;
189        if (argc > 1)
[527]190        {
[727]191                src = argv[1];
192                if (src == "-")
[527]193                {
[727]194                        StdioFILEDontClose in(stdin);
195                        src = "";
196                        loadSString(&in, src, false);
[527]197                }
198        }
[727]199        else
200                src = "X";
[975]201        SString dst = (argc > 2) ? argv[2] : Geno::F0_FORMAT_LIST;
[732]202        bool using_checkpoints = (argc > 3) ? (strcmp(argv[3], "checkpoints") == 0) : false;
[109]203
[727]204        printf("*** Source genotype:\n");
205        Geno g1(src);
206        printGen(g1);
207        MultiMap m;
[732]208        Geno g2 = g1.getConverted(dst, &m, using_checkpoints);
[975]209        printf("*** Converted:\n");
[727]210        printGen(g2);
[732]211
212        if (using_checkpoints)
213        { // using Model with checkpoints
[999]214                Model m1(g2, Model::SHAPETYPE_UNKNOWN, false, true);//true=using_checkpoints
[955]215                printf("\nModel built from the converted f%s genotype has %d checkpoints\n", g2.getFormat().c_str(), m1.getCheckpointCount());
[999]216                Model m2(g1, Model::SHAPETYPE_UNKNOWN, false, true);//true=using_checkpoints
[955]217                printf("Model built from the source f%s genotype has %d checkpoints\n", g1.getFormat().c_str(), m2.getCheckpointCount());
[732]218                // accessing individual checkpoint models (if available)
219                if (m1.getCheckpointCount() > 0)
220                {
221                        int c = m1.getCheckpointCount() / 2;
222                        Model *cm = m1.getCheckpoint(c);
223                        printf("Checkpoint #%d (%d parts, %d joint, %d neurons)\n%s", c, cm->getPartCount(), cm->getJointCount(), cm->getNeuroCount(), cm->getF0Geno().getGenesAndFormat().c_str());
224                }
225        }
[727]226        else
[732]227        { // there is no mapping for checkpoints so it's nothing interesting to see here in the checkpoints mode
228                if (m.isEmpty())
229                        printf("(conversion map not available)\n");
230                else
231                {
232                        printf("Conversion map:\n");
233                        m.print();
[739]234                        printConvMap(g1.getGenes(), g2.getGenes(), m, goodWidthForFormat(g1.getFormat()));
[732]235                        printf("Reverse conversion map:\n");
236                        MultiMap rm;
237                        rm.addReversed(m);
238                        rm.print();
[739]239                        printConvMap(g2.getGenes(), g1.getGenes(), rm, goodWidthForFormat(g2.getFormat()));
[732]240                }
241
[999]242                Model mod1(g1, Model::SHAPETYPE_UNKNOWN, 1);
[955]243                printf("\nModel map for f%s genotype:\n", g1.getFormat().c_str());
[739]244                ModelDisplayMap dm1(mod1);
245                dm1.print(goodWidthForFormat(g1.getFormat()));
[732]246                MultiMap mod1combined;
[739]247                mod1combined.addCombined(mod1.getMap(), dm1.getMap());
[732]248                mod1combined.print();
[999]249                Model mod2(g2, Model::SHAPETYPE_UNKNOWN, 1);
[955]250                printf("\nModel map for f%s genotype:\n", g2.getFormat().c_str());
[739]251                ModelDisplayMap dm2(mod2);
252                dm2.print(goodWidthForFormat(g2.getFormat()));
[732]253                MultiMap mod2combined;
[739]254                mod2combined.addCombined(mod2.getMap(), dm2.getMap());
[732]255                mod2combined.print();
[109]256        }
[727]257        return 0;
[109]258}
Note: See TracBrowser for help on using the repository browser.