annotate src/merge_metadata.py @ 0:e0b5980139d9

maaslin
author george-weingart
date Tue, 13 May 2014 22:00:40 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
1 #!/usr/bin/env python
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
2 #####################################################################################
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
3 #Copyright (C) <2012>
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
4 #
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
5 #Permission is hereby granted, free of charge, to any person obtaining a copy of
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
6 #this software and associated documentation files (the "Software"), to deal in the
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
7 #Software without restriction, including without limitation the rights to use, copy,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
8 #modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
9 #and to permit persons to whom the Software is furnished to do so, subject to
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
10 #the following conditions:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
11 #
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
12 #The above copyright notice and this permission notice shall be included in all copies
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
13 #or substantial portions of the Software.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
14 #
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
15 #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
16 #INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
17 #PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
18 #HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
19 #OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
20 #SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
21 #
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
22 # This file is a component of the MaAsLin (Multivariate Associations Using Linear Models),
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
23 # authored by the Huttenhower lab at the Harvard School of Public Health
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
24 # (contact Timothy Tickle, ttickle@hsph.harvard.edu).
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
25 #####################################################################################
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
26 """
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
27 Examples
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
28 ~~~~~~~~
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
29
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
30 ``metadata.txt``::
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
31
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
32 - Y Z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
33 a 1 x
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
34 b 0 y
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
35 c z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
36
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
37 ``data.pcl``::
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
38
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
39 - a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
40 A|B 1 2 3
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
41 A|C 4 5 6
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
42 D|E 7 8 9
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
43
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
44 ``Examples``::
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
45
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
46 $ merge_metadata.py metadata.txt < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
47 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
48 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
49 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
50 A 0.416667 0.466667 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
51 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
52 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
53 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
54
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
55 $ merge_metadata.py metadata.txt -t 0 < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
56 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
57 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
58 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
59 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
60 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
61 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
62
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
63 $ merge_metadata.py metadata.txt -t 1 < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
64 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
65 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
66 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
67 A 0.416667 0.466667 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
68 D 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
69
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
70 $ merge_metadata.py metadata.txt -t 0 -n < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
71 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
72 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
73 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
74 A|B 1 2 3
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
75 A|C 4 5 6
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
76 D|E 7 8 9
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
77
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
78 $ merge_metadata.py metadata.txt -t 0 -m 0.8 -s "-" < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
79 sample b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
80 Y 0 -
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
81 Z y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
82 A|B 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
83 A|C 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
84 D|E 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
85
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
86 $ merge_metadata.py -t 0 < data.pcl
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
87 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
88 A|B 1 2 3
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
89 A|C 4 5 6
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
90 D|E 7 8 9
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
91
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
92 .. testsetup::
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
93
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
94 from merge_metadata import *
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
95 """
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
96
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
97 import argparse
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
98 import blist
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
99 import csv
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
100 import re
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
101 import sys
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
102
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
103 c_dTarget = 1.0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
104 c_fRound = False
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
105
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
106 class CClade:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
107
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
108 def __init__( self ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
109
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
110 self.m_hashChildren = {}
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
111 self.m_adValues = None
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
112
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
113 def get( self, astrClade ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
114
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
115 return self.m_hashChildren.setdefault(
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
116 astrClade[0], CClade( ) ).get( astrClade[1:] ) if astrClade else self
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
117
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
118 def set( self, adValues ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
119
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
120 self.m_adValues = blist.blist( [0] ) * len( adValues )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
121 for i, d in enumerate( adValues ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
122 if d:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
123 self.m_adValues[i] = d
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
124
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
125 def impute( self ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
126
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
127 if not self.m_adValues:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
128 for pChild in self.m_hashChildren.values( ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
129 adChild = pChild.impute( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
130 if self.m_adValues:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
131 for i in range( len( adChild or [] ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
132 if adChild[i]:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
133 self.m_adValues[i] += adChild[i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
134 elif adChild:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
135 self.m_adValues = adChild[:]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
136
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
137 return self.m_adValues
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
138
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
139 def _freeze( self, hashValues, iTarget, astrClade, iDepth, fLeaves ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
140
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
141 fHit = ( not iTarget ) or ( ( fLeaves and ( iDepth == iTarget ) ) or ( ( not fLeaves ) and ( iDepth <= iTarget ) ) )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
142 iDepth += 1
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
143 setiRet = set()
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
144 if self.m_hashChildren:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
145 for strChild, pChild in self.m_hashChildren.items( ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
146 setiRet |= pChild._freeze( hashValues, iTarget, astrClade + [strChild], iDepth, fLeaves )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
147 setiRet = set( ( i + 1 ) for i in setiRet )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
148 else:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
149 setiRet.add( 0 )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
150 if iTarget < 0:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
151 if fLeaves:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
152 fHit = -( iTarget + 1 ) in setiRet
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
153 else:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
154 fHit = -( iTarget + 1 ) <= max( setiRet )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
155 if astrClade and self.m_adValues and fHit:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
156 hashValues["|".join( astrClade )] = self.m_adValues
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
157 return setiRet
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
158
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
159 def freeze( self, hashValues, iTarget, fLeaves ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
160
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
161 self._freeze( hashValues, iTarget, [], 0, fLeaves )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
162
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
163 def _repr( self, strClade ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
164
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
165 strRet = "<"
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
166 if strClade:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
167 strRet += "%s %s" % (strClade, self.m_adValues)
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
168 if self.m_hashChildren:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
169 strRet += " "
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
170 if self.m_hashChildren:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
171 strRet += " ".join( p._repr( s ) for (s, p) in self.m_hashChildren.items( ) )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
172
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
173 return ( strRet + ">" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
174
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
175 def __repr__( self ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
176
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
177 return self._repr( "" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
178
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
179 """
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
180 pTree = CClade( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
181 pTree.get( ("A", "B") ).set( [1, 2, 3] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
182 pTree.get( ("A", "C") ).set( [4, 5, 6] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
183 pTree.get( ("D", "E") ).set( [7, 8, 9] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
184 iTaxa = 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
185 if iTaxa:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
186 pTree.impute( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
187 hashFeatures = {}
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
188 pTree.freeze( hashFeatures, iTaxa )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
189 print( pTree )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
190 print( hashFeatures )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
191 sys.exit( 0 )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
192 #"""
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
193
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
194 def merge_metadata( aastrMetadata, aastrData, ostm, fNormalize, strMissing, astrExclude, dMin, iTaxa, fLeaves ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
195 """
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
196 Joins and outputs a data matrix with a metadata matrix, optionally normalizing and filtering it.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
197 A pipe-delimited taxonomy hierarchy can also be dynamically added or removed.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
198
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
199 :param aastrMetadata: Split lines from which metadata are read.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
200 :type aastrMetadata: collection of string collections
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
201 :param aastrData: Split lines from which data are read.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
202 :type aastrData: collection of string collections
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
203 :param ostm: Output stream to which joined rows are written.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
204 :type ostm: output stream
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
205 :param fNormalize: If true, divide data values by column sums.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
206 :type fNormalize: bool
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
207 :param strMissing: Representation for missing metadata values.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
208 :type strMissing: str
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
209 :param astrExclude: Lines from which excluded IDs are read.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
210 :type astrExclude: collection of strings
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
211 :param dMin: Minimum fraction of maximum value for per-column quality control.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
212 :type dMin: bool
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
213 :param iTaxa: Depth of taxonomy to be computed, -1 = leaves only, 0 = no change
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
214 :type iTaxa: int
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
215 :param fLeaves: Output only leaves, not complete taxonomy; ignored if taxa = 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
216 :type fLeaves: bool
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
217
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
218 Metadata are optional; if not provided, data will be optionally normalized or its taxonomy
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
219 modified as requested. Metadata are provided one row per sample, data one column per
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
220 sample, both files tab-delimited text with one header row and one header column.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
221
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
222 Metadata IDs that do not match data IDs are discarded, and data IDs without corresponding
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
223 metadata IDs are given missing values. Missing data values are always treated (and output)
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
224 as zero.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
225
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
226 Per-column quality control is performed if the requested minimum fraction is greater than
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
227 zero. Specifically, for each column i, the row j containing the maximum value d is
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
228 identified. If d is less than the minimum fraction of row j's maximum value over all columns,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
229 the entire column i is removed.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
230
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
231 A taxonomy hierarchy will be calculated by default if row IDs are pipe-delimited, i.e. of
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
232 the form A|B|C. All parent clades are computed by default, e.g. A|B and A, save when
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
233 they would be identical to a more specific child clade. Negative values are counted from the
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
234 bottom (right) of the hierarchy rather than the top. The special value of 0 deactivates
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
235 hierarchy calculation.
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
236
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
237 >>> aastrMetadata = [[t.strip( ) for t in s] for s in ("-YZ", "a1x", "b0y", "c z")]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
238 >>> aastrData = [s.split( ) for s in ( \
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
239 "- a b c", \
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
240 "A|B 1 2 3", \
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
241 "A|C 4 5 6", \
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
242 "D|E 7 8 9")]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
243 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", [], 0.01, -1, False ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
244 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
245 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
246 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
247 A 0.416667 0.466667 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
248 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
249 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
250 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
251
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
252 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", [], 0.01, -1, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
253 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
254 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
255 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
256 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
257 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
258 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
259
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
260 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", [], 0, 0, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
261 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
262 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
263 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
264 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
265 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
266 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
267
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
268 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", [], 0, 1, False ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
269 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
270 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
271 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
272 A 0.416667 0.466667 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
273 D 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
274
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
275 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", [], 0, -1, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
276 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
277 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
278 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
279 A|B 0.0833333 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
280 A|C 0.333333 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
281 D|E 0.583333 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
282
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
283 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, False, "", [], 0, 0, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
284 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
285 Y 1 0
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
286 Z x y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
287 A|B 1 2 3
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
288 A|C 4 5 6
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
289 D|E 7 8 9
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
290
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
291 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "-", [], 0.8, 0, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
292 sample b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
293 Y 0 -
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
294 Z y z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
295 A|B 0.133333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
296 A|C 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
297 D|E 0.533333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
298
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
299 >>> merge_metadata( None, aastrData, sys.stdout, False, "", [], 0, 0, True ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
300 sample a b c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
301 A|B 1 2 3
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
302 A|C 4 5 6
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
303 D|E 7 8 9
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
304
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
305 >>> merge_metadata( aastrMetadata, aastrData, sys.stdout, True, "", ["b"], 0.01, -1, False ) #doctest: +NORMALIZE_WHITESPACE
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
306 sample a c
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
307 Y 1
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
308 Z x z
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
309 A 0.416667 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
310 A|B 0.0833333 0.166667
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
311 A|C 0.333333 0.333333
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
312 D|E 0.583333 0.5
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
313 """
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
314
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
315 #Put metadata in a dictionary
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
316 #{"First line element",["line element 2","line element 3","line element 4"]}
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
317 #If there is no metadata then
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
318 astrMetadata = None
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
319 hashMetadata = {}
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
320 for astrLine in ( aastrMetadata or [] ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
321 if astrMetadata:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
322 hashMetadata[astrLine[0]] = astrLine[1:]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
323 else:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
324 astrMetadata = astrLine[1:]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
325
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
326 astrHeaders = adSeqs = iCol = None
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
327 pTree = CClade( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
328 aastrRaw = []
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
329 for astrLine in aastrData:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
330 if astrHeaders:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
331 if ( astrLine[0] == "EWEIGHT" ) or ( astrLine[0] == "total" ) or \
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
332 ( len( astrLine ) < 2 ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
333 continue
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
334 try:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
335 adCounts = [( float(strCur) if len( strCur.strip( ) ) else 0 ) for
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
336 strCur in astrLine[iCol:]]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
337 except ValueError:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
338 aastrRaw.append( astrLine )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
339 continue
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
340 for i in range( len( adCounts ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
341 adSeqs[i] += adCounts[i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
342 if ( iCol > 1 ) and ( astrLine[0] != astrLine[1] ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
343 if astrLine[1].find( astrLine[0] ) >= 0:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
344 astrLine[0] = astrLine[1]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
345 else:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
346 astrLine[0] += " " + astrLine[1]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
347 pTree.get( astrLine[0].split( "|" ) ).set( adCounts )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
348 else:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
349 iCol = 2 if ( astrLine[1].upper( ) == "NAME" ) else 1
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
350 astrHeaders = [strCur.replace( " ", "_" ) for strCur in astrLine[iCol:]]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
351 adSeqs = [0] * len( astrHeaders )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
352
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
353 if iTaxa:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
354 pTree.impute( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
355 hashFeatures = {}
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
356 pTree.freeze( hashFeatures, iTaxa, fLeaves )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
357 setstrFeatures = hashFeatures.keys( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
358
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
359 afOmit = [False] * len( astrHeaders )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
360 if dMin > 0:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
361 aadData = list(hashFeatures.values( ))
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
362 for i in range( len( astrHeaders ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
363 iMax = max( range( len( aadData ) ), key = lambda j: aadData[j][i] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
364 dMaxUs = aadData[iMax][i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
365 dMaxThem = max( aadData[iMax][j] for j in ( range( i ) + range( i + 1, len( astrHeaders ) ) ) )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
366 if dMaxUs < ( dMin * dMaxThem ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
367 sys.stderr.write( "Omitting: %s\n" % astrHeaders[i] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
368 afOmit[i] = True
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
369
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
370 if astrExclude:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
371 setstrExclude = set(s.strip( ) for s in astrExclude)
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
372 for i in range( len( astrHeaders ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
373 if ( not afOmit[i] ) and ( astrHeaders[i] in setstrExclude ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
374 afOmit[i] = True
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
375
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
376 adMult = [( ( c_dTarget / d ) if ( fNormalize and ( d > 0 ) ) else 1 ) for d in adSeqs]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
377 for strFeature, adCounts in hashFeatures.items( ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
378 for i in range( len( adCounts ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
379 if adCounts[i]:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
380 adCounts[i] *= adMult[i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
381 if c_fRound:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
382 adCounts[i] = round( adCounts[i] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
383 for strFeature, adCounts in hashFeatures.items( ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
384 astrFeature = strFeature.strip( ).split( "|" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
385 while len( astrFeature ) > 1:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
386 astrFeature = astrFeature[:-1]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
387 strParent = "|".join( astrFeature )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
388 adParent = hashFeatures.get( strParent )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
389 if adParent == adCounts:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
390 del hashFeatures[strParent]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
391 setstrFeatures.remove( strParent )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
392
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
393 if astrMetadata:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
394 for i in range( len( astrMetadata ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
395 hashFeatures[astrMetadata[i]] = astrCur = []
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
396 for strSubject in astrHeaders:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
397 astrSubject = hashMetadata.get( strSubject )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
398 if not astrSubject:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
399 strSubject = re.sub( '_.*$', "", strSubject )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
400 astrSubject = hashMetadata.get( strSubject, [] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
401 astrCur.append( astrSubject[i] if ( i < len( astrSubject ) ) else "" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
402
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
403 astrFeatures = sorted( astrMetadata or [] ) + sorted( setstrFeatures )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
404 aiHeaders = filter( lambda i: not afOmit[i], range( len( astrHeaders ) ) )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
405 csvw = csv.writer( sys.stdout, csv.excel_tab )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
406 csvw.writerow( ["sample"] + [astrHeaders[i] for i in aiHeaders] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
407 for iFeature in range( len( astrFeatures ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
408 strFeature = astrFeatures[iFeature]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
409 adFeature = hashFeatures[strFeature]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
410 astrValues = [adFeature[i] for i in aiHeaders]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
411 for i in range( len( astrValues ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
412 strValue = astrValues[i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
413 if type( strValue ) in (int, float):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
414 astrValues[i] = "%g" % astrValues[i]
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
415 elif ( not strValue ) or ( ( type( strValue ) == str ) and
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
416 ( len( strValue ) == 0 ) ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
417 astrValues[i] = strMissing
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
418 csvw.writerow( [strFeature] + astrValues )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
419
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
420 for astrRaw in aastrRaw:
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
421 csvw.writerow( [astrRaw[i] for i in aiHeaders] )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
422
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
423 argp = argparse.ArgumentParser( prog = "merge_metadata.py",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
424 description = "Join a data matrix with a metadata matrix, optionally normalizing and filtering it.\n\n" +
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
425 "A pipe-delimited taxonomy hierarchy can also be dynamically added or removed." )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
426 argp.add_argument( "-n", dest = "fNormalize", action = "store_false",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
427 help = "Don't normalize data values by column sums" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
428 argp.add_argument( "-s", dest = "strMissing", metavar = "missing",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
429 type = str, default = " ",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
430 help = "String representing missing metadata values" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
431 argp.add_argument( "-m", dest = "dMin", metavar = "min",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
432 type = float, default = 0.01,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
433 help = "Per-column quality control, minimum fraction of maximum value" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
434 argp.add_argument( "-t", dest = "iTaxa", metavar = "taxa",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
435 type = int, default = -1,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
436 help = "Depth of taxonomy to be computed, negative = from right, 0 = no change" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
437 argp.add_argument( "-l", dest = "fLeaves", action = "store_true",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
438 help = "Output only leaves, not complete taxonomy" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
439 argp.add_argument( "-x", dest = "istmExclude", metavar = "exclude.txt",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
440 type = file,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
441 help = "File from which sample IDs to exclude are read" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
442 argp.add_argument( "istmMetadata", metavar = "metadata.txt",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
443 type = file, nargs = "?",
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
444 help = "File from which metadata is read" )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
445 __doc__ = "::\n\n\t" + argp.format_help( ).replace( "\n", "\n\t" ) + __doc__
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
446
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
447 def _main( ):
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
448 args = argp.parse_args( )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
449 merge_metadata( args.istmMetadata and csv.reader( args.istmMetadata, csv.excel_tab ),
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
450 csv.reader( sys.stdin, csv.excel_tab ), sys.stdout, args.fNormalize, args.strMissing,
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
451 args.istmExclude, args.dMin, args.iTaxa, args.fLeaves )
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
452
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
453 if __name__ == "__main__":
e0b5980139d9 maaslin
george-weingart
parents:
diff changeset
454 _main( )