source: experiments/frams/foraminifera/data/scripts/foraminifera.expdef @ 486

Last change on this file since 486 was 486, checked in by sz, 8 years ago

foraminifera scripts updated to match the upcoming Framsticks version (ExpParams? ==> ExpProperties?, Fields ==> NeuroProperties?, prop: ==> property:)

File size: 25.3 KB
Line 
1expdef:
2name:Reproduction of benthic foraminifera
3info:~
4Basic information about this simulation:
5www.framsticks.com/foraminifera
6
7Technical information:
8Genes and parameter values which control reproduction are stored in data->genes and data->lifeparams fields.
9
10genes:
11genes which are not encoded in Ff genotype:
12min_repro_energy - Minimum energy necessary for reproduction
13hibernation - Defines foram behavior in the case of no nutrients
14
15lifeparams:
16Physiological parameters of foraminifera:
17max_energy_level - maximum energy level reached so far
18gen - generation: 0 haploid, 1 diploid
19species - species: 0 not hibernating 1 hibernating
20hibernated - 0/1 foram is/isn't hibernated
21reproduce - 0/1 foram isn't/is ready for reproduction
22~
23code:~
24
25global chambers;
26global colors;
27global dir_change;
28global max_chamber_volume;
29global movePerStep;
30global nutrientenergywaiting;
31global o;
32global reprocounter;
33global changePeriod;
34global phase;
35
36@include "foraminifera.inc"
37
38// -------------------------------- experiment begin --------------------------------
39
40function onExpDefLoad()
41{
42        // define genotype and creature groups
43        GenePools.clear();
44        Populations.clear();
45        GenePools[0].name = "Unused";
46
47        var pop = Populations[0];
48        pop.name = "Forams";
49        pop.en_assim = 0;
50        pop.nnsim = 0;
51        pop.enableperf = 1;
52        pop.death = 1;
53        pop.energy = 1;
54        pop.selfmask = 0x10001;
55        pop.othermask = 0x20001;
56        //pop.selfmask = 0x20002; pop.othermask = 0x10002;
57        pop.perfperiod = 25;
58
59        pop = Populations.addGroup("Nutrients");
60        pop.nnsim = 0;
61        pop.enableperf = 0;
62        pop.death = 1;
63        pop.energy = 1;
64        pop.selfmask = 0x20002;
65        pop.othermask = 0x10000;
66        //pop.othermask = 0x10002;
67
68        pop = Populations.addGroup("ReticulopodiaNutrients");
69        pop.nnsim = 0;
70        pop.enableperf = 0;
71        pop.death = 0;
72        pop.energy = 0;
73        pop.selfmask = 0x20002;
74        pop.othermask = 0x10000;
75
76        //world
77        SignalView.mode = 1;
78        World.wrldwat = 200;
79        World.wrldsiz = micronsToFrams(40000);
80        World.wrldbnd = 1;
81        ExpProperties.stress = 1;
82        ExpProperties.creath = -0.99; //just above the bottom
83        ExpProperties.autorestart = 0;
84
85        //time
86        ExpProperties.secPerStep = 480;
87        ExpProperties.foramSpeedMmPerMin = 0.05;
88        movePerStep = getMovePerStep();
89
90        //ExpProperties.visualize = 1; //uncomment to visualize reticulopodia and indicate nutrients positions
91
92        //ExpProperties.logging = 1; //uncomment to enable logging simulation parameters to log files
93
94        //reproduction
95        ExpProperties.foramPop = 20;   
96        ExpProperties.crossprob = 0;
97        ExpProperties.mutationprob = 0;
98        ExpProperties.repro_time = 720;
99        ExpProperties.gametoPeriod = 43200;
100        ExpProperties.divisionCost = 15.6;
101        reprocounter = 0;
102
103        init_chambers();
104
105        //morphology
106        dir_change = 30000;
107        ExpProperties.zone1_range = micronsToFrams(1000);
108        ExpProperties.zone2_range = micronsToFrams(3000);
109        ExpProperties.chamber_growth_time = 720;
110        ExpProperties.chamberCostPerSec = 0.000001;
111        ExpProperties.chamber_proculus_haplo = micronsToFrams(50);
112        ExpProperties.chamber_difference_haplo = 0.0;
113        ExpProperties.chamber_proculus_diplo = micronsToFrams(20);
114        ExpProperties.chamber_difference_diplo = micronsToFrams(8);
115
116        max_chamber_volume = [Vector.new(), Vector.new()];
117        for (var j = 0; j < 2; j++)
118        {
119                for (var i = 0; i < chambers[0].size; i++)
120                {
121                        max_chamber_volume[j].add(((volumeInMicrons(getProperty(j, "chamber_proculus")) + volumeInMicrons(getProperty(j, "chamber_proculus") + (i) * getProperty(j, "chamber_difference")))*(i+1))/2); 
122                }                                 
123        }
124
125        //energetics
126        ExpProperties.min_repro_energ_haplo = 4;
127        ExpProperties.min_repro_energ_diplo = 6;
128
129        ExpProperties.e_meta = 0.0000005;
130        ExpProperties.energy_hib = 0.0000001;
131        ExpProperties.energy_move = 0.0000005;
132
133        ExpProperties.energies0_haplo = energyFromVolume(micronsToFrams(20),1);
134        ExpProperties.energies0_diplo = energyFromVolume(micronsToFrams(1.25),1);
135        ExpProperties.feedtrans = 0.001;
136        ExpProperties.e_repro_cost_haplo = 0.3;
137        ExpProperties.e_repro_cost_diplo = 0.2;
138
139        ExpProperties.e_death_level_haplo = 0.5;
140        ExpProperties.e_death_level_diplo = 0.5;
141
142        //nutrients
143        changePeriod = 0;
144        phase = "high";
145        ExpProperties.foodperiod = 21600;
146        ExpProperties.foodPeriodChange = 0;
147        ExpProperties.nutrientradius = micronsToFrams(10);
148        ExpProperties.energy_nut = energyFromVolume(ExpProperties.nutrientradius,1);
149        ExpProperties.feedrate = 1;
150        ExpProperties.ingestion = 0.25;
151        nutrientenergywaiting = 0;
152        ExpState.totaltestedcr = 0;
153        ExpState.nutrient = "";
154}
155
156@include "standard_placement.inc"
157
158function volumeInMicrons(radiusInFrams)
159{
160        return 4.0/3.0*Math.pi*Math.pow(framsToMicrons(radiusInFrams),3);
161}
162
163function energyFromVolume(base, isRadiusInFrams)
164{
165        if (isRadiusInFrams == 1) //radius in frams
166        {
167                return ExpProperties.picoCarbonPerMikro*volumeInMicrons(base);
168        }
169        else //volume in microns
170        {
171                return ExpProperties.picoCarbonPerMikro * base;
172        }
173}
174
175function getMovePerStep()
176{
177        return micronsToFrams((ExpProperties.foramSpeedMmPerMin/60)*1000)*ExpProperties.secPerStep;
178}
179
180function micronsToFrams(micrometers)
181{
182        return micrometers*0.025;
183}
184
185function framsToMicrons(framsworldunits)
186{
187        return framsworldunits/0.025;
188}
189
190function getProperty(gen, prop_id)
191{
192        var ploid = "haplo";
193        if (gen == 1) ploid = "diplo";
194        return ExpProperties.[prop_id + "_" + ploid];
195}
196
197function addForam(species, iter, chambernum, ploid)
198{
199        var geno = createForamGenotype(ploid, species, chambernum);
200        var cr = Populations[0].add(geno);
201        cr.name = "Initial creature" + species + "_" + iter;
202        placeCreatureRandomly(cr, 0, 0);
203        cr.energy0 = energyFromVolume(max_chamber_volume[ploid][chambernum],0);
204        cr.energy = cr.energy0;
205        setGenotype({"opt" : 0, "cr" : cr, "species" : species});
206        if (ploid == 1)
207        {
208                cr.data->lifeparams->gen = 1;
209                cr.data->genes = [cr.data->genes, cr.data->genes]; //TODO two different genes sets
210        }
211}
212
213function addInitialForam(species, iter)
214{
215        var ploid = 0;
216        if (Math.rnd01 > 0.5)
217        {
218                ploid = 1;
219        }       
220        //add new foram with random energy bewtween starting energy and reproduction treshold
221        addForam(species, iter, Math.rndUni(0,getProperty(ploid, "min_repro_energ")),ploid);
222}
223
224function onExpInit()
225{
226        Populations[0].clear();
227        Populations[1].clear();
228        Populations[2].clear(); //reticulopodia and nutrients
229
230        for (var i = 0; i < ExpProperties.foramPop; i++)
231        {
232                addInitialForam(0, i); 
233                //addInitialForam(1, i);
234        }
235        o = Populations[0][0].getMechPart(0).orient.clone();
236        ExpState.totaltestedcr = 0;
237        nutrientenergywaiting = ExpProperties.energy_nut;
238}
239
240function onExpLoad()
241{
242        for (var pop in Populations)
243                pop.clear();
244
245        Loader.addClass(sim_params.*);
246        Loader.setBreakLabel(Loader.BeforeUnknown, "onExpLoad_Unknown");
247        Loader.run();
248
249        Simulator.print("Loaded " + Populations[0].size + " Forams and " + Populations[1].size + " nutrient objects");
250}
251
252function onExpLoad_Unknown()
253{
254        if (Loader.objectName == "org") // saved by the old expdef
255        {
256                var g = Genotype.newFromString("");
257                Loader.currentObject = g;
258                Interface.makeFrom(g).setAllDefault();
259                Loader.loadObject();
260                var cr = Populations[0].add(g);
261                if (cr != null)
262                {
263                        //cr.rotate(0,0,Math.rnd01*Math.twopi);
264                        if ((typeof(g.data->genes) == "Vector") && (g.data->genes.size >= 3))
265                        {
266                                // [x,y,energy]
267                                cr.move(g.data->genes[0] - cr.center_x, g.data->genes[1] - cr.center_y, 0);
268                                cr.energy = g.data->genes[2];
269                        }
270                        else
271                        {
272                                cr.move(Math.rnd01 * World.wrldsiz - cr.center_x, Math.rnd01 * World.wrldsiz - cr.center_y, 0);
273                        }
274                }
275        }
276        else if (Loader.objectName == "Creature")
277        {
278                Loader.currentObject = CreatureSnapshot.new();
279                Loader.loadObject();
280                Populations[0].add(Loader.currentObject);
281        }
282}
283
284function onExpSave()
285{
286        File.writeComment("saved by '%s.expdef'" % Simulator.expdef);
287
288        var tmpvec = [], i;
289
290        for(var cr in Populations[1])
291                tmpvec.add([cr.center_x, cr.center_y, cr.energy]);
292
293        ExpState.nutrient = tmpvec;
294        File.writeObject(sim_params.*);
295        ExpState.nutrient = null; //vectors are only created for saving and then discarded
296
297        for (var cr in Populations[0])
298                File.writeObject(cr);
299}
300
301// -------------------------------- experiment end --------------------------------
302
303// -------------------------------- foram begin -----------------------------------
304
305function setForamMeta(cr)
306{
307        //percent of current energy
308        cr.idleen = (ExpProperties.e_meta * cr.energy)*ExpProperties.secPerStep;
309}
310
311function lastChamberNum(cr)
312{
313        return cr.numparts-1;
314}
315
316function getZoneRange(cr, zone_num)
317{
318        return ExpProperties.["zone"+zone_num+"_range"];
319}
320
321function onForamsBorn(cr)
322{
323        setForamMeta(cr);
324        if (ExpProperties.visualize == 1)
325        {
326                var ret = Populations[2].add("//0\np:sh=3,sx=0.01,sy="+getZoneRange(cr,1)+",sz="+getZoneRange(cr,1)+",ry=1.57,vr=1.0,1.0,1.0");
327                cr.data->reticulopodiacreature = ret;
328        }
329}
330
331function placeRandomlyNotColliding(cr)
332{
333        var retry = 100; //try 100 times
334        while (retry--)
335        {
336                placeCreatureRandomly(cr, 0, 0);
337                if (!cr.boundingBoxCollisions(0))
338                        return cr;
339        }
340
341        Populations[0].delete(cr);
342}
343
344function visualization(cr)
345{
346        var has_ret = 0;
347
348        if (cr.data->reticulopodiacreature != null)
349        {
350                if (Populations[2].findUID(cr.data->reticulopodiacreature.uid) != null)
351                {
352                        has_ret = 1;
353                }
354        }
355
356        return has_ret;
357}
358
359function foramGrow(cr, chamber_num)
360{
361        if ((chamber_num+1) < chambers[cr.data->lifeparams->species].size)
362        {
363                var geno = createForamGenotype(cr.data->lifeparams->gen, cr.data->lifeparams->species, chamber_num+1);
364                var cr2 = Populations[0].add(geno);
365
366                cr2.energy0 = cr.energy;
367                cr2.energy = cr2.energy0;
368
369                setGenotype({"cr" : cr2, "parent_genes" : cr.data->genes, "parent_lifeparams" : cr.data->lifeparams, "opt" : 2});
370                cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z);
371                setForamMeta(cr2);
372
373                if (visualization(cr))
374                {
375                        Populations[2].delete(cr.data->reticulopodiacreature);
376                }
377                Populations[0].delete(cr);
378        }
379}
380
381function stepToNearest(cr)
382{
383        var p = cr.getMechPart(0);
384        var n = cr.signals.receiveSet("nutrient", getZoneRange(cr,2));
385
386        //if signals are received find the source of the nearest
387        if (n.size > 0)
388        {
389                var i;
390                var mp;
391                var distvec = XYZ.new(0, 0, 0);
392                var dist;
393                var mindist = 100000000000.0;
394                var mindistvec = null;
395                var eating = 0;
396
397                for (i = 0; i < n.size; i++)
398                {
399                        mp = n[i].value.getMechPart(0);
400                        distvec.set(mp.pos);
401                        distvec.sub(p.pos);
402                        dist = distvec.length;
403                        if (dist < getZoneRange(cr,1))
404                        {
405                                if (n[i].value != null)
406                                {
407                                        energyTransfer(cr, n[i].value);
408                                        eating = 1;
409                                }
410                        }
411                        else if (eating == 0 && cr.data->lifeparams->hibernated == 0 && dist < mindist)
412                        {
413                                mindist = dist;
414                                mindistvec = distvec.clone();
415                        }
416                }
417
418                if (!eating && cr.data->lifeparams->hibernated == 0)
419                {
420                        mindistvec.normalize();
421                        mindistvec.scale(-1*movePerStep);
422                        cr.localDrive = mindistvec;
423                        moveEnergyDec(cr);
424                }
425
426                return 1;
427        }
428       
429        else
430        {
431                return 0;
432        }
433}
434
435function moveEnergyDec(cr)
436{
437        if (cr.data->lifeparams->hibernated == 0)
438        {
439                //percent of maximal energy
440                cr.energy_m += (ExpProperties.energy_move * cr.data->lifeparams->max_energy_level)*ExpProperties.secPerStep;
441        }
442}
443
444function foramMove(cr)
445{
446        //TODO moving inside sediment?
447
448        //adjustment in z axis
449        cr.moveAbs(cr.pos_x, cr.pos_y, 0);
450
451        //are there any nutrients in zone 1 or 2?
452        {
453                var moved = stepToNearest(cr); //TODO weighted sum of distance and energy
454                if (moved==1)
455                {
456                        return;
457                }
458        }
459
460        //no nutrients in zone 2
461        var hibernation = 0;
462        if (cr.data->lifeparams->gen == 0) hibernation =  cr.data->genes->hibernation;
463        else hibernation =  cr.data->genes[0]->hibernation;
464        //hibernation
465        if (hibernation == 1)
466        {
467                reverseHib(cr);
468                cr.localDrive = XYZ.new(0,0,0);
469        }
470        //random move
471        else if (cr.lifespan%int(dir_change/ExpProperties.secPerStep) == 0)
472        {
473                cr.data->lifeparams->dir = randomDir();
474                cr.localDrive = cr.data->lifeparams->dir;
475                moveEnergyDec(cr);
476        }
477        else
478        {
479                cr.localDrive = cr.data->lifeparams->dir;
480        }
481}
482
483function randomDir()
484{
485        var dir = (Math.rndUni(-ExpProperties.zone2_range, ExpProperties.zone2_range), Math.rndUni(-ExpProperties.zone2_range, ExpProperties.zone2_range), 0); 
486        dir.normalize();
487        dir.scale(-1*movePerStep);
488        return dir;
489}
490
491function energyTransfer(cr1, cr2)
492{
493        cr1.localDrive = XYZ.new(0,0,0);
494        var e =  ExpProperties.feedtrans*cr1.energy;//ExpProperties.feedtrans*cr1.energy*ExpProperties.ingestion*ExpProperties.secPerStep; //TODO efficiency dependent on age
495        e = Math.min(cr2.energy, e);
496        e *= ExpProperties.secPerStep;
497        //Simulator.print("transferring "+e +"("+e*ExpProperties.ingestion+")"+" to "+cr1.name +" ("+ cr1.energy+") " +" from "+cr2.name+" ("+cr2.energy+") "+ e/ExpProperties.secPerStep+ " per sec");
498        cr2.energy_m = cr2.energy_m + e + 0.0000001;
499        cr1.energy_p = cr1.energy_p + e*ExpProperties.ingestion;
500        if (cr1.data->lifeparams->hibernated == 1)
501        {
502                reverseHib(cr1);
503        }
504}
505
506function reverseHib(cr)
507{
508        if (cr.data->lifeparams->hibernated == 1)
509        {
510                setForamMeta(cr); //unhibernate
511        }
512        else
513        {
514                cr.idleen = (ExpProperties.energy_hib * cr.energy)*ExpProperties.secPerStep; //hibernate
515        }
516        cr.data->lifeparams->hibernated = 1 - cr.data->lifeparams->hibernated;
517}
518
519
520function onForamsStep(cr)
521{
522        //checking for gametogenesis process
523        if (cr.data->lifeparams->division_time > 0)
524        {
525                cr.data->lifeparams->division_time = Math.max(cr.data->lifeparams->division_time-1,0);
526        }
527        //checking for end of gametogenesis
528        else if (cr.data->lifeparams->division_time == 0)
529        {
530                //waiting for gamets fusion
531        }
532        //checking for chamber growth process
533        else if (cr.data->lifeparams->chamber_growth > 0)
534        {
535                cr.data->lifeparams->chamber_growth = Math.max(cr.data->lifeparams->chamber_growth-1,0);
536                //Simulator.print("chamber growing, time left = " + cr.data->lifeparams->chamber_growth*ExpProperties.secPerStep);
537                cr.energy_m += ExpProperties.chamberCostPerSec * cr.energy * ExpProperties.secPerStep;
538
539                //Simulator.print("energy " + cr2.energy + " subtracting " + growth_cost);
540        }
541        //checking for end of chamber growth process
542        else if (cr.data->lifeparams->chamber_growth == 0)
543        {
544                foramGrow(cr, lastChamberNum(cr));
545                cr.data->lifeparams->chamber_growth = -1;
546                //Simulator.print("chamber "+ (lastChamberNum(cr) + 1) +" complete");
547        }
548        else
549        {
550                //update of metabolism rate
551                if (cr.data->lifeparams->hibernated == 0)
552                {
553                        setForamMeta(cr);
554                }
555
556                cr.getMechPart(0).orient.set(o);
557                if (visualization(cr))
558                {
559                        cr.data->reticulopodiacreature.moveAbs(cr.center_x-getZoneRange(cr,1), cr.center_y-getZoneRange(cr,1), cr.center_z-getZoneRange(cr,1)-getProperty(cr.data->lifeparams->gen, "chamber_proculus"));
560                }
561
562                if (deathConditions(cr) == 1)
563                {
564                        Populations[0].kill(cr);
565                        return;
566                }
567
568                foramMove(cr);
569
570                var repro = foramReproduce(cr);
571                if (repro == 1)
572                {
573                        return;
574                }
575
576                cr.data->lifeparams->max_energy_level = Math.max(cr.energy, cr.data->lifeparams->max_energy_level);
577
578                //cheking conditions of chamber growth process start
579                if  (lastChamberNum(cr) != chambers[0].size-1)
580                {
581                        if ((cr.data->lifeparams->max_energy_level >= energyFromVolume(max_chamber_volume[cr.data->lifeparams->gen][lastChamberNum(cr)],0)))   
582                        {
583                                cr.data->lifeparams->chamber_growth = int(ExpProperties.chamber_growth_time/ExpProperties.secPerStep);
584                        }       
585                }
586        }       
587}
588
589function deathConditions(cr)
590{
591        if ((cr.energy <= getProperty(cr.data->lifeparams->gen,"e_death_level")*cr.data->lifeparams->max_energy_level) || (Math.rnd01 < ExpProperties.hunted_prob))
592        {
593                return 1;
594        }
595        else
596                return 0;
597}
598
599function onForamsDied(cr)
600{
601        if (visualization(cr))
602        {
603                Populations[2].delete(cr.data->reticulopodiacreature);
604        }
605        //fossilization
606        var geno = GenePools[0].add(cr.genotype);
607        geno.data->genes = cr.data->genes;
608        geno.data->lifeparams = cr.data->lifeparams;
609        if (ExpProperties.logging == 1) Simulator.print("\"" + cr.name + "\" died...");
610        ExpState.totaltestedcr++;
611}
612
613// --------------------------------foram end -------------------------------------
614
615// -------------------------------- nutrient begin --------------------------------
616
617function createNutrientGenotype(nutrientradius)
618{
619        return "//0\np:sh=3,sx="+nutrientradius+",sy="+nutrientradius+",sz="+nutrientradius+",ry=1.5,vr=0.0,1.0,0.0";
620}
621
622function onNutrientsStep(cr)
623{
624        cr.moveAbs(cr.pos_x % World.wrldsiz, cr.pos_y % World.wrldsiz, 0.5);
625}
626
627function addNutrient()
628{
629        var cr = Populations[1].add(createNutrientGenotype(ExpProperties.nutrientradius));
630
631        cr.name = "Nutrients";
632        cr.idleen = 0;
633        cr.energy0 = ExpProperties.energy_nut;
634        cr.energy = cr.energy0;
635        cr.signals.add("nutrient");
636
637        cr.signals[0].value = cr;
638
639        placeCreatureRandomly(cr, 0, 0);
640        if (ExpProperties.visualize == 1)
641        {
642                var nutsize = ExpProperties.nutrientradius*10;
643                var nut = Populations[2].add("//0\np:sh=2,sx="+nutsize+",sy="+nutsize+",sz="+nutsize+",ry=1.5,vr=0.0,1.0,0.0");
644                cr.data->reticulopodiacreature = nut;
645                nut.moveAbs(cr.pos_x-1.5*nutsize, cr.pos_y-1.5*nutsize, 0.5);
646        }
647}
648
649function onNutrientsDied(cr)
650{
651        if (visualization(cr))
652        {
653                Populations[2].delete(cr.data->reticulopodiacreature);
654        }
655}
656
657function nutrientGrowth()
658{
659        if (ExpProperties.foodPeriodChange > 0)
660        {
661                        changePeriod += 1;
662                        if (phase=="low" && (changePeriod*ExpProperties.secPerStep) >= 23328000) //9 months
663                        {
664                                ExpProperties.foodperiod = ExpProperties.foodperiod/ExpProperties.foodPeriodChange;
665                                phase = "high";
666                                changePeriod = 0;
667                        }
668               
669                        else if (phase == "high" && (changePeriod*ExpProperties.secPerStep) >= 7776000) //3 months
670                        {
671                                ExpProperties.foodperiod = ExpProperties.foodperiod*ExpProperties.foodPeriodChange;
672                                phase = "low";
673                                changePeriod = 0;
674                        }
675        }
676        nutrientenergywaiting = nutrientenergywaiting + 1;
677        if (nutrientenergywaiting*ExpProperties.secPerStep >= ExpProperties.foodperiod)
678        {
679                for (var i = 0; i < ExpProperties.feedrate; i++)
680                {   
681                        addNutrient();
682                }
683
684                nutrientenergywaiting = 0.0;
685                Simulator.checkpoint();
686        }
687}
688
689// -------------------------------- nutrient end --------------------------------
690
691// -------------------------------- step begin --------------------------------
692
693function onStep()
694{
695
696        nutrientGrowth();
697        if (ExpProperties.logging == 1)
698        {
699                createStatistics();
700        }
701
702        //reproduction --------------------------------------------
703        reprocounter += 1;
704        if (reprocounter*ExpProperties.secPerStep > ExpProperties.repro_time)
705        {
706                reprocounter = 0;
707                reproduce_parents(0);
708                reproduce_parents(1);
709        }
710
711        //check for extinction -----------------------------------------------
712        if (Populations[0].size == 0)
713        {
714                if (ExpProperties.autorestart)
715                {
716                        Simulator.print("no more creatures, restarting...");
717                        onExpInit();
718                }
719                else
720                {
721                        Simulator.print("no more creatures, stopped.");
722                        Simulator.stop();
723                }
724        }
725        if (ExpProperties.maxSteps > 0)
726        {
727                if (Simulator.stepNumber >= ExpProperties.maxSteps)
728                        Simulator.stop();
729        }
730}
731
732function createStatistics()
733{       
734        var number = [[0, 0],[0,0]]; // [species][gen]
735        var e_inc = [[0, 0],[0,0]];
736        var e_nut = 0.0;
737
738        for (var i = 0; i < Populations[0].size; i++)
739        {
740                var cr = Populations[0].get(i);
741                var gen = cr.data->lifeparams->gen;
742                var species = cr.data->lifeparams->species;
743
744                number[species][gen] = number[species][gen] + 1;
745                e_inc[species][gen] = e_inc[species][gen] + cr.energy;
746        }
747
748        for (var i = 0; i < Populations[1].size; i++)
749        {
750                var cr = Populations[1].get(i);
751                e_nut += cr.energy;
752        }
753
754        var log_numbers = [number[1][0], number[1][1], number[0][0], number[0][1], Populations[1].size];
755        var log_energies = [e_inc[1][0], e_inc[1][1], e_inc[0][0], e_inc[0][1], e_nut];
756
757        log(log_numbers, "forams_log.txt");
758    log(log_energies,  "energies_log.txt");
759}
760
761function log(tolog, fname)
762{
763        var f = File.appendDirect(fname, "forams data");
764        f.writeString("" + Simulator.stepNumber);
765        for (var  i = 0; i < tolog.size; i++)
766        {
767                f.writeString(";" + tolog[i]);
768        }
769        f.writeString("\n");
770        f.close();
771}
772
773// -------------------------------- step end --------------------------------
774//TODO default params values in frams instead of microns/seconds
775
776@include "standard_events.inc"
777
778~
779
780property:
781id:visualize
782name:Show reticulopodia and nutrients
783type:d 0 1 0
784group:Foraminifera
785
786property:
787id:maxSteps
788name:Stop after the given number of simulation steps
789type:d 0 1000000 0
790
791property:
792id:foramSpeedMmPerMin
793name:Speed of foraminfera in mm/min
794type:f 0.1
795flags: 16
796group:Foraminifera
797
798property:
799id:gametSuccessRate
800name:Ratio of successful gamets
801type:f 0.001
802group:Foraminifera
803
804property:
805id:gametoPeriod
806name:Time of gametogenesis
807type:f 720
808group:Foraminifera
809
810property:
811id:picoCarbonPerMikro
812name:Picograms of carbon in cubed micrometer
813type:f 0.13
814group:Foraminifera
815
816property:
817id:secPerStep
818name:Seconds per simulation step
819type:f 60.0
820flags: 16
821group:Foraminifera
822
823property:
824id:e_repro_cost_haplo
825name:Cost of reproduction
826type:f 0.1 0.9 0.5
827group:Foraminifera
828
829property:
830id:divisionCost
831name:Cost of division in pG
832type:f
833group:Foraminifera
834
835property:
836id:e_repro_cost_diplo
837name:Cost of reproduction
838type:f 0.1 0.9 0.3
839group:Foraminifera
840
841property:
842id:chamber_growth_time
843name:Time of the chamber growth in seconds
844type:f
845group:Foraminifera
846
847property:
848id:chamberCostPerSec
849name:Cost of growning chamber per second
850type:f
851group:Foraminifera
852
853property:
854id:chamber_proculus_haplo
855name:Size of proculus
856type:f
857group:Foraminifera
858
859property:
860id:chamber_proculus_diplo
861name:Size of proculus
862type:f
863group:Foraminifera
864
865property:
866id:chamber_difference_haplo
867name:Difference in size between subsequent chambers
868type:f
869group:Foraminifera
870
871property:
872id:chamber_difference_diplo
873name:Difference in size between subsequent chambers
874type:f
875group:Foraminifera
876
877property:
878id:hunted_prob
879name:Probability of being hunted
880type:f 0 1 0
881group:Forminifera
882
883property:
884id:zone1_range
885name:Zone 1 range
886type:f 0 200
887group:Foraminifera
888
889property:
890id:zone2_range
891name:Zone 2 range
892type:f 0 3000
893group:Foraminifera
894
895property:
896id:colors
897name:Haploid and diploid colors
898type:x
899group:Foraminifera
900
901property:
902id:min_repro_energ_haplo
903name:Min reproduction energy of forams
904type:f
905group:Foraminifera
906
907property:
908id:min_repro_energ_diplo
909name:Min reproduction energy of forams
910type:f
911group:Foraminifera
912
913property:
914id:repro_prob
915name:Probability of reproduction
916type:f 0 1 0.8
917group:Foraminifera
918
919property:
920id:energies0_haplo
921name:Energy of offspring from diploid forams
922type:f
923group:Foraminifera
924
925property:
926id:energies0_diplo
927name:Energy of offspring from diploid forams
928type:f
929group:Foraminifera
930
931property:
932id:e_death_level_haplo
933name:Minimal level of energy to sustain life of haploid
934type:f 0 20 0.2
935group:Foraminifera
936
937property:
938id:e_death_level_diplo
939name:Minimal level of energy to sustain life of diploid
940type:f 0 20 0.2
941group:Foraminifera
942
943property:
944id:energy_hib
945name:Energy used for hibernation during one step
946type:f 0 1 0.001
947group:Foraminifera
948
949property:
950id:energy_move
951name:Energy used for movement during one step
952type:f 0 20 0.001
953group:Foraminifera
954
955property:
956id:min_vol
957name:Minimal volume for reproduction
958type:f 100 900 100
959group:Foraminifera
960
961property:
962id:max_size
963name:Maximal size
964type:d 1 10 5
965group:Foraminifera
966
967property:
968id:foramPop
969name:Initial forams population size
970type:d 1 1000 100
971group:Foraminifera
972
973property:
974id:crossprob
975name:Crossover probability
976type:f 0 1 0
977group:Foraminifera
978
979property:
980id:mutationprob
981name:Mutation probability
982type:f 0 1 0
983group:Foraminifera
984
985property:
986id:e_meta
987name:Idle metabolism
988type:f 0 1
989group:Energy
990help:Each stick consumes this amount of energy in one time step
991
992property:
993id:feedrate
994name:Feeding rate
995type:f 0 1000000
996group:Energy
997help:How fast energy is created in the world
998
999property:
1000id:foodPeriodChange
1001name:Set variable feed rate
1002type:f 0
1003group:Energy
1004
1005property:
1006id:ingestion
1007name:Ingestion rate
1008type:f
1009group:Energy
1010
1011property:
1012id:energy_nut
1013name:Nutrient energy
1014type:f 0 100000
1015group:Energy
1016
1017property:
1018id:feedtrans
1019name:Energy transfer per second
1020type:f 0 100000
1021group:Energy
1022
1023property:
1024id:foodperiod
1025name:Time between food occurrences
1026type:f 0 1000000
1027group:Energy
1028
1029property:
1030id:nutrientradius
1031name:Nutrient size
1032type:f 0.1 0.9 0.1
1033group:Energy
1034
1035property:
1036id:stress
1037name:Environmental stress
1038type:d 0 1 1
1039group:World
1040
1041property:
1042id:repro_trigger
1043name:Reproduction trigger
1044type:d 0 1 1
1045group:World
1046
1047property:
1048id:repro_time
1049name:Time before reproduction
1050type:d 0 10000
1051
1052property:
1053id:creath
1054name:Creation height
1055type:f -1 50
1056help:~
1057Vertical position (above the surface) where new Forams are revived.
1058Negative values are only used in the water area:
1059  0   = at the surface
1060-0.5 = half depth
1061-1   = just above the bottom~
1062
1063state:
1064id:nutrient
1065name:Nutrient locations
1066help:vector of vectors [x,y,energy]
1067type:x
1068flags:32
1069
1070property:
1071id:autorestart
1072name:Restart after extinction
1073help:Restart automatically this experiment after the last creature has died?
1074type:d 0 1
1075
1076state:
1077id:notes
1078name:Notes
1079type:s 1
1080help:~
1081You can write anything here
1082(it will be saved to the experiment file)~
1083
1084state:
1085id:totaltestedcr
1086name:Evaluated Forams
1087help:Total number of the Forams evaluated in the experiment
1088type:d
1089flags:16
1090
1091property:
1092id:logging
1093name:Log statistics to file
1094type:d 0 1 0
Note: See TracBrowser for help on using the repository browser.