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

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

Updated f4 sources and made f4 available for GDK demo apps

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