expdef: name:Reproduction of benthic foraminifera info:~ Basic information about this simulation: www.framsticks.com/foraminifera Technical information: Genes and parameter values which control reproduction are stored in data->genes and data->lifeparams fields. genes: genes which are not encoded in Ff genotype: min_repro_energy - Minimum energy necessary for reproduction hibernation - Defines foram behavior in the case of no nutrients lifeparams: Physiological parameters of foraminifera: max_energy_level - maximum energy level reached so far gen - generation: 0 haploid, 1 diploid species - species: 0 not hibernating 1 hibernating hibernated - 0/1 foram is/isn't hibernated reproduce - 0/1 foram isn't/is ready for reproduction ~ code:~ global chambers; global colors; global dir_change; global max_chamber_volume; global movePerStep; global nutrientenergywaiting; global o; global reprocounter; global changePeriod; global phase; global species_genes; @include "foraminifera.inc" // -------------------------------- experiment begin -------------------------------- function onExpDefLoad() { // define genotype and creature groups GenePools.clear(); Populations.clear(); GenePools[0].name = "Unused"; var pop = Populations[0]; pop.name = "Forams"; pop.en_assim = 0; pop.nnsim = 0; pop.enableperf = 1; pop.death = 1; pop.energy = 1; pop.selfmask = 0; pop.othermask = 0; //pop.selfmask = 0x20002; pop.othermask = 0x10002; pop.perfperiod = 25; pop.bodysim = 0; pop = Populations.addGroup("Nutrients"); pop.nnsim = 0; pop.enableperf = 0; pop.death = 1; pop.energy = 1; pop.selfmask = 0; pop.othermask = 0; //pop.othermask = 0x10002; pop.bodysim = 0; pop = Populations.addGroup("ReticulopodiaNutrients"); pop.nnsim = 0; pop.enableperf = 0; pop.death = 0; pop.energy = 0; pop.selfmask = 0; pop.othermask = 0; pop.bodysim = 0; //world SignalView.mode = 1; World.wrldwat = 200; World.wrldsiz = micronsToFrams(40000); World.wrldbnd = 1; ExpProperties.stress = 1; ExpProperties.creath = -0.99; //just above the bottom ExpProperties.autorestart = 0; //time ExpProperties.secPerStep = 480; ExpProperties.foramSpeedMmPerMin = 0.05; movePerStep = getMovePerStep(); //ExpProperties.visualize = 1; //uncomment to visualize reticulopodia and indicate nutrients positions //ExpProperties.logging = 1; //uncomment to enable logging simulation parameters to log files //reproduction ExpProperties.foramPop = 20; ExpProperties.crossprob = 0; ExpProperties.mutationprob = 0; ExpProperties.repro_time = 720; ExpProperties.gametoPeriod = 43200; ExpProperties.divisionCost = 15.6; reprocounter = 0; species_genes = []; init_chambers(); //morphology dir_change = 30000; ExpProperties.zone1_range = micronsToFrams(1000); ExpProperties.zone2_range = micronsToFrams(3000); ExpProperties.chamber_growth_time = 720; ExpProperties.chamberCostPerSec = 0.000001; ExpProperties.chamber_proculus_haplo = micronsToFrams(50); ExpProperties.chamber_difference_haplo = 0.0; ExpProperties.chamber_proculus_diplo = micronsToFrams(20); ExpProperties.chamber_difference_diplo = micronsToFrams(8); max_chamber_volume = [Vector.new(), Vector.new()]; for (var j = 0; j < 2; j++) { for (var i = 0; i < chambers[0].size; i++) { max_chamber_volume[j].add(((volumeInMicrons(getProperty(j, "chamber_proculus")) + volumeInMicrons(getProperty(j, "chamber_proculus") + (i) * getProperty(j, "chamber_difference")))*(i+1))/2); } } //energetics ExpProperties.min_repro_energ_haplo = 4; ExpProperties.min_repro_energ_diplo = 6; ExpProperties.e_meta = 0.0000005; ExpProperties.energy_hib = 0.0000001; ExpProperties.energy_move = 0.0000005; ExpProperties.energies0_haplo = energyFromVolume(micronsToFrams(20),1); ExpProperties.energies0_diplo = energyFromVolume(micronsToFrams(1.25),1); ExpProperties.feedtrans = 0.001; ExpProperties.e_repro_cost_haplo = 0.3; ExpProperties.e_repro_cost_diplo = 0.2; ExpProperties.e_death_level_haplo = 0.5; ExpProperties.e_death_level_diplo = 0.5; //nutrients changePeriod = 0; phase = "high"; ExpProperties.foodperiod = 3600; ExpProperties.foodPeriodChange = 0; ExpProperties.nutrientradius = micronsToFrams(10); ExpProperties.energy_nut = energyFromVolume(ExpProperties.nutrientradius,1); ExpProperties.feedrate = 1; ExpProperties.ingestion = 0.25; nutrientenergywaiting = 0; ExpState.totaltestedcr = 0; ExpState.nutrient = ""; } @include "standard_placement.inc" function volumeInMicrons(radiusInFrams) { return 4.0/3.0*Math.pi*Math.pow(framsToMicrons(radiusInFrams),3); } function energyFromVolume(base, isRadiusInFrams) { if (isRadiusInFrams == 1) //radius in frams { return ExpProperties.picoCarbonPerMikro*volumeInMicrons(base); } else //volume in microns { return ExpProperties.picoCarbonPerMikro * base; } } function getMovePerStep() { return micronsToFrams((ExpProperties.foramSpeedMmPerMin/60)*1000)*ExpProperties.secPerStep; } function micronsToFrams(micrometers) { return micrometers*0.025; } function framsToMicrons(framsworldunits) { return framsworldunits/0.025; } function getProperty(gen, prop_id) { var ploid = "haplo"; if (gen == 1) ploid = "diplo"; return ExpProperties.[prop_id + "_" + ploid]; } function getGene(cr, gen_id, gen_set) { if (cr.data->lifeparams->gen == 0) return cr.data->genes[gen_id]; else return cr.data->genes[gen_set][gen_id]; } function addForam(species, iter, chambernum, ploid) { var geno = createForamMorphology(species_genes[species]->morphotype, ploid, chambernum); var cr = Populations[0].add(geno); cr.name = "Initial creature" + species + "_" + iter; placeCreatureRandomly(cr, 0, 0); cr.energy0 = energyFromVolume(max_chamber_volume[ploid][chambernum],0); cr.energy = cr.energy0; setGenotype({"opt" : 0, "cr" : cr, "species" : species, "energy0" : cr.energy0, "genes" : species_genes[species]}); if (ploid == 1) { cr.data->lifeparams->gen = 1; cr.data->genes = [cr.data->genes, cr.data->genes]; //TODO two different genes sets } } function addInitialForam(species, iter) { var ploid = 0; if (Math.rnd01 > 0.5) { ploid = 1; } //add new foram with random energy bewtween starting energy and reproduction treshold addForam(species, iter, Math.rndUni(0,species_genes[species]->min_repro_energies[ploid]),ploid); } //new species can be added as a dictionary with parameter values that are different than default values function addSpecies(new_genes) { species_genes.add({"min_repro_energies" : [4,6], "energies0" : [20, 1.25], "hibernation" : 0, "morphotype" : 0}); for (var i = 0; i < new_genes.size; i++) { var key = new_genes.getKey(i); species_genes[species_genes.size-1][key] = new_genes[key]; } } function onExpInit() { Populations[0].clear(); Populations[1].clear(); Populations[2].clear(); //reticulopodia and nutrients if (species_genes.size == 0) { addSpecies({}); //default } for (var spec = 0; spec < species_genes.size; spec++) { for (var i = 0; i < ExpProperties.foramPop; i++) { addInitialForam(spec, i); } } o = Populations[0][0].getMechPart(0).orient.clone(); ExpState.totaltestedcr = 0; } function onExpLoad() { for (var pop in Populations) pop.clear(); Loader.addClass(sim_params.*); Loader.setBreakLabel(Loader.BeforeUnknown, "onExpLoad_Unknown"); Loader.run(); Simulator.print("Loaded " + Populations[0].size + " Forams and " + Populations[1].size + " nutrient objects"); } function onExpLoad_Unknown() { if (Loader.objectName == "org") // saved by the old expdef { var g = Genotype.newFromString(""); Loader.currentObject = g; Interface.makeFrom(g).setAllDefault(); Loader.loadObject(); var cr = Populations[0].add(g); if (cr != null) { //cr.rotate(0,0,Math.rnd01*Math.twopi); if ((typeof(g.data->genes) == "Vector") && (g.data->genes.size >= 3)) { // [x,y,energy] cr.move(g.data->genes[0] - cr.center_x, g.data->genes[1] - cr.center_y, 0); cr.energy = g.data->genes[2]; } else { cr.move(Math.rnd01 * World.wrldsiz - cr.center_x, Math.rnd01 * World.wrldsiz - cr.center_y, 0); } } } else if (Loader.objectName == "Creature") { Loader.currentObject = CreatureSnapshot.new(); Loader.loadObject(); Populations[0].add(Loader.currentObject); } } function onExpSave() { File.writeComment("saved by '%s.expdef'" % Simulator.expdef); var tmpvec = [], i; for(var cr in Populations[1]) tmpvec.add([cr.center_x, cr.center_y, cr.energy]); ExpState.nutrient = tmpvec; File.writeObject(sim_params.*); ExpState.nutrient = null; //vectors are only created for saving and then discarded for (var cr in Populations[0]) File.writeObject(cr); } // -------------------------------- experiment end -------------------------------- // -------------------------------- foram begin ----------------------------------- function setForamMeta(cr) { //percent of current energy cr.idleen = (ExpProperties.e_meta * cr.energy)*ExpProperties.secPerStep; } function lastChamberNum(cr) { return cr.numparts-1; } function getZoneRange(cr, zone_num) { return ExpProperties.["zone"+zone_num+"_range"]; } function onForamsBorn(cr) { setForamMeta(cr); if (ExpProperties.visualize == 1) { 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"); cr.data->reticulopodiacreature = ret; } } function placeRandomlyNotColliding(cr) { var retry = 100; //try 100 times while (retry--) { placeCreatureRandomly(cr, 0, 0); if (!cr.boundingBoxCollisions(0)) return cr; } Populations[0].delete(cr); } function visualization(cr) { var has_ret = 0; if (cr.data->reticulopodiacreature != null) { if (Populations[2].findUID(cr.data->reticulopodiacreature.uid) != null) { has_ret = 1; } } return has_ret; } function foramGrow(cr, chamber_num) { if ((chamber_num+1) < chambers[cr.data->lifeparams->species].size) { var geno = createForamMorphology(getGene(cr, "morphotype", 0), cr.data->lifeparams->gen, chamber_num+1); var cr2 = Populations[0].add(geno); cr2.energy0 = cr.energy; cr2.energy = cr2.energy0; setGenotype({"cr" : cr2, "parent_genes" : cr.data->genes, "parent_lifeparams" : cr.data->lifeparams, "opt" : 2, "energy0" : cr.energy0}); cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z); setForamMeta(cr2); if (visualization(cr)) { Populations[2].delete(cr.data->reticulopodiacreature); } Populations[0].delete(cr); } } function stepToNearest(cr) { var p = cr.getMechPart(0); var n = cr.signals.receiveSet("nutrient", getZoneRange(cr,2)); //if signals are received find the source of the nearest if (n.size > 0) { var i; var mp; var distvec = XYZ.new(0, 0, 0); var dist; var mindist = 100000000000.0; var mindistvec = null; var eating = 0; for (i = 0; i < n.size; i++) { mp = n[i].value.getMechPart(0); distvec.set(mp.pos); distvec.sub(p.pos); dist = distvec.length; if (dist < getZoneRange(cr,1)) { if (n[i].value != null) { energyTransfer(cr, n[i].value); eating = 1; } } else if (eating == 0 && cr.data->lifeparams->hibernated == 0 && dist < mindist) { mindist = dist; mindistvec = distvec.clone(); } } if (!eating && cr.data->lifeparams->hibernated == 0) { mindistvec.normalize(); mindistvec.scale(-1*movePerStep); cr.localDrive = mindistvec; moveEnergyDec(cr); } return 1; } else { return 0; } } function moveEnergyDec(cr) { if (cr.data->lifeparams->hibernated == 0) { //percent of maximal energy cr.energy_m += (ExpProperties.energy_move * cr.data->lifeparams->max_energy_level)*ExpProperties.secPerStep; } } function fence(pos) { return Math.min(Math.max(0,pos),World.wrldsiz); } function foramMove(cr) { //TODO moving inside sediment? //adjustment in z axis cr.moveAbs(fence(cr.pos_x), fence(cr.pos_y), 0); //are there any nutrients in zone 1 or 2? { var moved = stepToNearest(cr); //TODO weighted sum of distance and energy if (moved==1) { return; } } //no nutrients in zone 2 if (getGene(cr, "hibernation",0) == 1) { reverseHib(cr); cr.localDrive = XYZ.new(0,0,0); } //random move else if (Simulator.stepNumber%int(dir_change/ExpProperties.secPerStep) == 0) { cr.data->lifeparams->dir = randomDir(); cr.localDrive = cr.data->lifeparams->dir; moveEnergyDec(cr); } else { cr.localDrive = cr.data->lifeparams->dir; } } function randomDir() { var dir = (Math.rndUni(-ExpProperties.zone2_range, ExpProperties.zone2_range), Math.rndUni(-ExpProperties.zone2_range, ExpProperties.zone2_range), 0); dir.normalize(); dir.scale(-1*movePerStep); return dir; } function energyTransfer(cr1, cr2) { cr1.localDrive = XYZ.new(0,0,0); var e = ExpProperties.feedtrans*cr1.energy;//ExpProperties.feedtrans*cr1.energy*ExpProperties.ingestion*ExpProperties.secPerStep; //TODO efficiency dependent on age e = Math.min(cr2.energy, e); e *= ExpProperties.secPerStep; //Simulator.print("transferring "+e +"("+e*ExpProperties.ingestion+")"+" to "+cr1.name +" ("+ cr1.energy+") " +" from "+cr2.name+" ("+cr2.energy+") "+ e/ExpProperties.secPerStep+ " per sec"); cr2.energy_m = cr2.energy_m + e + 0.0000001; cr1.energy_p = cr1.energy_p + e*ExpProperties.ingestion; if (cr1.data->lifeparams->hibernated == 1) { reverseHib(cr1); } } function reverseHib(cr) { if (cr.data->lifeparams->hibernated == 1) { setForamMeta(cr); //unhibernate } else { cr.idleen = (ExpProperties.energy_hib * cr.energy)*ExpProperties.secPerStep; //hibernate } cr.data->lifeparams->hibernated = 1 - cr.data->lifeparams->hibernated; } function onForamsStep(cr) { //checking for gametogenesis process if (cr.data->lifeparams->division_time > 0) { cr.data->lifeparams->division_time = Math.max(cr.data->lifeparams->division_time-1,0); } //checking for end of gametogenesis else if (cr.data->lifeparams->division_time == 0) { //waiting for gamets fusion } //checking for chamber growth process else if (cr.data->lifeparams->chamber_growth > 0) { cr.data->lifeparams->chamber_growth = Math.max(cr.data->lifeparams->chamber_growth-1,0); //Simulator.print("chamber growing, time left = " + cr.data->lifeparams->chamber_growth*ExpProperties.secPerStep); cr.energy_m += ExpProperties.chamberCostPerSec * cr.energy * ExpProperties.secPerStep; //Simulator.print("energy " + cr2.energy + " subtracting " + growth_cost); } //checking for end of chamber growth process else if (cr.data->lifeparams->chamber_growth == 0) { foramGrow(cr, lastChamberNum(cr)); cr.data->lifeparams->chamber_growth = -1; //Simulator.print("chamber "+ (lastChamberNum(cr) + 1) +" complete"); } else { //update of metabolism rate if (cr.data->lifeparams->hibernated == 0) { setForamMeta(cr); } cr.getMechPart(0).orient.set(o); if (visualization(cr)) { 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")); } if (deathConditions(cr) == 1) { Populations[0].kill(cr); return; } foramMove(cr); var repro = foramReproduce(cr); if (repro == 1) { return; } cr.data->lifeparams->max_energy_level = Math.max(cr.energy, cr.data->lifeparams->max_energy_level); //cheking conditions of chamber growth process start if (lastChamberNum(cr) != chambers[0].size-1) { if ((cr.data->lifeparams->max_energy_level >= energyFromVolume(max_chamber_volume[cr.data->lifeparams->gen][lastChamberNum(cr)],0))) { cr.data->lifeparams->chamber_growth = int(ExpProperties.chamber_growth_time/ExpProperties.secPerStep); } } } } function deathConditions(cr) { if ((cr.energy <= getProperty(cr.data->lifeparams->gen,"e_death_level")*cr.data->lifeparams->max_energy_level) || (Math.rnd01 < ExpProperties.hunted_prob)) { return 1; } else return 0; } function onForamsDied(cr) { if (visualization(cr)) { Populations[2].delete(cr.data->reticulopodiacreature); } //fossilization var geno = GenePools[0].add(cr.genotype); geno.data->genes = cr.data->genes; geno.data->lifeparams = cr.data->lifeparams; if (ExpProperties.logging == 1) Simulator.print("\"" + cr.name + "\" died..."); ExpState.totaltestedcr++; } // --------------------------------foram end ------------------------------------- // -------------------------------- nutrient begin -------------------------------- function createNutrientGenotype(nutrientradius) { return "//0\np:sh=3,sx="+nutrientradius+",sy="+nutrientradius+",sz="+nutrientradius+",ry=1.5,vr=0.0,1.0,0.0"; } function onNutrientsStep(cr) { cr.moveAbs(cr.pos_x % World.wrldsiz, cr.pos_y % World.wrldsiz, 0.5); } function addNutrient() { var cr = Populations[1].add(createNutrientGenotype(ExpProperties.nutrientradius)); cr.name = "Nutrients"; cr.idleen = 0; cr.energy0 = ExpProperties.energy_nut; cr.energy = cr.energy0; cr.signals.add("nutrient"); cr.signals[0].value = cr; placeCreatureRandomly(cr, 0, 0); if (ExpProperties.visualize == 1) { var nutsize = ExpProperties.nutrientradius*10; 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"); cr.data->reticulopodiacreature = nut; nut.moveAbs(cr.pos_x-1.5*nutsize, cr.pos_y-1.5*nutsize, 0.5); } } function onNutrientsDied(cr) { if (visualization(cr)) { Populations[2].delete(cr.data->reticulopodiacreature); } } function nutrientGrowth() { if (ExpProperties.foodPeriodChange > 0) { changePeriod += 1; if (phase=="low" && (changePeriod*ExpProperties.secPerStep) >= 23328000) //9 months { ExpProperties.foodperiod = ExpProperties.foodperiod/ExpProperties.foodPeriodChange; phase = "high"; changePeriod = 0; } else if (phase == "high" && (changePeriod*ExpProperties.secPerStep) >= 7776000) //3 months { ExpProperties.foodperiod = ExpProperties.foodperiod*ExpProperties.foodPeriodChange; phase = "low"; changePeriod = 0; } } nutrientenergywaiting = nutrientenergywaiting + 1; if (nutrientenergywaiting*ExpProperties.secPerStep >= ExpProperties.foodperiod) { for (var i = 0; i < ExpProperties.feedrate; i++) { addNutrient(); } nutrientenergywaiting = 0.0; Simulator.checkpoint(); } } // -------------------------------- nutrient end -------------------------------- // -------------------------------- step begin -------------------------------- function onStep() { nutrientGrowth(); if (ExpProperties.logging == 1) { createStatistics(); } //reproduction -------------------------------------------- reprocounter += 1; if (reprocounter*ExpProperties.secPerStep > ExpProperties.repro_time) { reprocounter = 0; reproduce_parents(0); reproduce_parents(1); } //check for extinction ----------------------------------------------- if (Populations[0].size == 0) { if (ExpProperties.autorestart) { Simulator.print("no more creatures, restarting..."); onExpInit(); } else { Simulator.print("no more creatures, stopped."); Simulator.stop(); } } if (ExpProperties.maxSteps > 0) { if (Simulator.stepNumber >= ExpProperties.maxSteps) Simulator.stop(); } } function createStatistics() { var number = []; var e_inc = []; var e_nut = 0.0; for (var s = 0; s < species_genes.size; s++) { number.add([0,0]);// [haplo][diplo] e_inc.add([0,0]); } for (var i = 0; i < Populations[0].size; i++) { var cr = Populations[0].get(i); var gen = cr.data->lifeparams->gen; var species = cr.data->lifeparams->species; number[species][gen] = number[species][gen] + 1; e_inc[species][gen] = e_inc[species][gen] + cr.energy; } for (var i = 0; i < Populations[1].size; i++) { var cr = Populations[1].get(i); e_nut += cr.energy; } var log_numbers = []; var log_energies = []; for (var s = 0; s < species_genes.size; s++) { for (var p = 0; p < 2; p++) { log_numbers.add(number[s][p]); log_energies.add(e_inc[s][p]); } } log_numbers.add(Populations[1].size); log_energies.add(e_nut); log(log_numbers, "forams_log.txt"); log(log_energies, "energies_log.txt"); } function log(tolog, fname) { var f = File.appendDirect(fname, "forams data"); f.writeString("" + Simulator.stepNumber); for (var i = 0; i < tolog.size; i++) { f.writeString(";" + tolog[i]); } f.writeString("\n"); f.close(); } // -------------------------------- step end -------------------------------- //TODO default params values in frams instead of microns/seconds @include "standard_events.inc" ~ property: id:visualize name:Show reticulopodia and nutrients type:d 0 1 0 group:Foraminifera property: id:maxSteps name:Stop after the given number of simulation steps type:d 0 1000000 0 property: id:foramSpeedMmPerMin name:Speed of foraminfera in mm/min type:f 0.1 flags: 16 group:Foraminifera property: id:gametSuccessRate name:Ratio of successful gamets type:f 0.001 group:Foraminifera property: id:gametoPeriod name:Time of gametogenesis type:f 720 group:Foraminifera property: id:picoCarbonPerMikro name:Picograms of carbon in cubed micrometer type:f 0.13 group:Foraminifera property: id:secPerStep name:Seconds per simulation step type:f 60.0 flags: 16 group:Foraminifera property: id:e_repro_cost_haplo name:Cost of reproduction type:f 0.1 0.9 0.5 group:Foraminifera property: id:divisionCost name:Cost of division in pG type:f group:Foraminifera property: id:e_repro_cost_diplo name:Cost of reproduction type:f 0.1 0.9 0.3 group:Foraminifera property: id:chamber_growth_time name:Time of the chamber growth in seconds type:f group:Foraminifera property: id:chamberCostPerSec name:Cost of growning chamber per second type:f group:Foraminifera property: id:chamber_proculus_haplo name:Size of proculus type:f group:Foraminifera property: id:chamber_proculus_diplo name:Size of proculus type:f group:Foraminifera property: id:chamber_difference_haplo name:Difference in size between subsequent chambers type:f group:Foraminifera property: id:chamber_difference_diplo name:Difference in size between subsequent chambers type:f group:Foraminifera property: id:hunted_prob name:Probability of being hunted type:f 0 1 0 group:Forminifera property: id:zone1_range name:Zone 1 range type:f 0 200 group:Foraminifera property: id:zone2_range name:Zone 2 range type:f 0 3000 group:Foraminifera property: id:colors name:Haploid and diploid colors type:x group:Foraminifera property: id:min_repro_energ_haplo name:Min reproduction energy of forams type:f group:Foraminifera property: id:min_repro_energ_diplo name:Min reproduction energy of forams type:f group:Foraminifera property: id:repro_prob name:Probability of reproduction type:f 0 1 0.8 group:Foraminifera property: id:energies0_haplo name:Energy of offspring from diploid forams type:f group:Foraminifera property: id:energies0_diplo name:Energy of offspring from diploid forams type:f group:Foraminifera property: id:e_death_level_haplo name:Minimal level of energy to sustain life of haploid type:f 0 20 0.2 group:Foraminifera property: id:e_death_level_diplo name:Minimal level of energy to sustain life of diploid type:f 0 20 0.2 group:Foraminifera property: id:energy_hib name:Energy used for hibernation during one step type:f 0 1 0.001 group:Foraminifera property: id:energy_move name:Energy used for movement during one step type:f 0 20 0.001 group:Foraminifera property: id:min_vol name:Minimal volume for reproduction type:f 100 900 100 group:Foraminifera property: id:max_size name:Maximal size type:d 1 10 5 group:Foraminifera property: id:foramPop name:Initial forams population size type:d 1 1000 100 group:Foraminifera property: id:crossprob name:Crossover probability type:f 0 1 0 group:Foraminifera property: id:mutationprob name:Mutation probability type:f 0 1 0 group:Foraminifera property: id:e_meta name:Idle metabolism type:f 0 1 group:Energy help:Each stick consumes this amount of energy in one time step property: id:feedrate name:Feeding rate type:f 0 1000000 group:Energy help:How fast energy is created in the world property: id:foodPeriodChange name:Set variable feed rate type:f 0 group:Energy property: id:ingestion name:Ingestion rate type:f group:Energy property: id:energy_nut name:Nutrient energy type:f 0 100000 group:Energy property: id:feedtrans name:Energy transfer per second type:f 0 100000 group:Energy property: id:foodperiod name:Time between food occurrences type:f 0 1000000 group:Energy property: id:nutrientradius name:Nutrient size type:f 0.1 0.9 0.1 group:Energy property: id:stress name:Environmental stress type:d 0 1 1 group:World property: id:repro_trigger name:Reproduction trigger type:d 0 1 1 group:World property: id:repro_time name:Time before reproduction type:d 0 10000 property: id:creath name:Creation height type:f -1 50 help:~ Vertical position (above the surface) where new Forams are revived. Negative values are only used in the water area: 0 = at the surface -0.5 = half depth -1 = just above the bottom~ state: id:nutrient name:Nutrient locations help:vector of vectors [x,y,energy] type:x flags:32 property: id:autorestart name:Restart after extinction help:Restart automatically this experiment after the last creature has died? type:d 0 1 state: id:notes name:Notes type:s 1 help:~ You can write anything here (it will be saved to the experiment file)~ state: id:totaltestedcr name:Evaluated Forams help:Total number of the Forams evaluated in the experiment type:d flags:16 property: id:logging name:Log statistics to file type:d 0 1 0