def detparam(self,s,category): s1 = s ss = [] while len(s1)>0 : plus = s1.find("+") minus= s1.find("-") if (plus == -1)and(minus == -1) : ss.append(s1) s1 = "" else : if plus>=0 : posigne = plus; else : posigne = minus; ss.append(s1[:posigne]) s1 = s1[posigne+1:] for j in range(len(ss)) : if not isaninteger(ss[j]): pr = param.HistParameter() pr.category,pr.prior = category, None pr.name, pr.value = ss[j], None if len(self.parameters) >0 : trouve = False i = -1 while (not trouve) and (i<len(self.parameters)-1) : i +=1 trouve = pr.name == self.parameters[i].name if trouve and (self.parameters[i].category != category): raise IOScreenError, "%s is used as a %s parameter and %s parameter"%(pr.name,param.HistParameter.categorydict[category],param.HistParameter.categorydict[self.parameters[i].category] ) if not trouve : self.parameters.append(pr) else : self.parameters.append(pr)
def checkread(self,textarray,data=None): if len(self.parameters)>0 : self.parametersbackup = copy.deepcopy(self.parameters) self.parameters = [] else : self.parametersbackup = [] ligne0 = textarray[0] #take the first line of the scenario ligne =ligne0.upper() #put it in uppercase if ligne.find('SAMPLE')+ligne.find('REFSAMPLE')+ligne.find('MERGE')+ligne.find('VARNE')+ligne.find('SPLIT')+ligne.find('SEXUAL')>-4: raise IOScreenError, "The first line must provide effective population sizes" ls = ligne0.split() self.npop = len(ls) self.history = History() Ncur=[] for l in ls : NN = Ne0() NNc = Ne0() if isaninteger(l): NN.name, NN.val, NNc.name, NNc.val = str(l),int(l),str(l),int(l) else : NN.name, NN.val, NNc.name, NNc.val = l, None, l, None self.history.ne0s.append(NN) Ncur.append(NNc) if NN.val == None : self.detparam(NN.name,"N") self.nsamp = 0 self.nrefsamp = 0 nevent = 0 pat = re.compile(r'\s+') for i,li_n_c in enumerate(textarray[1:]): li = pat.sub(' ',li_n_c) if li.upper().find('SAMPLE')+li.upper().find('REFSAMPLE') > -1 : self.nsamp+=1 if li.upper().find('REFSAMPLE') > -1 : self.dicoPopRefNindRef[int(li.strip().split(' ')[-3])] = int(li.strip().split(' ')[-1]) + int(li.strip().split(' ')[-2]) self.nrefsamp+=1 if (len(li.strip().split(' ')) < 3)or(len(li.strip().split(' ')) == 4): raise IOScreenError, "At line %i, the number of words is incorrect"%(i+2) # verif que le nombre apres "sample" est bien inférieur ou egal au nombre de pop (len(Ncur)) if (li.upper().find(' SAMPLE')>-1) and (int(li.strip().split(' ')[2]) > len(Ncur)): raise IOScreenError, "At line %i, the population number (%s) is higher than the number of population (%s) defined at line 1"%((i+2),li.split(' ')[-1],len(Ncur)) if (li.upper().find('REFSAMPLE')>-1) and (int(li.strip().split(' ')[2]) > len(Ncur)): raise IOScreenError, "At line %i, the population number (%s) is higher than the number of population (%s) defined at line 1"%((i+2),li.split(' ')[-1],len(Ncur)) if self.nsamp<1 : raise IOScreenError, "You must indicate when samples are taken" if data!=None: #print self.nsamp,"========", data.nsample if self.nsamp != data.nsample+self.nrefsamp : raise IOScreenError, "The number of samples in scenario %s does not match the data file"%(self.number) if len(textarray)>1 : for ili0 in range(0,len(textarray)-1) : for ili1 in range(ili0+1,len(textarray)) : li0tem = textarray[ili0].split() li1tem = textarray[ili1].split() idem = False if len(li0tem) == len(li1tem) : idem = True j = 0 while idem and (j<len(li0tem)) : idem = (li0tem[j] == li1tem[j]) j +=1 if idem : raise IOScreenError,"Lines %s and %s of scenario %s are identical"%(ili0+1,ili1+1,self.number) j,ns = 0, 0 for jli0 in range(1,len(textarray)): if len(textarray[jli0])>0: j +=1 li = textarray[jli0] Li = li.upper() litem = li.split() nitems = len(litem) if Li.find(" SAMPLE")+ Li.find("REFSAMPLE")>-1: if (nitems<3)or(nitems==4): raise IOScreenError, "Line %s of scenario %s is incomplete"%(jli0+1,self.number) self.cevent = Event() self.cevent.numevent0 = nevent nevent +=1 if Li.find(" SAMPLE")>-1 : self.cevent.action = "SAMPLE" if Li.find("REFSAMPLE")>-1 : self.cevent.action = "REFSAMPLE" self.cevent.stime = litem[0] if isaninteger(litem[0]) : self.cevent.time = int(litem[0]) else : self.detparam(litem[0],"T") if isaninteger(litem[2]): self.cevent.pop = int(litem[2]) else : raise IOScreenError, "Unable to read population number on line %s of scenario %s"%(jli0+1,self.number) self.cevent.Ne=Ncur[self.cevent.pop-1].val self.cevent.sNe=Ncur[self.cevent.pop-1].name ns +=1 self.cevent.sample = ns self.time_sample.append(self.cevent.time) if (nitems==5): if isaninteger(litem[3]): self.cevent.nindMref = int(litem[3]) else : raise IOScreenError, "Unable to read number of males on line %s of scenario %s"%(jli0+1,self.number) if isaninteger(litem[4]): self.cevent.nindFref = int(litem[4]) else : raise IOScreenError, "Unable to read number of females on line %s of scenario %s"%(jli0+1,self.number) #print self.cevent.nindMref," ",self.cevent.nindFref #print " ",data.nind[0] if Li.find(" SAMPLE") != -1 and (data!=None): if self.cevent.nindMref+self.cevent.nindFref > data.nind[self.cevent.pop-1] : raise IOScreenError, "The total number of reference individuals (%s) is larger than that of the data set (%s) on line %s of scenario %s"%(self.cevent.nindMref+self.cevent.nindFref,data.nind[self.cevent.pop-1],jli0+1,self.number) elif Li.find("VARNE")>-1: if nitems<4: raise IOScreenError, "Line %s of scenario %s is incomplete"%(jli0+1,self.number) self.cevent = Event() self.cevent.numevent0 = nevent nevent +=1 self.cevent.action = "VARNE" self.cevent.stime = litem[0] if isaninteger(litem[0]) : self.cevent.time = int(litem[0]) else : self.detparam(litem[0],"T") if isaninteger(litem[2]): self.cevent.pop = int(litem[2]) else : raise IOScreenError, "Unable to read population number on line %s of scenario %s"%(jli0+1,self.number) if isaninteger(litem[3]): self.cevent.Ne = int(litem[3]);self.cevent.sNe = None else : self.cevent.sNe = litem[3];self.cevent.Ne = None self.detparam(litem[3],"N") Ncur[self.cevent.pop-1].val=self.cevent.Ne Ncur[self.cevent.pop-1].name=self.cevent.sNe elif Li.find("MERGE")>-1: if nitems<4: raise IOScreenError, "Line %s of scenario %s is incomplete"%(jli0+1,self.number) if nitems>4: raise IOScreenError, "At line %i, the number of words is incorrect"%(i+2) self.cevent = Event() self.cevent.numevent0 = nevent nevent +=1 self.cevent.action = "MERGE" self.cevent.stime = litem[0] if isaninteger(litem[0]) : self.cevent.time = int(litem[0]) else : self.detparam(litem[0],"T") if isaninteger(litem[2]): self.cevent.pop = int(litem[2]) else : raise IOScreenError, "Unable to read the first population number on line %s of scenario %s"%(jli0+1,self.number) if isaninteger(litem[3]): self.cevent.pop1 = int(litem[3]) else : raise IOScreenError, "Unable to read the second population number on line %s of scenario %s"%(jli0+1,self.number) self.cevent.Ne=Ncur[self.cevent.pop-1].val self.cevent.sNe=Ncur[self.cevent.pop-1].name elif Li.find("SPLIT")>-1: if nitems<6: raise IOScreenError, "Line %s of scenario %s is incomplete"%(jli0+1,self.number) self.cevent = Event() self.cevent.numevent0 = nevent nevent +=1 self.cevent.action = "SPLIT" self.cevent.stime = litem[0] if isaninteger(litem[0]) : self.cevent.time = int(litem[0]) else : self.detparam(litem[0],"T") if isaninteger(litem[2]): self.cevent.pop = int(litem[2]) else : raise IOScreenError, "Unable to read the first population number on line %s of scenario %s"%(jli0+1,self.number) if isaninteger(litem[3]): self.cevent.pop1 = int(litem[3]) else : raise IOScreenError, "Unable to read the second population number on line %s of scenario %s"%(jli0+1,self.number) if isaninteger(litem[4]): self.cevent.pop2 = int(litem[4]) else : raise IOScreenError, "Unable to read the third population number on line %s of scenario %s"%(jli0+1,self.number) if isafloat(litem[5]): self.cevent.admixrate = float(litem[5]) else : self.cevent.sadmixrate = litem[5] self.detparam(litem[5],"A") self.cevent.Ne=Ncur[self.cevent.pop-1].val self.cevent.sNe=Ncur[self.cevent.pop-1].name elif Li.find("SEXUAL")>-1: if nitems<3: raise IOScreenError, "Line %s of scenario %s is incomplete"%(jli0+1,self.number) self.cevent = Event() self.cevent.numevent0 = nevent nevent +=1 self.cevent.action = "SEXUAL" self.cevent.stime = litem[0] if isaninteger(litem[0]) : self.cevent.time = int(litem[0]) else : self.detparam(litem[0],"T") if isaninteger(litem[2]): self.cevent.pop = int(litem[2]) else : raise IOScreenError, "Unable to read population number on line %s of scenario %s"%(jli0+1,self.number) self.cevent.Ne=Ncur[self.cevent.pop-1].val self.cevent.sNe=Ncur[self.cevent.pop-1].name ns +=1 self.cevent.sample = ns self.time_sample.append(self.cevent.time) else : raise IOScreenError,"Uninterpretable line %s in scenario %s"%(jli0+1,self.number) self.history.events.append(self.cevent) if self.cevent.pop>self.popmax : self.popmax=self.cevent.pop self.setgraphtime() if len(self.parametersbackup)>0 : for pb in self.parametersbackup : trouve = False i = -1 while (not trouve)and(i<len(self.parameters)-1) : i +=1 p = self.parameters[i] trouve = (pb.name == p.name) and (pb.category == p.category) if trouve : self.parameters[i].value = pb.value