annotate commons/tools/CorrelateTEageWithGCcontent.py @ 18:94ab73e8a190

Uploaded
author m-zytnicki
date Mon, 29 Apr 2013 03:20:15 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
1 #!/usr/bin/env python
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
2
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
3 import sys
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
4 import os
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
5 import getopt
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
6 import math
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
7 from commons.core.sql.DbMySql import DbMySql
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
8 from commons.core.sql.TablePathAdaptator import TablePathAdaptator
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
9 from commons.core.sql.TableSeqAdaptator import TableSeqAdaptator
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
10 from commons.core.coord.PathUtils import PathUtils
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
11 from commons.core.coord.SetUtils import SetUtils
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
12 from commons.core.seq.BioseqUtils import BioseqUtils
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
13
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
14
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
15 class CorrelateTEageWithGCcontent( object ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
16
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
17 def __init__( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
18 self._inputCoord = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
19 self._inputGenome = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
20 self._inputTErefseq = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
21 self._configFile = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
22 self._outFile = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
23 self._verbose = 0
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
24 self._db = None
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
25 self._tableCoord = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
26 self._pathA = TablePathAdaptator()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
27 self._tableGenome = ""
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
28 self._seqA = TableSeqAdaptator()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
29
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
30
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
31 def help( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
32 print
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
33 print "usage: CorrelateTEageWithGCcontent.py [ options ]"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
34 print "options:"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
35 print " -h: this help"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
36 print " -i: input TE coordinates (can be file or table)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
37 print " TEs as subjects in 'path' format"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
38 print " -g: input genome sequences (can be fasta file or table)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
39 print " -r: input TE reference sequences (can be fasta file or table)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
40 print " -C: configuration file (if table as input)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
41 print " -o: output fasta file (default=inputCoord+'.gc')"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
42 print " -v: verbosity level (default=0/1)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
43 print
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
44
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
45
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
46 def setAttributesFromCmdLine( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
47 try:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
48 opts, args = getopt.getopt(sys.argv[1:],"hi:g:r:C:o:v:")
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
49 except getopt.GetoptError, err:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
50 msg = "%s" % str(err)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
51 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
52 self.help(); sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
53 for o,a in opts:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
54 if o == "-h":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
55 self.help(); sys.exit(0)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
56 elif o == "-i":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
57 self._inputCoord = a
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
58 elif o == "-g":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
59 self._inputGenome = a
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
60 elif o == "-r":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
61 self._inputTErefseq = a
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
62 elif o == "-C":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
63 self._configFile = a
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
64 elif o =="-o":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
65 self._outFile = a
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
66 elif o == "-v":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
67 self._verbose = int(a)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
68
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
69
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
70 def checkAttributes( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
71 if self._inputCoord == "":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
72 msg = "ERROR: missing input TE coordinates (-i)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
73 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
74 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
75 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
76 if not os.path.exists( self._inputCoord ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
77 if not os.path.exists( self._configFile ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
78 msg = "ERROR: neither input file '%s' nor configuration file '%s'" % ( self._inputCoord, self._configFile )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
79 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
80 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
81 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
82 if not os.path.exists( self._configFile ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
83 msg = "ERROR: can't find configuration file '%s'" % ( self._configFile )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
84 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
85 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
86 self._db = DbMySql( cfgFileName=self._configFile )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
87 if not self._db.exist( self._inputCoord ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
88 msg = "ERROR: can't find table '%s'" % ( self._inputCoord )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
89 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
90 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
91 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
92 self._tableCoord = self._inputCoord
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
93 else:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
94 self._tableCoord = self._inputCoord.replace(".","_")
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
95 if self._inputGenome == "":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
96 msg = "ERROR: missing input genome sequences (-g)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
97 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
98 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
99 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
100 if not os.path.exists( self._inputGenome ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
101 if not self._db.doesTableExist( self._inputGenome ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
102 msg = "ERROR: can't find table '%s'" % ( self._inputGenome )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
103 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
104 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
105 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
106 self._tableGenome = self._inputGenome
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
107 else:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
108 self._tableGenome = self._inputGenome.replace(".","_")
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
109 if self._inputTErefseq == "":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
110 msg = "ERROR: missing input TE reference sequences (-r)"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
111 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
112 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
113 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
114 if not os.path.exists( self._inputTErefseq ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
115 if not self._db.doesTableExist( self._inputTErefseq ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
116 msg = "ERROR: can't find table '%s'" % ( self._inputTErefseq )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
117 sys.stderr.write( "%s\n" % msg )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
118 self.help()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
119 sys.exit(1)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
120 if self._outFile == "":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
121 self._outFile = "%s.gc" % ( self._inputCoord )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
122
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
123
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
124 def getLengthOfTErefseqs( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
125 if os.path.exists( self._inputTErefseq ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
126 return BioseqUtils.getLengthPerSeqFromFile( self._inputTErefseq )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
127 else:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
128 dTErefseq2Length = {}
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
129 refseqA = TableSeqAdaptator( self._db, self._inputTErefseq )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
130 lAccessions = refseqA.getAccessionsList()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
131 for acc in lAccessions:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
132 dTErefseq2Length[ acc ] = refseqA.getSeqLengthFromAccession( acc )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
133 return dTErefseq2Length
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
134
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
135
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
136 def start( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
137 self.checkAttributes()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
138 if self._verbose > 0:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
139 print "START CorrelateTEageWithGCcontent.py"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
140 sys.stdout.flush()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
141 if os.path.exists( self._inputCoord ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
142 self._db = DbMySql( cfgFileName=self._configFile )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
143 self._db.createTable( self._tableCoord, "path", self._inputCoord, True )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
144 self._pathA = TablePathAdaptator( self._db, self._tableCoord )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
145 if os.path.exists( self._inputGenome ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
146 self._db.createTable( self._tableGenome, "seq", self._inputGenome, True )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
147 self._seqA = TableSeqAdaptator( self._db, self._tableGenome )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
148 if self._verbose > 0:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
149 print "output fasta file: %s" % self._outFile
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
150
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
151
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
152 def end( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
153 if os.path.exists( self._inputCoord ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
154 self._db.dropTable( self._tableCoord )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
155 if os.path.exists( self._inputGenome ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
156 self._db.dropTable( self._tableGenome )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
157 self._db.close()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
158 if self._verbose > 0:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
159 print "END CorrelateTEageWithGCcontent.py"
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
160 sys.stdout.flush()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
161
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
162
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
163 def run( self ):
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
164 self.start()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
165
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
166 dTErefseq2Length = self.getLengthOfTErefseqs()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
167
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
168 outFileHandler = open( self._outFile, "w" )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
169 outFileHandler.write( "copy\tTE\tchr\tlength\tid\tGC\tlengthPerc\n" )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
170
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
171 lIdentifiers = self._pathA.getIdList()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
172 nbTEcopies = len(lIdentifiers)
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
173 if self._verbose > 0:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
174 print "nb of TE copies: %i" % ( nbTEcopies )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
175 sys.stdout.flush()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
176 count = 0
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
177 power10 = int( math.floor( math.log10( nbTEcopies ) ) ) - 1
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
178 for id in lIdentifiers:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
179 count += 1
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
180 if self._verbose > 0 and power10 > 0 and count % math.pow(10,power10) == 0:
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
181 print "%s / %s" % ( str(count).zfill(power10+2), str(nbTEcopies).zfill(power10+2) )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
182 sys.stdout.flush()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
183 lPaths = self._pathA.getPathListFromId( id )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
184 lSets = PathUtils.getSetListFromQueries( lPaths )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
185 lMergedSets = SetUtils.mergeSetsInList( lSets )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
186 bs = self._seqA.getBioseqFromSetList( lMergedSets )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
187 data = "%i" % id
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
188 data += "\t%s" % ( bs.header.split("::")[0] )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
189 data += "\t%s" % ( lPaths[0].getQueryName() )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
190 data += "\t%i" % ( bs.getLength() )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
191 data += "\t%.2f" % ( PathUtils.getIdentityFromPathList( lPaths ) )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
192 data += "\t%.2f" % ( bs.getGCpercentage() )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
193 data += "\t%.2f" % ( 100 * bs.getLength() / float( dTErefseq2Length[ bs.header.split("::")[0] ] ) )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
194 outFileHandler.write( "%s\n" % data )
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
195
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
196 outFileHandler.close()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
197
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
198 self.end()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
199
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
200
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
201 if __name__ == "__main__":
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
202 i = CorrelateTEageWithGCcontent()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
203 i.setAttributesFromCmdLine()
94ab73e8a190 Uploaded
m-zytnicki
parents:
diff changeset
204 i.run()