Ignore:
Timestamp:
06/24/15 19:28:25 (10 years ago)
Author:
Maciej Komosinski
Message:

Extended Foraminifera simulation - physical collisions; visible haplo/diplo generations; growing; and much more

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  
    11expdef:
    2 name:Foraminifera simulation
     2name:Benthic foraminifera reproduction
    33info:~
    44Genes and parameter values which control reproduction are stored in user1 and user2 fields.
     
    1616code:~
    1717
     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
    1828global foodenergywaiting;
    1929global reprocounter;
     30global delta_change;
     31
     32@include "forams_repro.inc"
    2033
    2134// -------------------------------- experiment begin --------------------------------
     
    2336function onExpDefLoad()
    2437{
     38
    2539        // define genotype and creature groups
    2640        GenePools.clear();
    2741        Populations.clear();
    2842        GenePools[0].name = "Unused";
     43
     44        SignalView.mode = 1;
    2945
    3046        var pop = Populations[0];
     
    3652        pop.energy = 1;
    3753        pop.selfmask = 0x10001;
    38         pop.othermask = 0x30000;
     54        pop.othermask = 0x20001;
     55        //pop.selfmask = 0x20002; pop.othermask = 0x10002;
    3956        pop.perfperiod = 25;
    4057
     
    4562        pop.energy = 1;
    4663        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";
    5271        ExpParams.e_meta = 0.1;
    53         ExpParams.feedrate = 0.7;
     72        ExpParams.feedrate = 0.5;
    5473        ExpParams.feede0 = 100;
    5574        ExpParams.feedtrans = 3;
    5675        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";
    5877        ExpParams.autorestart = 0;
    5978        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;
    6797        ExpParams.repro_time = 200;
    6898        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;
    69104
    70105        ExpState.totaltestedcr = 0;
     
    73108        reprocounter = 0;
    74109
    75         ExpParams.wsize = 30;
    76 
     110        ExpParams.wsize = 50;
    77111        World.wrldwat = 50;
    78112        World.wrldsiz = ExpParams.wsize;
    79113        World.wrldbnd = 1;
     114
     115        delta_change = 0.5;
    80116}
    81117
     
    94130                cr.energ0 = ExpParams.v_min_h - ExpParams.repro_thr;
    95131                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};
    98134        }
    99135        ExpState.totaltestedcr = 0;
     
    124160                if (cr != null)
    125161                {
    126                         cr.rotate(0, 0, Math.rnd01*Math.twopi);
     162                        //cr.rotate(0,0,Math.rnd01*Math.twopi);
    127163                        if ((typeof(g.user1) == "Vector") && (g.user1.size >= 3))
    128                         { // [x,y,energy]
     164                        {
     165                                // [x,y,energy]
    129166                                cr.move(g.user1[0] - cr.center_x, g.user1[1] - cr.center_y, 0);
    130167                                cr.energy = g.user1[2];
     
    132169                        else
    133170                        {
    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);
    135172                        }
    136173                }
     
    148185        File.writeComment("saved by '%s.expdef'" % Simulator.expdef);
    149186
    150         var i, tmpvec = [];
    151 
    152         for (var cr in Populations[1])
     187        var tmpvec = [], i;
     188
     189        for(var cr in Populations[1])
    153190                tmpvec.add([cr.center_x, cr.center_y, cr.energy]);
    154191
     
    170207}
    171208
     209function 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
    172222function readyToRepro(cr)
    173223{
    174224        cr.signals.add("repro");
    175         cr.signals.get(0).power = 1;
     225        cr.signals[0].power = 1;
     226
    176227}
    177228
    178229function onCreaturesStep(cr)
    179230{
    180         cr.moveAbs(cr.pos_x, cr.pos_y, 0);
     231        cr.moveAbs(cr.pos_x, cr.pos_y, 0); //adjustment in z axis
    181232        var p = cr.getMechPart(0);
    182233        var n = cr.signals.receiveSet("food", ExpParams.food_range);
    183234
     235        //if signals are received find the source of the nearest
    184236        if (n.size > 0)
    185237        {
     238
    186239                var i;
    187240                var mp;
     
    191244                var mindistvec = null;
    192245
    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;
    211249                        distvec.set(mp.pos);
    212250                        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                        }
    214257                }
    215258
    216259                mindistvec.normalize();
    217                 mindistvec.scale( -0.1);
     260                mindistvec.scale(-0.08);
    218261                cr.localDrive = mindistvec;
    219262        }
     263
    220264        else
    221265        {
    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))
    233335                {
    234336                        readyToRepro(cr);
    235337                }
    236         }
    237         if ( properAge && properSize && (cr.signals.receive("repro") > 0))
    238         {
    239                 readyToRepro(cr);
    240338        }
    241339}
     
    270368        cr.signals.add("food");
    271369
    272         cr.signals.get(0).value = cr.getMechPart(0);
    273 
    274         var retry = 50; //try 50 times
     370        cr.signals[0].value = cr.getMechPart(0);
     371
     372        var retry = 100; //try 100 times
    275373        while (retry--)
    276374        {
    277375                placeCreatureRandomly(cr, 0, 0);
    278                 cr.signals.get(0).value = cr.getMechPart(0);
    279376                if (!cr.boundingBoxCollisions(0))
    280377                        return cr;
     
    292389                Collision.Creature1.energy_m = Collision.Creature1.energy_m + e;
    293390                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"]);
    295392                var sum = float(float(ener) + float(e));
    296                 Collision.Creature2.user2.set("Va", float(sum));
     393                Collision.Creature2.user2["Va"] = float(sum);
    297394        }
    298395}
     
    300397// -------------------------------- food end --------------------------------
    301398
    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                         else
    321                         {
    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 }
    333399
    334400function log(tolog, fname)
    335401{
    336         var f = File.appendDirect(fname, "description");
     402        var f = File.appendDirect(fname, "forams data");
    337403        f.writeString("" + Simulator.stepNumber);
    338         for (var i = 0; i < tolog.size; i++)
     404        for (var  i = 0; i < tolog.size; i++)
    339405        {
    340406                f.writeString(";" + tolog[i]);
     
    346412
    347413
    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                 else
    365                 {
    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                                 else
    420                                 {
    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                 else
    444                 {
    445                         Simulator.print("no more creatures, stopped.");
    446                         Simulator.stop();
    447                 }
    448         }
    449 }
    450 
    451 // -------------------------------- step end --------------------------------
    452 
    453414
    454415@include "standard_events.inc"
     
    457418
    458419prop:
     420id:max_age
     421name:Maximal age
     422type:d 100 1000 500
     423
     424prop:
    459425id:wsize
    460 name:world size
     426name:World size
    461427type:d 10 1000 20
    462428
    463429prop:
     430id:haplo_rad
     431name:Haploid radius
     432type:f 0.1 3 1.2
     433
     434prop:
     435id:growth_step
     436name:Growth step
     437type:d 50 10000 1000
     438
     439prop:
     440id:delta_rate
     441name:Delta rate
     442type:f 0.0001 0.1 0.001
     443
     444prop:
     445id:diplo_rad
     446name:Diploid radius
     447type:f 0.1 3 0.6
     448
     449prop:
    464450id:foodPop
    465 name:food size
     451name:Food size
    466452type:d 1 1000 10
    467453
    468454prop:
    469455id:age_min
    470 name:minimal age for reproduction
     456name:Minimal age for reproduction
    471457type:d 100 10000 200
    472458
     
    486472id:v_min_h
    487473name:Min reproduction energy of haploid forams
    488 type:d 100 10000 300
     474type:f 10 10000 300
    489475group:Foraminifera
    490476
     
    492478id:v_min_d
    493479name:Min reproduction energy of diploid forams
    494 type:d 100 10000 150
     480type:f 10 10000 150
    495481group:Foraminifera
    496482
    497483prop:
    498484id:repro_thr
    499 name:treshold for reproduction
     485name:Threshold for reproduction
    500486type:d 1 1000 1
    501487
    502488prop:
    503489id:food_range
    504 name:range of food smell
     490name:Range of food smell
    505491type:d 0 10000 10000
    506492
    507493prop:
    508494id:repro_time
    509 name:time before reproduction
     495name:Time before reproduction
    510496type:d 0 1000
    511497
    512498prop:
    513499id:psize
    514 name:initial population size
     500name:Initial population size
    515501type:d 1 1000 100
     502
     503prop:
     504id:logging
     505name:Log statistics to file
     506type:d 0 1 0
    516507
    517508prop:
     
    529520prop:
    530521id:repro_prob
    531 name:probability of reproduction
     522name:Probability of reproduction
    532523type:f 0 1 0.9
    533524
    534525prop:
    535526id:crossprob
    536 name:crossover probability
    537 type:f 0 1
     527name:Crossover probability
     528type:f 0 1 0
     529
     530prop:
     531id:mutationprob
     532name:Mutation probability
     533type:f 0 1 0
    538534
    539535prop:
     
    561557
    562558prop:
    563 id:p_mut
    564 name:Mutations
    565 type:f 0 100
    566 
    567 prop:
    568559id:e_meta
    569560name:Idle metabolism
     
    600591id:autorestart
    601592name:Restart after extinction
    602 group:
    603593help:Restart automatically this experiment after the last creature has died?
    604594type:d 0 1
Note: See TracChangeset for help on using the changeset viewer.