source: experiments/frams/foraminifera/data/scripts/forams_benthic.expdef @ 403

Last change on this file since 403 was 402, checked in by Maciej Komosinski, 9 years ago

Invalid index to fix

File size: 14.7 KB
Line 
1expdef:
2name:Benthic foraminifera reproduction
3info:~
4Genes and parameter values which control reproduction are stored in user1 and user2 fields.
5
6user1:
7genes which are not encoded in Ff genotype:
8Vamin - Minimum stored energy necessary for reproduction
9amin - minimal age for reproduction
10
11user2:
12Physiological parameters of foraminifera:
13Va - amount of the stored energy
14gen - generation: 0 haploid, 1 diploid
15~
16code:~
17
18/*
19changes 2015-06-24:
20- xxx.get(...) changed to xxx[...]
21- xxx.set(...,...) changed to xxx[...]=...
22- function placeRandomlyNotColliding(cr) explicitly called when adding a new creature, and removed collision checking from onCreaturesBorn() which is also called when "growing" (since "growing" is implemented as creating a new creature in place of the old one, so onCreaturesBorn() is also called)
23- use creature's center (not the bbox corner) when growing
24- added "S" receptor to visualize the difference between diplo and haplo generations
25- signal.value is a MechPart (a reference) so it does not have to be updated after changing the object location
26*/
27
28/* TODO fix
29[ERROR] Population.kill: Invalid index 35 (allowed range is 0..34)
30[ERROR] Population.kill: ... called from reproduce_haploid()  <forams_repro.inc:54>
31[ERROR] Population.kill: ... called from onStep()  <forams_repro.inc:228>
32*/
33
34global foodenergywaiting;
35global reprocounter;
36global delta_change;
37
38@include "forams_repro.inc"
39
40// -------------------------------- experiment begin --------------------------------
41
42function onExpDefLoad()
43{
44
45        // define genotype and creature groups
46        GenePools.clear();
47        Populations.clear();
48        GenePools[0].name = "Unused";
49
50        SignalView.mode = 1;
51
52        var pop = Populations[0];
53        pop.name = "Creatures";
54        pop.en_assim = 0;
55        pop.nnsim = 1;
56        pop.enableperf = 1;
57        pop.death = 1;
58        pop.energy = 1;
59        pop.selfmask = 0x10001;
60        pop.othermask = 0x20001;
61        //pop.selfmask = 0x20002; pop.othermask = 0x10002;
62        pop.perfperiod = 25;
63
64        pop = Populations.addGroup("Food");
65        pop.nnsim = 0;
66        pop.enableperf = 0;
67        pop.death = 1;
68        pop.energy = 1;
69        pop.selfmask = 0x20002;
70        pop.othermask = 0x10000;
71
72
73        var size_h = ExpParams.haplo_rad * ExpParams.delta_rate + ExpParams.haplo_rad;
74        var size_d = ExpParams.diplo_rad * ExpParams.delta_rate + ExpParams.diplo_rad;
75        ExpParams.gend = "//0\np:sh=1,sx=" + ExpParams.diplo_rad + ",sy=" + ExpParams.diplo_rad + ",sz=" + ExpParams.diplo_rad + ", rz=3.14159265358979";
76        ExpParams.genh = "//0\np:sh=1,sx=" + size_h + ",sy=" + size_h + ",sz=" + size_h + ", rz=3.14159265358979";
77        ExpParams.e_meta = 0.1;
78        ExpParams.feedrate = 0.5;
79        ExpParams.feede0 = 100;
80        ExpParams.feedtrans = 3;
81        ExpParams.creath = -0.99; //just above the bottom
82        ExpParams.foodgen = "//0\np:sh=2,sx=0.1,sy=0.1,sz=0.1\nn:d=T,p=0";
83        ExpParams.autorestart = 0;
84        ExpParams.psize = 10;
85        ExpParams.logging = 0;
86
87        //number of offspring
88        ExpParams.ofnumh = 40;
89        ExpParams.ofnumd = 25;
90        //minial volume for reproduction
91        ExpParams.v_min_d = 300;
92        ExpParams.v_min_h = 300;
93        //radius of the chamber
94        ExpParams.haplo_rad = 1.2;
95        ExpParams.diplo_rad = 0.6;
96        //minimal age for reproduction
97        ExpParams.age_min_d = 100;
98        ExpParams.age_min_h = 100;
99        //crossover probability
100        ExpParams.crossprob = 0.4;
101        //mutation probability
102        ExpParams.mutationprob = 0.2;
103        ExpParams.repro_time = 200;
104        ExpParams.repro_thr = 1;
105
106        //size change rate
107        ExpParams.delta_rate = 0.1;
108        //grwoth speed in time steps
109        ExpParams.growth_step = 50;
110
111        ExpState.totaltestedcr = 0;
112        ExpState.food = "";
113        foodenergywaiting = ExpParams.feede0;
114        reprocounter = 0;
115
116        ExpParams.wsize = 50;
117        World.wrldwat = 50;
118        World.wrldsiz = ExpParams.wsize;
119        World.wrldbnd = 1;
120
121        delta_change = 0.5;
122}
123
124@include "standard_placement.inc"
125
126function onExpInit()
127{
128        Populations[0].clear();
129        Populations[1].clear();
130
131        for (var i = 0; i < ExpParams.psize; i++)
132        {
133                var cr = Populations[0].add(ExpParams.genh);
134                cr.name = "Initial creature" + i;
135                placeCreatureRandomly(cr, 0, 0);
136                cr.energ0 = ExpParams.v_min_h - ExpParams.repro_thr;
137                cr.energy = cr.energ0;
138                cr.user1 = {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h, "delta_h" : ExpParams.haplo_rad * ExpParams.delta_rate, "delta_d" : ExpParams.diplo_rad * ExpParams.delta_rate};
139                cr.user2 = {"Va" : ExpParams.v_min_h - ExpParams.repro_thr, "gen" : 0, "growth_step" : ExpParams.growth_step, "rsize" : ExpParams.haplo_rad, "vinit" : ExpParams.v_min_h - ExpParams.repro_thr};
140        }
141        ExpState.totaltestedcr = 0;
142        foodenergywaiting = ExpParams.feede0;
143}
144
145function onExpLoad()
146{
147        for (var pop in Populations)
148                pop.clear();
149
150        Loader.addClass(sim_params.*);
151        Loader.setBreakLabel(Loader.BeforeUnknown, "onExpLoad_Unknown");
152        Loader.run();
153
154        Simulator.print("Loaded " + Populations[0].size + " creatures and " + Populations[1].size + " food objects");
155}
156
157function onExpLoad_Unknown()
158{
159        if (Loader.objectName == "org") // saved by the old expdef
160        {
161                var g = Genotype.newFromString("");
162                Loader.currentObject = g;
163                Interface.makeFrom(g).setAllDefault();
164                Loader.loadObject();
165                var cr = Populations[0].add(g);
166                if (cr != null)
167                {
168                        //cr.rotate(0,0,Math.rnd01*Math.twopi);
169                        if ((typeof(g.user1) == "Vector") && (g.user1.size >= 3))
170                        {
171                                // [x,y,energy]
172                                cr.move(g.user1[0] - cr.center_x, g.user1[1] - cr.center_y, 0);
173                                cr.energy = g.user1[2];
174                        }
175                        else
176                        {
177                                cr.move(Math.rnd01 * World.wrldsiz - cr.center_x, Math.rnd01 * World.wrldsiz - cr.center_y, 0);
178                        }
179                }
180        }
181        else if (Loader.objectName == "Creature")
182        {
183                Loader.currentObject = CreatureSnapshot.new();
184                Loader.loadObject();
185                Populations[0].add(Loader.currentObject);
186        }
187}
188
189function onExpSave()
190{
191        File.writeComment("saved by '%s.expdef'" % Simulator.expdef);
192
193        var tmpvec = [], i;
194
195        for(var cr in Populations[1])
196                tmpvec.add([cr.center_x, cr.center_y, cr.energy]);
197
198        ExpState.food = tmpvec;
199        File.writeObject(sim_params.*);
200        ExpState.food = null; //vectors are only created for saving and then discarded
201
202        for (var cr in Populations[0])
203                File.writeObject(cr);
204}
205
206// -------------------------------- experiment end --------------------------------
207
208// -------------------------------- creature begin --------------------------------
209
210function onCreaturesBorn(cr)
211{
212        cr.idleen = ExpParams.e_meta;
213}
214
215function placeRandomlyNotColliding(cr)
216{
217        var retry = 100; //try 100 times
218        while (retry--)
219        {
220                placeCreatureRandomly(cr, 0, 0);
221                if (!cr.boundingBoxCollisions(0))
222                        return cr;
223        }
224
225        Populations[0].delete(cr);
226}
227
228function readyToRepro(cr)
229{
230        cr.signals.add("repro");
231        cr.signals[0].power = 1;
232
233}
234
235function onCreaturesStep(cr)
236{
237        cr.moveAbs(cr.pos_x, cr.pos_y, 0); //adjustment in z axis
238        var p = cr.getMechPart(0);
239        var n = cr.signals.receiveSet("food", ExpParams.food_range);
240
241        //if signals are received find the source of the nearest
242        if (n.size > 0)
243        {
244
245                var i;
246                var mp;
247                var distvec = XYZ.new(0, 0, 0);
248                var dist;
249                var mindist = 100000000000;
250                var mindistvec = null;
251
252                for (i = 0; i < n.size; i++)
253                {
254                        mp = n[i].value;
255                        distvec.set(mp.pos);
256                        distvec.sub(p.pos);
257                        dist = distvec.length;
258                        if (dist < mindist)
259                        {
260                                mindist = dist;
261                                mindistvec = distvec.clone();
262                        }
263                }
264
265                mindistvec.normalize();
266                mindistvec.scale(-0.08);
267                cr.localDrive = mindistvec;
268        }
269
270        else
271        {
272                cr.localDrive = (0.1 * Math.rnd01, 0.1 * Math.rnd01, 0);
273        }
274
275        //energy costs depend on size
276        if (cr.energy > 100)
277        {
278                // cr.energy_m = cr.user2["Va"]/cr.user2["vinit"];
279        }
280
281        if (cr.lifespan >= ExpParams.max_age)
282        {
283                Populations[0].kill(cr);
284        }
285
286        //foram growth
287        else if (cr.lifespan == cr.user2["growth_step"])
288        {
289                var pos = [cr.center_x, cr.center_y, cr.center_z];
290                var energy = cr.energy;
291                var cr2 = null;
292                if (cr.user2["gen"] == 0)
293                {
294                        var new_r = ExpParams.haplo_rad * Math.min(Math.max(cr.user2["Va"] / cr.user2["vinit"] * 0.5, 1), 2.5);
295                        cr.user2["rsize"] = new_r;
296                        cr2 = Populations[0].add("//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979");
297                        cr2.user1 = {"vamin" : cr.user1["vamin"], "amin": cr.user1["amin"], "delta_h" : cr.user1["delta_h"], "delta_d" : cr.user1["delta_d"]};
298                }
299                else if (cr.user2["gen"] == 1)
300                {
301                        var new_r = ExpParams.diplo_rad * Math.min(Math.max(cr.user2["Va"] / cr.user2["vinit"] * 0.5, 1), 2.5);
302                        cr.user2["rsize"] = new_r;
303
304                        var geno = "//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979";
305                        geno += "\nn:p=0,d=\"S\""; //TODO is this the only difference with haploid code? TODO why initial genotypes are not used as defined in ExpParams?
306                        //TODO maybe it would be nice if they rotated so the "S" would show where they are going (direction/intention)
307                        cr2 = Populations[0].add(geno);
308
309
310                        cr2.user1 = [ {"vamin" : cr.user1[0]["vamin"], "amin": cr.user1[0]["amin"], "delta_h" : cr.user1[0].get("delta_h"), "delta_d" : cr.user1[0]["delta_d"]  }, {"vamin" : cr.user1[1]["vamin"], "amin": cr.user1[1]["amin"], "delta_h" : cr.user1[1]["delta_h"], "delta_d" : cr.user1[1]["delta_d"]  }];
311                }
312                cr2.energy = energy;
313                cr2.user2 = {"Va" : cr.user2["Va"], "gen" : cr.user2["gen"], "growth_step" : cr.user2["growth_step"], "rsize" : cr.user2["rsize"], "vinit": cr.user2["vinit"]};
314                cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z);
315
316                Populations[0].delete(cr);
317        }
318        else
319        {
320                var properSize = 0;
321
322                if (cr.user2["gen"] == 0)
323                {
324                        properSize = cr.user2["Va"] >= cr.user1["vamin"];
325                }
326                else
327                {
328                        properSize = cr.user2["Va"] >= cr.user1[0]["vamin"];
329                }
330
331                //if creature has proper age and cytoplasm amount
332                if ( properSize )
333                {
334                        //reproduce with probability repro_prob
335                        if (Math.rnd01 <= ExpParams.repro_prob)
336                        {
337                                readyToRepro(cr);
338                        }
339                }
340                if ( properSize && (cr.signals.receive("repro") > 0))
341                {
342                        readyToRepro(cr);
343                }
344        }
345}
346
347function onCreaturesDied(cr)
348{
349        //fossilization
350        var geno = GenePools[0].add(cr.genotype);
351        geno.user1 = cr.user1;
352        geno.user2 = cr.user2;
353        Simulator.print("\"" + cr.name + "\" died...");
354        ExpState.totaltestedcr++;
355}
356
357// -------------------------------- creature end --------------------------------
358
359// -------------------------------- food begin --------------------------------
360
361function onFoodStep(cr)
362{
363        cr.moveAbs(cr.pos_x % ExpParams.wsize, cr.pos_y % ExpParams.wsize, 0.5);
364}
365
366function addfood()
367{
368        var cr = Populations[1].add(ExpParams.foodgen);
369
370        cr.name = "Food";
371        cr.idleen = 0;
372        cr.energ0 = ExpParams.feede0;
373        cr.energy = cr.energ0;
374        cr.signals.add("food");
375
376        cr.signals[0].value = cr.getMechPart(0);
377
378        var retry = 100; //try 100 times
379        while (retry--)
380        {
381                placeCreatureRandomly(cr, 0, 0);
382                if (!cr.boundingBoxCollisions(0))
383                        return cr;
384        }
385
386        return cr;
387}
388
389function onFoodCollision()
390{
391        if (Collision.Creature2.user2 != null)
392        {
393                var e = Collision.Part2.ing * ExpParams.feedtrans;
394                //Simulator.print("transferring "+e+" from "+Collision.Creature1.name+" to "+Collision.Creature2.name+" ("+Collision.Creature2.energy+")");
395                Collision.Creature1.energy_m = Collision.Creature1.energy_m + e;
396                Collision.Creature2.energy_p = Collision.Creature2.energy_p + e;
397                var ener = float(Collision.Creature2.user2["Va"]);
398                var sum = float(float(ener) + float(e));
399                Collision.Creature2.user2["Va"] = float(sum);
400        }
401}
402
403// -------------------------------- food end --------------------------------
404
405
406function log(tolog, fname)
407{
408        var f = File.appendDirect(fname, "forams data");
409        f.writeString("" + Simulator.stepNumber);
410        for (var  i = 0; i < tolog.size; i++)
411        {
412                f.writeString(";" + tolog[i]);
413        }
414        f.writeString("\n");
415        f.close();
416}
417
418
419
420
421@include "standard_events.inc"
422
423~
424
425prop:
426id:max_age
427name:Maximal age
428type:d 100 1000 500
429
430prop:
431id:wsize
432name:World size
433type:d 10 1000 20
434
435prop:
436id:haplo_rad
437name:Haploid radius
438type:f 0.1 3 1.2
439
440prop:
441id:growth_step
442name:Growth step
443type:d 50 10000 1000
444
445prop:
446id:delta_rate
447name:Delta rate
448type:f 0.0001 0.1 0.001
449
450prop:
451id:diplo_rad
452name:Diploid radius
453type:f 0.1 3 0.6
454
455prop:
456id:foodPop
457name:Food size
458type:d 1 1000 10
459
460prop:
461id:age_min
462name:Minimal age for reproduction
463type:d 100 10000 200
464
465prop:
466id:age_min_h
467name:Min reproduction age of haploid forams
468type:d 100 10000 300
469group:Foraminifera
470
471prop:
472id:age_min_d
473name:Min reproduction age of diploid forams
474type:d 100 10000 200
475group:Foraminifera
476
477prop:
478id:v_min_h
479name:Min reproduction energy of haploid forams
480type:f 10 10000 300
481group:Foraminifera
482
483prop:
484id:v_min_d
485name:Min reproduction energy of diploid forams
486type:f 10 10000 150
487group:Foraminifera
488
489prop:
490id:repro_thr
491name:Threshold for reproduction
492type:d 1 1000 1
493
494prop:
495id:food_range
496name:Range of food smell
497type:d 0 10000 10000
498
499prop:
500id:repro_time
501name:Time before reproduction
502type:d 0 1000
503
504prop:
505id:psize
506name:Initial population size
507type:d 1 1000 100
508
509prop:
510id:logging
511name:Log statistics to file
512type:d 0 1 0
513
514prop:
515id:ofnumh
516name:Number of offspring from haploid forams
517type:d
518group:Foraminifera
519
520prop:
521id:ofnumd
522name:Number of offspring from diploid forams
523type:d
524group:Foraminifera
525
526prop:
527id:repro_prob
528name:Probability of reproduction
529type:f 0 1 0.9
530
531prop:
532id:crossprob
533name:Crossover probability
534type:f 0 1 0
535
536prop:
537id:mutationprob
538name:Mutation probability
539type:f 0 1 0
540
541prop:
542id:genh
543name:Initial genotype of haploid forams
544type:s 1
545group:Foraminifera
546
547prop:
548id:gend
549name:Initial genotype of diploid forams
550type:s 1
551group:Foraminifera
552
553prop:
554id:creath
555name:Creation height
556type:f -1 50
557help:~
558Vertical position (above the surface) where new creatures are revived.
559Negative values are only used in the water area:
560  0   = at the surface
561-0.5 = half depth
562-1   = just above the bottom~
563
564prop:
565id:e_meta
566name:Idle metabolism
567type:f 0 1
568group:Energy
569help:Each stick consumes this amount of energy in one time step
570
571prop:
572id:feedrate
573name:Feeding rate
574type:f 0 100
575group:Energy
576help:How fast energy is created in the world
577
578prop:
579id:feede0
580name:Food's energy
581group:Energy
582type:f 0 1000
583
584prop:
585id:feedtrans
586name:Ingestion multiplier
587group:Energy
588type:f 0 100
589
590prop:
591id:foodgen
592name:Food's genotype
593group:Energy
594type:s 1
595
596prop:
597id:autorestart
598name:Restart after extinction
599help:Restart automatically this experiment after the last creature has died?
600type:d 0 1
601
602state:
603id:notes
604name:Notes
605type:s 1
606help:~
607You can write anything here
608(it will be saved to the experiment file)~
609
610state:
611id:totaltestedcr
612name:Evaluated creatures
613help:Total number of the creatures evaluated in the experiment
614type:d
615flags:16
616
617state:
618id:food
619name:Food locations
620help:vector of vectors [x,y,energy]
621type:x
622flags:32
623
Note: See TracBrowser for help on using the repository browser.