source: cpp/frams/genetics/f4/conv_f4.cpp @ 718

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

Code formatting

  • Property svn:eol-style set to native
File size: 6.7 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[671]2// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[193]4
[196]5// Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL
6
[193]7#include "conv_f4.h"
[375]8#include <common/log.h>
[196]9#include "../oper_fx.h" //for GENOPER_OK constant
[193]10
11#ifdef DMALLOC
12#include <dmalloc.h>
13#endif
14
15
[196]16GenoConv_f40::GenoConv_f40()
[193]17{
[196]18        name = "Developmental encoding";
19        in_format = '4';
20        out_format = '0';
21        mapsupport = 1;
[193]22}
23
24
[196]25SString GenoConv_f40::convert(SString &in, MultiMap * map)
[193]26{
[196]27        int res;
28        f4_Model * model = new f4_Model();
29        res = model->buildFromF4(in);
30        if (GENOPER_OK != res) return SString();  // oops
31        if (NULL != map)
32                // generate to-f0 conversion map
33                model->getCurrentToF0Map(*map);
[534]34        SString out = model->getF0Geno().getGenes();
[196]35        delete model;
36        return out;
[193]37}
38
39
40GenoConv_F41_TestOnly::GenoConv_F41_TestOnly()
41{
[196]42        name = "test-only approximate f4 -> f1 converter";
43        in_format = '4';
44        out_format = '1';
45        mapsupport = 0;
46        info = "This is for testing.  Do not use in production! (adam)";
[193]47}
48
49
50SString GenoConv_F41_TestOnly::convert(SString &in, MultiMap * map)
51{
[196]52        int res;
53        f4_Model * model = new f4_Model();
54        res = model->buildFromF4(in);
55        if (GENOPER_OK != res) return SString();  // oops
56        SString out;
57        model->toF1Geno(out);
58        delete model;
59        return out;
[193]60}
61
62
63f4_Model::f4_Model() : Model()
64{
[196]65        cells = NULL;
[193]66}
67
68f4_Model::~f4_Model()
69{
[196]70        if (cells) delete cells;
[193]71}
72
73int f4_Model::buildFromF4(SString &geno)
74{
[196]75        int i;
[193]76
[196]77        error = GENOPER_OK;
78        errorpos = -1;
[193]79
[196]80        // build cells, and simulate
81        if (cells) delete cells;
82        cells = new f4_Cells(geno, 0);
83        if (GENOPER_OK != cells->geterror())
84        {
85                error = cells->geterror();
86                errorpos = cells->geterrorpos();
87                //delete cells;
88                return error;
89        }
[193]90
[196]91        cells->simulate();
92        if (GENOPER_OK != cells->geterror())
93        {
94                error = cells->geterror();
95                errorpos = cells->geterrorpos();
96                return error;
97        }
[193]98
[196]99        // reset recursive traverse flags
100        for (i = 0; i < cells->nc; i++)
101                cells->C[i]->recProcessedFlag = 0;
[193]102
[196]103        open(); // begin model build
[193]104
[196]105        // process every cell
106        int res;
107        for (i = 0; i < cells->nc; i++)
108        {
109                res = buildModelRec(cells->C[i]);
110                if (res)
111                {
[375]112                        logMessage("f4_Model", "buildModelRec", 2, "Error in building Model");
[196]113                        error = res;
114                        break;
115                }
116        }
[193]117
[196]118        res = close();
119        if (0 == res) // invalid
120                error = -10;
[193]121
[196]122        return error;
[193]123}
124
125
126f4_Cell * f4_Model::getStick(f4_Cell * C)
127{
[196]128        if (T_STICK4 == C->type) return C;
129        if (NULL != C->dadlink)
130                return getStick(C->dadlink);
131        // we have no more dadlinks, find any stick
132        for (int i = 0; i < cells->nc; i++)
133                if (cells->C[i]->type == T_STICK4)
134                        return cells->C[i];
135        // none!
[375]136        logMessage("f4_Model", "getStick", 2, "Not a single stick");
[196]137        return NULL;
[193]138}
139
140
[287]141/// updated by Macko to follow new SDK standards (no more neuroitems)
[193]142int f4_Model::buildModelRec(f4_Cell * C)
143{
[196]144        int partidx;
145        int j, res;
146        MultiRange range;
[193]147
[196]148        if (C->recProcessedFlag)
149                // already processed
150                return 0;
[193]151
[196]152        // mark it processed
153        C->recProcessedFlag = 1;
[193]154
[196]155        // make sure parent is a stick
156        if (NULL != C->dadlink)
157                if (C->dadlink->type != T_STICK4)
158                {
[675]159                C->dadlink = getStick(C->dadlink);
[196]160                }
[193]161
[196]162        // make sure its parent is processed first
163        if (NULL != C->dadlink)
164        {
165                res = buildModelRec(C->dadlink);
166                if (res) return res;
167        }
[193]168
[196]169        char tmpLine[100];
[193]170
[196]171        range = C->genoRange;
172        if (C->type == T_STICK4)
173        {
174                int jj_p1_refno;  // save for later
175                // first end is connected to dad, or new
176                if (C->dadlink == NULL)
177                {
178                        // new part object for firstend
179                        // coordinates are left to be computed by Model
[528]180                        sprintf(tmpLine, "p:fr=%g,ing=%g,as=%g",
[671]181                                /*1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation
[196]182                                //C->firstend.x, C->firstend.y, C->firstend.z
183                                );
184                        partidx = singleStepBuild(tmpLine, &range);
185                        if (partidx < 0) return -1;
186                        jj_p1_refno = partidx;
187                }
188                else {
189                        // adjust mass/vol of first endpoint
190                        jj_p1_refno = C->dadlink->p2_refno;
191                        Part * p1 = getPart(jj_p1_refno);
192                        p1->mass += 1.0;
193                        //      p1->volume += 1.0/C->P.mass;
194                }
195                // new part object for lastend
[528]196                sprintf(tmpLine, "p:fr=%g,ing=%g,as=%g",
[196]197                        //C->lastend.x, C->lastend.y, C->lastend.z
[671]198                        /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation
[196]199                        );
200                partidx = singleStepBuild(tmpLine, &range);
201                if (partidx < 0) return -2;
202                C->p2_refno = partidx;
[193]203
[196]204                // new joint object
205                // check that the part references are valid
206                int jj_p2_refno = C->p2_refno;
207                if ((jj_p1_refno < 0) || (jj_p1_refno >= getPartCount())) return -11;
208                if ((jj_p2_refno < 0) || (jj_p2_refno >= getPartCount())) return -12;
209                sprintf(tmpLine, "j:p1=%ld,p2=%ld,dx=%g,dy=0,dz=0,rx=%g,ry=0,rz=%g"\
210                        ",stam=%g",
211                        jj_p1_refno, jj_p2_refno,
212                        // relative position -- always (len, 0, 0), along the stick
213                        // this is optional!
[671]214                        C->P.length,
[196]215                        // relative rotation
216                        C->xrot, C->zrot,
217                        //C->P.ruch,   // rotstif
[671]218                        C->P.stamina
[196]219                        );
220                partidx = singleStepBuild(tmpLine, &range);
221                if (partidx < 0) return -13;
222                C->joint_refno = partidx;
223        }
[193]224
[196]225        if (C->type == T_NEURON4) ///<this case was updated by MacKo
226        {
227                // new neuron object
228                // it is linked to a part (not a joint!)
229                int p_refno = C->dadlink->p2_refno;
230                if ((p_refno < 0) || (p_refno >= getPartCount())) return -21;
231                // joint_refno is currently not used
232                sprintf(tmpLine, "n:p=%ld,d=\"N:in=%g,fo=%g,si=%g\"",
233                        p_refno,
234                        C->inertia, C->force, C->sigmo);
235                partidx = singleStepBuild(tmpLine, &range);
236                if (partidx < 0) return -22;
237                C->neuro_refno = partidx;
238                int n_refno = C->neuro_refno;
[193]239
[196]240                if (C->ctrl)
241                {
242                        if (1 == C->ctrl)
[671]243                                sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.muscle_power);
[196]244                        else
[671]245                                sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P.muscle_power, C->mz);
[196]246                        partidx = singleStepBuild(tmpLine, &range);
247                        if (partidx < 0) return -32;
248                        sprintf(tmpLine, "c:%d,%d", partidx, n_refno);
249                        if (singleStepBuild(tmpLine, &range) < 0) return -33;
250                }
[193]251
[196]252                for (j = 0; j < C->nolink; j++)
253                {
254                        if (NULL != C->links[j]->from)
255                                buildModelRec(C->links[j]->from);
[193]256
[196]257                        tmpLine[0] = 0;
258                        if (1 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"*\"", p_refno);
259                        if (2 == C->links[j]->t) sprintf(tmpLine, "n:j=%d,d=\"G\"", C->dadlink->joint_refno);
260                        if (3 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"T\"", p_refno);
261                        if (4 == C->links[j]->t) sprintf(tmpLine, "n:p=%d,d=\"S\"", p_refno);
262                        int from = -1;
263                        if (tmpLine[0]) //input from receptor
264                        {
265                                from = singleStepBuild(tmpLine, &range);
266                                if (from < 0) return -34;
267                        } /*could be 'else'...*/
268                        if (NULL != C->links[j]->from) // input from another neuron
269                                from = C->links[j]->from->neuro_refno;
270                        if (from >= 0)
271                        {
272                                sprintf(tmpLine, "c:%d,%d,%g", n_refno, from, C->links[j]->w);
273                                if (singleStepBuild(tmpLine, &range) < 0) return -35;
274                        }
275                }
276        }
277        return 0;
[193]278}
279
280
281void f4_Model::toF1Geno(SString &out)
282{
[196]283        cells->toF1Geno(out);
[193]284}
Note: See TracBrowser for help on using the repository browser.