source: experiments/frams/foraminifera/data/scripts/foraminifera.inc @ 1152

Last change on this file since 1152 was 1152, checked in by Maciej Komosinski, 20 months ago

Foraminifera show has now smaller world compared to expdef (and adjusted other parameters), so it is better suited for visualization and demonstration

File size: 9.2 KB
Line 
1
2function create_genotype(proculus_size, number_of_chambers, rgbstring, lastchambergrowth) //lastchambergrowth is 0..1
3{
4        const shift = 0.7;
5        const angle_delta = 0.8;
6        const angle_delta_delta = -0.01;
7        const growing = 1.07; //7% growth
8
9        var str = "//0s\nm:Vstyle=foram\n";
10        var size = proculus_size;
11        for(var i = 0; i < number_of_chambers; i++)
12        {
13                var effectivesize = size; //'effectivesize' is introduced only to consider the last chamber
14                if (i == number_of_chambers - 1) //last chamber
15                {
16                        effectivesize *= lastchambergrowth;
17                        size = size * (1.35 - 0.35 * lastchambergrowth); //last iteration: 'size' is only used for shifting (dx). The last chamber emerges at the surface of the previous one
18                        if (lastchambergrowth < 1)
19                                rgbstring = "0.9,0.9,0.9,i=\"growing=%g\"" % lastchambergrowth; //when the last chamber is growing, make it bright gray and add extra information in its "i" field
20                }
21                effectivesize = Math.max(effectivesize, MIN_PART_SIZE);
22                str += "p:sh=1,sx=%g,sy=%g,sz=%g,rz=3.14159265358979,vr=%s\n" % effectivesize % effectivesize % effectivesize % rgbstring;
23                if (i > 0)
24                        str += "j:%d,%d,sh=1,dx=%g,rz=%g\n" % (i - 1) % i % (size * shift) % (angle_delta + i * angle_delta_delta);
25                size *= growing;
26        }
27        return str;
28}
29
30function setGenotype(mode)
31{
32        if (mode->opt == "growth")
33        {
34                mode->cr.data->genes = mode->parent_genes;
35                mode->cr.data->lifeparams = mode->parent_lifeparams;
36        }
37
38        else if (mode->opt == "birth")
39        {
40                foram_uid += 1;
41                var new_id = "c" + string(foram_uid);
42                mode->cr.data->genes = String.deserialize(String.serialize(mode->genes));
43                mode->cr.data->lifeparams = {"max_energy_level" : mode->energy0, "gen" : mode->gen,  "hibernated" : 0, "species" : mode->species, "reproduce" : 0, "dir" : randomDir(), "dir_counter" : Math.random(int(secToSimSteps(ExpProperties.dir_change_sec))), "chamber_growth" : -1, "division_time" : -1, "uid" : new_id};
44
45                var oper = "cloning";
46                var inherit = [1.0];
47                if (mode->parentsuids.size > 1)
48                {
49                        oper = "cross-over";
50                        inherit = [0.5, 0.5];
51                }
52
53                var dict = {"Time": Simulator.stepNumber, "FromIDs": mode->parentsuids, "ID": new_id, "Inherited": inherit, "Operation": oper, "Kind" : mode->gen};
54                if (ExpProperties.print_evol_progress == 1)
55                        Simulator.print("[OFFSPRING] " + String.serialize(dict));
56        }
57}
58
59function getEnergy0(radius)
60{
61        return energyFromVolume(micronsToFrams(radius), 1);
62}
63
64function gametsDivision(parent_energy, energy0)
65{
66        var number = 1;
67        var result = parent_energy;
68        while ((result - ExpProperties.divisionCost) >= energy0)
69        {
70                result = (result - ExpProperties.divisionCost) / 2;
71                number *= 2;
72        }
73        //Simulator.print("parent: " + parent_energy + " result: " + result + " number " + number);
74        return {"energy" : result, "number" : number};
75}
76
77function reproduce_haploid(parent, parent2, clone)
78{
79        var number, energy0, new_genes, gen;
80        if (clone == 1)
81        {
82                var offspring = gametsDivision(parent.energy, getEnergy0(getGene(parent, "energies0", 0)[0]));
83                energy0 = offspring->energy;
84                number = offspring->number;
85                new_genes = parent.data->genes;
86                parent.data->lifeparams->gen = 1 - parent.data->lifeparams->gen; //because of reversal of "gen" in createOffspring function
87                gen = parent.data->lifeparams->gen;
88        }
89        else
90        {
91                var offspring1 = gametsDivision(parent.energy, getEnergy0(getGene(parent, "energies0", 0)[1]));
92                var offspring2 = gametsDivision(parent2.energy, getEnergy0(getGene(parent2, "energies0", 0)[1]));
93                energy0 = (offspring1->energy + offspring2->energy);
94                number = ExpProperties.gametSuccessRate * (offspring1->number + offspring2->number) / 2;
95                new_genes = [parent.data->genes, parent2.data->genes];
96                gen = 1 - parent.data->lifeparams->gen;
97
98                if (ExpProperties.logging == 1)
99                {
100                        log(createLogVector(parent, parent.energy), ExpProperties.logPref + "repro_energies_log.txt");
101                        log(createLogVector(parent2, parent2.energy), ExpProperties.logPref + "repro_energies_log.txt");
102                        log(createLogVector(parent, number), ExpProperties.logPref + "repro_num_log.txt");
103                        log(createLogVector(parent, parent.lifespan), ExpProperties.logPref + "lifespan_log.txt");
104                        log(createLogVector(parent2, parent2.lifespan), ExpProperties.logPref + "lifespan_log.txt");
105                }
106        }
107
108        //Simulator.print("haploid number of offspring: " + number + " energ0: " + energy0);
109
110        for (var j = 0; j < number; j++)
111        {
112                createOffspring(create_genotype(ExpProperties.chamber_proculus_diplo, 1, colors[1], 1), energy0, new_genes, parent.data->lifeparams, [parent.data->lifeparams->uid, parent2.data->lifeparams->uid]);
113        }
114}
115
116function reproduce_diploid(parent)
117{
118        var offspring = gametsDivision(parent.energy, getEnergy0(getGene(parent, "energies0", 0)[0]));
119        var energy0 = offspring->energy;
120        var number = offspring->number;
121
122        if (ExpProperties.logging == 1)
123        {
124                log(createLogVector(parent, parent.energy), ExpProperties.logPref + "repro_energies_log.txt");
125                log(createLogVector(parent, number), ExpProperties.logPref + "repro_num_log.txt");
126                log(createLogVector(parent, parent.lifespan), ExpProperties.logPref + "lifespan_log.txt");
127        }
128
129        //Simulator.print("diploid number of offspring: " + number+ " energ0: " + energy0);
130
131        for (var j = 0; j < number / 2; j++)
132        {
133                var crossed = 0;
134                //crossover
135                if (Math.rnd01 < ExpProperties.crossprob)
136                {
137                        crossover(parent, "min_repro_energies");
138                        crossed = 1;
139                }
140
141                for (var k = 0; k < 2; k++)
142                {
143                        createOffspring(create_genotype(ExpProperties.chamber_proculus_haplo, 1, colors[0], 1), energy0, parent.data->genes[0], parent.data->lifeparams, [parent.data->lifeparams->uid]);
144                }
145
146                //reverse of crossover for fossilization
147                if (crossed == 1)
148                {
149                        crossover(parent, "min_repro_energies");
150                        crossed = 0;
151                }
152
153        }
154}
155
156function reproduce_parents(species)
157{
158        var parent1 = null;
159        var parent2 = null;
160        var pop = Populations[0];
161        for (var i = pop.size - 1; i >= 0; i--)
162        {
163                if (pop[i].data->lifeparams->reproduce == 1 && pop[i].data->lifeparams->species == species)
164                {
165                        if ((pop[i].data->lifeparams->gen == 1) || ((pop[i].data->lifeparams->gen == 0) && ExpProperties.stress == 0))
166                        {
167                                continue;
168                        }
169                        else if (parent1 == null)
170                        {
171                                parent1 = pop[i];
172                        }
173                        else if (parent2 == null)
174                        {
175                                parent2 = pop[i];
176                        }
177                        if (parent1 != null && parent2 != null)
178                        {
179                                //when parents are ready for reproduction start gametogenesis
180                                if (parent1.data->lifeparams->division_time == -1 && parent2.data->lifeparams->division_time == -1)
181                                {
182                                        var time = int(secToSimSteps(ExpProperties.gametoPeriodSec));
183                                        parent1.data->lifeparams->division_time = time;
184                                        parent2.data->lifeparams->division_time = time;
185                                        parent1.idleen = 0;
186                                        parent2.idleen = 0;
187                                        //Simulator.print("parents "+parent1.uid + " " + parent2.uid + " ready to repro: "+Simulator.stepNumber);
188                                }
189                                //when gametogenesis is finished fuse gamets
190                                else if (parent1.data->lifeparams->division_time == 0 && parent2.data->lifeparams->division_time == 0)
191                                {
192                                        reproduce_haploid(parent1, parent2, 0);
193                                        //print_repro_info(parent1);
194                                        //print_repro_info(parent2);
195                                        pop.kill(parent1);
196                                        pop.kill(parent2);
197                                        parent1 = null;
198                                        parent2 = null;
199                                }
200                        }
201                }
202        }
203}
204
205function readyToRepro(cr)
206{
207        var reproduced = 1;
208
209        if (cr.data->lifeparams->gen == 1)
210        {
211                reproduce_diploid(cr);
212        }
213
214        else if (ExpProperties.stress == 0)
215        {
216                reproduce_haploid(cr, null, 1);
217        }
218
219        else
220        {
221                if (cr.signals.size == 0)
222                {
223                        cr.signals.add("repro" + cr.data->lifeparams->species);
224                        cr.signals[0].power = 1;
225                }
226                reproduced = 0;
227                cr.data->lifeparams->reproduce = 1;
228        }
229
230        if (reproduced == 1)
231        {
232                //print_repro_info(cr);
233                Populations[0].kill(cr);
234        }
235
236        return reproduced;
237}
238
239function foramReproduce(cr)
240{
241        var properEnergy = cr.energy >= getGene(cr, "min_repro_energies", 0)[cr.data->lifeparams->gen];
242        var reproduced = 0;
243
244        //if creature has proper energy
245        if ( properEnergy )
246        {
247                //reproduce with probability repro_prob
248                if (Math.rnd01 <= ExpProperties.repro_prob) //TODO env trigger
249                {
250                        reproduced = readyToRepro(cr);
251                }
252                else if (cr.signals.receive("repro" + cr.data->lifeparams->species) > 0)
253                {
254                        reproduced = readyToRepro(cr);
255                }
256                if (reproduced == 1)
257                        return 1;
258        }
259
260        else if (!properEnergy)
261        {
262                cr.signals.clear();
263                cr.data->lifeparams->reproduce = 0;
264        }
265
266        return 0;
267}
268
269function crossover(parent, gene)
270{
271        var tmp = parent.data->genes[0][gene];
272        parent.data->genes[0][gene] = parent.data->genes[1][gene];
273        parent.data->genes[1][gene] = tmp;
274}
275
276function createOffspring(geno, energy, parent_genes, parent_lifeparams, parentsuids)
277{
278        curColor = colors[1 - parent_lifeparams->gen];
279        var cr = createAndRotate(geno, 0, 2 * Math.pi, 0);
280        cr.energy0 = energy;
281        cr.energy = cr.energy0;
282        setGenotype({"opt" : "birth", "cr" : cr, "gen" : 1 - parent_lifeparams->gen, "species" : parent_lifeparams->species, "energy0" : cr.energy0, "genes" : parent_genes, "parentsuids" : parentsuids});
283        placeRandomlyNotColliding(cr);
284}
285
286function print_repro_info(cr)
287{
288        if (ExpProperties.print_evol_progress == 1)
289                Simulator.print("Reproduced " + cr.data->lifeparams->gen + " of species " + cr.data->lifeparams->species + " energy: " + cr.energy);
290}
Note: See TracBrowser for help on using the repository browser.