Index: experiments/frams/foraminifera/data/scripts/foraminifera.expdef
===================================================================
--- experiments/frams/foraminifera/data/scripts/foraminifera.expdef	(revision 406)
+++ experiments/frams/foraminifera/data/scripts/foraminifera.expdef	(revision 406)
@@ -0,0 +1,593 @@
+expdef:
+name:Reproduction of benthic foraminifera
+info:~
+Genes and parameter values which control reproduction are stored in user1 and user2 fields.
+
+user1:
+genes which are not encoded in Ff genotype:
+Vamin - Minimum stored energy necessary for reproduction
+amin - minimal age for reproduction
+
+user2:
+Physiological parameters of foraminifera:
+Va - amount of the stored energy
+gen - generation: 0 haploid, 1 diploid
+~
+code:~
+
+/*
+changes 2015-06-24:
+- xxx.get(...) changed to xxx[...]
+- xxx.set(...,...) changed to xxx[...]=...
+- 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)
+- use creature's center (not the bbox corner) when growing
+- added "S" receptor to visualize the difference between diplo and haplo generations
+- signal.value is a MechPart (a reference) so it does not have to be updated after changing the object location
+*/
+
+/* TODO fix
+[ERROR] Population.kill: Invalid index 35 (allowed range is 0..34)
+[ERROR] Population.kill: ... called from reproduce_haploid()  <foraminifera.inc:54>
+[ERROR] Population.kill: ... called from onStep()  <foraminifera.inc:228>
+*/
+
+global foodenergywaiting;
+global reprocounter;
+
+@include "foraminifera.inc"
+
+// -------------------------------- experiment begin --------------------------------
+
+function onExpDefLoad()
+{
+
+	// define genotype and creature groups
+	GenePools.clear();
+	Populations.clear();
+	GenePools[0].name = "Unused";
+
+	SignalView.mode = 1;
+
+	var pop = Populations[0];
+	pop.name = "Creatures";
+	pop.en_assim = 0;
+	pop.nnsim = 0;
+	pop.enableperf = 1;
+	pop.death = 1;
+	pop.energy = 1;
+	pop.selfmask = 0x10001;
+	pop.othermask = 0x20001;
+	//pop.selfmask = 0x20002; pop.othermask = 0x10002;
+	pop.perfperiod = 25;
+
+	pop = Populations.addGroup("Food");
+	pop.nnsim = 0;
+	pop.enableperf = 0;
+	pop.death = 1;
+	pop.energy = 1;
+	pop.selfmask = 0x20002;
+	pop.othermask = 0x10000;
+
+	//radius of the chamber
+	ExpParams.rads = [1.2, 0.6];
+	//inital genotypes
+	ExpParams.genh = "//0\np:sh=1,sx=" + ExpParams.rads[0] + ",sy=" + ExpParams.rads[0] + ",sz=" + ExpParams.rads[0] + ", rz=3.14159265358979";
+	ExpParams.gend = "//0\np:sh=1,sx=" + ExpParams.rads[1] + ",sy=" + ExpParams.rads[1] + ",sz=" + ExpParams.rads[1] + ", rz=3.14159265358979";
+	ExpParams.gend += "\nn:p=0,d=\"S\"";
+	ExpParams.e_meta = 0.1;
+	ExpParams.feedrate = 0.5;
+	ExpParams.feede0 = 100;
+	ExpParams.feedtrans = 3;
+	ExpParams.creath = -0.99; //just above the bottom
+	ExpParams.foodgen = "//0\np:sh=2,sx=0.1,sy=0.1,sz=0.1\nn:d=T,p=0";
+	ExpParams.autorestart = 0;
+	ExpParams.psize = 10;
+	ExpParams.logging = 0;
+
+	//number of offspring
+	ExpParams.ofnumh = 40;
+	ExpParams.ofnumd = 25;
+	//minial volume for reproduction
+	ExpParams.v_min_d = 300;
+	ExpParams.v_min_h = 300;
+	//minimal age for reproduction
+	ExpParams.age_min_d = 100;
+	ExpParams.age_min_h = 100;
+	//crossover probability
+	ExpParams.crossprob = 0.4;
+	//mutation probability
+	ExpParams.mutationprob = 0.2;
+	ExpParams.repro_time = 200;
+	ExpParams.repro_thr = 1;
+
+	//grwoth speed in time steps
+	ExpParams.growth_step = 50;
+
+	ExpState.totaltestedcr = 0;
+	ExpState.food = "";
+	foodenergywaiting = ExpParams.feede0;
+	reprocounter = 0;
+
+	ExpParams.wsize = 50;
+	World.wrldwat = 50;
+	World.wrldsiz = ExpParams.wsize;
+	World.wrldbnd = 1;
+}
+
+@include "standard_placement.inc"
+
+function onExpInit()
+{
+	Populations[0].clear();
+	Populations[1].clear();
+
+	for (var i = 0; i < ExpParams.psize; i++)
+	{
+		var cr = Populations[0].add(ExpParams.genh);
+		cr.name = "Initial creature" + i;
+		placeCreatureRandomly(cr, 0, 0);
+		cr.energ0 = ExpParams.v_min_h - ExpParams.repro_thr;
+		cr.energy = cr.energ0;
+		cr.user1 = {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h};
+		cr.user2 = {"Va" : ExpParams.v_min_h - ExpParams.repro_thr, "gen" : 0, "growth_step" : ExpParams.growth_step, "rsize" : ExpParams.rads[0], "vinit" : ExpParams.v_min_h - ExpParams.repro_thr};
+	}
+	ExpState.totaltestedcr = 0;
+	foodenergywaiting = ExpParams.feede0;
+}
+
+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 + " creatures and " + Populations[1].size + " food 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.user1) == "Vector") && (g.user1.size >= 3))
+			{
+				// [x,y,energy]
+				cr.move(g.user1[0] - cr.center_x, g.user1[1] - cr.center_y, 0);
+				cr.energy = g.user1[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.food = tmpvec;
+	File.writeObject(sim_params.*);
+	ExpState.food = null; //vectors are only created for saving and then discarded
+
+	for (var cr in Populations[0])
+		File.writeObject(cr);
+}
+
+// -------------------------------- experiment end --------------------------------
+
+// -------------------------------- creature begin --------------------------------
+
+function onCreaturesBorn(cr)
+{
+	cr.idleen = ExpParams.e_meta;
+}
+
+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 readyToRepro(cr)
+{
+	cr.signals.add("repro");
+	cr.signals[0].power = 1;
+}
+
+function onCreaturesStep(cr)
+{
+	//TODO moving inside sediment?
+	cr.moveAbs(cr.pos_x, cr.pos_y, 0); //adjustment in z axis
+	var p = cr.getMechPart(0);
+	var n = cr.signals.receiveSet("food", ExpParams.food_range);
+
+	//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;
+		var mindistvec = null;
+
+		for (i = 0; i < n.size; i++)
+		{
+			mp = n[i].value;
+			distvec.set(mp.pos);
+			distvec.sub(p.pos);
+			dist = distvec.length;
+			if (dist < mindist)
+			{
+				mindist = dist;
+				mindistvec = distvec.clone();
+			}
+		}
+
+		mindistvec.normalize();
+		mindistvec.scale(-0.08);
+		cr.localDrive = mindistvec;
+	}
+
+	else
+	{
+		cr.localDrive = (0.1 * Math.rnd01, 0.1 * Math.rnd01, 0);
+	}
+
+	//energy costs depend on size
+	if (cr.energy > 100)
+	{
+		//TODO energy costs dependent on size
+		// cr.energy_m = cr.user2["Va"]/cr.user2["vinit"];
+	}
+
+	if (cr.lifespan >= ExpParams.max_age)
+	{
+		//TODO what is max age value? should there be one?
+		Populations[0].kill(cr);
+		return;
+	}
+
+	//foram growth
+	if (cr.lifespan == cr.user2["growth_step"])
+	{
+		//TODO how size is related to the energy?
+		cr.user2["rsize"] = ExpParams.rads[cr.user2["gen"]] * Math.min(Math.max(float(cr.user2["Va"] / cr.user2["vinit"]) * 0.5, 1.0), 2.5);
+		var geno = "//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979";
+		if (cr.user2["gen"] == 1)
+		{
+			geno += "\nn:p=0,d=\"S\""; //TODO why initial genotypes are not used as defined in ExpParams?
+			//TODO maybe it would be nice if they rotated so the "S" would show where they are going (direction/intention)
+		}
+		var cr2 = Populations[0].add(geno);
+		cr2.energy = cr.energy;
+		setGenotype(cr2, cr.user1, cr.user2);
+		cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z);
+
+		Populations[0].delete(cr);
+	}
+	else
+	{
+		var properSize = 0;
+
+		if (cr.user2["gen"] == 0)
+		{
+			properSize = cr.user2["Va"] >= cr.user1["vamin"];
+		}
+		else
+		{
+			properSize = cr.user2["Va"] >= cr.user1[0]["vamin"];
+		}
+
+		//if creature has proper age and cytoplasm amount
+		if ( properSize )
+		{
+			//reproduce with probability repro_prob
+			if (Math.rnd01 <= ExpParams.repro_prob)
+			{
+				readyToRepro(cr);
+			}
+		}
+		if ( properSize && (cr.signals.receive("repro") > 0))
+		{
+			readyToRepro(cr);
+		}
+	}
+}
+
+function onCreaturesDied(cr)
+{
+	//fossilization
+	var geno = GenePools[0].add(cr.genotype);
+	geno.user1 = cr.user1;
+	geno.user2 = cr.user2;
+	Simulator.print("\"" + cr.name + "\" died...");
+	ExpState.totaltestedcr++;
+}
+
+function setGenotype(cr, new_user1, new_user2)
+{
+	cr.user2 = {"Va" : new_user2["Va"], "gen" : new_user2["gen"], "growth_step" : new_user2["growth_step"], "rsize" : new_user2["rsize"], "vinit": new_user2["vinit"]};
+	if (cr.user2["gen"] == 0)
+	{
+		cr.user1 = {"vamin" : new_user1["vamin"], "amin": new_user1["amin"] };
+	}
+	else if (cr.user2["gen"] == 1)
+	{
+		cr.user1 = [ {"vamin" : new_user1[0]["vamin"], "amin": new_user1[0]["amin"] }, {"vamin" : new_user1[1]["vamin"], "amin": new_user1[1]["amin"] }];
+	}
+
+}
+
+// -------------------------------- creature end --------------------------------
+
+// -------------------------------- food begin --------------------------------
+
+function onFoodStep(cr)
+{
+	cr.moveAbs(cr.pos_x % ExpParams.wsize, cr.pos_y % ExpParams.wsize, 0.5);
+}
+
+function addfood()
+{
+	var cr = Populations[1].add(ExpParams.foodgen);
+
+	cr.name = "Food";
+	cr.idleen = 0;
+	cr.energ0 = ExpParams.feede0;
+	cr.energy = cr.energ0;
+	cr.signals.add("food");
+
+	cr.signals[0].value = cr.getMechPart(0);
+
+	placeRandomlyNotColliding(cr);
+}
+
+function onFoodCollision()
+{
+	if (Collision.Creature2.user2 != null)
+	{
+		var e = Collision.Part2.ing * ExpParams.feedtrans;
+		//Simulator.print("transferring "+e+" from "+Collision.Creature1.name+" to "+Collision.Creature2.name+" ("+Collision.Creature2.energy+")");
+		Collision.Creature1.energy_m = Collision.Creature1.energy_m + e;
+		Collision.Creature2.energy_p = Collision.Creature2.energy_p + e;
+		Collision.Creature2.user2["Va"] = float(Collision.Creature2.user2["Va"]) + float(e);
+	}
+}
+
+// -------------------------------- food end --------------------------------
+
+
+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();
+}
+
+
+
+
+@include "standard_events.inc"
+
+~
+
+prop:
+id:max_age
+name:Maximal age
+type:d 100 1000 500
+
+prop:
+id:wsize
+name:World size
+type:d 10 1000 20
+
+prop:
+id:growth_step
+name:Growth step
+type:d 10 10000 1000
+
+prop:
+id:rads
+name:Haploid and diploid radius
+type:x
+
+prop:
+id:age_min_h
+name:Min reproduction age of haploid forams
+type:d 100 10000 300
+group:Foraminifera
+
+prop:
+id:age_min_d
+name:Min reproduction age of diploid forams
+type:d 100 10000 200
+group:Foraminifera
+
+prop:
+id:v_min_h
+name:Min reproduction energy of haploid forams
+type:f 10 10000 300
+group:Foraminifera
+
+prop:
+id:v_min_d
+name:Min reproduction energy of diploid forams
+type:f 10 10000 150
+group:Foraminifera
+
+prop:
+id:repro_thr
+name:Energy creatures need to gather to reproduce
+type:d 1 1000 1
+
+prop:
+id:food_range
+name:Range of food smell
+type:d 0 10000 10000
+
+prop:
+id:repro_time
+name:Time before reproduction
+type:d 0 1000
+
+prop:
+id:psize
+name:Initial population size
+type:d 1 1000 100
+
+prop:
+id:logging
+name:Log statistics to file
+type:d 0 1 0
+
+prop:
+id:ofnumh
+name:Number of offspring from haploid forams
+type:d
+group:Foraminifera
+
+prop:
+id:ofnumd
+name:Number of offspring from diploid forams
+type:d
+group:Foraminifera
+
+prop:
+id:repro_prob
+name:Probability of reproduction
+type:f 0 1 0.9
+
+prop:
+id:crossprob
+name:Crossover probability
+type:f 0 1 0
+
+prop:
+id:mutationprob
+name:Mutation probability
+type:f 0 1 0
+
+prop:
+id:genh
+name:Initial genotype of haploid forams
+type:s 1
+group:Foraminifera
+
+prop:
+id:gend
+name:Initial genotype of diploid forams
+type:s 1
+group:Foraminifera
+
+prop:
+id:creath
+name:Creation height
+type:f -1 50
+help:~
+Vertical position (above the surface) where new creatures are revived.
+Negative values are only used in the water area:
+  0   = at the surface
+-0.5 = half depth
+-1   = just above the bottom~
+
+prop:
+id:e_meta
+name:Idle metabolism
+type:f 0 1
+group:Energy
+help:Each stick consumes this amount of energy in one time step
+
+prop:
+id:feedrate
+name:Feeding rate
+type:f 0 100
+group:Energy
+help:How fast energy is created in the world
+
+prop:
+id:feede0
+name:Food's energy
+group:Energy
+type:f 0 1000
+
+prop:
+id:feedtrans
+name:Ingestion multiplier
+group:Energy
+type:f 0 100
+
+prop:
+id:foodgen
+name:Food's genotype
+group:Energy
+type:s 1
+
+prop:
+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 creatures
+help:Total number of the creatures evaluated in the experiment
+type:d
+flags:16
+
+prop:
+id:foodPop
+name:Food size
+type:d 1 1000 10
+
+state:
+id:food
+name:Food locations
+help:vector of vectors [x,y,energy]
+type:x
+flags:32
Index: experiments/frams/foraminifera/data/scripts/foraminifera.inc
===================================================================
--- experiments/frams/foraminifera/data/scripts/foraminifera.inc	(revision 406)
+++ experiments/frams/foraminifera/data/scripts/foraminifera.inc	(revision 406)
@@ -0,0 +1,209 @@
+//size versus energy
+//real proportions
+
+// -------------------------------- step begin --------------------------------
+
+function reproduce_haploid(repro_list)
+{
+	var len = repro_list.size;
+	if (len % 2 != 0) len = repro_list.size - 1;
+
+	for (var i = 0; i < len - 2 ; i = i + 2)
+	{
+		var parent = Populations[0].get(repro_list[i]);
+		var parent2 = Populations[0].get(repro_list[i + 1]);
+
+		var number = parent.user2["Va"] / ExpParams.ofnumd + parent2.user2["Va"] / ExpParams.ofnumd;
+
+		for (var j = 0; j < number; j++)
+		{
+			createOffspring(ExpParams.gend, ExpParams.ofnumd, [parent.user1, parent2.user1], {"Va" : ExpParams.ofnumd, "gen" : 1 , "growth_step" : ExpParams.growth_step, "rsize": ExpParams.rads[1], "vinit": ExpParams.ofnumd}); //TODO genes from both generations in user1
+		}
+	}
+	killParents(repro_list);
+}
+
+function reproduce_diploid(repro_list)
+{
+	for (var i = 0; i < repro_list.size; i++)
+	{
+		var parent = Populations[0].get(repro_list[i]);
+
+		if (parent.user2["gen"] != 1)
+		{
+			Simulator.print("gen: " + parent.user2["gen"]);
+		}
+
+		if (parent.user2["gen"] == 1)
+		{
+			var number = parent.user2["Va"] / ExpParams.ofnumh;
+			for (var j = 0; j < number / 2; j++)
+			{
+				var crossed = 0;
+				//crossover
+				if (Math.rnd01 < ExpParams.crossprob)
+				{
+					crossover(parent, "vamin");
+					crossed = 1;
+				}
+
+				for (var k = 0; k < 2; k++)
+				{
+					createOffspring(ExpParams.genh, ExpParams.ofnumh, {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h}, {"Va" : ExpParams.ofnumh, "gen" : 0 , "growth_step" : ExpParams.growth_step, "rsize" : ExpParams.rads[0], "vinit": ExpParams.ofnumh});
+				}
+
+				//reverse of crossover for fossilization
+				if (crossed == 1)
+				{
+					crossover(parent, "vamin");
+					crossed = 0;
+				}
+			}
+		}
+	}
+	killParents(repro_list);
+}
+
+function crossover(parent, gene)
+{
+	var tmp = parent.user1[0][gene];
+	parent.user1[0][gene] = parent.user1[1][gene];
+	parent.user1[1][gene] = tmp;
+}
+
+function killParents(repro_list)
+{
+	for (var j = 0; j < repro_list.size; j++)
+	{
+		Populations[0].kill(repro_list[j]);
+	}
+}
+
+function createOffspring(geno, energy, new_user1, new_user2)
+{
+	var cr = Populations[0].add(geno);
+	cr.energ0 = energy;
+	cr.energy = cr.energ0;
+	setGenotype(cr, new_user1, new_user2);
+	placeRandomlyNotColliding(cr);
+}
+
+function onStep()
+{
+	var haploids = 0;
+	var diploids = 0;
+	var e_inc_h = 0.0;
+	var e_inc_d = 0.0;
+	var e_nut = 0.0;
+	var size_h = 0.0;
+	var size_d = 0.0;
+	var vmin_h = 0.0;
+	var vmin_d = 0.0;
+
+	for (var i = 0; i < Populations[0].size; i++)
+	{
+		var cr = Populations[0].get(i);
+		if (cr.user2["gen"] == 0)
+		{
+			haploids += 1;
+			e_inc_h += cr.energy;
+			size_h += ExpParams.rads[0]; //TODO change of size dependent on gene
+			vmin_h += cr.user1["vamin"];
+		}
+		else if (cr.user2["gen"] == 1)
+		{
+			diploids += 1;
+			e_inc_d += cr.energy;
+			size_d += ExpParams.rads[1]; //TODO change of size dependent on gene
+			vmin_d += cr.user1[0]["vamin"];
+		}
+	}
+
+	for (var i = 0; i < Populations[1].size; i++)
+	{
+		var cr = Populations[1].get(i);
+		e_nut += cr.energy;
+	}
+
+	if (haploids < 2 && diploids == 0)
+	{
+		Simulator.print("no more creatures, stopped.");
+		Simulator.stop();
+	}
+
+	var l1 = [haploids, diploids, Populations[1].size];
+	var l2 = [e_inc_h, e_inc_d, e_nut];
+	var dp = diploids;
+	var hp = haploids;
+	if (dp == 0) dp = 0.000001;
+	if (hp == 0) hp = 0.000001;
+	var l3 = [size_h / hp, vmin_h / hp, size_d / dp, vmin_d / dp];
+
+	if (ExpParams.logging == 1)
+	{
+		log(l1, "log.txt");
+		log(l2, "log2.txt");
+		log(l3, "log3.txt");
+	}
+	//food growth ---------------------------------------------
+	foodenergywaiting = foodenergywaiting + ExpParams.feedrate;
+	if (foodenergywaiting > ExpParams.feede0)
+	{
+		for (var i = 0; i < ExpParams.foodPop; i++)
+		{
+			addfood();
+		}
+
+		foodenergywaiting = 0.0;
+		Simulator.checkpoint();
+	}
+
+	//reproduction --------------------------------------------
+	reprocounter += 1;
+	if (reprocounter > ExpParams.repro_time)
+	{
+		reprocounter = 0;
+		var to_repro_h = [];
+		var to_repro_d = [];
+		for (var i = 0; i < Populations[0].size; i++)
+		{
+			var cr = Populations[0].get(i);
+			if (cr.signals.size > 0)
+			{
+				if (cr.user2["gen"] == 0)
+				{
+					to_repro_h.add(i);
+				}
+				if (cr.user2["gen"] == 1)
+				{
+					to_repro_d.add(i);
+				}
+			}
+		}
+		if (to_repro_h.size > 1)
+		{
+			reproduce_haploid(to_repro_h);
+		}
+		if (to_repro_d.size > 0)
+		{
+			reproduce_diploid(to_repro_d);
+		}
+	}
+
+	//check for death -----------------------------------------------
+	if (Populations[0].size == 0)
+	{
+		if (ExpParams.autorestart)
+		{
+			Simulator.print("no more creatures, restarting...");
+			onExpInit();
+		}
+		else
+		{
+			Simulator.print("no more creatures, stopped.");
+			Simulator.stop();
+		}
+	}
+}
+
+// -------------------------------- step end --------------------------------
Index: experiments/frams/foraminifera/data/scripts/foraminifera.show
===================================================================
--- experiments/frams/foraminifera/data/scripts/foraminifera.show	(revision 406)
+++ experiments/frams/foraminifera/data/scripts/foraminifera.show	(revision 406)
@@ -0,0 +1,113 @@
+show:
+name:Reproduction of benthic foraminifera
+info:~
+Genes and parameter values which control reproduction are stored in user1 and user2 fields.
+
+user1:
+genes which are not encoded in ff genotype:
+Vamin - Minimum stored energy necessary for reproduction
+amin - minimal age for reproduction
+
+user2:
+Physiological parameters of foraminifera:
+Va - amount of the stored energy
+gen - generation: 0 haploid, 1 diploid
+
+~
+expdef:foraminifera
+code:~
+
+function onLoad()
+{
+	Simulator.init();
+	GLDisplay.desiredsimspeed = 50;
+	GLDisplay.minfps = 10;
+}
+
+function ShowParams_minimalVolume_set()
+{
+	switch (ShowParams.minimalVolume)
+	{
+	case 0:
+		ExpParams.v_min_h = 300;
+		ExpParams.v_min_d = 300;
+		break;
+	case 1:
+		ExpParams.v_min_h = 150;
+		ExpParams.v_min_d = 500;
+		break;
+	}
+}
+
+function ShowParams_offspingNumber_set()
+{
+	switch (ShowParams.offspingNumber)
+	{
+	case 0:
+		ExpParams.ofnumh = 300;
+		ExpParams.ofnumd = 300;
+		break;
+	case 1:
+		ExpParams.ofnumh = 150;
+		ExpParams.ofnumd = 500;
+		break;
+	}
+}
+
+function ShowParams_populationSize_set()
+{
+	switch (ShowParams.populationSize)
+	{
+	case 0:
+		ExpParams.psize = 5;
+		break;
+	case 1:
+		ExpParams.psize = 10;
+		break;
+	case 2:
+		ExpParams.psize = 15;
+		break;
+	case 3:
+		ExpParams.psize = 20;
+		break;
+	}
+}
+
+function ShowParams_feedRate_set()
+{
+	switch (ShowParams.feedRate)
+	{
+	case 0:
+		ExpParams.feedrate = 0.5;
+		break;
+	case 1:
+		ExpParams.feedrate = 0.7;
+		break;
+	case 2:
+		ExpParams.feedrate = 0.9;
+		break;
+	}
+}
+
+~
+
+
+prop:
+id:minimalVolume
+name:Min reproduction energy haploid/diploid
+type:f 0 1 ~300 / 300~150 / 500
+
+prop:
+id:populationSize
+name:Initial population size
+type:d 0 3 ~5~10~15~20
+
+prop:
+id:offspingNumber
+name:Number of offspring haploi/diploid
+type:d 0 2 ~20 / 4~10 / 5
+
+prop:
+id:feedRate
+name:Feeding rate
+type:d 0 2 ~50~70~90
Index: experiments/frams/foraminifera/data/scripts/forams_benthic.expdef
===================================================================
--- experiments/frams/foraminifera/data/scripts/forams_benthic.expdef	(revision 405)
+++ 	(revision )
@@ -1,593 +1,0 @@
-expdef:
-name:Benthic foraminifera reproduction
-info:~
-Genes and parameter values which control reproduction are stored in user1 and user2 fields.
-
-user1:
-genes which are not encoded in Ff genotype:
-Vamin - Minimum stored energy necessary for reproduction
-amin - minimal age for reproduction
-
-user2:
-Physiological parameters of foraminifera:
-Va - amount of the stored energy
-gen - generation: 0 haploid, 1 diploid
-~
-code:~
-
-/*
-changes 2015-06-24:
-- xxx.get(...) changed to xxx[...]
-- xxx.set(...,...) changed to xxx[...]=...
-- 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)
-- use creature's center (not the bbox corner) when growing
-- added "S" receptor to visualize the difference between diplo and haplo generations
-- signal.value is a MechPart (a reference) so it does not have to be updated after changing the object location
-*/
-
-/* TODO fix
-[ERROR] Population.kill: Invalid index 35 (allowed range is 0..34)
-[ERROR] Population.kill: ... called from reproduce_haploid()  <forams_repro.inc:54>
-[ERROR] Population.kill: ... called from onStep()  <forams_repro.inc:228>
-*/
-
-global foodenergywaiting;
-global reprocounter;
-
-@include "forams_repro.inc"
-
-// -------------------------------- experiment begin --------------------------------
-
-function onExpDefLoad()
-{
-
-	// define genotype and creature groups
-	GenePools.clear();
-	Populations.clear();
-	GenePools[0].name = "Unused";
-
-	SignalView.mode = 1;
-
-	var pop = Populations[0];
-	pop.name = "Creatures";
-	pop.en_assim = 0;
-	pop.nnsim = 0;
-	pop.enableperf = 1;
-	pop.death = 1;
-	pop.energy = 1;
-	pop.selfmask = 0x10001;
-	pop.othermask = 0x20001;
-	//pop.selfmask = 0x20002; pop.othermask = 0x10002;
-	pop.perfperiod = 25;
-
-	pop = Populations.addGroup("Food");
-	pop.nnsim = 0;
-	pop.enableperf = 0;
-	pop.death = 1;
-	pop.energy = 1;
-	pop.selfmask = 0x20002;
-	pop.othermask = 0x10000;
-
-	//radius of the chamber
-	ExpParams.rads = [1.2, 0.6];
-	//inital genotypes
-	ExpParams.genh = "//0\np:sh=1,sx=" + ExpParams.rads[0] + ",sy=" + ExpParams.rads[0] + ",sz=" + ExpParams.rads[0] + ", rz=3.14159265358979";
-	ExpParams.gend = "//0\np:sh=1,sx=" + ExpParams.rads[1] + ",sy=" + ExpParams.rads[1] + ",sz=" + ExpParams.rads[1] + ", rz=3.14159265358979";
-	ExpParams.gend += "\nn:p=0,d=\"S\"";
-	ExpParams.e_meta = 0.1;
-	ExpParams.feedrate = 0.5;
-	ExpParams.feede0 = 100;
-	ExpParams.feedtrans = 3;
-	ExpParams.creath = -0.99; //just above the bottom
-	ExpParams.foodgen = "//0\np:sh=2,sx=0.1,sy=0.1,sz=0.1\nn:d=T,p=0";
-	ExpParams.autorestart = 0;
-	ExpParams.psize = 10;
-	ExpParams.logging = 0;
-
-	//number of offspring
-	ExpParams.ofnumh = 40;
-	ExpParams.ofnumd = 25;
-	//minial volume for reproduction
-	ExpParams.v_min_d = 300;
-	ExpParams.v_min_h = 300;
-	//minimal age for reproduction
-	ExpParams.age_min_d = 100;
-	ExpParams.age_min_h = 100;
-	//crossover probability
-	ExpParams.crossprob = 0.4;
-	//mutation probability
-	ExpParams.mutationprob = 0.2;
-	ExpParams.repro_time = 200;
-	ExpParams.repro_thr = 1;
-
-	//grwoth speed in time steps
-	ExpParams.growth_step = 50;
-
-	ExpState.totaltestedcr = 0;
-	ExpState.food = "";
-	foodenergywaiting = ExpParams.feede0;
-	reprocounter = 0;
-
-	ExpParams.wsize = 50;
-	World.wrldwat = 50;
-	World.wrldsiz = ExpParams.wsize;
-	World.wrldbnd = 1;
-}
-
-@include "standard_placement.inc"
-
-function onExpInit()
-{
-	Populations[0].clear();
-	Populations[1].clear();
-
-	for (var i = 0; i < ExpParams.psize; i++)
-	{
-		var cr = Populations[0].add(ExpParams.genh);
-		cr.name = "Initial creature" + i;
-		placeCreatureRandomly(cr, 0, 0);
-		cr.energ0 = ExpParams.v_min_h - ExpParams.repro_thr;
-		cr.energy = cr.energ0;
-		cr.user1 = {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h};
-		cr.user2 = {"Va" : ExpParams.v_min_h - ExpParams.repro_thr, "gen" : 0, "growth_step" : ExpParams.growth_step, "rsize" : ExpParams.rads[0], "vinit" : ExpParams.v_min_h - ExpParams.repro_thr};
-	}
-	ExpState.totaltestedcr = 0;
-	foodenergywaiting = ExpParams.feede0;
-}
-
-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 + " creatures and " + Populations[1].size + " food 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.user1) == "Vector") && (g.user1.size >= 3))
-			{
-				// [x,y,energy]
-				cr.move(g.user1[0] - cr.center_x, g.user1[1] - cr.center_y, 0);
-				cr.energy = g.user1[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.food = tmpvec;
-	File.writeObject(sim_params.*);
-	ExpState.food = null; //vectors are only created for saving and then discarded
-
-	for (var cr in Populations[0])
-		File.writeObject(cr);
-}
-
-// -------------------------------- experiment end --------------------------------
-
-// -------------------------------- creature begin --------------------------------
-
-function onCreaturesBorn(cr)
-{
-	cr.idleen = ExpParams.e_meta;
-}
-
-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 readyToRepro(cr)
-{
-	cr.signals.add("repro");
-	cr.signals[0].power = 1;
-}
-
-function onCreaturesStep(cr)
-{
-	//TODO moving inside sediment?
-	cr.moveAbs(cr.pos_x, cr.pos_y, 0); //adjustment in z axis
-	var p = cr.getMechPart(0);
-	var n = cr.signals.receiveSet("food", ExpParams.food_range);
-
-	//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;
-		var mindistvec = null;
-
-		for (i = 0; i < n.size; i++)
-		{
-			mp = n[i].value;
-			distvec.set(mp.pos);
-			distvec.sub(p.pos);
-			dist = distvec.length;
-			if (dist < mindist)
-			{
-				mindist = dist;
-				mindistvec = distvec.clone();
-			}
-		}
-
-		mindistvec.normalize();
-		mindistvec.scale(-0.08);
-		cr.localDrive = mindistvec;
-	}
-
-	else
-	{
-		cr.localDrive = (0.1 * Math.rnd01, 0.1 * Math.rnd01, 0);
-	}
-
-	//energy costs depend on size
-	if (cr.energy > 100)
-	{
-		//TODO energy costs dependent on size
-		// cr.energy_m = cr.user2["Va"]/cr.user2["vinit"];
-	}
-
-	if (cr.lifespan >= ExpParams.max_age)
-	{
-		//TODO what is max age value? should there be one?
-		Populations[0].kill(cr);
-		return;
-	}
-
-	//foram growth
-	if (cr.lifespan == cr.user2["growth_step"])
-	{
-		//TODO how size is related to the energy?
-		cr.user2["rsize"] = ExpParams.rads[cr.user2["gen"]] * Math.min(Math.max(float(cr.user2["Va"] / cr.user2["vinit"]) * 0.5, 1.0), 2.5);
-		var geno = "//0\np:sh=1,sx=" + cr.user2["rsize"] + ",sy=" + cr.user2["rsize"] + ",sz=" + cr.user2["rsize"] + ", rz=3.14159265358979";
-		if (cr.user2["gen"] == 1)
-		{
-			geno += "\nn:p=0,d=\"S\""; //TODO why initial genotypes are not used as defined in ExpParams?
-			//TODO maybe it would be nice if they rotated so the "S" would show where they are going (direction/intention)
-		}
-		var cr2 = Populations[0].add(geno);
-		cr2.energy = cr.energy;
-		setGenotype(cr2, cr.user1, cr.user2);
-		cr2.moveAbs(cr.center_x - cr2.size_x / 2, cr.center_y - cr2.size_y / 2, cr.pos_z);
-
-		Populations[0].delete(cr);
-	}
-	else
-	{
-		var properSize = 0;
-
-		if (cr.user2["gen"] == 0)
-		{
-			properSize = cr.user2["Va"] >= cr.user1["vamin"];
-		}
-		else
-		{
-			properSize = cr.user2["Va"] >= cr.user1[0]["vamin"];
-		}
-
-		//if creature has proper age and cytoplasm amount
-		if ( properSize )
-		{
-			//reproduce with probability repro_prob
-			if (Math.rnd01 <= ExpParams.repro_prob)
-			{
-				readyToRepro(cr);
-			}
-		}
-		if ( properSize && (cr.signals.receive("repro") > 0))
-		{
-			readyToRepro(cr);
-		}
-	}
-}
-
-function onCreaturesDied(cr)
-{
-	//fossilization
-	var geno = GenePools[0].add(cr.genotype);
-	geno.user1 = cr.user1;
-	geno.user2 = cr.user2;
-	Simulator.print("\"" + cr.name + "\" died...");
-	ExpState.totaltestedcr++;
-}
-
-function setGenotype(cr, new_user1, new_user2)
-{
-	cr.user2 = {"Va" : new_user2["Va"], "gen" : new_user2["gen"], "growth_step" : new_user2["growth_step"], "rsize" : new_user2["rsize"], "vinit": new_user2["vinit"]};
-	if (cr.user2["gen"] == 0)
-	{
-		cr.user1 = {"vamin" : new_user1["vamin"], "amin": new_user1["amin"] };
-	}
-	else if (cr.user2["gen"] == 1)
-	{
-		cr.user1 = [ {"vamin" : new_user1[0]["vamin"], "amin": new_user1[0]["amin"] }, {"vamin" : new_user1[1]["vamin"], "amin": new_user1[1]["amin"] }];
-	}
-
-}
-
-// -------------------------------- creature end --------------------------------
-
-// -------------------------------- food begin --------------------------------
-
-function onFoodStep(cr)
-{
-	cr.moveAbs(cr.pos_x % ExpParams.wsize, cr.pos_y % ExpParams.wsize, 0.5);
-}
-
-function addfood()
-{
-	var cr = Populations[1].add(ExpParams.foodgen);
-
-	cr.name = "Food";
-	cr.idleen = 0;
-	cr.energ0 = ExpParams.feede0;
-	cr.energy = cr.energ0;
-	cr.signals.add("food");
-
-	cr.signals[0].value = cr.getMechPart(0);
-
-	placeRandomlyNotColliding(cr);
-}
-
-function onFoodCollision()
-{
-	if (Collision.Creature2.user2 != null)
-	{
-		var e = Collision.Part2.ing * ExpParams.feedtrans;
-		//Simulator.print("transferring "+e+" from "+Collision.Creature1.name+" to "+Collision.Creature2.name+" ("+Collision.Creature2.energy+")");
-		Collision.Creature1.energy_m = Collision.Creature1.energy_m + e;
-		Collision.Creature2.energy_p = Collision.Creature2.energy_p + e;
-		Collision.Creature2.user2["Va"] = float(Collision.Creature2.user2["Va"]) + float(e);
-	}
-}
-
-// -------------------------------- food end --------------------------------
-
-
-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();
-}
-
-
-
-
-@include "standard_events.inc"
-
-~
-
-prop:
-id:max_age
-name:Maximal age
-type:d 100 1000 500
-
-prop:
-id:wsize
-name:World size
-type:d 10 1000 20
-
-prop:
-id:growth_step
-name:Growth step
-type:d 10 10000 1000
-
-prop:
-id:rads
-name:Haploid and diploid radius
-type:x
-
-prop:
-id:age_min_h
-name:Min reproduction age of haploid forams
-type:d 100 10000 300
-group:Foraminifera
-
-prop:
-id:age_min_d
-name:Min reproduction age of diploid forams
-type:d 100 10000 200
-group:Foraminifera
-
-prop:
-id:v_min_h
-name:Min reproduction energy of haploid forams
-type:f 10 10000 300
-group:Foraminifera
-
-prop:
-id:v_min_d
-name:Min reproduction energy of diploid forams
-type:f 10 10000 150
-group:Foraminifera
-
-prop:
-id:repro_thr
-name:Energy creatures need to gather to reproduce
-type:d 1 1000 1
-
-prop:
-id:food_range
-name:Range of food smell
-type:d 0 10000 10000
-
-prop:
-id:repro_time
-name:Time before reproduction
-type:d 0 1000
-
-prop:
-id:psize
-name:Initial population size
-type:d 1 1000 100
-
-prop:
-id:logging
-name:Log statistics to file
-type:d 0 1 0
-
-prop:
-id:ofnumh
-name:Number of offspring from haploid forams
-type:d
-group:Foraminifera
-
-prop:
-id:ofnumd
-name:Number of offspring from diploid forams
-type:d
-group:Foraminifera
-
-prop:
-id:repro_prob
-name:Probability of reproduction
-type:f 0 1 0.9
-
-prop:
-id:crossprob
-name:Crossover probability
-type:f 0 1 0
-
-prop:
-id:mutationprob
-name:Mutation probability
-type:f 0 1 0
-
-prop:
-id:genh
-name:Initial genotype of haploid forams
-type:s 1
-group:Foraminifera
-
-prop:
-id:gend
-name:Initial genotype of diploid forams
-type:s 1
-group:Foraminifera
-
-prop:
-id:creath
-name:Creation height
-type:f -1 50
-help:~
-Vertical position (above the surface) where new creatures are revived.
-Negative values are only used in the water area:
-  0   = at the surface
--0.5 = half depth
--1   = just above the bottom~
-
-prop:
-id:e_meta
-name:Idle metabolism
-type:f 0 1
-group:Energy
-help:Each stick consumes this amount of energy in one time step
-
-prop:
-id:feedrate
-name:Feeding rate
-type:f 0 100
-group:Energy
-help:How fast energy is created in the world
-
-prop:
-id:feede0
-name:Food's energy
-group:Energy
-type:f 0 1000
-
-prop:
-id:feedtrans
-name:Ingestion multiplier
-group:Energy
-type:f 0 100
-
-prop:
-id:foodgen
-name:Food's genotype
-group:Energy
-type:s 1
-
-prop:
-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 creatures
-help:Total number of the creatures evaluated in the experiment
-type:d
-flags:16
-
-prop:
-id:foodPop
-name:Food size
-type:d 1 1000 10
-
-state:
-id:food
-name:Food locations
-help:vector of vectors [x,y,energy]
-type:x
-flags:32
Index: experiments/frams/foraminifera/data/scripts/forams_benthic.show
===================================================================
--- experiments/frams/foraminifera/data/scripts/forams_benthic.show	(revision 405)
+++ 	(revision )
@@ -1,113 +1,0 @@
-show:
-name:Benthic foraminifera reproduction
-info:~
-Genes and parameter values which control reproduction are stored in user1 and user2 fields.
-
-user1:
-genes which are not encoded in ff genotype:
-Vamin - Minimum stored energy necessary for reproduction
-amin - minimal age for reproduction
-
-user2:
-Physiological parameters of foraminifera:
-Va - amount of the stored energy
-gen - generation: 0 haploid, 1 diploid
-
-~
-expdef:forams_benthic
-code:~
-
-function onLoad()
-{
-	Simulator.init();
-	GLDisplay.desiredsimspeed = 50;
-	GLDisplay.minfps = 10;
-}
-
-function ShowParams_minimalVolume_set()
-{
-	switch (ShowParams.minimalVolume)
-	{
-	case 0:
-		ExpParams.v_min_h = 300;
-		ExpParams.v_min_d = 300;
-		break;
-	case 1:
-		ExpParams.v_min_h = 150;
-		ExpParams.v_min_d = 500;
-		break;
-	}
-}
-
-function ShowParams_offspingNumber_set()
-{
-	switch (ShowParams.offspingNumber)
-	{
-	case 0:
-		ExpParams.ofnumh = 300;
-		ExpParams.ofnumd = 300;
-		break;
-	case 1:
-		ExpParams.ofnumh = 150;
-		ExpParams.ofnumd = 500;
-		break;
-	}
-}
-
-function ShowParams_populationSize_set()
-{
-	switch (ShowParams.populationSize)
-	{
-	case 0:
-		ExpParams.psize = 5;
-		break;
-	case 1:
-		ExpParams.psize = 10;
-		break;
-	case 2:
-		ExpParams.psize = 15;
-		break;
-	case 3:
-		ExpParams.psize = 20;
-		break;
-	}
-}
-
-function ShowParams_feedRate_set()
-{
-	switch (ShowParams.feedRate)
-	{
-	case 0:
-		ExpParams.feedrate = 0.5;
-		break;
-	case 1:
-		ExpParams.feedrate = 0.7;
-		break;
-	case 2:
-		ExpParams.feedrate = 0.9;
-		break;
-	}
-}
-
-~
-
-
-prop:
-id:minimalVolume
-name:Min reproduction energy haploid/diploid
-type:f 0 1 ~300 / 300~150 / 500
-
-prop:
-id:populationSize
-name:Initial population size
-type:d 0 3 ~5~10~15~20
-
-prop:
-id:offspingNumber
-name:Number of offspring haploi/diploid
-type:d 0 2 ~20 / 4~10 / 5
-
-prop:
-id:feedRate
-name:Feeding rate
-type:d 0 2 ~50~70~90
Index: experiments/frams/foraminifera/data/scripts/forams_repro.inc
===================================================================
--- experiments/frams/foraminifera/data/scripts/forams_repro.inc	(revision 405)
+++ 	(revision )
@@ -1,209 +1,0 @@
-//size versus energy
-//real proportions
-
-// -------------------------------- step begin --------------------------------
-
-function reproduce_haploid(repro_list)
-{
-	var len = repro_list.size;
-	if (len % 2 != 0) len = repro_list.size - 1;
-
-	for (var i = 0; i < len - 2 ; i = i + 2)
-	{
-		var parent = Populations[0].get(repro_list[i]);
-		var parent2 = Populations[0].get(repro_list[i + 1]);
-
-		var number = parent.user2["Va"] / ExpParams.ofnumd + parent2.user2["Va"] / ExpParams.ofnumd;
-
-		for (var j = 0; j < number; j++)
-		{
-			createOffspring(ExpParams.gend, ExpParams.ofnumd, [parent.user1, parent2.user1], {"Va" : ExpParams.ofnumd, "gen" : 1 , "growth_step" : ExpParams.growth_step, "rsize": ExpParams.rads[1], "vinit": ExpParams.ofnumd}); //TODO genes from both generations in user1
-		}
-	}
-	killParents(repro_list);
-}
-
-function reproduce_diploid(repro_list)
-{
-	for (var i = 0; i < repro_list.size; i++)
-	{
-		var parent = Populations[0].get(repro_list[i]);
-
-		if (parent.user2["gen"] != 1)
-		{
-			Simulator.print("gen: " + parent.user2["gen"]);
-		}
-
-		if (parent.user2["gen"] == 1)
-		{
-			var number = parent.user2["Va"] / ExpParams.ofnumh;
-			for (var j = 0; j < number / 2; j++)
-			{
-				var crossed = 0;
-				//crossover
-				if (Math.rnd01 < ExpParams.crossprob)
-				{
-					crossover(parent, "vamin");
-					crossed = 1;
-				}
-
-				for (var k = 0; k < 2; k++)
-				{
-					createOffspring(ExpParams.genh, ExpParams.ofnumh, {"vamin" : ExpParams.v_min_h, "amin": ExpParams.age_min_h}, {"Va" : ExpParams.ofnumh, "gen" : 0 , "growth_step" : ExpParams.growth_step, "rsize" : ExpParams.rads[0], "vinit": ExpParams.ofnumh});
-				}
-
-				//reverse of crossover for fossilization
-				if (crossed == 1)
-				{
-					crossover(parent, "vamin");
-					crossed = 0;
-				}
-			}
-		}
-	}
-	killParents(repro_list);
-}
-
-function crossover(parent, gene)
-{
-	var tmp = parent.user1[0][gene];
-	parent.user1[0][gene] = parent.user1[1][gene];
-	parent.user1[1][gene] = tmp;
-}
-
-function killParents(repro_list)
-{
-	for (var j = 0; j < repro_list.size; j++)
-	{
-		Populations[0].kill(repro_list[j]);
-	}
-}
-
-function createOffspring(geno, energy, new_user1, new_user2)
-{
-	var cr = Populations[0].add(geno);
-	cr.energ0 = energy;
-	cr.energy = cr.energ0;
-	setGenotype(cr, new_user1, new_user2);
-	placeRandomlyNotColliding(cr);
-}
-
-function onStep()
-{
-	var haploids = 0;
-	var diploids = 0;
-	var e_inc_h = 0.0;
-	var e_inc_d = 0.0;
-	var e_nut = 0.0;
-	var size_h = 0.0;
-	var size_d = 0.0;
-	var vmin_h = 0.0;
-	var vmin_d = 0.0;
-
-	for (var i = 0; i < Populations[0].size; i++)
-	{
-		var cr = Populations[0].get(i);
-		if (cr.user2["gen"] == 0)
-		{
-			haploids += 1;
-			e_inc_h += cr.energy;
-			size_h += ExpParams.rads[0]; //TODO change of size dependent on gene
-			vmin_h += cr.user1["vamin"];
-		}
-		else if (cr.user2["gen"] == 1)
-		{
-			diploids += 1;
-			e_inc_d += cr.energy;
-			size_d += ExpParams.rads[1]; //TODO change of size dependent on gene
-			vmin_d += cr.user1[0]["vamin"];
-		}
-	}
-
-	for (var i = 0; i < Populations[1].size; i++)
-	{
-		var cr = Populations[1].get(i);
-		e_nut += cr.energy;
-	}
-
-	if (haploids < 2 && diploids == 0)
-	{
-		Simulator.print("no more creatures, stopped.");
-		Simulator.stop();
-	}
-
-	var l1 = [haploids, diploids, Populations[1].size];
-	var l2 = [e_inc_h, e_inc_d, e_nut];
-	var dp = diploids;
-	var hp = haploids;
-	if (dp == 0) dp = 0.000001;
-	if (hp == 0) hp = 0.000001;
-	var l3 = [size_h / hp, vmin_h / hp, size_d / dp, vmin_d / dp];
-
-	if (ExpParams.logging == 1)
-	{
-		log(l1, "log.txt");
-		log(l2, "log2.txt");
-		log(l3, "log3.txt");
-	}
-	//food growth ---------------------------------------------
-	foodenergywaiting = foodenergywaiting + ExpParams.feedrate;
-	if (foodenergywaiting > ExpParams.feede0)
-	{
-		for (var i = 0; i < ExpParams.foodPop; i++)
-		{
-			addfood();
-		}
-
-		foodenergywaiting = 0.0;
-		Simulator.checkpoint();
-	}
-
-	//reproduction --------------------------------------------
-	reprocounter += 1;
-	if (reprocounter > ExpParams.repro_time)
-	{
-		reprocounter = 0;
-		var to_repro_h = [];
-		var to_repro_d = [];
-		for (var i = 0; i < Populations[0].size; i++)
-		{
-			var cr = Populations[0].get(i);
-			if (cr.signals.size > 0)
-			{
-				if (cr.user2["gen"] == 0)
-				{
-					to_repro_h.add(i);
-				}
-				if (cr.user2["gen"] == 1)
-				{
-					to_repro_d.add(i);
-				}
-			}
-		}
-		if (to_repro_h.size > 1)
-		{
-			reproduce_haploid(to_repro_h);
-		}
-		if (to_repro_d.size > 0)
-		{
-			reproduce_diploid(to_repro_d);
-		}
-	}
-
-	//check for death -----------------------------------------------
-	if (Populations[0].size == 0)
-	{
-		if (ExpParams.autorestart)
-		{
-			Simulator.print("no more creatures, restarting...");
-			onExpInit();
-		}
-		else
-		{
-			Simulator.print("no more creatures, stopped.");
-			Simulator.stop();
-		}
-	}
-}
-
-// -------------------------------- step end --------------------------------
