Changeset 401 for experiments/frams/foraminifera
- Timestamp:
- 06/24/15 19:28:25 (10 years ago)
- Location:
- experiments/frams/foraminifera/data/scripts
- Files:
-
- 2 added
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
experiments/frams/foraminifera/data/scripts/forams_benthic.expdef
r399 r401 1 1 expdef: 2 name: Foraminifera simulation2 name:Benthic foraminifera reproduction 3 3 info:~ 4 4 Genes and parameter values which control reproduction are stored in user1 and user2 fields. … … 16 16 code:~ 17 17 18 /* 19 changes 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 18 28 global foodenergywaiting; 19 29 global reprocounter; 30 global delta_change; 31 32 @include "forams_repro.inc" 20 33 21 34 // -------------------------------- experiment begin -------------------------------- … … 23 36 function onExpDefLoad() 24 37 { 38 25 39 // define genotype and creature groups 26 40 GenePools.clear(); 27 41 Populations.clear(); 28 42 GenePools[0].name = "Unused"; 43 44 SignalView.mode = 1; 29 45 30 46 var pop = Populations[0]; … … 36 52 pop.energy = 1; 37 53 pop.selfmask = 0x10001; 38 pop.othermask = 0x30000; 54 pop.othermask = 0x20001; 55 //pop.selfmask = 0x20002; pop.othermask = 0x10002; 39 56 pop.perfperiod = 25; 40 57 … … 45 62 pop.energy = 1; 46 63 pop.selfmask = 0x20002; 47 pop.othermask = 0x30002; 48 49 ExpParams.genh = "/*F*/1,1.1,1.1,1.1,1,1,1"; 50 ExpParams.gend = "/*F*/1,1,1,1,1,1,1"; 51 ExpParams.p_mut = 50; 64 pop.othermask = 0x10000; 65 66 67 var size_h = ExpParams.haplo_rad * ExpParams.delta_rate + ExpParams.haplo_rad; 68 var size_d = ExpParams.diplo_rad * ExpParams.delta_rate + ExpParams.diplo_rad; 69 ExpParams.gend = "//0\np:sh=1,sx=" + ExpParams.diplo_rad + ",sy=" + ExpParams.diplo_rad + ",sz=" + ExpParams.diplo_rad + ", rz=3.14159265358979"; 70 ExpParams.genh = "//0\np:sh=1,sx=" + size_h + ",sy=" + size_h + ",sz=" + size_h + ", rz=3.14159265358979"; 52 71 ExpParams.e_meta = 0.1; 53 ExpParams.feedrate = 0. 7;72 ExpParams.feedrate = 0.5; 54 73 ExpParams.feede0 = 100; 55 74 ExpParams.feedtrans = 3; 56 75 ExpParams.creath = -0.99; //just above the bottom 57 ExpParams.foodgen = "//0\np:sh= 1,sx=0.1,sy=0.1,sz=0.1";76 ExpParams.foodgen = "//0\np:sh=2,sx=0.1,sy=0.1,sz=0.1\nn:d=T,p=0"; 58 77 ExpParams.autorestart = 0; 59 78 ExpParams.psize = 10; 60 ExpParams.ofnumh = 14; 61 ExpParams.ofnumd = 4; 62 ExpParams.v_min_d = 200; 63 ExpParams.v_min_h = 500; 64 ExpParams.age_min_d = 150; 65 ExpParams.age_min_h = 300; 66 ExpParams.crossprob = 0.3; 79 ExpParams.logging = 0; 80 81 //number of offspring 82 ExpParams.ofnumh = 40; 83 ExpParams.ofnumd = 25; 84 //minial volume for reproduction 85 ExpParams.v_min_d = 300; 86 ExpParams.v_min_h = 300; 87 //radius of the chamber 88 ExpParams.haplo_rad = 1.2; 89 ExpParams.diplo_rad = 0.6; 90 //minimal age for reproduction 91 ExpParams.age_min_d = 100; 92 ExpParams.age_min_h = 100; 93 //crossover probability 94 ExpParams.crossprob = 0.4; 95 //mutation probability 96 ExpParams.mutationprob = 0.2; 67 97 ExpParams.repro_time = 200; 68 98 ExpParams.repro_thr = 1; 99 100 //size change rate 101 ExpParams.delta_rate = 0.1; 102 //grwoth speed in time steps 103 ExpParams.growth_step = 50; 69 104 70 105 ExpState.totaltestedcr = 0; … … 73 108 reprocounter = 0; 74 109 75 ExpParams.wsize = 30; 76 110 ExpParams.wsize = 50; 77 111 World.wrldwat = 50; 78 112 World.wrldsiz = ExpParams.wsize; 79 113 World.wrldbnd = 1; 114 115 delta_change = 0.5; 80 116 } 81 117 … … 94 130 cr.energ0 = ExpParams.v_min_h - ExpParams.repro_thr; 95 131 cr.energy = cr.energ0; 96 cr.user1 = {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h };97 cr.user2 = {"Va" : ExpParams.v_min_h - ExpParams.repro_thr, "gen" : 0 132 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}; 133 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}; 98 134 } 99 135 ExpState.totaltestedcr = 0; … … 124 160 if (cr != null) 125 161 { 126 cr.rotate(0, 0,Math.rnd01*Math.twopi);162 //cr.rotate(0,0,Math.rnd01*Math.twopi); 127 163 if ((typeof(g.user1) == "Vector") && (g.user1.size >= 3)) 128 { // [x,y,energy] 164 { 165 // [x,y,energy] 129 166 cr.move(g.user1[0] - cr.center_x, g.user1[1] - cr.center_y, 0); 130 167 cr.energy = g.user1[2]; … … 132 169 else 133 170 { 134 cr.move(Math.rnd01 *World.wrldsiz - cr.center_x, Math.rnd01*World.wrldsiz - cr.center_y, 0);171 cr.move(Math.rnd01 * World.wrldsiz - cr.center_x, Math.rnd01 * World.wrldsiz - cr.center_y, 0); 135 172 } 136 173 } … … 148 185 File.writeComment("saved by '%s.expdef'" % Simulator.expdef); 149 186 150 var i, tmpvec = [];151 152 for 187 var tmpvec = [], i; 188 189 for(var cr in Populations[1]) 153 190 tmpvec.add([cr.center_x, cr.center_y, cr.energy]); 154 191 … … 170 207 } 171 208 209 function placeRandomlyNotColliding(cr) 210 { 211 var retry = 100; //try 100 times 212 while (retry--) 213 { 214 placeCreatureRandomly(cr, 0, 0); 215 if (!cr.boundingBoxCollisions(0)) 216 return cr; 217 } 218 219 Populations[0].delete(cr); 220 } 221 172 222 function readyToRepro(cr) 173 223 { 174 224 cr.signals.add("repro"); 175 cr.signals.get(0).power = 1; 225 cr.signals[0].power = 1; 226 176 227 } 177 228 178 229 function onCreaturesStep(cr) 179 230 { 180 cr.moveAbs(cr.pos_x, cr.pos_y, 0); 231 cr.moveAbs(cr.pos_x, cr.pos_y, 0); //adjustment in z axis 181 232 var p = cr.getMechPart(0); 182 233 var n = cr.signals.receiveSet("food", ExpParams.food_range); 183 234 235 //if signals are received find the source of the nearest 184 236 if (n.size > 0) 185 237 { 238 186 239 var i; 187 240 var mp; … … 191 244 var mindistvec = null; 192 245 193 if (Math.rnd01 < 0.8) 194 { 195 for (i = 0;i < n.size;i++) 196 { 197 mp = n[i].value; 198 distvec.set(mp.pos); 199 distvec.sub(p.pos); 200 dist = distvec.length; 201 if (dist < mindist) 202 { 203 mindist = dist; 204 mindistvec = distvec.clone(); 205 } 206 } 207 } 208 else 209 { 210 mp = n[Math.random(n.size)].value; 246 for (i = 0; i < n.size; i++) 247 { 248 mp = n[i].value; 211 249 distvec.set(mp.pos); 212 250 distvec.sub(p.pos); 213 mindistvec = distvec.clone(); 251 dist = distvec.length; 252 if (dist < mindist) 253 { 254 mindist = dist; 255 mindistvec = distvec.clone(); 256 } 214 257 } 215 258 216 259 mindistvec.normalize(); 217 mindistvec.scale( -0.1);260 mindistvec.scale(-0.08); 218 261 cr.localDrive = mindistvec; 219 262 } 263 220 264 else 221 265 { 222 cr.localDrive = (0.1, 0, 0); 223 } 224 225 var properAge = cr.user2["Va"] >= cr.user1["vamin"]; 226 var properSize = cr.user1["amin"] <= cr.lifespan; 227 228 //if creature has proper age and cytoplasm amount 229 if ( properAge && properSize ) 230 { 231 //reproduce with probability repro_prob 232 if (Math.rnd01 <= ExpParams.repro_prob) 266 cr.localDrive = (0.1 * Math.rnd01, 0.1 * Math.rnd01, 0); 267 } 268 269 //energy costs depend on size 270 if (cr.energy > 100) 271 { 272 // cr.energy_m = cr.user2["Va"]/cr.user2["vinit"]; 273 } 274 275 if (cr.lifespan >= ExpParams.max_age) 276 { 277 Populations[0].kill(cr); 278 } 279 280 //foram growth 281 else if (cr.lifespan == cr.user2["growth_step"]) 282 { 283 var pos = [cr.center_x, cr.center_y, cr.center_z]; 284 var energy = cr.energy; 285 var cr2 = null; 286 if (cr.user2["gen"] == 0) 287 { 288 var new_r = ExpParams.haplo_rad * Math.min(Math.max(cr.user2["Va"] / cr.user2["vinit"] * 0.5, 1), 2.5); 289 cr.user2["rsize"] = new_r; 290 cr2 = Populations[0].add("//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979"); 291 cr2.user1 = {"vamin" : cr.user1["vamin"], "amin": cr.user1["amin"], "delta_h" : cr.user1["delta_h"], "delta_d" : cr.user1["delta_d"]}; 292 } 293 else if (cr.user2["gen"] == 1) 294 { 295 var new_r = ExpParams.diplo_rad * Math.min(Math.max(cr.user2["Va"] / cr.user2["vinit"] * 0.5, 1), 2.5); 296 cr.user2["rsize"] = new_r; 297 298 var geno = "//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979"; 299 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? 300 //TODO maybe it would be nice if they rotated so the "S" would show where they are going (direction/intention) 301 cr2 = Populations[0].add(geno); 302 303 304 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"] }]; 305 } 306 cr2.energy = energy; 307 cr2.user2 = {"Va" : cr.user2["Va"], "gen" : cr.user2["gen"], "growth_step" : cr.user2["growth_step"], "rsize" : cr.user2["rsize"], "vinit": cr.user2["vinit"]}; 308 cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z); 309 310 Populations[0].delete(cr); 311 } 312 else 313 { 314 var properSize = 0; 315 316 if (cr.user2["gen"] == 0) 317 { 318 properSize = cr.user2["Va"] >= cr.user1["vamin"]; 319 } 320 else 321 { 322 properSize = cr.user2["Va"] >= cr.user1[0]["vamin"]; 323 } 324 325 //if creature has proper age and cytoplasm amount 326 if ( properSize ) 327 { 328 //reproduce with probability repro_prob 329 if (Math.rnd01 <= ExpParams.repro_prob) 330 { 331 readyToRepro(cr); 332 } 333 } 334 if ( properSize && (cr.signals.receive("repro") > 0)) 233 335 { 234 336 readyToRepro(cr); 235 337 } 236 }237 if ( properAge && properSize && (cr.signals.receive("repro") > 0))238 {239 readyToRepro(cr);240 338 } 241 339 } … … 270 368 cr.signals.add("food"); 271 369 272 cr.signals .get(0).value = cr.getMechPart(0);273 274 var retry = 50; //try 50 times370 cr.signals[0].value = cr.getMechPart(0); 371 372 var retry = 100; //try 100 times 275 373 while (retry--) 276 374 { 277 375 placeCreatureRandomly(cr, 0, 0); 278 cr.signals.get(0).value = cr.getMechPart(0);279 376 if (!cr.boundingBoxCollisions(0)) 280 377 return cr; … … 292 389 Collision.Creature1.energy_m = Collision.Creature1.energy_m + e; 293 390 Collision.Creature2.energy_p = Collision.Creature2.energy_p + e; 294 var ener = float(Collision.Creature2.user2 .get("Va"));391 var ener = float(Collision.Creature2.user2["Va"]); 295 392 var sum = float(float(ener) + float(e)); 296 Collision.Creature2.user2 .set("Va", float(sum));393 Collision.Creature2.user2["Va"] = float(sum); 297 394 } 298 395 } … … 300 397 // -------------------------------- food end -------------------------------- 301 398 302 // -------------------------------- step begin --------------------------------303 304 function reproduce(repro_list, number)305 {306 for (var i = 0; i < repro_list.size; i++)307 {308 var parent = Populations[0].get(repro_list[i]);309 310 var energ = parent.user2["Va"] / number;311 for (var j = 0; j < number; j++)312 {313 var cr = Populations[0].add(ExpParams.gend);314 cr.energ0 = energ;315 cr.energy = cr.energ0;316 if (parent.user2["gen"] == 0)317 {318 cr.user1 = {"vamin" : ExpParams.v_min_d, "amin": ExpParams.age_min_d};319 }320 else321 {322 cr.user1 = {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h};323 }324 cr.user2 = { "Va" : cr.energ0, "gen" : 1 - parent.user2["gen"] };325 placeCreatureRandomly(cr, 0, 0);326 }327 }328 for (var j = 0; j < repro_list.size; j++)329 {330 Populations[0].kill(repro_list[j]);331 }332 }333 399 334 400 function log(tolog, fname) 335 401 { 336 var f = File.appendDirect(fname, " description");402 var f = File.appendDirect(fname, "forams data"); 337 403 f.writeString("" + Simulator.stepNumber); 338 for (var i = 0; i < tolog.size; i++)404 for (var i = 0; i < tolog.size; i++) 339 405 { 340 406 f.writeString(";" + tolog[i]); … … 346 412 347 413 348 function onStep()349 {350 var haploids = 0;351 var diploids = 0;352 var e_inc_h = 0.0;353 var e_inc_d = 0.0;354 var e_nut = 0.0;355 356 for (var i = 0; i < Populations[0].size; i++)357 {358 var cr = Populations[0].get(i);359 if (cr.user2["gen"] == 0)360 {361 haploids += 1;362 e_inc_h += cr.energy;363 }364 else365 {366 diploids += 1;367 e_inc_d += cr.energy;368 }369 }370 371 for (var i = 0; i < Populations[1].size; i++)372 {373 var cr = Populations[1].get(i);374 e_nut += cr.energy;375 }376 377 if (haploids < 2 && diploids == 0)378 {379 Simulator.print("no more creatures, stopped.");380 Simulator.stop();381 }382 383 var l1 = Vector.new();384 l1 = [haploids, diploids, Populations[1].size];385 var l2 = Vector.new();386 l2 = [e_inc_h, e_inc_d, e_nut];387 388 log(l1, "log.txt");389 log(l2, "log2.txt");390 //food growth ---------------------------------------------391 foodenergywaiting = foodenergywaiting + ExpParams.feedrate;392 if (foodenergywaiting > ExpParams.feede0)393 {394 for (var i = 0; i < ExpParams.foodPop; i++)395 {396 addfood();397 }398 399 foodenergywaiting = 0.0;400 Simulator.checkpoint();401 }402 403 //reproduction --------------------------------------------404 reprocounter += 1;405 if (reprocounter > ExpParams.repro_time)406 {407 reprocounter = 0;408 var to_repro_h = Vector.new();409 var to_repro_d = Vector.new();410 for (var i = 0; i < Populations[0].size; i++)411 {412 var cr = Populations[0].get(i);413 if (cr.signals.size > 0)414 {415 if (cr.user2["gen"] == 0)416 {417 to_repro_h.add(i);418 }419 else420 {421 to_repro_d.add(i);422 }423 }424 }425 if (to_repro_h.size > 0)426 {427 reproduce(to_repro_h, ExpParams.ofnumh);428 }429 if (to_repro_d.size > 1)430 {431 reproduce(to_repro_d, ExpParams.ofnumd);432 }433 }434 435 //check for death -----------------------------------------------436 if (Populations[0].size == 0)437 {438 if (ExpParams.autorestart)439 {440 Simulator.print("no more creatures, restarting...");441 onExpInit();442 }443 else444 {445 Simulator.print("no more creatures, stopped.");446 Simulator.stop();447 }448 }449 }450 451 // -------------------------------- step end --------------------------------452 453 414 454 415 @include "standard_events.inc" … … 457 418 458 419 prop: 420 id:max_age 421 name:Maximal age 422 type:d 100 1000 500 423 424 prop: 459 425 id:wsize 460 name: world size426 name:World size 461 427 type:d 10 1000 20 462 428 463 429 prop: 430 id:haplo_rad 431 name:Haploid radius 432 type:f 0.1 3 1.2 433 434 prop: 435 id:growth_step 436 name:Growth step 437 type:d 50 10000 1000 438 439 prop: 440 id:delta_rate 441 name:Delta rate 442 type:f 0.0001 0.1 0.001 443 444 prop: 445 id:diplo_rad 446 name:Diploid radius 447 type:f 0.1 3 0.6 448 449 prop: 464 450 id:foodPop 465 name: food size451 name:Food size 466 452 type:d 1 1000 10 467 453 468 454 prop: 469 455 id:age_min 470 name: minimal age for reproduction456 name:Minimal age for reproduction 471 457 type:d 100 10000 200 472 458 … … 486 472 id:v_min_h 487 473 name:Min reproduction energy of haploid forams 488 type: d 100 10000 300474 type:f 10 10000 300 489 475 group:Foraminifera 490 476 … … 492 478 id:v_min_d 493 479 name:Min reproduction energy of diploid forams 494 type: d 100 10000 150480 type:f 10 10000 150 495 481 group:Foraminifera 496 482 497 483 prop: 498 484 id:repro_thr 499 name: treshold for reproduction485 name:Threshold for reproduction 500 486 type:d 1 1000 1 501 487 502 488 prop: 503 489 id:food_range 504 name: range of food smell490 name:Range of food smell 505 491 type:d 0 10000 10000 506 492 507 493 prop: 508 494 id:repro_time 509 name: time before reproduction495 name:Time before reproduction 510 496 type:d 0 1000 511 497 512 498 prop: 513 499 id:psize 514 name: initial population size500 name:Initial population size 515 501 type:d 1 1000 100 502 503 prop: 504 id:logging 505 name:Log statistics to file 506 type:d 0 1 0 516 507 517 508 prop: … … 529 520 prop: 530 521 id:repro_prob 531 name: probability of reproduction522 name:Probability of reproduction 532 523 type:f 0 1 0.9 533 524 534 525 prop: 535 526 id:crossprob 536 name:crossover probability 537 type:f 0 1 527 name:Crossover probability 528 type:f 0 1 0 529 530 prop: 531 id:mutationprob 532 name:Mutation probability 533 type:f 0 1 0 538 534 539 535 prop: … … 561 557 562 558 prop: 563 id:p_mut564 name:Mutations565 type:f 0 100566 567 prop:568 559 id:e_meta 569 560 name:Idle metabolism … … 600 591 id:autorestart 601 592 name:Restart after extinction 602 group:603 593 help:Restart automatically this experiment after the last creature has died? 604 594 type:d 0 1
Note: See TracChangeset
for help on using the changeset viewer.