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

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

Removed extra checkpoint

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