source: cpp/frams/genetics/f4/f4_conv.cpp @ 783

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

Removed the unused "info" field and fixed a bug with incorrect pointers to content stored in a vector

  • Property svn:eol-style set to native
File size: 8.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
[760]6// Copyright (C) since 2001 Maciej Komosinski
7// 2018, Grzegorz Latosinski, added support for new API for neuron types and their properties
[196]8
[779]9#include "f4_conv.h"
[375]10#include <common/log.h>
[779]11#include "../genooperators.h" //for GENOPER_OK constant
[193]12
13#ifdef DMALLOC
14#include <dmalloc.h>
15#endif
16
17
[196]18GenoConv_f40::GenoConv_f40()
[193]19{
[196]20        name = "Developmental encoding";
21        in_format = '4';
22        out_format = '0';
23        mapsupport = 1;
[193]24}
25
26
[774]27SString GenoConv_f40::convert(SString &in, MultiMap *map, bool using_checkpoints)
[193]28{
[196]29        int res;
[774]30        f4_Model *model = new f4_Model();
[760]31        res = model->buildFromF4(in, using_checkpoints);
[196]32        if (GENOPER_OK != res) return SString();  // oops
33        if (NULL != map)
34                // generate to-f0 conversion map
35                model->getCurrentToF0Map(*map);
[534]36        SString out = model->getF0Geno().getGenes();
[196]37        delete model;
38        return out;
[193]39}
40
41
42GenoConv_F41_TestOnly::GenoConv_F41_TestOnly()
43{
[783]44        name = "Only for testing, approximate f4->f1 converter"; //Do not use in production! (adam)
[196]45        in_format = '4';
46        out_format = '1';
47        mapsupport = 0;
[193]48}
49
50
[774]51SString GenoConv_F41_TestOnly::convert(SString &in, MultiMap *map, bool using_checkpoints)
[193]52{
[196]53        int res;
[774]54        f4_Model *model = new f4_Model();
[760]55        res = model->buildFromF4(in, using_checkpoints);
[196]56        if (GENOPER_OK != res) return SString();  // oops
57        SString out;
58        model->toF1Geno(out);
59        delete model;
60        return out;
[193]61}
62
63
64f4_Model::f4_Model() : Model()
65{
[196]66        cells = NULL;
[193]67}
68
69f4_Model::~f4_Model()
70{
[196]71        if (cells) delete cells;
[193]72}
73
[760]74int f4_Model::buildFromF4(SString &geno, bool using_checkpoints)
[193]75{
[196]76        int i;
[193]77
[196]78        error = GENOPER_OK;
79        errorpos = -1;
[193]80
[196]81        // build cells, and simulate
82        if (cells) delete cells;
83        cells = new f4_Cells(geno, 0);
84        if (GENOPER_OK != cells->geterror())
85        {
86                error = cells->geterror();
87                errorpos = cells->geterrorpos();
88                //delete cells;
89                return error;
90        }
[193]91
[196]92        cells->simulate();
93        if (GENOPER_OK != cells->geterror())
94        {
95                error = cells->geterror();
96                errorpos = cells->geterrorpos();
97                return error;
98        }
[193]99
[196]100        // reset recursive traverse flags
101        for (i = 0; i < cells->nc; i++)
102                cells->C[i]->recProcessedFlag = 0;
[193]103
[760]104        open(using_checkpoints); // begin model build
[193]105
[196]106        // process every cell
107        int res;
108        for (i = 0; i < cells->nc; i++)
109        {
110                res = buildModelRec(cells->C[i]);
111                if (res)
112                {
[375]113                        logMessage("f4_Model", "buildModelRec", 2, "Error in building Model");
[196]114                        error = res;
115                        break;
116                }
117        }
[193]118
[196]119        res = close();
120        if (0 == res) // invalid
121                error = -10;
[193]122
[196]123        return error;
[193]124}
125
126
[774]127f4_Cell* f4_Model::getStick(f4_Cell *C)
[193]128{
[196]129        if (T_STICK4 == C->type) return C;
130        if (NULL != C->dadlink)
131                return getStick(C->dadlink);
132        // we have no more dadlinks, find any stick
133        for (int i = 0; i < cells->nc; i++)
134                if (cells->C[i]->type == T_STICK4)
135                        return cells->C[i];
136        // none!
[375]137        logMessage("f4_Model", "getStick", 2, "Not a single stick");
[196]138        return NULL;
[193]139}
140
141
[287]142/// updated by Macko to follow new SDK standards (no more neuroitems)
[774]143int f4_Model::buildModelRec(f4_Cell *C)
[193]144{
[196]145        int partidx;
146        int j, res;
147        MultiRange range;
[193]148
[196]149        if (C->recProcessedFlag)
150                // already processed
151                return 0;
[193]152
[196]153        // mark it processed
154        C->recProcessedFlag = 1;
[193]155
[196]156        // make sure parent is a stick
157        if (NULL != C->dadlink)
158                if (C->dadlink->type != T_STICK4)
159                {
[675]160                C->dadlink = getStick(C->dadlink);
[196]161                }
[193]162
[196]163        // make sure its parent is processed first
164        if (NULL != C->dadlink)
165        {
166                res = buildModelRec(C->dadlink);
167                if (res) return res;
168        }
[193]169
[196]170        char tmpLine[100];
[193]171
[196]172        range = C->genoRange;
173        if (C->type == T_STICK4)
174        {
175                int jj_p1_refno;  // save for later
176                // first end is connected to dad, or new
177                if (C->dadlink == NULL)
178                {
179                        // new part object for firstend
180                        // coordinates are left to be computed by Model
[726]181                        sprintf(tmpLine, "fr=%g,ing=%g,as=%g",
[671]182                                /*1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation
[196]183                                //C->firstend.x, C->firstend.y, C->firstend.z
184                                );
[726]185                        partidx = addFromString(PartType, tmpLine, &range);
[196]186                        if (partidx < 0) return -1;
[760]187                        this->checkpoint();
[196]188                        jj_p1_refno = partidx;
189                }
190                else {
191                        // adjust mass/vol of first endpoint
192                        jj_p1_refno = C->dadlink->p2_refno;
[774]193                        Part *p1 = getPart(jj_p1_refno);
[196]194                        p1->mass += 1.0;
195                        //      p1->volume += 1.0/C->P.mass;
196                }
197                // new part object for lastend
[726]198                sprintf(tmpLine, "fr=%g,ing=%g,as=%g",
[196]199                        //C->lastend.x, C->lastend.y, C->lastend.z
[671]200                        /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingestion, C->P.assimilation
[196]201                        );
[726]202                partidx = addFromString(PartType, tmpLine, &range);
[196]203                if (partidx < 0) return -2;
204                C->p2_refno = partidx;
[193]205
[196]206                // new joint object
207                // check that the part references are valid
208                int jj_p2_refno = C->p2_refno;
209                if ((jj_p1_refno < 0) || (jj_p1_refno >= getPartCount())) return -11;
210                if ((jj_p2_refno < 0) || (jj_p2_refno >= getPartCount())) return -12;
[726]211                sprintf(tmpLine, "p1=%ld,p2=%ld,dx=%g,dy=0,dz=0,rx=%g,ry=0,rz=%g"\
[196]212                        ",stam=%g",
213                        jj_p1_refno, jj_p2_refno,
214                        // relative position -- always (len, 0, 0), along the stick
215                        // this is optional!
[671]216                        C->P.length,
[196]217                        // relative rotation
218                        C->xrot, C->zrot,
219                        //C->P.ruch,   // rotstif
[671]220                        C->P.stamina
[196]221                        );
[726]222                partidx = addFromString(JointType, tmpLine, &range);
[196]223                if (partidx < 0) return -13;
[760]224                this->checkpoint();
[196]225                C->joint_refno = partidx;
226        }
[193]227
[196]228        if (C->type == T_NEURON4) ///<this case was updated by MacKo
229        {
[774]230                const char* nclass = C->neuclass->name.c_str();
[760]231                int partno, jointno;
232                if (C->neuclass->getPreferredLocation() == 0)
233                {
234                        if (strcmp(nclass, "N") == 0)
235                        {
236                                partno = C->dadlink->p2_refno;
237                                if ((partno < 0) || (partno >= getPartCount())) return -21;
238                                else sprintf(tmpLine, "p=%ld,d=\"N:in=%g,fo=%g,si=%g\"", partno, C->inertia, C->force, C->sigmo);
239                        }
240                        else
241                        {
242                                sprintf(tmpLine, "d=\"%s\"", nclass);
243                        }
244                        partidx = addFromString(NeuronType, tmpLine, &range);
245                        if (partidx < 0) return -22;
246                        this->checkpoint();
247                        C->neuro_refno = partidx;
248                }
249                else if (C->neuclass->getPreferredLocation() == 1) // attached to Part or have no required attachment - also part
250                {
251                        partno = C->dadlink->p2_refno;
252                        if ((partno < 0) || (partno >= getPartCount())) return -21;
253                        if (strcmp(nclass, "N") == 0)
254                        {
255                                sprintf(tmpLine, "d=\"N:in=%g,fo=%g,si=%g\"", partno, C->inertia, C->force, C->sigmo);
256                        }
257                        else
258                        {
259                                sprintf(tmpLine, "p=%ld,d=\"%s\"", partno, nclass);
260                        }
261                        partidx = addFromString(NeuronType, tmpLine, &range);
262                        if (partidx < 0) return -22;
263                        this->checkpoint();
264                        C->neuro_refno = partidx;
265                }
266                else // attached to Joint
267                {
268                        jointno = C->dadlink->joint_refno;
269                        sprintf(tmpLine, "n:j=%d,d=\"%s\"", jointno, nclass);
270                        partidx = addFromString(NeuronType, tmpLine, &range);
271                        if (partidx < 0) return -32;
272                        this->checkpoint();
273                }
[196]274                C->neuro_refno = partidx;
275                int n_refno = C->neuro_refno;
[193]276
[760]277                if ((strcmp(nclass,"N") == 0) && C->ctrl)
[196]278                {
279                        if (1 == C->ctrl)
[726]280                                sprintf(tmpLine, "j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.muscle_power);
[196]281                        else
[726]282                                sprintf(tmpLine, "j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P.muscle_power, C->mz);
283                        partidx = addFromString(NeuronType, tmpLine, &range);
[196]284                        if (partidx < 0) return -32;
[726]285                        sprintf(tmpLine, "%d,%d", partidx, n_refno);
286                        if (addFromString(NeuronConnectionType, tmpLine, &range) < 0) return -33;
[760]287                        this->checkpoint();
[196]288                }
[193]289
[196]290                for (j = 0; j < C->nolink; j++)
291                {
292                        if (NULL != C->links[j]->from)
293                                buildModelRec(C->links[j]->from);
[193]294
[196]295                        tmpLine[0] = 0;
[760]296                        if (C->links[j]->from == NULL)
297                        {
[774]298                                const char* nclass = C->links[j]->t.c_str();
299                                char* temp = (char*)C->links[j]->t.c_str();
300                                NeuroClass *sensortest = GenoOperators::parseNeuroClass(temp);
[760]301                                //backward compatibility for G*TS
302                                if (C->links[j]->t == "*" || C->links[j]->t == "S" || C->links[j]->t == "T")
303                                {
304                                        sprintf(tmpLine, "p=%d,d=\"%s\"", partno, nclass);
305                                }
306                                else if (C->links[j]->t == "G")
307                                {
308                                        jointno = C->dadlink->joint_refno;
309                                        sprintf(tmpLine, "j=%d,d=\"%s\"", jointno, nclass);
310                                }                               
311                                else if (sensortest->getPreferredLocation() == 0)
312                                {
313                                        sprintf(tmpLine, "d=\"%s\"",nclass);
314                                }
315                                else if (sensortest->getPreferredLocation() == 1)
316                                {
317                                        sprintf(tmpLine, "p=%d,d=\"%s\"", partno, nclass);
318                                }
319                                else
320                                {
321                                        jointno = C->dadlink->joint_refno;
322                                        sprintf(tmpLine, "j=%d,d=\"%s\"", jointno, nclass);
323                                }
324
325                        }
[196]326                        int from = -1;
327                        if (tmpLine[0]) //input from receptor
328                        {
[726]329                                from = addFromString(NeuronType, tmpLine, &range);
[196]330                                if (from < 0) return -34;
[760]331                                this->checkpoint();
[196]332                        } /*could be 'else'...*/
[760]333
[196]334                        if (NULL != C->links[j]->from) // input from another neuron
335                                from = C->links[j]->from->neuro_refno;
336                        if (from >= 0)
337                        {
[726]338                                sprintf(tmpLine, "%d,%d,%g", n_refno, from, C->links[j]->w);
339                                if (addFromString(NeuronConnectionType, tmpLine, &range) < 0) return -35;
[760]340                                this->checkpoint();
[196]341                        }
342                }
343        }
344        return 0;
[193]345}
346
347
348void f4_Model::toF1Geno(SString &out)
349{
[196]350        cells->toF1Geno(out);
[193]351}
Note: See TracBrowser for help on using the repository browser.