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

Last change on this file since 372 was 372, checked in by sz, 9 years ago

Renamed some classes and functions to make their purpose more obvious:

All MessageHandlers? must now be given the explicit "Enable" argument if you want them to automatically become active. This makes side effects clearly visible.

  • Property svn:eol-style set to native
File size: 6.7 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5// Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL
6
7#include "conv_f4.h"
8#include <common/hmessage.h>
9#include "../oper_fx.h" //for GENOPER_OK constant
10
11#ifdef DMALLOC
12#include <dmalloc.h>
13#endif
14
15
16GenoConv_f40::GenoConv_f40()
17{
18        name = "Developmental encoding";
19        in_format = '4';
20        out_format = '0';
21        mapsupport = 1;
22}
23
24
25SString GenoConv_f40::convert(SString &in, MultiMap * map)
26{
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);
34        SString out = model->getF0Geno().getGene();
35        delete model;
36        return out;
37}
38
39
40GenoConv_F41_TestOnly::GenoConv_F41_TestOnly()
41{
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)";
47}
48
49
50SString GenoConv_F41_TestOnly::convert(SString &in, MultiMap * map)
51{
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;
60}
61
62
63f4_Model::f4_Model() : Model()
64{
65        cells = NULL;
66}
67
68f4_Model::~f4_Model()
69{
70        if (cells) delete cells;
71}
72
73int f4_Model::buildFromF4(SString &geno)
74{
75        int i;
76
77        error = GENOPER_OK;
78        errorpos = -1;
79
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        }
90
91        cells->simulate();
92        if (GENOPER_OK != cells->geterror())
93        {
94                error = cells->geterror();
95                errorpos = cells->geterrorpos();
96                return error;
97        }
98
99        // reset recursive traverse flags
100        for (i = 0; i < cells->nc; i++)
101                cells->C[i]->recProcessedFlag = 0;
102
103        open(); // begin model build
104
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                {
112                        Hmessage("f4_Model", "buildModelRec", "Error in building Model", 2);
113                        error = res;
114                        break;
115                }
116        }
117
118        res = close();
119        if (0 == res) // invalid
120                error = -10;
121
122        return error;
123}
124
125
126f4_Cell * f4_Model::getStick(f4_Cell * C)
127{
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!
136        Hmessage("f4_Model", "getStick", "Not a single stick", 2);
137        return NULL;
138}
139
140
141/// updated by Macko to follow new SDK standards (no more neuroitems)
142int f4_Model::buildModelRec(f4_Cell * C)
143{
144        int partidx;
145        int j, res;
146        MultiRange range;
147
148        if (C->recProcessedFlag)
149                // already processed
150                return 0;
151
152        // mark it processed
153        C->recProcessedFlag = 1;
154
155        // make sure parent is a stick
156        if (NULL != C->dadlink)
157                if (C->dadlink->type != T_STICK4)
158                {
159                        C->dadlink = getStick(C->dadlink);
160                }
161
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        }
168
169        char tmpLine[100];
170
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
180                        sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g",
181                                /*1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim
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
196                sprintf(tmpLine, "p:m=1,fr=%g,ing=%g,as=%g",
197                        //C->lastend.x, C->lastend.y, C->lastend.z
198                        /*"vol=" 1.0/C->P.mass,*/ C->P.friction, C->P.ingest, C->P.assim
199                        );
200                partidx = singleStepBuild(tmpLine, &range);
201                if (partidx < 0) return -2;
202                C->p2_refno = partidx;
203
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!
214                        C->P.len,
215                        // relative rotation
216                        C->xrot, C->zrot,
217                        //C->P.ruch,   // rotstif
218                        C->P.odpor
219                        );
220                partidx = singleStepBuild(tmpLine, &range);
221                if (partidx < 0) return -13;
222                C->joint_refno = partidx;
223        }
224
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;
239
240                if (C->ctrl)
241                {
242                        if (1 == C->ctrl)
243                                sprintf(tmpLine, "n:j=%d,d=\"@:p=%g\"", C->dadlink->joint_refno, C->P.ruch);
244                        else
245                                sprintf(tmpLine, "n:j=%d,d=\"|:p=%g,r=%g\"", C->dadlink->joint_refno, C->P.ruch, C->mz);
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                }
251
252                for (j = 0; j < C->nolink; j++)
253                {
254                        if (NULL != C->links[j]->from)
255                                buildModelRec(C->links[j]->from);
256
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;
278}
279
280
281void f4_Model::toF1Geno(SString &out)
282{
283        cells->toF1Geno(out);
284}
Note: See TracBrowser for help on using the repository browser.