annotate PsiCLASS-1.0.2/AddGeneName.cpp @ 0:903fc43d6227 draft default tip

Uploaded
author lsong10
date Fri, 26 Mar 2021 16:52:45 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
1 #include <stdio.h>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
2 #include <string.h>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
3 #include <stdlib.h>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
4
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
5 #include <string>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
6 #include <map>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
7 #include <vector>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
8 #include <algorithm>
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
9
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
10 char usage[] = "Usage: ./add-genename annotation.gtf gtflist [OPTIONS]\n"
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
11 "\t-o: the directory for output gtf files (default: ./)\n" ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
12
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
13 struct _interval
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
14 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
15 char chrom[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
16 char geneName[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
17
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
18 int start, end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
19 } ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
20
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
21 char line[10000] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
22 char buffer[10000], buffer2[10000], buffer3[10000] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
23
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
24 int CompInterval( const struct _interval &a, const struct _interval &b )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
25 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
26 int chromCmp = strcmp( a.chrom, b.chrom ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
27 if ( chromCmp )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
28 return chromCmp ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
29 else if ( a.start != b.start )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
30 return a.start - b.start ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
31 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
32 return a.end - b.end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
33 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
34
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
35 bool Comp( const struct _interval &a, const struct _interval &b )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
36 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
37 int cmp = CompInterval( a, b ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
38 if ( cmp < 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
39 return true ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
40 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
41 return false ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
42
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
43 return false ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
44 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
45
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
46 void SortAndCleanIntervals( std::vector<struct _interval> &it )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
47 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
48 std::sort( it.begin(), it.end(), Comp ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
49
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
50 int i, k ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
51 int size = it.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
52 if ( size == 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
53 return ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
54
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
55 k = 1 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
56 for ( i = 1 ; i < size ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
57 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
58 if ( CompInterval( it[k - 1], it[i] ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
59 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
60 it[k] = it[i] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
61 ++k ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
62 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
63 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
64 it.resize( k ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
65 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
66
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
67 int GetGTFField( char *ret, char *line, const char *fid )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
68 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
69 char *p = strstr( line, fid ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
70 if ( p == NULL )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
71 return 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
72 //printf( "%s %s\n", line, fid ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
73 for ( ; *p != ' ' ; ++p )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
74 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
75 p += 2 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
76
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
77 sscanf( p, "%s", ret ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
78 p = ret + strlen( ret ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
79 while ( p != ret && *p != '\"' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
80 --p ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
81 *p = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
82 return 1 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
83 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
84
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
85 void UpdateIdToAnnoId( std::vector<struct _interval> &transcript, char *tid, int exonTag, int intronTag, std::vector<struct _interval> &exons, std::vector<struct _interval> &introns,
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
86 std::map<std::string, std::string> &txptIdToAnnoId, std::map<std::string, std::string> &geneIdToAnnoId )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
87 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
88 int i, k ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
89 bool flag = false ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
90 // First, try whether intron works.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
91 int ecnt = transcript.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
92 int intronSize = introns.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
93 int exonSize = exons.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
94
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
95 struct _interval itron ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
96 strcpy( itron.chrom, transcript[0].chrom ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
97 k = intronTag ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
98 for ( i = 0 ; i < ecnt - 1 && !flag ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
99 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
100 itron.start = transcript[i].end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
101 itron.end = transcript[i + 1].start ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
102 for ( ; k < intronSize ; ++k )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
103 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
104 //printf( "hi %d: %s %d %d; %d %s %d %d\n", 0, itron.chrom, itron.start, itron.end, k, introns[k].chrom, introns[k].start, introns[k].end ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
105 if ( strcmp( introns[k].chrom, itron.chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
106 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
107
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
108 int cmp = CompInterval( introns[k], itron ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
109 if ( cmp == 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
110 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
111 txptIdToAnnoId[ std::string( tid ) ] = introns[k].geneName ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
112 geneIdToAnnoId[ std::string( transcript[0].geneName ) ] = introns[k].geneName ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
113 flag = true ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
114 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
115 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
116 else if ( cmp > 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
117 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
118 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
119 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
120
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
121 // Next, try whether exon works
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
122 k = exonTag ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
123 for ( i = 0 ; i < ecnt && !flag ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
124 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
125 for ( ; k < exonSize ; ++k )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
126 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
127 if ( strcmp( exons[k].chrom, transcript[i].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
128 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
129
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
130 if ( exons[k].end < transcript[i].start )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
131 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
132 else if ( exons[k].start > transcript[i].end )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
133 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
134 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
135 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
136 txptIdToAnnoId[ std::string( tid ) ] = exons[k].geneName ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
137 geneIdToAnnoId[ std::string( transcript[0].geneName ) ] = exons[k].geneName ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
138 flag = true ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
139 break ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
140 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
141 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
142 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
143 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
144
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
145 int main( int argc, char *argv[] )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
146 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
147 int i, j, k ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
148 FILE *fp ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
149 FILE *fpList ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
150 char outputPath[1024] = "./" ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
151 char prevTid[97] = "" ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
152
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
153 std::vector<struct _interval> introns, exons ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
154 std::map<std::string, std::string> txptIdToAnnoId, geneIdToAnnoId ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
155 std::map<std::string, int> chromIdMapIntrons, chromIdMapExons ; // the index for the starting of a chrom.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
156
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
157 if ( argc < 3 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
158 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
159 fprintf( stderr, "%s", usage ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
160 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
161 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
162
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
163 for ( i = 3 ; i < argc ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
164 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
165 if ( !strcmp( argv[i], "-o" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
166 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
167 strcpy( outputPath, argv[i + 1 ] ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
168 ++i ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
169 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
170 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
171 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
172 fprintf( stderr, "Unknown argument: %s\n", argv[i] ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
173 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
174 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
175 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
176
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
177 // Get the exons, introns from the annotation.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
178 fp = fopen( argv[1], "r" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
179 while ( fgets( line, sizeof( line ), fp ) != NULL )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
180 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
181 if ( line[0] == '#' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
182 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
183 char tid[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
184 char gname[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
185 char chrom[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
186 char type[50] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
187 int start, end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
188
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
189 sscanf( line, "%s %s %s %d %d", chrom, buffer, type, &start, &end ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
190 if ( strcmp( type, "exon" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
191 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
192 if ( GetGTFField( gname, line, "gene_name" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
193 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
194 struct _interval ne ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
195 strcpy( ne.chrom, chrom ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
196 strcpy( ne.geneName, gname ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
197 ne.start = start ; ne.end = end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
198
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
199 exons.push_back( ne ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
200 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
201 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
202 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
203 fprintf( stderr, "%s has no field of gene_name.\n", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
204 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
205 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
206
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
207 if ( GetGTFField( tid, line, "transcript_id" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
208 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
209 if ( !strcmp( tid, prevTid ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
210 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
211 struct _interval ni ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
212
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
213 strcpy( ni.chrom, chrom ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
214 strcpy( ni.geneName, gname ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
215
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
216 int size = exons.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
217 if ( size < 2 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
218 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
219
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
220 struct _interval &e1 = exons[ size - 2 ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
221 struct _interval &e2 = exons[ size - 1 ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
222 if ( e1.start < e2.start )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
223 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
224 ni.start = e1.end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
225 ni.end = e2.start ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
226 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
227 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
228 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
229 ni.start = e2.end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
230 ni.end = e1.start ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
231 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
232
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
233 introns.push_back( ni ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
234 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
235 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
236 strcpy( prevTid, tid ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
237 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
238 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
239 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
240 fprintf( stderr, "%s has no field of transcript_id.\n", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
241 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
242 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
243 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
244 fclose( fp ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
245 SortAndCleanIntervals( exons ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
246 SortAndCleanIntervals( introns ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
247 int exonSize = exons.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
248 int intronSize = introns.size() ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
249 // Determine the offset for each chrom on the list of features.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
250 if ( exonSize )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
251 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
252 chromIdMapExons[ std::string( exons[0].chrom ) ] = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
253 for ( i = 1 ; i < exonSize ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
254 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
255 if ( strcmp( exons[i].chrom, exons[i - 1].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
256 chromIdMapExons[ std::string( exons[i].chrom ) ] = i ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
257 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
258 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
259
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
260 if ( intronSize )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
261 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
262 chromIdMapIntrons[ std::string( introns[0].chrom ) ] = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
263 for ( i = 1 ; i < intronSize ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
264 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
265 if ( strcmp( introns[i].chrom, introns[i - 1].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
266 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
267 //printf( "%s %d\n", introns[i].chrom, i ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
268 chromIdMapIntrons[ std::string( introns[i].chrom ) ] = i ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
269 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
270 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
271
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
272 //for ( i = 0 ; i < intronSize ; ++i )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
273 // printf( "%s\t%d\t%d\n", introns[i].chrom, introns[i].start, introns[i].end ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
274 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
275 //printf( "%d %d\n", exonSize, intronSize ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
276
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
277 // Go through all the GTF files to find the map between PsiCLASS's gene_id to annotation's gene name
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
278 fpList = fopen( argv[2], "r ") ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
279 std::vector<struct _interval> transcript ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
280 int exonTag = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
281 int intronTag = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
282
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
283 while ( fscanf( fpList, "%s", line ) != EOF )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
284 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
285 // Set the output file
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
286 //printf( "hi: %s\n", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
287 char *p ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
288 p = line + strlen( line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
289 while ( p != line && *p != '/' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
290 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
291 if ( *p == '\n' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
292 *p = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
293 --p ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
294 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
295 sprintf( buffer, "%s/%s", outputPath, p ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
296
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
297 // Test whether this will overwrite the input gtf file.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
298 if ( realpath( buffer, buffer2 ) != NULL )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
299 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
300 if ( realpath( line, buffer3 ) && !strcmp( buffer2, buffer3 ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
301 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
302 fprintf( stderr, "Output will overwrite the input files. Please use -o to specify a different output directory.\n" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
303 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
304 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
305 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
306
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
307 fp = fopen( line, "r" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
308 transcript.resize( 0 ) ; // hold the exons in the transcript.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
309 prevTid[0] = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
310 exonTag = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
311 intronTag = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
312 int farthest = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
313
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
314 while ( fgets( line, sizeof( line ), fp ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
315 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
316 char tid[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
317 //char gname[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
318 char chrom[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
319 char type[50] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
320 int start, end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
321
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
322 if ( line[0] == '#' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
323 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
324
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
325 sscanf( line, "%s %s %s %d %d", chrom, buffer, type, &start, &end ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
326 if ( strcmp( type, "exon" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
327 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
328
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
329 if ( GetGTFField( tid, line, "transcript_id" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
330 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
331 struct _interval ne ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
332 strcpy( ne.chrom, chrom ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
333 ne.start = start ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
334 ne.end = end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
335 GetGTFField( ne.geneName, line, "gene_id" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
336
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
337 if ( !strcmp( tid, prevTid ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
338 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
339 transcript.push_back( ne ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
340 if ( end > farthest )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
341 farthest = end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
342 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
343 else if ( transcript.size() > 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
344 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
345 // the non-existed chrom will be put to offset 0, and that's fine
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
346 if ( strcmp( transcript[0].chrom, introns[intronTag].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
347 intronTag = chromIdMapIntrons[ std::string( transcript[0].chrom ) ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
348 if ( strcmp( transcript[0].chrom, introns[intronTag].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
349 exonTag = chromIdMapIntrons[ std::string( transcript[0].chrom ) ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
350
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
351 UpdateIdToAnnoId( transcript, prevTid, exonTag, intronTag, exons, introns, txptIdToAnnoId, geneIdToAnnoId ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
352
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
353 // Adjust the offset if we are done with a gene cluster
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
354 // We don't need to worry about the case of changing chrom here.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
355 if ( !strcmp( ne.geneName, transcript[0].geneName ) &&
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
356 start > farthest ) // Use farthest to avoid inteleaved gene.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
357 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
358 while ( intronTag < intronSize && !strcmp( introns[intronTag ].chrom, ne.chrom )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
359 && introns[intronTag].end < ne.start )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
360 ++intronTag ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
361
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
362 while ( exonTag < exonSize && !strcmp( exons[ exonTag ].chrom, ne.chrom )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
363 && exons[ exonTag ].end < ne.start )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
364 ++exonTag ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
365
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
366 farthest = end ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
367 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
368
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
369 transcript.resize( 0 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
370 transcript.push_back( ne ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
371
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
372 // Find the overlaps.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
373 strcpy( prevTid, tid ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
374 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
375 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
376 strcpy( prevTid, tid ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
377 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
378 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
379 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
380 fprintf( stderr, "Could not find transcript_id field in GTF file: %s", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
381 exit( 1 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
382 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
383 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
384
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
385 if ( transcript.size() > 0 )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
386 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
387 if ( strcmp( transcript[0].chrom, introns[intronTag].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
388 intronTag = chromIdMapIntrons[ std::string( transcript[0].chrom ) ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
389 if ( strcmp( transcript[0].chrom, introns[intronTag].chrom ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
390 exonTag = chromIdMapIntrons[ std::string( transcript[0].chrom ) ] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
391
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
392 UpdateIdToAnnoId( transcript, prevTid, exonTag, intronTag, exons, introns, txptIdToAnnoId, geneIdToAnnoId ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
393 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
394 fclose( fp ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
395 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
396 fclose( fpList ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
397
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
398 // Add the gene_name field.
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
399 fpList = fopen( argv[2], "r" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
400 int novelCnt = 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
401 while ( fscanf( fpList, "%s", line ) != EOF )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
402 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
403 FILE *fpOut ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
404 // Set the output file
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
405 char *p ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
406 p = line + strlen( line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
407 while ( p != line && *p != '/' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
408 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
409 if ( *p == '\n' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
410 *p = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
411 --p ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
412 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
413 sprintf( buffer, "%s/%s", outputPath, p ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
414 fpOut = fopen( buffer, "w" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
415
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
416 // Process the input file
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
417 fp = fopen( line, "r" ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
418
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
419 transcript.resize( 0 ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
420 prevTid[0] = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
421 while ( fgets( line, sizeof( line ), fp ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
422 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
423 char gname[97] ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
424 if ( line[0] == '#' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
425 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
426 fprintf( fpOut, "%s", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
427 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
428 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
429
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
430 if ( GetGTFField( buffer, line, "transcript_id" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
431 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
432 if ( txptIdToAnnoId.find( std::string( buffer ) ) != txptIdToAnnoId.end() )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
433 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
434 int len = strlen( line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
435 if ( line[len - 1] == '\n' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
436 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
437 line[len - 1] = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
438 --len ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
439 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
440 fprintf( fpOut, "%s gene_name \"%s\";\n", line, txptIdToAnnoId[std::string( buffer )].c_str() ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
441 continue ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
442 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
443 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
444
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
445 if ( GetGTFField( gname, line, "gene_id" ) )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
446 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
447 int len = strlen( line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
448 if ( line[len - 1] == '\n' )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
449 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
450 line[len - 1] = '\0' ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
451 --len ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
452 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
453 if ( geneIdToAnnoId.find( std::string( gname ) ) != geneIdToAnnoId.end() )
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
454 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
455 fprintf( fpOut, "%s gene_name \"%s\";\n", line, geneIdToAnnoId[std::string(gname)].c_str() ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
456 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
457 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
458 {
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
459 sprintf( buffer, "novel_%d", novelCnt ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
460 geneIdToAnnoId[ std::string( gname ) ] = std::string( buffer ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
461 fprintf( fpOut, "%s gene_name \"%s\";\n", line, buffer ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
462 ++novelCnt ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
463 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
464
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
465 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
466 else
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
467 fprintf( fpOut, "%s", line ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
468
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
469 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
470
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
471 fclose( fp ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
472 fclose( fpOut ) ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
473 }
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
474
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
475 return 0 ;
903fc43d6227 Uploaded
lsong10
parents:
diff changeset
476 }