]> git.donarmstrong.com Git - rsem.git/blob - GTFItem.h
Deleted a ';' at the end of RSEM v1.2.15 updates
[rsem.git] / GTFItem.h
1 #ifndef __GTFITEM__
2 #define __GTFITEM__
3
4 #include<cstdio>
5 #include<cstdlib>
6 #include<cassert>
7 #include<string>
8 #include<sstream>
9
10 #include "utils.h"
11
12 class GTFItem {
13 public:
14
15         GTFItem() {
16                 seqname = source = feature = "";
17                 score = "";
18                 start = end = 0;
19                 strand = 0; //strand is a char variable
20                 frame = "";
21                 gene_id = transcript_id = "";
22                 left = "";
23         }
24
25         bool operator<(const GTFItem& o) const {
26                 if (gene_id != o.gene_id) return gene_id < o.gene_id;
27                 if (transcript_id != o.transcript_id) return transcript_id < o.transcript_id;
28                 return start < o.start;
29         }
30
31         void my_assert(char value, std::string& line, const std::string& msg) {
32                 if (!value) {
33                         fprintf(stderr, ".gtf file might be corrupted!\n");
34                         fprintf(stderr, "Stop at line : %s\n", line.c_str());
35                         fprintf(stderr, "Error Message: %s\n", msg.c_str());
36                         exit(-1);
37                 }
38         }
39
40         void parse(std::string line) {
41                 std::istringstream strin(line);
42                 std::string tmp;
43
44                 getline(strin, seqname, '\t');
45                 getline(strin, source, '\t');
46                 getline(strin, feature, '\t');
47                 getline(strin, tmp, '\t');
48                 start = atoi(tmp.c_str());
49                 getline(strin, tmp, '\t');
50                 end = atoi(tmp.c_str());
51                 getline(strin, score, '\t');
52                 getline(strin, tmp, '\t');
53                 my_assert((tmp.length() == 1 && (tmp[0] == '+' || tmp[0] == '-')), line, "Strand is neither '+' nor '-'!");
54                 strand = tmp[0];
55                 getline(strin, frame, '\t');
56
57                 getline(strin, left); // assign attributes and possible comments into "left"
58
59                 strin.clear(); strin.str(left);
60                 bool find_gene_id = false, find_transcript_id = false;
61
62                 while (getline(strin, tmp, ';') && (!find_gene_id || !find_transcript_id)) {
63                         tmp = cleanStr(tmp);
64                         size_t pos = tmp.find(' ');
65                         my_assert((pos != std::string::npos), line, "Cannot separate the identifier from the value for attribute " + tmp + "!");
66                         std::string identifier = tmp.substr(0, pos);
67
68                         if (identifier == "gene_id") {
69                                 my_assert(!find_gene_id, line, "gene_id appear more than once!");
70                                 tmp = cleanStr(tmp.substr(pos));
71                                 my_assert((tmp[0] == '"' && tmp[tmp.length() - 1] == '"'), line, "Textual attributes should be surrounded by doublequotes!");
72                                 gene_id = tmp.substr(1, tmp.length() - 2);
73                                 find_gene_id = true;
74                         } else if (identifier == "transcript_id") {
75                                 my_assert(!find_transcript_id, line, "transcript_id appear more than once!");
76                                 tmp = cleanStr(tmp.substr(pos));
77                                 my_assert((tmp[0] == '"' && tmp[tmp.length() - 1] == '"'), line, "Textual attributes should be surrounded by doublequotes!");
78                                 transcript_id = tmp.substr(1, tmp.length() - 2);
79                                 find_transcript_id = true;
80                         }
81                 }
82
83                 my_assert(feature != "exon" || find_gene_id, line, "Cannot find gene_id!");
84                 my_assert(feature != "exon" || find_transcript_id, line, "Cannot find transcript_id!");
85                 if (!find_gene_id && feature != "exon") { printf("Warning: line \" %s \" does not contain a gene_id attribute! Since this line will not be used for reference construction, it is skipped. But if you think this GTF file is corrupted, you should find a complelete GTF file instead and rebuild the reference.\n", line.c_str()); }
86                 if (!find_transcript_id && feature != "exon") { printf("Warning: line \" %s \" does not contain a transcript_id attribute! Since this line will not be used for reference construction, it is skipped. But if you think this GTF file is corrupted, you should find a complelete GTF file instead and rebuild the reference.\n", line.c_str()); }
87         }
88
89         std::string getSeqName() { return seqname; }
90         std::string getSource() { return source; }
91         std::string getFeature() { return feature; }
92         int getStart() { return start; }
93         int getEnd() { return end; }
94         char getStrand() { return strand; }
95         std::string getScore() { return score; }  // float, integer or "." ; let downstream programs parse it
96         std::string getFrame() { return frame; }  // 0, 1, 2, or "."; let downstream programs parse it
97         std::string getGeneID() { return gene_id; }
98         std::string getTranscriptID() { return transcript_id; }
99         std::string getLeft() { return left; }
100
101         void setGeneID(const std::string& gene_id) {
102                 this->gene_id = gene_id;
103         }
104
105         std::string toString() {
106                 std::string val;
107                 std::ostringstream strout;
108                 strout<<seqname<<'\t'<<source<<'\t'<<feature<<'\t'<<start<<'\t'<<end<<'\t'<<score<<'\t'<<strand<<'\t'<<frame<<'\t';
109                 strout<<"gene_id \""<<gene_id<<"\"; transcript_id \""<<transcript_id<<"\";"<<left;
110                 val = strout.str();
111
112                 return val;
113         }
114
115 private:
116         std::string seqname, source, feature;
117         std::string score;
118         int start, end;
119         char strand;
120         std::string frame;
121         std::string gene_id, transcript_id;
122         std::string left;
123 };
124
125 #endif