1 |
#ifndef LayoutParser_H |
2 |
#define LayoutParser_H |
3 |
|
4 |
#include "GBase.h" |
5 |
#include "GList.hh" |
6 |
#include "GHash.hh" |
7 |
#include <stdio.h> |
8 |
//hash data associated with a contig/sequence name |
9 |
//a contig name key is always stored as its name plus .<length> |
10 |
|
11 |
class LytCtgData; |
12 |
|
13 |
struct LytSeqInterSeg { |
14 |
int segEnd, segRClip; |
15 |
int nextStart, nextLClip; |
16 |
char segRSplice, nextLSplice; |
17 |
int nextSegSeq; |
18 |
LytSeqInterSeg(int end, int nextstart, int rclip=0, int nextlclip=0, |
19 |
char segrsplice=0, char nextlsplice=0, int seqpos=0) { |
20 |
segEnd=end; segRClip=rclip; |
21 |
nextStart=nextstart; nextLClip=nextlclip; |
22 |
segRSplice=segrsplice; |
23 |
nextLSplice=nextlsplice; |
24 |
nextSegSeq=seqpos; |
25 |
} |
26 |
int length() { |
27 |
return (nextStart-segEnd-1); |
28 |
} |
29 |
}; |
30 |
|
31 |
class LytSeqInfo { //info for a sequence within the file |
32 |
int xlen; //total sequence length (with all the added * within contig) |
33 |
int interseglen; |
34 |
public: |
35 |
char *name; |
36 |
LytCtgData* contig; //contig data containing this sequence, as above |
37 |
bool segmented; |
38 |
int numisegs; // number of intersegs[] |
39 |
LytSeqInterSeg* intersegs; |
40 |
off_t fpos; //file position for the sequence data |
41 |
unsigned char reversed; |
42 |
int offs; //offset in contig (of the very left end) |
43 |
int left,right; //clear range (relative to sequence itself, max 1..xlen) |
44 |
LytSeqInfo(char* seqid, LytCtgData* ctg, int pos=0, unsigned char minus=0, |
45 |
int slen=0, int clpL=0, int clpR=0) { |
46 |
contig=ctg; |
47 |
offs=pos; |
48 |
reversed=minus; |
49 |
fpos=0; |
50 |
interseglen=0; |
51 |
xlen=slen; |
52 |
left=clpL+1; //1 if no clpL given |
53 |
right=xlen-clpR; //0 if no len given |
54 |
segmented=false; |
55 |
numisegs=0; |
56 |
name=Gstrdup(seqid); |
57 |
intersegs=NULL; |
58 |
} |
59 |
~LytSeqInfo() { |
60 |
GFREE(name); |
61 |
GFREE(intersegs); |
62 |
} |
63 |
bool hasIntrons() { return (numisegs>0); } |
64 |
void addInterSeg(int end, int nextstart, int rclip=0, int nextlclip=0, |
65 |
char splice=0, char nextsplice=0, int seqofs=0) { |
66 |
GREALLOC(intersegs,(numisegs+1)*sizeof(LytSeqInterSeg)); |
67 |
interseglen+=nextstart-end-1; |
68 |
intersegs[numisegs].segEnd=end; intersegs[numisegs].segRClip=rclip; |
69 |
intersegs[numisegs].nextStart=nextstart; intersegs[numisegs].nextLClip=nextlclip; |
70 |
intersegs[numisegs].segRSplice=splice; |
71 |
intersegs[numisegs].nextLSplice=nextsplice; |
72 |
intersegs[numisegs].nextSegSeq=seqofs; |
73 |
numisegs++; |
74 |
} |
75 |
|
76 |
void setLength(int len) { |
77 |
//should only be called BEFORE setting the real clipping coordinates |
78 |
//(left,right) |
79 |
xlen=len; |
80 |
left=1; |
81 |
right=xlen; |
82 |
} |
83 |
int length() { return xlen; } //xtended span, including introns |
84 |
int seglen() { return xlen-interseglen; } //segments only, no introns |
85 |
bool operator==(const LytSeqInfo& s) { |
86 |
return (offs+left-1==s.offs+s.left-1); |
87 |
} |
88 |
bool operator<(const LytSeqInfo& s) { |
89 |
return (offs+left-1<s.offs+s.left-1); |
90 |
} |
91 |
char* expandGaps(char* s); |
92 |
}; |
93 |
|
94 |
|
95 |
class LytCtgData { |
96 |
public: |
97 |
char* name; //contig name, as stored in file |
98 |
unsigned int len; //contig length (lsequence, from ACE file) |
99 |
int lpos, rpos; |
100 |
int numseqs; |
101 |
int offs; //some other type of user data that might be of use |
102 |
off_t fpos; //position in file for this contig's entry |
103 |
GList<LytSeqInfo> seqs; |
104 |
LytCtgData(off_t pos=0):seqs(false,false,false) { |
105 |
name=NULL; |
106 |
offs=0; |
107 |
len=0; |
108 |
numseqs=0; |
109 |
fpos=pos; |
110 |
} |
111 |
~LytCtgData() { |
112 |
GFREE(name); |
113 |
seqs.Clear(); |
114 |
} |
115 |
|
116 |
char* readName(char* s, GHash<int>& names); |
117 |
|
118 |
bool operator==(const LytCtgData& s) { |
119 |
return (strcmp(name,s.name)==0); |
120 |
} |
121 |
bool operator<(const LytCtgData& s) { |
122 |
return (strcmp(name,s.name)<0); |
123 |
} |
124 |
}; |
125 |
//callback -- called after a read or contig sequence is loaded |
126 |
typedef bool fnLytSeq(int ctgno, LytCtgData* d, LytSeqInfo* s, char* seq); |
127 |
|
128 |
class LayoutParser { |
129 |
protected: |
130 |
FILE* f; //file stream |
131 |
off_t f_pos; |
132 |
char* fname; |
133 |
LytCtgData* currentContig; // currently loaded contig -- for browsing/loading |
134 |
int numContigs; //total number of contigs found in this file |
135 |
//int numSeqs; //total number of (distinct) sequences found in this file |
136 |
GHash<LytSeqInfo> seqinfo; //sequence locations in the file |
137 |
GHash<int> ctgIDs; //contig IDs, to make them unique! |
138 |
|
139 |
GList<LytCtgData> contigs; //list of contig names with their size, |
140 |
//number of sequences and filepos |
141 |
protected: |
142 |
GLineReader* linebuf; //the line buffer |
143 |
off_t fskipTo(const char* linestart, const char* butnot=NULL); |
144 |
bool startsWith(const char* s, const char* start, int tlen); |
145 |
virtual LytSeqInfo* addSeq(char* s, LytCtgData* ctg); |
146 |
int seek(off_t offset) { |
147 |
int r=fseeko(f, offset, SEEK_SET); |
148 |
if (r==0) f_pos=offset; |
149 |
return r; |
150 |
} |
151 |
|
152 |
public: |
153 |
LayoutParser(const char* filename):contigs(false,true) { |
154 |
f=NULL; |
155 |
f_pos=0; |
156 |
numContigs=0; |
157 |
currentContig=NULL; |
158 |
if (filename==NULL) { |
159 |
f=stdin; |
160 |
fname=Gstrdup("stdin"); |
161 |
} |
162 |
else |
163 |
fname=Gstrdup(filename); |
164 |
linebuf=new GLineReader(); |
165 |
} |
166 |
virtual ~LayoutParser() { |
167 |
ctgIDs.Clear(); |
168 |
GFREE(fname); |
169 |
delete linebuf; |
170 |
close(); |
171 |
numContigs=0; |
172 |
seqinfo.Clear(); |
173 |
contigs.Clear(); |
174 |
} |
175 |
virtual bool open(); |
176 |
void close(); |
177 |
virtual bool parse(fnLytSeq* seqfn=NULL); //load all the file offsets |
178 |
virtual bool parseContigs(); //load all the file offsets for contigs |
179 |
virtual bool loadContig(int ctgidx, fnLytSeq* seqfn=NULL, bool re_pos=true); //for loading by browsing |
180 |
//if parsefn is not NULL, it is executed, passing the sequence data(first time, with the contig sequence) |
181 |
//if parserfn returns true, the data is freed after it is processed |
182 |
virtual char getFileType() { return 'L'; } |
183 |
//sequence loading - only by request |
184 |
LytCtgData* getContig(int idx) { return contigs[idx]; } |
185 |
virtual char* getSeq(LytSeqInfo* sqinfo) { return NULL; } |
186 |
virtual char* getContigSeq(LytCtgData* ctgdata) { return NULL; } |
187 |
int getNumContigs() { return numContigs; } |
188 |
//int getNumSeqs() { return numSeqs; } |
189 |
off_t getFilePos() { return f_pos; } |
190 |
//sorting the list of contigs: |
191 |
void contigsByName(); |
192 |
void contigsByLen(); |
193 |
void contigsByNumSeqs(); |
194 |
}; |
195 |
|
196 |
#endif |