@@ -41,13 +41,16 @@ def dataminer(indfile_name, fmt, popfile=None):
4141
4242 # Parse popfile if provided
4343 if popfile :
44- # Assuming popfile has 2 columns with pop name in 1st column and number
45- # of samples in the 2nd column
46- poparray = np .genfromtxt (popfile , dtype = None )
44+ # Assuming popfile has 3 columns with pop name in 1st column, number
45+ # of samples in the 2nd column and input file order number in the 3rd.
46+ datatype = np .dtype ([("popname" , "|U20" ), ("num_indiv" , int ),
47+ ("original_order" , int )])
48+ poparray = np .genfromtxt (popfile , dtype = datatype )
4749 # Final pop list
48- poplist = [(x , y .decode ("utf-8" )) for x , y in
49- zip (np .cumsum ([x [1 ] for x in poparray ]),
50- [x [0 ] for x in poparray ])]
50+ poplist = [([x ]* y , z ) for x , y , z in
51+ zip ([x [0 ] for x in poparray ],
52+ [x [1 ] for x in poparray ],
53+ [x [2 ] for x in poparray ])]
5154
5255 # Parse structure/faststructure output file
5356 if fmt == "fastStructure" :
@@ -89,11 +92,52 @@ def dataminer(indfile_name, fmt, popfile=None):
8992 # is the boundary of a population in the x-axis
9093 poplist = Counter (poplist )
9194 poplist = [(x , None ) for x in np .cumsum (list (poplist .values ()))]
95+ print ("oh" )
9296
9397
98+ if popfile :
99+ # Re-order the qvalues to match what is specified in the popfile.
100+ qvalues = re_order (qvalues , poplist )
101+
94102 return qvalues , poplist
95103
96104
105+ def re_order (qvalues , poplist ):
106+ """
107+ Recieves a list of q-values, re-orders them according to the order
108+ specified in the popfile and returns that list.
109+ """
110+ qvalues = qvalues .tolist ()
111+ locations_dict = {pos :(index , len (loc )) for index , (loc , pos ) in
112+ enumerate (poplist )}
113+
114+ offsets = [None ] * len (poplist )
115+
116+
117+ def compute_offset (pos ):
118+ """
119+ Recursively compute the offset values.
120+ """
121+ # compute new offset from offset and length of previous position. End of
122+ # recursion at position 1: we’re at the beginning of the list
123+ offset = sum (compute_offset (pos - 1 )) if pos > 1 else 0
124+ # get index at where to store current offset + length of current location
125+ index , length = locations_dict [pos ]
126+ offsets [index ] = (offset , length )
127+
128+ return offsets [index ]
129+
130+
131+ compute_offset (len (poplist ))
132+
133+ qvalues = [value for offset , length in offsets for value in
134+ qvalues [offset :offset + length ]]
135+
136+ qvalues = np .array (qvalues )
137+
138+ return qvalues
139+
140+
97141def plotter (qvalues , poplist , outfile ):
98142 """
99143 Plot the qvalues histogram.
@@ -120,8 +164,7 @@ def plotter(qvalues, poplist, outfile):
120164 ax = fig .add_subplot (111 , xlim = (0 , numinds ), ylim = (0 , 1 ))
121165
122166 for i in range (qvalues .shape [1 ]):
123- # Get bar color. If K exceeds the 12 colors in colors, generate random
124- # color
167+ # Get bar color. If K exceeds the 12 colors, generate random color
125168 try :
126169 clr = colors [i ]
127170 except IndexError :
@@ -138,13 +181,15 @@ def plotter(qvalues, poplist, outfile):
138181
139182 # Annotate population info
140183 if poplist :
184+ orderings = [(x , y [0 ][0 ]) for x , y in zip (np .cumsum ([len (x [0 ]) for x in
185+ poplist ]), poplist )]
141186 count = 1
142- for ppl , vals in enumerate (poplist ):
187+ for ppl , vals in enumerate (orderings ):
143188 # Add population delimiting lines
144189 plt .axvline (x = vals [0 ], linewidth = 1.5 , color = 'black' )
145190 # Add population labels
146191 # Determine x pos
147- xpos = vals [0 ] - ((vals [0 ] - poplist [ppl - 1 ][0 ]) / 2 ) if ppl > 0 \
192+ xpos = vals [0 ] - ((vals [0 ] - orderings [ppl - 1 ][0 ]) / 2 ) if ppl > 0 \
148193 else vals [0 ] / 2
149194 # Draw text
150195 ax .text (xpos , - 0.05 , vals [1 ] if vals [1 ] else "Pop{}" .format (count ),
0 commit comments