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

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

Fixed broken neuron creation (missing argument - regression from r760, when support was added in f4 for new API for neuron types and their properties)

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