Exemplo n.º 1
0
class TestPlottingFunction(object):
    def test_population_has_plotting_option(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        try:
            self.pop.launch(dev='on')
        except TypeError as e:
            assert False, "allow for 'on' device to show plots"
        os.remove("output/vigilance_out.txt")
        os.remove("output/vigilance_out.gif")
        os.remove('output/resources_out.txt')
        os.remove('output/exploration_out.txt')
        os.remove('output/grid_out.gif')

    def test_gif_is_created_only_when_dev_on(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        self.pop.launch(dev='on')

        self.filesListRootOut = os.listdir("./output")
        assert "vigilance_out.gif" in self.filesListRootOut, "no output gif created"
        os.remove("output/vigilance_out.gif")

        self.pop.launch()
        self.filesListRootOut = os.listdir("./output")
        assert "vigilance_out.gif" not in self.filesListRootOut, "should not have created output gif!"
        os.remove("output/vigilance_out.txt")
        os.remove('output/resources_out.txt')
        os.remove('output/exploration_out.txt')
        os.remove('output/grid_out.gif')

    def test_grid_gif_is_created(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        self.pop.launch(dev='on')

        self.filesListRootOut = os.listdir("./output")
        assert "grid_out.gif" in self.filesListRootOut, "no output grid gif created"
        os.remove("output/vigilance_out.txt")
        os.remove("output/vigilance_out.gif")
        os.remove('output/resources_out.txt')
        os.remove('output/exploration_out.txt')
        os.remove('output/grid_out.gif')
Exemplo n.º 2
0
from model.population import Population as Pop
import sys
  
try:
	visual = sys.argv[1]
except IndexError:
	visual = "off"
	print("Visualisation turned off. Type 'python run.py on' to run simulation with visualisation")

pop = Pop()
pop.create()
pop.launch(dev=visual)
# pop.launch(dev='on')
class TestMutationFunction(object):
    def test_mutation_function_takes_and_returns_phenotype(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create(n=1)
        self.indiv = self.pop.individuals[0]

        self.indiv.mutate(mutRate=0.5, mutStep=0.5)
        x = self.indiv.vigilance
        assert type(
            x
        ) is float, "Phenotypic values ({0}) must be of type float, and not {1}".format(
            x, type(x))
        assert 0 <= x <= 1, "Phenotypic values must be in range [0,1]"

        gc.collect()

    def test_mutants_are_defined(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create(n=1)
        self.indiv = self.pop.individuals[0]

        self.indiv.mutate(mutRate=0.5, mutStep=0.5)
        assert hasattr(
            self.indiv, "mutant"
        ), "We don't know if our individual is a mutant because it doesn't have this attribute"
        assert type(self.indiv.mutant) is bool

        gc.collect()

    def test_mutants_depend_on_seed(self, pseudorandom):
        self.nIndividuals = 1000
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=self.nIndividuals)

        mutants = []

        for ind in self.fakepop.individuals:
            pseudorandom(0)
            ind.mutate(mutRate=0.3, mutStep=0.1)
            mutants.append(ind.mutant)

        assert all(mutants) or not any(
            mutants), "Mutant does not depend on seed: {0}".format(
                set(mutants))

    def test_mutants_are_drawn_from_binomial(self, pseudorandom):
        pseudorandom(0)
        self.nIndividuals = 1000
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=self.nIndividuals)
        self.mutationRate = 0.2

        self.mutantCount = 0
        for ind in self.fakepop.individuals:
            ind.mutate(mutRate=self.mutationRate, mutStep=0.05)
            if ind.mutant:
                self.mutantCount += 1

        stat1, pval1 = scistats.ttest_1samp(
            [1] * self.mutantCount + [0] *
            (self.nIndividuals - self.mutantCount), self.mutationRate)
        assert pval1 > 0.05, "T-test mean failed. Observed: {0}, Expected: {1}".format(
            self.mutantCount / self.nIndividuals, self.mutationRate)
        self.test = scistats.binom_test(self.mutantCount,
                                        self.nIndividuals,
                                        self.mutationRate,
                                        alternative="two-sided")
        assert self.test > 0.05, "Success rate = {0} when mutation rate = {1}".format(
            self.mutantCount / self.nIndividuals, self.mutationRate)

        gc.collect()

    def test_deviation_depends_on_seed(self, pseudorandom):
        self.nIndividuals = 1000
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=self.nIndividuals)

        mutationDeviations = []

        for ind in self.fakepop.individuals:
            pseudorandom(0)
            ind.mutate(mutRate=1, mutStep=0.05)
            mutationDeviations.append(ind.mutationDeviation)

        assert all([
            x == mutationDeviations[0] for x in mutationDeviations
        ]), "Mutation deviation does not depend on seed: {0}".format(
            set(mutationDeviations))

    def test_deviation_function_returns_float(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=1)
        self.indiv = self.fakepop.individuals[0]
        self.v = self.indiv.vigilance

        for mutationBool in [True, False]:
            self.indiv.mutant = mutationBool
            self.indiv.deviate(mutStep=0.05)
            assert type(self.indiv.mutationDeviation) is float

        gc.collect()

    def test_mutants_get_deviation_from_phenotype(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=1)
        self.indiv = self.fakepop.individuals[0]
        self.indiv.mutate(mutRate=1, mutStep=0.05)
        assert hasattr(
            self.indiv, "mutationDeviation"
        ), "Individual is a mutant: it needs to be set a deviation from phenotype"

        assert -1 < self.indiv.mutationDeviation < 1

        gc.collect()

    def test_only_mutants_change_phenotype(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=2)
        assert len(self.fakepop.individuals) == 2

        self.mutantIndivTrue = self.fakepop.individuals[0]
        self.mutantIndivFalse = self.fakepop.individuals[1]

        self.mutantIndivTrue.mutate(mutRate=1, mutStep=0.05)
        assert bool(
            self.mutantIndivTrue.mutant
        ), "Uh-oh, looks like the individual did not mutate when it should have..."
        assert self.mutantIndivTrue.mutationDeviation != 0, "Your mutant (bool={0}) phenotype does not deviate!".format(
            self.mutantIndivTrue.mutant)

        self.mutantIndivFalse.mutate(mutRate=0, mutStep=0.05)
        assert not bool(self.mutantIndivFalse.mutant)
        assert self.mutantIndivFalse.mutationDeviation == 0, "Phenotype deviates even though individual not a mutant!"

        gc.collect()

    def test_mutation_deviation_follows_normal_distribution(
            self, pseudorandom):
        pseudorandom(0)
        self.nIndividuals = 1000
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(self.nIndividuals)

        self.distri = []
        for ind in self.fakepop.individuals:
            ind.mutate(mutRate=1, mutStep=0.05)
            self.distri.append(ind.mutationDeviation)

        stat1, pval1 = scistats.ttest_1samp(self.distri, float(0))
        assert pval1 > 0.05, "T-test mean failed. Observed: {0}, Expected: {1}".format(
            mean(self.distri), 0)
        stat2, pval2 = scistats.kstest(self.distri,
                                       'norm',
                                       args=(0, 0.05),
                                       N=self.nIndividuals)
        assert pval2 > 0.05, "Test for goodness of fit failed"
        stat3, pval3 = scistats.shapiro(self.distri)
        assert pval3 > 0.05, "Test of normality failed"

        gc.collect()

    def test_mutation_adds_deviation_to_phenotype(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(2)

        # WHEN THERE IS MUTATION
        self.trueMutant = self.fakepop.individuals[0]
        self.oldPhenTrueMutant = self.trueMutant.vigilance

        self.trueMutant.mutant = True
        self.trueMutant.deviate(mutStep=0.05)
        assert self.trueMutant.mutationDeviation != 0, "Deviation = {0}".format(
            self.trueMutant.mutationDeviation)

        self.trueMutant.applyMutation(self.trueMutant.mutationDeviation,
                                      bound=True)
        assert self.trueMutant.vigilance != self.oldPhenTrueMutant, "New:{0}, Old:{1}".format(
            self.trueMutant.vigilance, self.oldPhenTrueMutant)

        # Reset to test the whole thing together:
        self.trueMutant.vigilance = self.oldPhenTrueMutant
        self.trueMutant.mutant = None
        self.trueMutant.mutationDeviation = None

        self.trueMutant.mutate(mutRate=1, mutStep=0.05)
        assert type(self.oldPhenTrueMutant) is float and type(
            self.trueMutant.mutationDeviation
        ) is float, "Check that both {0} and {1} are float".format(
            self.oldPhenTrueMutant, self.trueMutant.mutationDeviation)

        assert min(
            1,
            max(0, self.oldPhenTrueMutant + self.trueMutant.mutationDeviation)
        ) == pytest.approx(
            self.trueMutant.vigilance
        ), "Deviation not added to mutant phenotype: returns {0} instead of {1}!".format(
            self.trueMutant.vigilance,
            self.oldPhenTrueMutant + self.trueMutant.mutationDeviation)

        # WHEN THERE IS NO MUTATION
        self.falseMutant = self.fakepop.individuals[1]
        self.oldPhenFalseMutant = self.falseMutant.vigilance

        self.falseMutant.mutant = False
        self.falseMutant.deviate(mutStep=0.05)
        assert self.falseMutant.mutationDeviation == 0, "Deviation = {0}".format(
            self.falseMutant.mutationDeviation)

        self.falseMutant.applyMutation(self.falseMutant.mutationDeviation,
                                       bound=True)
        assert self.falseMutant.vigilance == self.oldPhenFalseMutant, "New:{0}, Old:{1}".format(
            self.falseMutant.vigilance, self.oldPhenFalseMutant)

        # Reset to test the whole thing together:
        self.falseMutant.vigilance = self.oldPhenFalseMutant
        self.falseMutant.mutant = None
        self.falseMutant.mutationDeviation = None

        self.falseMutant.mutate(mutRate=0, mutStep=0.05)
        assert self.oldPhenFalseMutant == self.falseMutant.vigilance, "Your individual shows mutant characteristic = {0}. Yet its phenotype deviates by {1}".format(
            self.falseMutant.mutant, [
                x - y for x, y in zip(self.falseMutant.vigilance,
                                      self.oldPhenFalseMutant)
            ])
        assert self.oldPhenFalseMutant == self.falseMutant.vigilance, "Before: {0}, Deviation: {1}, After: {2}".format(
            self.oldPhenFalseMutant, self.falseMutant.mutationDeviation,
            self.falseMutant.vigilance)

        gc.collect()

    def test_mutation_does_not_affect_phenotype_type(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create(n=1)
        self.indiv = self.fakepop.individuals[0]
        self.phen = self.indiv.vigilance

        self.indiv.mutate(mutRate=1, mutStep=0.05)
        assert type(self.indiv.vigilance) is float

        gc.collect()

    def test_individual_mutation_can_be_unbounded(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.nIndiv = 100
        self.fakepop.initialVigilance = 1
        self.fakepop.create()

        collectPhenotypes = []

        for ind in self.fakepop.individuals:
            ind.mutate(1, 0.5, bounded=False)
            collectPhenotypes.append(ind.vigilance)

        assert any([i > 1 for i in collectPhenotypes
                    ]), "no phenotype went over 1, even when unbounded."
Exemplo n.º 4
0
class TestReproductionFunction(object):
    def test_individual_can_reproduce(self):
        assert hasattr(Ind(m=3), "reproduce"), "ind cannot reproduce"

    def test_fertility_returns_positive_float(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create()

        for ind in range(len(self.fakepop.individuals)):
            indiv = self.fakepop.individuals[ind]
            setattr(indiv, "storage", 1 + 9 * ind)
            indiv.reproduce(fecundity=2)
            assert type(indiv.fertility) is float
            assert indiv.fertility >= 0

    def test_fertility_increases_with_storage(self):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.create()

        fertility = 0

        for ind in range(len(self.fakepop.individuals)):
            indiv = self.fakepop.individuals[ind]
            setattr(indiv, "storage", 1 + 9 * ind)
            indiv.reproduce(fecundity=2)
            assert indiv.fertility > fertility
            fertility = indiv.fertility

    def test_reproduction_gives_offspring_number(self):
        self.indiv = Ind(m=3)

        self.indiv.reproduce(fecundity=2)
        assert self.indiv.offspring != None, "No offspring number generated"
        assert type(
            self.indiv.offspring
        ) is int, "Offspring number of wrong format: {0} instead of integer".format(
            type(self.indiv.offspring))
        assert self.indiv.offspring >= 0, "Offspring number cannot be negative"

    def test_offspring_number_increases_with_fertility(self):
        self.indLowFertility = Ind(m=3)
        self.indHighFertility = Ind(m=3)

        self.indLowFertility.storage = 1
        self.indLowFertility.reproduce(fecundity=0.5)
        self.indHighFertility.storage = 10
        self.indHighFertility.reproduce(fecundity=2)

        assert self.indLowFertility.offspring < self.indHighFertility.offspring, "high fertility should lead to higher offspring number"

    def test_reproduction_is_seed_dependent(self, pseudorandom):
        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.nIndiv = 1000
        self.fakepop.create()

        offspring = []

        for ind in self.fakepop.individuals:
            setattr(ind, "storage", 4)
            pseudorandom(0)
            ind.reproduce(fecundity=2)
            offspring.append(ind.offspring)

        assert all([
            x == offspring[0] for x in offspring
        ]), "number of offspring differs with same seed, {0}".format(
            set(offspring))

    def test_reproduction_follows_a_poisson_distribution(self, pseudorandom):
        #http://www2.stat-athens.aueb.gr/~exek/papers/Xekalaki-Statistician2000(355-382)ft.pdf
        pseudorandom(0)

        self.fakepop = Pop("test/test/parameters.txt")
        self.fakepop.nIndiv = 1000
        self.fakepop.create()
        self.explambda = 8

        offspringPerInd = []
        for ind in self.fakepop.individuals:
            setattr(ind, "storage", 4)
            ind.reproduce(fecundity=2)
            offspringPerInd.append(ind.offspring)

        d = Counter(offspringPerInd)
        a, b = list(d.keys()), list(d.values())
        maxCount = max(a)
        observedCount = []
        expectedCount = []

        for k in range(maxCount):
            if k in a:
                observedCount.append(d[k])
            else:
                observedCount.append(0)

            expProbability = m.pow(m.e, (-self.explambda)) * (m.pow(
                self.explambda, k)) / m.factorial(k)
            expectedCount.append(self.fakepop.nIndiv * expProbability)

        chisq, pval = scistats.chisquare(observedCount, expectedCount)
        assert len(expectedCount) == len(
            observedCount), "len obs = {0}, len exp = {1}".format(
                len(observedCount), len(expectedCount))
        #assert sum(expectedCount) == sum(observedCount), "n obs = {0}, n exp = {1}".format(sum(observedCount), sum(expectedCount))
        assert pval > 0.05, "Test for goodness of fit failed: obs = {0}, exp = {1}".format(
            observedCount, expectedCount)
class TestPopulationObject(object):
    def test_population_has_individual_instances(self):
        self.pop = Pop("test/test/parameters.txt")

        assert hasattr(self.pop, "create"), "cannot create pop"
        self.pop.create(2)
        assert hasattr(self.pop, "individuals"), "no indivs in this pop"

    def test_population_has_correct_density(self):
        self.pop = Pop("test/test/parameters.txt")

        d1 = 2
        self.pop.create(d1)

        assert type(self.pop.individuals) is list
        assert len(self.pop.individuals) == d1
        for i in self.pop.individuals:
            assert type(i) is Ind

        d2 = 10
        self.pop.create(d2)

        assert type(self.pop.individuals) is list
        assert len(self.pop.individuals) == d2
        for i in self.pop.individuals:
            assert type(i) is Ind

    def test_population_individuals_are_unlinked(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()

        assert len(set(self.pop.individuals)) == self.pop.nIndiv

    def test_population_has_life_cycle(self):
        assert hasattr(Pop(), "lifeCycle")
        assert callable(getattr(Pop(), "lifeCycle"))

    # def test_share_calculated_and_assigned_to_grid(self):
    # 	assert False, "write this test"

    # def test_pool_is_wiped_out_at_beginning_of_cycle(self):
    # 	assert False, "write this test"

    def test_population_creates_grid(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create(n=20)

        assert hasattr(self.pop, "grid")
        assert type(self.pop.grid) is Grid
        assert self.pop.grid.resources.shape == (self.pop.gridSize,
                                                 self.pop.gridSize)

    def test_population_explores_grid(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()

        assert hasattr(self.pop, "explore")

    def test_population_exploration_leads_to_change_in_coord(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.nIndiv = 1000
        self.pop.gridSize = 60
        self.pop.create()

        coord = []
        for ind in self.pop.individuals:
            coord.append(ind.coordinates)

        self.pop.explore()

        newCoord = []
        for ind in self.pop.individuals:
            newCoord.append(ind.coordinates)

        assert all([coord[x] == newCoord[x]
                    for x in range(len(coord))]) == False

    def test_population_exploration_gives_share_info(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        self.pop.explore()
        m = self.pop.gridSize

        assert hasattr(self.pop, "ncell")
        assert type(self.pop.ncell) is np.ndarray
        assert self.pop.ncell.shape == (m, m)
        assert hasattr(self.pop, "vcell")
        assert type(self.pop.vcell) is np.ndarray
        assert self.pop.vcell.shape == (m, m)

    def test_only_live_individuals_explore(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        coord = []

        for ind in self.pop.individuals:
            ind.alive = False
            coord.append(ind.coordinates)

        self.pop.explore()

        newCoord = []
        for ind in self.pop.individuals:
            newCoord.append(ind.coordinates)

        assert all([coord[x] == newCoord[x] for x in range(len(coord))])

    def test_population_can_gather_vs_survive(self):
        assert hasattr(Pop(), "gatherAndSurvive")
        assert callable(getattr(Pop(), "gatherAndSurvive"))

        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        try:
            self.pop.gatherAndSurvive()
        except ValueError as e:
            assert False, "missing info: {0}".format(e)

    def test_gathering_gives_individuals_storage(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        self.pop.grid.share = np.full([self.pop.gridSize, self.pop.gridSize],
                                      0.8)

        for i in self.pop.individuals:
            i.vigilance = 0

        self.pop.gatherAndSurvive()

        for i in self.pop.individuals:
            assert i.storage > 0

    def test_only_live_individuals_gather_and_survive(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        self.pop.explore()

        for ind in self.pop.individuals:
            ind.alive = False

        self.pop.gatherAndSurvive()

        for ind in self.pop.individuals:
            assert ind.alive == False
            assert ind.storage == 0

    def test_population_has_a_routine(self):
        assert hasattr(Pop(), "routine")
        assert callable(getattr(Pop(), "routine"))

    def test_population_routine_changes_share_grid(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()

        shareG = self.pop.grid.share

        self.pop.routine()

        compareGrids = self.pop.grid.share == shareG

        assert compareGrids.all() == False

    def test_population_routine_changes_resources_grid(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()

        resG = self.pop.grid.resources

        self.pop.routine()

        compareGrids = self.pop.grid.resources != resG

        assert compareGrids.all()

    def test_reproduction_at_population_level(self):
        assert hasattr(Pop(), "reproduce")
        assert callable(getattr(Pop(), "reproduce"))

        gc.collect()

    def test_reproduction_creates_pool(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        self.pop.routine()
        self.pop.reproduce()

        assert hasattr(self.pop,
                       "nextGeneration"), "population pool does not exist"
        assert type(self.pop.nextGeneration) is list
        assert len(self.pop.nextGeneration) > 0

        for elem in self.pop.nextGeneration:
            assert type(elem) is int
            assert elem in range(10)

        gc.collect()

    def test_pool_is_a_mix_of_individuals(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.initRes = 10
        self.pop.create()
        self.pop.routine()

        for ind in self.pop.individuals:
            ind.alive = True

        self.pop.reproduce()
        assert len(set(
            self.pop.nextGeneration)) > 1, "ids missing in {0}".format(
                set(self.pop.nextGeneration))

        gc.collect()

    def test_only_live_individuals_reproduce(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.initRes = 10
        self.pop.create()
        self.pop.routine()

        for ind in self.pop.individuals:
            ind.alive = False
        self.pop.individuals[0].alive = True

        self.pop.reproduce()
        #assert len(set(self.pop.nextGeneration)) > 1, "ids missing in {0}".format(set(self.pop.nextGeneration))
        assert len(set(self.pop.nextGeneration)
                   ) == 1, "there should be only one id in {0}".format(
                       set(self.pop.nextGeneration))
        assert self.pop.nextGeneration.count(
            0
        ) == self.pop.nIndiv, "only ind #0 should reproduce, not {0}".format(
            set(self.pop.nextGeneration))

        gc.collect()

    def test_death_counter(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.predation = 1
        self.pop.create()

        for ind in self.pop.individuals:
            ind.vigilance = 0

        self.pop.routine()
        for ind in self.pop.individuals:
            assert ind.alive == False

        self.pop.reproduce()

        assert self.pop.deathCount == 10

    def test_population_gets_updated_at_new_gen(self):
        assert hasattr(Pop(), "update")
        assert callable(getattr(Pop(), "update"))

    def test_update_replaces_old_gen_with_new_gen(self):
        self.pop = Pop("test/test/parameters.txt")
        self.pop.create()
        self.pop.routine()
        self.pop.reproduce()
        oldgen = self.pop.individuals
        self.pop.update()

        assert len(self.pop.individuals) == self.pop.nIndiv
        assert self.pop.individuals != oldgen

    def test_update_returns_population_vigilance_info(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        self.pop.routine()
        self.pop.reproduce()
        self.pop.update()

        assert hasattr(self.pop, "vigilance")
        assert self.pop.vigilance is not None
        assert type(self.pop.vigilance) is float
        assert 0 <= self.pop.vigilance <= 1

    def test_population_vigilance_is_correct(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        self.pop.routine()
        self.pop.reproduce()
        self.pop.update()

        collectVigilances = []

        for ind in self.pop.individuals:
            collectVigilances.append(ind.vigilance)

        assert self.pop.vigilance == pytest.approx(np.mean(collectVigilances),
                                                   0.1)

    def test_lam_error_when_resources_too_big(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.initRes = 20000000000000000000
        self.pop.create()
        try:
            self.pop.lifeCycle()
        except ValueError as e:
            assert str(
                e
            ) == 'lam value too large', "This program should fail at poisson random draw, not '{0}'".format(
                e)

    def test_resources_crash_when_too_large(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.initRes = 20
        self.pop.growth = 100
        self.pop.create()
        self.pop.lifeCycle()

        for cell in np.nditer(self.pop.grid.resources):
            assert cell <= self.pop.initRes, "resources too large, should have crashed"

    def test_population_keeps_track_of_ecological_time(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()

        assert hasattr(
            self.pop,
            "ecoTime"), "population must keep track of its ecological time!"

    def test_ecological_time_correctly_assessed(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        self.pop.lifeCycle()
        ngen = 5

        assert self.pop.ecoTime == self.pop.routineSteps, "one life cycle should be {0} units of ecological time, not {1}".format(
            self.pop.routineSteps, self.pop.ecoTime)

        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        for i in range(ngen):
            self.pop.lifeCycle()

        assert self.pop.ecoTime == self.pop.routineSteps * ngen, "{2} life cycles should be {0} units of ecological time, not {1}".format(
            self.pop.routineSteps * 10, self.pop.ecoTime, ngen)

    def test_population_keeps_track_of_resources_over_life_cycle(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()

        assert hasattr(
            self.pop, "ecologyShortHistory"
        ), "population must keep track of its ecological history!"

    def test_resources_info_augmented_at_each_routine(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()
        for i in range(self.pop.routineSteps):
            self.pop.routine()

        assert self.pop.ecologyShortHistory.shape == ((self.pop.gridSize**2) *
                                                      self.pop.routineSteps, 4)

    def test_population_keeps_track_of_exploration_over_life_cycle(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.create()

        assert hasattr(
            self.pop, "explorationShortHistory"
        ), "population must keep track of its exploration history!"

    def test_exploration_info_augmented_at_each_routine(self):
        self.pop = Pop(par="test/test/parameters.txt")
        self.pop.predation = 0
        self.pop.create()
        for i in range(self.pop.routineSteps):
            self.pop.routine()

        assert self.pop.explorationShortHistory.shape == (
            self.pop.nIndiv * self.pop.routineSteps, 4)