Closed fmarande closed 7 years ago
Hi, Florianne,
I can reproduce your problem with python 3 (with some slight change of code style). After I wrap the parent-determination code with
try:
for ind in pop.individuals():
if ind.sex() == 1:
#choice of the male according to their fecundity
fathers.extend([ind] * pop.dvars().male_age_fecundity[int(ind.age)])
else:
#choice of the female according to their fecundity
mothers.extend([ind] * pop.dvars().female_age_fecundity[int(ind.age)])
except:
print(pop.dvars().female_age_fecundity)
print(pop.dvars().male_age_fecundity)
print(set(int(x.age) for x in pop.individuals()))
sys.exit()
I found that the error happens with
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
I can see that you are accessing the 19th element of a list of size 18, which caused an index error and broke the parent selection process.
So it appears to me that you should change
mothers.extend([ind] * pop.dvars().female_age_fecundity[int(ind.age)])
and the father part to
mothers.extend([ind] * pop.dvars().female_age_fecundity[int(ind.age)-1])
Hello Bo, thank you for this quick answer and for your help !!
Here's the new choose_parent function as you suggest :
def choose_parents(pop):
#name convention required
fathers = []
mothers = []
for ind in pop.individuals():
if ind.sex() == 1:
#choice of the male according to their fecundity
fathers.extend([ind] * pop.dvars().male_age_fecundity[int(ind.age)-1])
else:
#choice of the female according to their fecundity
mothers.extend([ind] * pop.dvars().female_age_fecundity[int(ind.age)-1])
while True:
#random choice of parents in the parents pool
father = random.choice(fathers)
mother = random.choice(mothers)
yield father, mother
However I tried to run it and it works sometimes and sometimes a new error appears :
Traceback (most recent call last):
File "
", line 155, in gen=num_gens) ValueError: Function call failed
If you don't have this error, I suppose it can be due to my python settlement ?
Florianne
I got
Traceback (most recent call last):
File "test.py", line 35, in kill
cut = pop.dvars().survival_female[int(i.age)]
IndexError: list index out of range
so it looks like survival_female
is also shorter than i.age
? Please check carefully about such things. The try...except
approach I used can be really helpful in such cases.
Thanks, I will try to track all the dimension things. I don't find the same error as you but I will continue digging this way. Thanks you for answer !
But what I really don't understand is that the issue is related to "index out if range". It should never run and it should not run sometimes and sometimes not run ?
The whole evolutionary process is random. You have a small population size, so the probability that some parent having the extreme age (18) is chosen for reproduction is rather low. This is why the IndexError
only happens from time to time. If you significantly increase the size of population, such error will almost surely occur each time.
Ok, now I understand better what's the matter is. I will try to check all the index length. Thank you for all your help ! It was very usefull and I hope I will succeed to fix it !
Dear Mr Peng,
I'am currently trying to simulate a complex demography population with specific age-survival, sexual maturity at age 5 and a maximum age at 15 years. My code is largely inspired from Tiago Antao book - Bioinformatics with Python Cookbook and I've to say I'm quite new with python and simuPOP. Final aim is to simulate a large number of individuals (>1 000 000) and a large number of SNPs (>2 000) for assessing the power of effective population size estimators for large natural populations.
My code works relatively well : sex ratio is around 1:1, age structure is stable after 10 generations and the export of SNPs data set is working but my code sometimes doesn't work (the frequence of the error increases with the population size).
As this error occurs sometimes, I've the feeling (maybe wrong) that it's due to the initialisation process. Maybe the age structure initialisation which is currently randomly assigned :
init_ops['Age'] = sp.InitInfo(lambda: random.randint(0, len(survival_male) - 1), infoFields='age')
Is there a way to assign age structure with frequency ? (If it's in the simuPOP help, I'm sorry I didn't find it) to avoid an assignment of only immature individuals.
I'm not sure it is the issue if you have any other idea just tell me. I'm starting to be desperate about finding what's wrong....
Thank you very much ! Best Regards,
Florianne
PS : the complet code is above
Reference : Tiago Antao - 2015 - Bioinformatics with Python Cookbook - Packt Publishing Limited - pages 143-149