1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : ali_solution.hxx // |
---|
4 | // Purpose : // |
---|
5 | // // |
---|
6 | // Institute of Microbiology (Technical University Munich) // |
---|
7 | // http://www.arb-home.de/ // |
---|
8 | // // |
---|
9 | // =============================================================== // |
---|
10 | |
---|
11 | #ifndef ALI_SOLUTION_HXX |
---|
12 | #define ALI_SOLUTION_HXX |
---|
13 | |
---|
14 | #ifndef ALI_PROFILE_HXX |
---|
15 | #include "ali_profile.hxx" |
---|
16 | #endif |
---|
17 | |
---|
18 | class ALI_MAP : virtual Noncopyable { |
---|
19 | unsigned long first_seq_base, last_seq_base; |
---|
20 | unsigned long first_ref_base, last_ref_base; |
---|
21 | long **mapping; |
---|
22 | unsigned char **inserted; |
---|
23 | unsigned char **undefined; |
---|
24 | unsigned long insert_counter; |
---|
25 | public: |
---|
26 | ALI_MAP(unsigned long first_seq_base, unsigned long last_seq_base, |
---|
27 | unsigned long first_ref_base, unsigned long last_ref_base); |
---|
28 | ALI_MAP(ALI_MAP *map); |
---|
29 | ~ALI_MAP() { |
---|
30 | if (mapping) |
---|
31 | free((char *) mapping); |
---|
32 | if (inserted) |
---|
33 | free((char *) inserted); |
---|
34 | if (undefined) |
---|
35 | free((char *) undefined); |
---|
36 | } |
---|
37 | unsigned long first_base() { |
---|
38 | return first_seq_base; |
---|
39 | } |
---|
40 | unsigned long last_base() { |
---|
41 | return last_seq_base; |
---|
42 | } |
---|
43 | unsigned long first_reference_base() { |
---|
44 | return first_ref_base; |
---|
45 | } |
---|
46 | unsigned long last_reference_base() { |
---|
47 | return last_ref_base; |
---|
48 | } |
---|
49 | // Set position of base to position (relative to first_ref_base) |
---|
50 | void set(unsigned long base, unsigned long pos, int insert = -1) { |
---|
51 | unsigned long b; |
---|
52 | |
---|
53 | if (base < first_seq_base || base > last_seq_base) |
---|
54 | ali_fatal_error("Base number out of range", "ALI_MAP::set()"); |
---|
55 | |
---|
56 | if (pos > last_ref_base - first_ref_base) |
---|
57 | ali_fatal_error("Position out of range", "ALI_MAP::set()"); |
---|
58 | |
---|
59 | b = base - first_seq_base; |
---|
60 | (*mapping)[b] = pos; |
---|
61 | (*undefined)[b/8] &= (unsigned char) ~(0x01<<(7-(b%8))); |
---|
62 | switch (insert) { |
---|
63 | case 0: |
---|
64 | if ((*inserted)[b/8]>>(7-(b%8)) & 0x01) { |
---|
65 | if (insert_counter > 0) |
---|
66 | insert_counter--; |
---|
67 | else |
---|
68 | ali_fatal_error("Inconsistent insert_counter", |
---|
69 | "ALI_MAP::set()"); |
---|
70 | (*inserted)[b/8] &= (unsigned char) ~(0x01<<(7-(b%8))); |
---|
71 | } |
---|
72 | break; |
---|
73 | case 1: |
---|
74 | if (!((*inserted)[b/8]>>(7-(b%8)) & 0x01)) { |
---|
75 | (*inserted)[b/8] |= (unsigned char) (0x01<<(7-(b%8))); |
---|
76 | insert_counter++; |
---|
77 | } |
---|
78 | } |
---|
79 | } |
---|
80 | long position(unsigned long base) { |
---|
81 | if (base < first_seq_base || base > last_seq_base) |
---|
82 | ali_fatal_error("Out of range", "ALI_MAP::position()"); |
---|
83 | return (*mapping)[base - first_seq_base]; |
---|
84 | } |
---|
85 | unsigned long insertations() { |
---|
86 | return insert_counter; |
---|
87 | } |
---|
88 | int is_inserted(unsigned long base) { |
---|
89 | unsigned long b; |
---|
90 | if (base < first_seq_base && base > last_seq_base) |
---|
91 | ali_fatal_error("Out of range", "ALI_MAP::inserted"); |
---|
92 | b = base - first_seq_base; |
---|
93 | if (((*inserted)[b/8]>>(7-(b%8))) & 0x01) |
---|
94 | return 1; |
---|
95 | else |
---|
96 | return 0; |
---|
97 | } |
---|
98 | void undefine(unsigned long base) { |
---|
99 | unsigned long b; |
---|
100 | if (base < first_seq_base && base > last_seq_base) |
---|
101 | ali_fatal_error("Out of range", "ALI_MAP::undefine()"); |
---|
102 | b = base - first_seq_base; |
---|
103 | (*undefined)[b/8] |= (unsigned char) (0x01<<(7-(b%8))); |
---|
104 | } |
---|
105 | void unundefine(unsigned long base) { |
---|
106 | unsigned long b; |
---|
107 | if (base < first_seq_base && base > last_seq_base) |
---|
108 | ali_fatal_error("Out of range", "ALI_MAP::unundefine()"); |
---|
109 | b = base - first_seq_base; |
---|
110 | (*undefined)[b/8] &= (unsigned char) ~(0x01<<(7-(b%8))); |
---|
111 | } |
---|
112 | int is_undefined(unsigned long base) { |
---|
113 | unsigned long b; |
---|
114 | if (base < first_seq_base && base > last_seq_base) |
---|
115 | ali_fatal_error("Out of range", "ALI_MAP::undefined()"); |
---|
116 | b = base - first_seq_base; |
---|
117 | if (((*undefined)[b/8]>>(7-(b%8))) & 0x01) |
---|
118 | return 1; |
---|
119 | else |
---|
120 | return 0; |
---|
121 | } |
---|
122 | int have_undefined() { |
---|
123 | unsigned long b; |
---|
124 | for (b = first_seq_base; b <= last_seq_base; b++) |
---|
125 | if (is_undefined(b)) |
---|
126 | return 1; |
---|
127 | return 0; |
---|
128 | } |
---|
129 | |
---|
130 | int is_konsistent(); |
---|
131 | int is_equal(ALI_MAP *map) { |
---|
132 | unsigned long i; |
---|
133 | if (first_seq_base != map->first_seq_base || |
---|
134 | last_seq_base != map->last_seq_base || |
---|
135 | first_ref_base != map->first_ref_base || |
---|
136 | last_ref_base != map->last_ref_base) |
---|
137 | return 0; |
---|
138 | for (i = 0; i < last_seq_base - first_seq_base + 1; i++) |
---|
139 | if ((*mapping)[i] != (*map->mapping)[i]) |
---|
140 | return 0; |
---|
141 | for (i = 0; i < ((last_seq_base - first_seq_base) / 8) + 1; i++) |
---|
142 | if ((*inserted)[i] != (*map->inserted)[i]) |
---|
143 | return 0; |
---|
144 | return 1; |
---|
145 | } |
---|
146 | ALI_SEQUENCE *sequence(ALI_NORM_SEQUENCE *ref_seq); |
---|
147 | ALI_SEQUENCE *sequence_without_inserts(ALI_NORM_SEQUENCE *ref_seq); |
---|
148 | ALI_MAP *inverse_without_inserts(); |
---|
149 | char *insert_marker(); |
---|
150 | void print() { |
---|
151 | unsigned long i; |
---|
152 | printf("Map: Bases %ld to %ld, Positions %ld to %ld\n", |
---|
153 | first_seq_base, last_seq_base, first_ref_base, last_ref_base); |
---|
154 | printf("Undefined : "); |
---|
155 | for (i = first_seq_base; i <= last_seq_base; i++) |
---|
156 | if (is_undefined(i)) |
---|
157 | printf("%ld ", i); |
---|
158 | printf("\n"); |
---|
159 | /* |
---|
160 | for (i = 0; i <= (last_seq_base - first_seq_base); i++) |
---|
161 | printf("%d, ",first_ref_base + (*mapping)[i]); |
---|
162 | printf("\n"); |
---|
163 | */ |
---|
164 | } |
---|
165 | }; |
---|
166 | |
---|
167 | class ALI_SUB_SOLUTION : virtual Noncopyable { |
---|
168 | ALI_PROFILE *profile; |
---|
169 | ALI_TLIST<ALI_MAP *> map_list; |
---|
170 | |
---|
171 | public: |
---|
172 | |
---|
173 | ALI_SUB_SOLUTION(ALI_PROFILE *prof) : map_list() { |
---|
174 | profile = prof; |
---|
175 | } |
---|
176 | ALI_SUB_SOLUTION(ALI_PROFILE *prof, ALI_MAP *map) : map_list(map) { |
---|
177 | profile = prof; |
---|
178 | } |
---|
179 | ALI_SUB_SOLUTION(ALI_SUB_SOLUTION *solution); |
---|
180 | ~ALI_SUB_SOLUTION(); |
---|
181 | int free_area(unsigned long *start, unsigned long *end, |
---|
182 | unsigned long *start_ref, unsigned long *end_ref, |
---|
183 | unsigned long area_number = 0); |
---|
184 | unsigned long number_of_free_areas(); |
---|
185 | int is_konsistent(ALI_MAP *map); |
---|
186 | int insert(ALI_MAP *map); |
---|
187 | int delete_map(ALI_MAP *map); |
---|
188 | ALI_MAP *make_one_map(); |
---|
189 | void print(); |
---|
190 | }; |
---|
191 | |
---|
192 | #else |
---|
193 | #error ali_solution.hxx included twice |
---|
194 | #endif // ALI_SOLUTION_HXX |
---|