]> git.donarmstrong.com Git - rsem.git/blob - HitContainer.h
add --no-bam-output option to not generate output bam files
[rsem.git] / HitContainer.h
1 #ifndef HITCONTAINER_H_
2 #define HITCONTAINER_H_
3
4 #include<cassert>
5 #include<iostream>
6 #include<vector>
7
8 #include<algorithm>
9 #include "GroupInfo.h"
10
11 template<class HitType>
12 class HitContainer {
13 public:
14         HitContainer() {
15                 clear();
16         }
17
18         void clear() {
19                 n = nhits = 0;
20                 s.clear();
21                 hits.clear();
22
23                 s.push_back(0);
24         }
25
26         bool read(std::istream&); // each time a read
27         void write(std::ostream&); // write all reads' hit out
28
29         void push_back(const HitType& hit)  {
30                 hits.push_back(hit);
31                 ++nhits;
32         }
33
34         //update read information vector etc
35         void updateRI() {
36                 if (nhits > s.back()) {  //Do not change if last read does not have hits
37                         s.push_back(nhits);
38                         ++n;
39                 }
40         }
41
42         int getN() { return n; }
43
44         int getNHits() { return nhits; }
45
46         int calcNumGeneMultiReads(const GroupInfo&);
47         int calcNumIsoformMultiReads();
48
49         int getSAt(int pos) { assert(pos >= 0 && pos <= n); return s[pos]; }
50
51         HitType& getHitAt(int pos) { assert(pos >= 0 && pos < nhits); return hits[pos]; }
52
53 private:
54         int n; // n reads in total
55         int nhits; // # of hits
56         std::vector<int> s;
57         std::vector<HitType> hits;
58 };
59
60 //Each time only read one read's hits. If you want to start over, must call clear() first!
61 template<class HitType>
62 bool HitContainer<HitType>::read(std::istream& in) {
63         int tot;
64
65         if (!(in>>tot)) return false;
66         assert(tot > 0);
67         for (int i = 0; i < tot; i++) {
68                 HitType hit;
69                 if (!hit.read(in)) return false;
70                 hits.push_back(hit);
71         }
72
73         nhits = nhits + tot;
74         ++n;
75         s.push_back(nhits);
76
77         return true;
78 }
79
80 template<class HitType>
81 void HitContainer<HitType>::write(std::ostream& out) {
82         if (n <= 0) return;
83         for (int i = 0; i < n; i++) {
84                 out<<s[i + 1] - s[i];
85                 for (int j = s[i]; j < s[i + 1]; j++) {
86                         hits[j].write(out);
87                 }
88                 out<<std::endl;
89         }
90 }
91
92 template<class HitType>
93 int HitContainer<HitType>::calcNumGeneMultiReads(const GroupInfo& gi) {
94         int res = 0;
95         int *sortgids = NULL;
96
97         for (int i = 0; i < n; i++) {
98                 int num = s[i + 1] - s[i];
99                 sortgids = new int[num];
100                 for (int j = s[i]; j < s[i + 1]; j++) sortgids[j] = gi.gidAt(hits[j].getSid());
101                 std::sort(sortgids, sortgids + num);
102                 if (std::unique(sortgids, sortgids + num) - sortgids > 1) ++res;
103                 delete[] sortgids;
104         }
105
106         return res;
107 }
108
109 template<class HitType>
110 int HitContainer<HitType>::calcNumIsoformMultiReads() {
111         int res = 0;
112         for (int i = 0; i < n; i++)
113                 if (s[i + 1] - s[i] > 1) ++res;
114         return res;
115 }
116
117 #endif /* HITCONTAINER_H_ */