source: branches/port5/NALIGNER/ali_solution.cxx

Last change on this file was 5183, checked in by westram, 17 years ago
  • fixed shadow warnings
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.0 KB
Line 
1
2
3// #include <malloc.h>
4#include <stdlib.h>
5#include "ali_misc.hxx"
6#include "ali_solution.hxx"
7
8
9/*****************************************************************************
10 *
11 * ALI_MAP
12 *
13 *****************************************************************************/
14
15ALI_MAP::ALI_MAP(unsigned long first_seq, unsigned long last_seq,
16                 unsigned long first_ref, unsigned long last_ref)
17{
18    unsigned long l;
19
20    insert_counter = 0;
21    first_seq_base = first_seq;
22    last_seq_base = last_seq;
23    first_ref_base = first_ref;
24    last_ref_base = last_ref;
25
26    mapping = (long **) CALLOC((unsigned int) (last_seq_base - first_seq_base + 1),sizeof(long));
27    //mapping = (long (*) [1]) CALLOC((unsigned int) (last_seq_base - first_seq_base + 1),sizeof(long));
28    inserted = (unsigned char **) CALLOC((unsigned int) ((last_seq_base - first_seq_base)/8) + 1,sizeof(unsigned char));
29    //inserted = (unsigned char (*) [1]) CALLOC((unsigned int) ((last_seq_base - first_seq_base)/8) + 1,sizeof(unsigned char));
30    undefined = (unsigned char **) CALLOC((unsigned int) ((last_seq_base - first_seq_base)/8) + 1,sizeof(unsigned char));
31    //undefined = (unsigned char (*) [1]) CALLOC((unsigned int) ((last_seq_base - first_seq_base)/8) + 1,sizeof(unsigned char));
32    if (mapping == 0 || inserted == 0 || undefined == 0) {
33        ali_fatal_error("Out of memory");
34    }
35
36    for (l = 0; l < (last_seq_base - first_seq_base)/8 + 1; l++)
37        (*undefined)[l] = 0xff;
38}
39
40ALI_MAP::ALI_MAP(ALI_MAP *map)
41{
42    unsigned long l;
43
44    first_seq_base = map->first_seq_base;
45    last_seq_base = map->last_seq_base;
46    first_ref_base = map->first_ref_base;
47    last_ref_base = map->last_ref_base;
48
49    mapping = (long **) CALLOC((unsigned int) (last_seq_base - first_seq_base + 1), sizeof(long));
50    //mapping = (long (*) [1]) CALLOC((unsigned int) (last_seq_base - first_seq_base + 1), sizeof(long));
51    inserted = (unsigned char **) CALLOC((unsigned int) ((last_seq_base - first_seq_base) / 8) + 1,sizeof(unsigned char));
52    //inserted = (unsigned char (*) [1]) CALLOC((unsigned int) ((last_seq_base - first_seq_base) / 8) + 1,sizeof(unsigned char));
53    undefined = (unsigned char **) CALLOC((unsigned int) ((last_seq_base - first_seq_base) / 8) + 1,sizeof(unsigned char));
54    //undefined = (unsigned char (*) [1]) CALLOC((unsigned int) ((last_seq_base - first_seq_base) / 8) + 1,sizeof(unsigned char));
55    if (mapping == 0 || inserted == 0 || undefined == 0) {
56        ali_fatal_error("Out of memory");
57    }
58
59    for (l = 0; l < last_seq_base - first_seq_base + 1; l++) {
60        if (l < (last_seq_base - first_seq_base)/8 + 1) {
61            (*inserted)[l] = (*map->inserted)[l];
62            (*undefined)[l] = (*map->undefined)[l];
63        }
64        (*mapping)[l] = (*map->mapping)[l];
65    }
66}
67
68int ALI_MAP::is_konsistent(void)
69{
70    unsigned long i;
71
72    for (i = 1; i <= last_seq_base - first_seq_base; i++)
73        if ((*mapping)[i-1] >= (*mapping)[i])
74            return 0;
75
76    return 1;
77}
78
79ALI_SEQUENCE *ALI_MAP::sequence(ALI_NORM_SEQUENCE *ref_seq)
80{
81    int ins_counter;
82    int begin_flag = 0, undefined_flag;
83    unsigned long map_pos, seq_pos;
84    unsigned char *seq, *seq_buffer;
85
86    seq_buffer = (unsigned char *) CALLOC((unsigned int)
87                                          (last_ref_base - first_ref_base + insert_counter + 1),
88                                          sizeof(unsigned char));
89
90    if (seq_buffer == 0)
91        ali_fatal_error("Out of memory");
92
93    seq = seq_buffer;
94    seq_pos = 0;
95    undefined_flag = 0;
96    ins_counter = 0;
97    for (map_pos = 0; map_pos <= last_seq_base - first_seq_base; map_pos++) {
98        if (!undefined_flag)
99            begin_flag = ref_seq->is_begin(first_seq_base + map_pos);
100        if (!(((*undefined)[map_pos/8]>>(7-(map_pos%8))) & 0x01)) {
101            for (;seq_pos < (unsigned long)((*mapping)[map_pos] + ins_counter); seq_pos++) {
102                if (begin_flag)
103                    *seq++ = ALI_DOT_CODE;
104                else
105                    *seq++ = ALI_GAP_CODE;
106            }
107            *seq++ = ref_seq->base(first_seq_base + map_pos);
108            seq_pos++;
109            undefined_flag = 0;
110        }
111        else {
112            undefined_flag = 1;
113        }
114        if ((*inserted)[map_pos/8]>>(7-(map_pos%8)) & 0x01)
115            ins_counter++;
116    }
117
118    begin_flag = ref_seq->is_begin(first_seq_base + map_pos);
119    for (;seq_pos <= last_ref_base - first_ref_base + ins_counter;seq_pos++) {
120        if (begin_flag)
121            *seq++ = ALI_DOT_CODE;
122        else
123            *seq++ = ALI_GAP_CODE;
124    }
125
126    return new ALI_SEQUENCE(ref_seq->name(),seq_buffer,
127                            last_ref_base - first_ref_base + insert_counter + 1);
128}
129
130ALI_SEQUENCE *ALI_MAP::sequence_without_inserts(ALI_NORM_SEQUENCE *ref_seq)
131{
132    int begin_flag = 0, undefined_flag;
133    unsigned long map_pos, seq_pos;
134    unsigned char *seq, *seq_buffer;
135
136    seq_buffer = (unsigned char *) CALLOC((unsigned int)
137                                          (last_ref_base - first_ref_base + 1), sizeof(unsigned char));
138    if (seq_buffer == 0)
139        ali_fatal_error("Out of memory");
140
141    seq = seq_buffer;
142    seq_pos = 0;
143    undefined_flag = 0;
144    for (map_pos = 0; map_pos <= last_seq_base - first_seq_base; map_pos++) {
145        if (!undefined_flag)
146            begin_flag = ref_seq->is_begin(first_seq_base + map_pos);
147        if (!((*undefined)[map_pos/8]>>(7-(map_pos%8)) & 0x01) &&
148            !((*inserted)[map_pos/8]>>(7-(map_pos%8)) & 0x01)) {
149            for (;seq_pos < (unsigned long)((*mapping)[map_pos]); seq_pos++) {
150                if (begin_flag)
151                    *seq++ = ALI_DOT_CODE;
152                else
153                    *seq++ = ALI_GAP_CODE;
154            }
155            *seq++ = ref_seq->base(first_seq_base + map_pos);
156            seq_pos++;
157            undefined_flag = 0;
158        }
159        else
160            undefined_flag = 1;
161    }
162
163    begin_flag = ref_seq->is_begin(first_seq_base + map_pos);
164    for (;seq_pos <= last_ref_base - first_ref_base; seq_pos++) {
165        if (begin_flag)
166            *seq++ = ALI_DOT_CODE;
167        else
168            *seq++ = ALI_GAP_CODE;
169    }
170
171    return new ALI_SEQUENCE(ref_seq->name(),seq_buffer,
172                            last_ref_base - first_ref_base + 1);
173}
174
175ALI_MAP *ALI_MAP::inverse_without_inserts(void)
176{
177    unsigned long map_pos;
178    ALI_MAP *inv_map;
179
180    inv_map = new ALI_MAP(first_ref_base, last_ref_base,
181                          first_seq_base, last_seq_base);
182
183    for (map_pos = 0; map_pos <= last_seq_base - first_seq_base; map_pos++) {
184        if (!((*undefined)[map_pos/8]>>(7-(map_pos%8)) & 0x01) &&
185            !((*inserted)[map_pos/8]>>(7-(map_pos%8)) & 0x01)) {
186            inv_map->set(first_ref_base + (*mapping)[map_pos],
187                         map_pos);
188        }
189    }
190
191    return inv_map;
192}
193
194char *ALI_MAP::insert_marker(void)
195{
196    int ins_counter;
197    unsigned long map_pos, seq_pos;
198    char *seq, *seq_buffer;
199
200    seq_buffer = (char *) CALLOC( (last_ref_base - first_ref_base + insert_counter + 2),
201                                  sizeof(char));
202
203    seq = seq_buffer;
204    seq_pos = 0;
205    ins_counter = 0;
206    for (map_pos = 0; map_pos <= last_seq_base - first_seq_base; map_pos++) {
207        if (!(((*undefined)[map_pos/8]>>(7-(map_pos%8))) & 0x01)) {
208            for (;seq_pos < (unsigned long)((*mapping)[map_pos] + ins_counter); seq_pos++) {
209                *seq++ = '.';
210            }
211            if ((*inserted)[map_pos/8]>>(7-(map_pos%8)) & 0x01)
212                *seq++ = 'X';
213            else
214                *seq++ = '.';
215            seq_pos++;
216        }
217        if ((*inserted)[map_pos/8]>>(7-(map_pos%8)) & 0x01)
218            ins_counter++;
219    }
220
221    for (;seq_pos <= last_ref_base - first_ref_base + ins_counter;seq_pos++) {
222        *seq++ = '.';
223    }
224
225    *seq = '\0';
226
227    return seq_buffer;
228}
229
230
231/*****************************************************************************
232 *
233 * ALI_SUB_SOLUTION
234 *
235 *****************************************************************************/
236
237ALI_SUB_SOLUTION::ALI_SUB_SOLUTION(ALI_SUB_SOLUTION *solution)
238{
239    ALI_MAP *map;
240    ALI_TLIST<ALI_MAP *> *list;
241
242    profile = solution->profile;
243
244    if (!solution->map_list.is_empty()) {
245        list = &solution->map_list;
246        map = new ALI_MAP(list->first());
247        map_list.append_end(map);
248        while (list->is_next()) {
249            map = new ALI_MAP(list->next());
250            map_list.append_end(map);
251        }
252    }
253}
254
255ALI_SUB_SOLUTION::~ALI_SUB_SOLUTION(void)
256{
257    ALI_MAP *map;
258
259    if (!map_list.is_empty()) {
260        map = map_list.first();
261        delete map;
262        while (map_list.is_next()) {
263            map = map_list.next();
264            delete map;
265        }
266    }
267}
268
269int ALI_SUB_SOLUTION::free_area(
270                                unsigned long *start, unsigned long *end,
271                                unsigned long *start_ref, unsigned long *end_ref,
272                                unsigned long area_number)
273{
274    ALI_MAP *map;
275    unsigned long last_of_prev, last_of_prev_ref;
276    unsigned long area_number_akt;
277
278    if (map_list.is_empty()) {
279        if (area_number > 0)
280            return 0;
281        *start = 0;
282        *end = profile->sequence_length() - 1;
283        *start_ref = 0;
284        *end_ref = profile->length() - 1;
285        return 1;
286    }
287
288    area_number_akt = 0;
289    map = map_list.first();
290    if (map->first_base() > 0 &&
291        map->first_reference_base() > 0) {
292        if (area_number_akt == area_number) {
293            *start = 0;
294            *end = map->first_base() - 1;
295            *start_ref = 0;
296            *end_ref = map->first_reference_base() - 1;
297            return 1;
298        }
299        area_number_akt++;
300    }
301
302    last_of_prev = map->last_base();
303    last_of_prev_ref = map->last_reference_base();
304    while (map_list.is_next()) {
305        map = map_list.next();
306        if (map->first_base() > last_of_prev + 1) {
307            if (area_number_akt == area_number) {
308                *start = last_of_prev + 1;
309                *end = map->first_base() - 1;
310                *start_ref = last_of_prev_ref + 1;
311                *end_ref = map->first_reference_base() - 1;
312                return 1;
313            }
314            area_number_akt++;
315        }
316        last_of_prev = map->last_base();
317        last_of_prev_ref = map->last_reference_base();
318    }
319
320    if (map->last_base() < profile->sequence_length() - 1 &&
321        area_number_akt == area_number) {
322        *start = map->last_base() + 1;
323        *end = profile->sequence_length() - 1;
324        *start_ref = map->last_reference_base() + 1;
325        *end_ref = profile->length() - 1;
326        return 1;
327    }
328
329    return 0;
330}
331
332unsigned long ALI_SUB_SOLUTION::number_of_free_areas(void)
333{
334    ALI_MAP *map;
335    unsigned long last_of_prev;
336    unsigned long counter;
337
338    if (map_list.is_empty())
339        return 1;
340
341    counter = 0;
342    map = map_list.first();
343    if (map->first_base() > 0 && map->first_reference_base() > 0)
344        counter++;
345
346    last_of_prev = map->last_base();
347    while (map_list.is_next()) {
348        map = map_list.next();
349        if (map->first_base() > last_of_prev + 1)
350            counter++;
351        last_of_prev = map->last_base();
352    }
353
354    if (map->last_base() < profile->sequence_length() - 1)
355        counter++;
356
357    return counter;
358}
359
360
361int ALI_SUB_SOLUTION::is_konsistent(ALI_MAP *in_map)
362{
363    ALI_MAP *map;
364    unsigned long last_of_prev, last_of_prev_ref;
365
366    if (map_list.is_empty()) {
367        if (in_map->last_base() < profile->sequence_length() &&
368            in_map->last_reference_base() < profile->length())
369            return 1;
370        return 0;
371    }
372
373    map = map_list.first();
374    if (in_map->last_base() < map->first_base() &&
375        in_map->last_reference_base() < map->first_reference_base()) {
376        return 1;
377    }
378
379    last_of_prev = map->last_base();
380    last_of_prev_ref = map->last_reference_base();
381    while (map_list.is_next()) {
382        map = map_list.next();
383        if (last_of_prev < in_map->first_base() &&
384            in_map->last_base() < map->first_base() &&
385            last_of_prev_ref < in_map->first_reference_base() &&
386            in_map->last_reference_base() < map->first_reference_base()) {
387            return 1;
388        }
389        last_of_prev = map->last_base();
390        last_of_prev_ref = map->last_reference_base();
391    }
392
393    if (map->last_base() < in_map->first_base() &&
394        in_map->last_base() < profile->sequence_length() &&
395        map->last_reference_base() < in_map->first_base() &&
396        in_map->last_base() < profile->length()) {
397        return 1;
398    }
399
400    return 0;
401}
402
403int ALI_SUB_SOLUTION::insert(ALI_MAP *in_map)
404{
405    ALI_MAP *map;
406    unsigned long last_of_prev, last_of_prev_ref;
407
408    if (map_list.is_empty()) {
409        if (in_map->last_base() < profile->sequence_length() &&
410            in_map->last_reference_base() < profile->length()) {
411            map_list.append_end(in_map);
412            return 1;
413        }
414        return 0;
415    }
416
417    map = map_list.first();
418    if (in_map->last_base() < map->first_base() &&
419        in_map->last_reference_base() < map->first_reference_base()) {
420        map_list.insert_bevor(in_map);
421        return 1;
422    }
423
424    last_of_prev = map->last_base();
425    last_of_prev_ref = map->last_reference_base();
426    while (map_list.is_next()) {
427        map = map_list.next();
428        if (last_of_prev < in_map->first_base() &&
429            in_map->last_base() < map->first_base() &&
430            last_of_prev_ref < in_map->first_reference_base() &&
431            in_map->last_reference_base() < map->first_reference_base()) {
432            map_list.insert_bevor(in_map);
433            return 1;
434        }
435        last_of_prev = map->last_base();
436        last_of_prev_ref = map->last_reference_base();
437    }
438
439    if (map->last_base() < in_map->first_base() &&
440        in_map->last_base() < profile->sequence_length() &&
441        map->last_reference_base() < in_map->first_reference_base() &&
442        in_map->last_reference_base() < profile->length()) {
443        map_list.append_end(in_map);
444        return 1;
445    }
446
447    return 0;
448}
449
450int ALI_SUB_SOLUTION::delete_map(ALI_MAP *del_map)
451{
452    ALI_MAP *map;
453
454    if (map_list.is_empty())
455        return 0;
456
457    map = map_list.first();
458    if (map == del_map) {
459        map_list.delete_element();
460        return 1;
461    }
462
463    while (map_list.is_next()) {
464        map = map_list.next();
465        if (map == del_map) {
466            map_list.delete_element();
467            return 1;
468        }
469    }
470
471    return 0;
472}
473
474ALI_MAP *ALI_SUB_SOLUTION::make_one_map(void)
475{
476    ALI_MAP *map, *new_map;
477    unsigned long i;
478    unsigned long last_pos;
479    unsigned long first_base_of_first, first_reference_of_first;
480    unsigned long last_base_of_last, last_reference_of_last;
481
482    /*
483     * check if maps are closed
484     */
485    if (map_list.is_empty())
486        return 0;
487
488    map = map_list.first();
489    first_base_of_first = map->first_base();
490    first_reference_of_first = map->first_reference_base();
491    last_base_of_last = map->last_base();
492    last_reference_of_last = map->last_reference_base();
493
494    while (map_list.is_next()) {
495        map = map_list.next();
496        if (last_base_of_last != map->first_base() - 1 ||
497            last_reference_of_last != map->first_reference_base() - 1)
498            ali_fatal_error("maps are not compact",
499                            "ALI_SUB_SOLUTION::make_one_map()");
500        last_base_of_last = map->last_base();
501        last_reference_of_last = map->last_reference_base();
502    }
503
504    new_map = new ALI_MAP(first_base_of_first,last_base_of_last,
505                          first_reference_of_first,last_reference_of_last);
506
507    map = map_list.first();
508    do {
509        last_pos = 0;
510        for (i = map->first_base(); i <= map->last_base(); i++) {
511            if (map->is_undefined(i))
512                ali_fatal_error("Unexpected value",
513                                "ALI_SUB_SOLUTION::make_one_map()");
514            if ((unsigned long)(map->position(i)) < last_pos)
515                ali_fatal_error("Inconsistent positions",
516                                "ALI_SUB_SOLUTION::make_one_map()");
517            last_pos = map->position(i);
518
519            if (map->is_inserted(i))
520                new_map->set(i,map->first_reference_base() +
521                             map->position(i) - first_reference_of_first,1);
522            else
523                new_map->set(i,map->first_reference_base() +
524                             map->position(i) - first_reference_of_first,0);
525        }
526
527        if (map_list.is_next())
528            map = map_list.next();
529        else
530            map = 0;
531    } while (map != 0);
532
533    return new_map;
534}
535
536void ALI_SUB_SOLUTION::print(void)
537{
538    ALI_MAP *map;
539
540    printf("ALI_SUB_SOLUTION:\n");
541    if (!map_list.is_empty()) {
542        map = map_list.first();
543        printf("(%ld to %ld) -> (%ld to %ld)\n",
544               map->first_base(), map->last_base(),
545               map->first_reference_base(), map->last_reference_base());
546        while (map_list.is_next()) {
547            map = map_list.next();
548            printf("(%ld to %ld) -> (%ld to %ld)\n",
549                   map->first_base(), map->last_base(),
550                   map->first_reference_base(), map->last_reference_base());
551        }
552    }
553}
554
555
556
557
558
559
560
561
Note: See TracBrowser for help on using the repository browser.