|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/desktop/glbpic.c |
source navigation diff markup identifier search freetext search file search |
1 /* panview.c
2 *
3 * File Name: testseq.c
4 *
5 * Author: Jinghui Zhang
6 *
7 * Version Creation Date: 2/10/93
8 *
9 * File Description:
10 *
11 * Modifications:
12 * --------------------------------------------------------------------------
13 * Date Name Description of modification
14 * ------- ---------- -----------------------------------------------------
15 *11/6/93 used as a main() for testing the functions written
16 * for the sequence displayer
17 * SetFeatureProc can be reused universally
18 *
19 * ==========================================================================
20 */
21
22 #include <vibrant.h>
23 #include <glbpic.h>
24 #include <fstyle.h>
25 #include <lsqfetch.h>
26 #include <drawseq.h>
27
28 #define MIN_WIDTH 20
29
30 /***************************************************************************
31 *
32 * functions related to freeing the GlobalDrawPtr
33 *
34 ****************************************************************************/
35 static ValNodePtr GlobalDataFree(ValNodePtr gbp_list)
36 {
37 GlobalBspPtr gbp;
38 ValNodePtr curr, next;
39 AlignRegionPtr arp;
40
41 while(gbp_list)
42 {
43 gbp = gbp_list->data.ptrvalue;
44 next = gbp_list->next;
45 gbp_list->next = NULL;
46
47 if(gbp->l_marks != NULL)
48 ValNodeFreeData(gbp->l_marks);
49 if(gbp->cyto_marks != NULL)
50 ValNodeFreeData(gbp->cyto_marks);
51 if(gbp->g_marks != NULL)
52 ValNodeFreeData(gbp->g_marks);
53
54 /*freeing the global display of repeat features and alignment*/
55 if(gbp->rrp_list)
56 ValNodeFreeData(gbp->rrp_list);
57 if(gbp->arp_list)
58 {
59 for(curr = gbp->arp_list; curr != NULL; curr = curr->next)
60 {
61 arp = curr->data.ptrvalue;
62 ValNodeFreeData(arp->intervals);
63 }
64 ValNodeFreeData(gbp->arp_list);
65 }
66
67 if(gbp->label)
68 MemFree(gbp->label);
69 ValNodeFreeData(gbp_list);
70 gbp_list = next;
71 }
72
73 return NULL;
74 }
75
76 static void separate_vnp_list(ValNodePtr PNTR head, ValNodePtr list)
77 {
78 ValNodePtr prev = NULL, curr;
79
80 if(list == NULL)
81 return;
82
83 curr = *head;
84 while(curr)
85 {
86 if(curr == list)
87 {
88 if(prev == NULL)
89 *head = NULL;
90 else
91 prev->next = NULL;
92 return;
93 }
94 prev = curr;
95 curr = curr->next;
96 }
97 }
98
99 /**************************************************************************
100 *
101 * free_gkibak_draw(gdraw_p)
102 * free all the data related to the global draw
103 *
104 ***************************************************************************/
105 GlobalDrawPtr free_global_draw(GlobalDrawPtr gdraw_p)
106 {
107 GlobalDataFree(gdraw_p->gbp_list);
108
109 separate_vnp_list(&(gdraw_p->equiv_align_list), gdraw_p->ext_align);
110 ValNodeFree(gdraw_p->equiv_align_list);
111
112 GeneDataFree(gdraw_p->g_data);
113
114 if(gdraw_p->free_data)
115 {
116 FreeEquivAlign(gdraw_p->ext_align);
117 /* ValNodeFreeData(gdraw_p->g_list); */
118 FreeMuskSep(gdraw_p->msp_list);
119 }
120 else
121 ValNodeFree(gdraw_p->msp_list);
122
123
124 /*there are selected slp_list*/
125 if(gdraw_p->slp_list)
126 free_slp_list(gdraw_p->slp_list);
127
128 MemFree(gdraw_p);
129 return NULL;
130 }
131
132 /***************************************************************************
133 *
134 * functions related to creating the GlobalDrawPtr
135 *
136 ****************************************************************************/
137 /***************************************************************************
138 *
139 * create the structure of GeneDataPtr from a list of gene symbols
140 *
141 ****************************************************************************/
142 GeneDataPtr create_gene_data (ValNodePtr msp_list, ValNodePtr mark_list)
143 {
144 ValNodePtr curr;
145 MuskSepPtr msp;
146 GeneDataPtr gdp = NULL;
147 Int2 seglevels;
148 SeqEntryPtr sep;
149 BioseqPtr bsp;
150 SeqLoc sl;
151 SeqLocPtr slp;
152
153 if(msp_list == NULL)
154 return NULL;
155
156
157 for(curr = msp_list; curr != NULL; curr = curr->next)
158 {
159 msp = (MuskSepPtr)curr->data.ptrvalue;
160 if(msp && msp->sep)
161 {
162 sep = msp->sep;
163 bsp = find_big_bioseq(sep);
164 if(bsp != NULL)
165 {
166 seglevels = get_seglevels(bsp);
167 if(seglevels == 1)
168 {
169 sl.choice = SEQLOC_WHOLE;
170 sl.data.ptrvalue = bsp->id;
171 sl.next = NULL;
172 slp = &sl;
173 }
174 else
175 slp = NULL;
176
177 load_gdata_marks(slp, mark_list, seglevels, msp->sep, &gdp);
178 }
179 }
180 }
181
182 return gdp;
183 }
184
185
186
187 /***************************************************************************
188 *
189 * load the alignment data for landmark genes
190 *
191 ****************************************************************************/
192
193 static Boolean load_inconsistent_align(StdSegPtr ssp, Int4 min_inconsist_sp)
194 {
195 Int4 min_val, max_val;
196 SeqLocPtr slp;
197
198 min_val = -1;
199 max_val = -1;
200 for(slp = ssp->loc; slp != NULL; slp = slp->next)
201 {
202 if(min_val == -1)
203 min_val = SeqLocStart(slp);
204 else
205 min_val = MIN(min_val, SeqLocStart(slp));
206 if(max_val == -1)
207 max_val = SeqLocStop(slp);
208 else
209 max_val = MAX(max_val, SeqLocStop(slp));
210 }
211
212 return ((max_val - min_val + 1 ) > min_inconsist_sp);
213 }
214
215 static Boolean load_std_seg(StdSegPtr ssp, SeqLocPtr location, ValNodePtr PNTR head, Uint1 type, Int4 min_inconsist_sp)
216 {
217 SeqLocPtr locs;
218 StdSegPtr t_ssp;
219
220 for(locs = ssp->loc; locs != NULL; locs = locs->next)
221 {
222 if(SeqLocCompare(locs, location) == SLC_A_EQ_B)
223 {
224 if(type == 2) /*inconsistent markers*/
225 {
226 if(min_inconsist_sp >0 &&
227 !load_inconsistent_align(ssp, min_inconsist_sp))
228 return TRUE;
229 }
230 if(*head == NULL)
231 ValNodeAddPointer(head, type, ssp);
232 else
233 {
234 t_ssp = (*head)->data.ptrvalue;
235 if(type == 4 || t_ssp->dim < ssp->dim)
236 {
237 (*head)->data.ptrvalue = ssp;
238 (*head)->choice = type; /*the type of markers. consistent/inconsistent*/
239 }
240 }
241 return TRUE;
242 }
243 }
244 return FALSE;
245 }
246
247 static Boolean check_std_align(SeqLocPtr location, SeqAlignPtr align, ValNodePtr PNTR head, Uint1 type, Int4 min_inconsist_sp)
248 {
249 StdSegPtr ssp;
250 if(align->type == 3)
251 {
252 ssp = align->segs;
253 while(ssp)
254 {
255 if(load_std_seg(ssp, location, head, type, min_inconsist_sp))
256 return TRUE;
257 ssp = ssp->next;
258 }
259 }
260 return FALSE;
261 }
262
263 static void collect_equiv_align_for_landmark(GeneDataPtr gdp, ValNodePtr ealign_list, Int4 min_inconsist_sp)
264 {
265 SeqAnnotPtr annot;
266 SeqAlignPtr align;
267 GeneDataPtr curr;
268 Int2 type;
269 StdSegPtr ssp;
270 GeneDataPtr prev;
271
272 if(gdp == NULL)
273 return;
274 prev = gdp;
275 while(prev->next != NULL)
276 prev = prev->next;
277
278 while(ealign_list)
279 {
280 annot = (SeqAnnotPtr)(ealign_list->data.ptrvalue);
281 type = GetEquivAlignType(annot);
282 if(type == -1)
283 type = 1;
284 if(type != 0 && type != 3) /*excluding alignment with type 3*/
285 {
286 align = (SeqAlignPtr)(annot->data);
287 if(type == 4)
288 {
289 while(align)
290 {
291 ssp = align->segs;
292 while(ssp)
293 {
294 curr = MemNew(sizeof(GeneData));
295 ValNodeAddPointer(&(curr->align_seg), (Uint1)type, ssp);
296 prev->next = curr;
297 prev = curr;
298 ssp = ssp->next;
299 }
300 align = align->next;
301 }
302 }
303 else
304 {
305 while(align)
306 {
307 for(curr = gdp; curr!=NULL; curr = curr->next)
308 {
309 /* if(curr->landmark) */
310 check_std_align(curr->location, align, &(curr->align_seg), (Uint1)type, min_inconsist_sp);
311 }
312
313 align = align->next;
314 }
315 }
316 }
317 ealign_list = ealign_list->next;
318 }
319 }
320
321
322
323
324
325 static Boolean add_genedata_to_GlobalBsp(GlobalBspPtr g_bsp, GeneDataPtr gdp)
326 {
327 MapMarkPtr mmp;
328
329 if(g_bsp == NULL || gdp == NULL)
330 return FALSE;
331
332 while(gdp)
333 {
334 if(BioseqMatch(g_bsp->bsp, SeqLocId(gdp->location)))
335 {
336 mmp = MemNew(sizeof(MapMark));
337 /* StringCpy(mmp->label, gdp->symbol); */
338 LabelCopy(mmp->label, gdp->symbol, 19);
339 mmp->pos = (SeqLocStart(gdp->location) + SeqLocStop(gdp->location))/2;
340 /*mmp->inward = IS_NUM_GENE(gdp->symbol);*/
341 if(gdp->landmark)
342 ValNodeAddPointer(&(g_bsp->l_marks), 0, mmp);
343 else
344 ValNodeAddPointer(&(g_bsp->g_marks), 0, mmp);
345 }
346 gdp = gdp->next;
347 }
348 return TRUE;
349 }
350
351
352
353 static int LIBCALLBACK MapMarkCompProc (VoidPtr ptr1, VoidPtr ptr2)
354 {
355 MapMarkPtr mmp_1, mmp_2;
356 ValNodePtr vnp1, vnp2;
357
358 if(ptr1!=NULL && ptr2 != NULL)
359 {
360 vnp1 = *((ValNodePtr PNTR) ptr1);
361 vnp2 = *((ValNodePtr PNTR) ptr2);
362 if(vnp1 !=NULL && vnp2 != NULL)
363 {
364 mmp_1 = vnp1->data.ptrvalue;
365 mmp_2 = vnp2->data.ptrvalue;
366 if(mmp_1->pos > mmp_2->pos)
367 return 1;
368 if(mmp_1->pos < mmp_2->pos)
369 return -1;
370 }
371 }
372
373 return 0;
374 }
375
376
377 static ValNodePtr sort_map_marker(ValNodePtr marks)
378 {
379 return SortValNode(marks, MapMarkCompProc);
380 }
381
382 static ValNodePtr LoadCytoNode(BioseqPtr bsp, ValNodePtr PNTR head)
383 {
384 SeqFeatPtr sfp;
385 MapMarkPtr mmp;
386 UserObjectPtr uop;
387 Int4 pos;
388 SeqLocPtr slp;
389 CharPtr band_name;
390
391 if(bsp->repr !=Seq_repr_map)
392 return (*head);
393 sfp = bsp->seq_ext;
394 if(sfp->data.choice != 14)
395 return (*head);
396
397 while(sfp)
398 {
399 slp = sfp->location;
400 pos = (SeqLocStart(slp) + SeqLocStop(slp))/2;
401 uop = sfp->data.value.ptrvalue;
402 band_name = get_band_name(uop);
403 if(band_name !=NULL)
404 {
405 mmp = MemNew(sizeof(MapMark));
406 /* StringCpy(mmp->label, band_name); */
407 LabelCopy(mmp->label, band_name, 19);
408 mmp->pos = pos;
409 mmp->inward = TRUE;
410 ValNodeAddPointer(head, 1, mmp);
411 }
412 sfp = sfp->next;
413 }
414
415 return (*head);
416 }
417
418 /***************************************************************************
419 *
420 * GlobalDataNew(): Create a ValNode that contains the information for
421 * bsp: the map Bioseq
422 * map_type: the map type, such as GENETIC, PHYSICAL, etc
423 * show_map_unit: label the map unit in drawing
424 * check_cyto: checking if it is a cytogenetic map
425 * head: the pre-existing GlobalData.
426 * gdp: the GeneDataPtr which will map some into the individual
427 * The new GlobalData will be linked to the end of the head, and the
428 * return TRUE for a circular molecule. FALSE for a linear
429 *
430 ****************************************************************************/
431 static Boolean GlobalDataNew(BioseqPtr bsp, Uint1 map_type, Boolean show_map_unit, Boolean check_cyto, GeneDataPtr gdp, ValNodePtr PNTR head, Uint2 priority)
432 {
433 GlobalBspPtr g_bsp;
434 Uint1 val;
435
436 if(bsp == NULL)
437 return FALSE;
438
439 g_bsp = MemNew(sizeof(GlobalBsp));
440
441 g_bsp->hide = FALSE;
442 g_bsp->bsp = bsp;
443 g_bsp->map_type = map_type;
444 g_bsp->show_map_unit = show_map_unit;
445 g_bsp->check_cyto = check_cyto;
446 g_bsp->l_marks = NULL;
447 g_bsp->g_marks = NULL;
448 g_bsp->cyto_marks = NULL;
449 g_bsp->priority = priority;
450 g_bsp->num_lod_score = GetLODScoreNumber (bsp);
451 if(priority == SEQINDEX_VAL)
452 g_bsp->is_seqindex_map = TRUE;
453 if(check_cyto)
454 LoadCytoNode(bsp, &(g_bsp->cyto_marks));
455
456 add_genedata_to_GlobalBsp(g_bsp, gdp);
457 g_bsp->l_marks = sort_map_marker(g_bsp->l_marks);
458
459 if(bsp->topology == 2)
460 val = CIRCLE_BSP;
461 else
462 val = LINEAR_BSP;
463 ValNodeAddPointer(head, val, g_bsp);
464 return (val == CIRCLE_BSP);
465 }
466
467
468 static Int4 map_linear_xpos (Int4 pos, Int4 seq_len, Int4 left, Int4 right)
469 {
470 FloatHi temp;
471
472 if(seq_len == 0)
473 return -1;
474 temp = (FloatHi)pos * (FloatHi)(right - left)/(FloatHi)seq_len ;
475
476 return (left + (Int4)temp);
477 }
478
479
480 static Int4 find_global_alignment_position (ValNodePtr PNTR list, Int4 left, Int4 right, Int4 width, Int4 offset)
481 {
482 BoolPtr line_data;
483 ValNodePtr curr;
484 ValNodePtr vnp, prev = NULL;
485 Int4 line = 0;
486 Int4 j;
487 Boolean found;
488 Int4 pix_space = 5;
489
490 left -= offset;
491 right -= offset;
492
493 found = FALSE;
494 curr = *list;
495 prev = NULL;
496 while(curr)
497 {
498 line_data = curr->data.ptrvalue;
499 if(line_data[left] == 0 && line_data[right] == 0)
500 {
501 found = TRUE;
502 for(j = left; j<right; ++j)
503 {
504 if(line_data[j] != FALSE)
505 {
506 found = FALSE;
507 break;
508 }
509 }
510 }
511 if(!found)
512 {
513 prev = curr;
514 ++line;
515 }
516 else
517 break;
518 curr = curr->next;
519 }
520
521 if(!found)
522 {
523 line_data = MemNew((size_t)width * sizeof(Boolean));
524 vnp = ValNodeNew(NULL);
525 vnp->data.ptrvalue = line_data;
526 if(prev == NULL)
527 *list = vnp;
528 else
529 prev->next = vnp;
530 }
531
532 left = MAX(0, left - pix_space);
533 right = MIN(width -1, right + pix_space);
534 MemSet(line_data+left, 1, (size_t)(right - left +1) * sizeof(Boolean));
535 return line;
536 }
537
538
539
540
541 static ValNodePtr layout_one_alignment_view(ValNodePtr arp_list,
542 Int4 bsp_len, Int4 left, Int4 right, Boolean align_has_status)
543 {
544 Int4 num;
545 ValNodePtr curr;
546 Int4Ptr y_pos;
547 AlignRegionPtr arp;
548 Int4 t_left, t_right;
549 ValNodePtr line_data = NULL;
550
551 if(arp_list == NULL)
552 return NULL;
553
554 line_data = NULL;
555 num = 0;
556 for(curr = arp_list; curr != NULL; curr = curr->next)
557 {
558 arp = curr->data.ptrvalue;
559 arp->g_left = map_linear_xpos (arp->gr.left, bsp_len, left, right);
560 arp->g_right = map_linear_xpos (arp->gr.right, bsp_len, left, right);
561 if(align_has_status)
562 arp->line = find_global_alignment_position (&line_data, arp->g_left, arp->g_right, (right-left+1), left);
563 else
564 ++num;
565 }
566 ValNodeFreeData(line_data);
567 if(align_has_status)
568 return (arp_list);
569
570 /*for alignment that does not have status*/
571 y_pos = MemNew((size_t)(num*2) * sizeof(Int4));
572 for(curr = arp_list; curr != NULL; curr = curr->next)
573 {
574 arp = curr->data.ptrvalue;
575 t_left = arp->g_left;
576 t_right = arp->g_right;
577 arp->line = find_f_pos(t_left, t_right, y_pos, 1, (Int2)num);
578 }
579 MemFree(y_pos);
580 return (arp_list);
581 }
582
583
584 static ValNodePtr extract_align_range(ValNodePtr PNTR arp_list, Uint1 displayOrder)
585 {
586 ValNodePtr curr, prev = NULL, list = NULL, p_list, next;
587 AlignRegionPtr arp;
588
589 curr = *arp_list;
590 p_list = NULL;
591 prev = NULL;
592 while(curr)
593 {
594 next = curr->next;
595 arp = curr->data.ptrvalue;
596 if(arp->displayOrder == displayOrder)
597 {
598 if(p_list == NULL)
599 list = curr;
600 else
601 p_list->next = curr;
602 p_list = curr;
603 curr->next = NULL;
604 if(prev == NULL)
605 *arp_list = next;
606 else
607 prev->next = next;
608 }
609 else
610 prev = curr;
611 curr = next;
612 }
613
614 return list;
615 }
616
617
618
619 static Boolean layout_alignment_view(ValNodePtr arp_list,
620 Int4 bsp_len, Int4 left, Int4 right, Boolean align_has_status)
621 {
622 ValNodePtr curr, prev, next;
623 AlignRegionPtr arp, n_arp;
624
625 if(arp_list == NULL)
626 return FALSE;
627 curr = arp_list;
628 while(curr)
629 {
630 arp = curr->data.ptrvalue;
631 next = curr->next;
632 prev = curr;
633 while(next)
634 {
635 n_arp = next->data.ptrvalue;
636 if(n_arp->displayOrder == arp->displayOrder)
637 {
638 prev = next;
639 next = next->next;
640 }
641 else
642 break;
643 }
644
645 prev->next = NULL;
646 layout_one_alignment_view(curr, bsp_len,
647 left, right, align_has_status);
648 prev->next = next;
649 curr = next;
650 }
651
652 return TRUE;
653 }
654
655
656
657 /****************************************************************
658 *
659 * There are two cases that the alignments and repeats
660 * need to be displayed together with the sequences in the
661 * global view
662 * 1) single sequence, show both repeats and alignments
663 * 2) multiple maps with FISH mapping data, show the alignments
664 * for the FISH mapping. No repeats
665 *
666 ****************************************************************/
667 static GlobalBspPtr find_bsp_for_repeat_align(ValNodePtr gbp_list, BoolPtr show_repeats)
668 {
669 GlobalBspPtr gbp;
670
671 *show_repeats = FALSE;
672 if(gbp_list == NULL)
673 return NULL;
674 if(gbp_list->next == NULL)
675 { /*single sequence*/
676 gbp = gbp_list->data.ptrvalue;
677 if(gbp->bsp == NULL)
678 return NULL;
679 *show_repeats = TRUE;
680 return gbp;
681 }
682 else
683 { /*check for the FISH alignment*/
684 while(gbp_list != NULL)
685 {
686 gbp = gbp_list->data.ptrvalue;
687 if(gbp->bsp)
688 {
689 if (get_FISH_align (gbp->bsp))
690 {
691 gbp->has_fish_align = TRUE;
692 return gbp;
693 }
694 }
695 gbp_list = gbp_list->next;
696 }
697
698 }
699 return NULL;
700 }
701
702
703 /***************************************************************************
704 *
705 * CreateGlobalDrawData(msp_list, ext_align, user_list, need_free)
706 * Create the GlobalDrawPtr structure to draw the global view
707 * msp_list: externally loaded Seq-entry and its file name (used for saving)
708 * ext_align: the externally loaded sequence-alignment for equiv maps
709 * user_list: a list of user-selected gene symbols
710 * need_free: if TRUE, the free callback will free msp_list, ext_align and
711 * user_list.
712 * if(for_picture), it will create the stuff for drawing the global view
713 * otherwise, landmakrs, repeats, etc will not be created
714 *
715 ****************************************************************************/
716 GlobalDrawPtr CreateGlobalDrawData(ValNodePtr msp_list, ValNodePtr ext_align, ValNodePtr user_list, Boolean need_free, Boolean for_picture, Uint1 equiv_align_option)
717 {
718 ValNodePtr bsp_list = NULL;
719 ValNodePtr e_align = NULL;
720 MuskSepPtr msp;
721 ValNodePtr vnp, new;
722 ValNodePtr landmarks = NULL;
723 Boolean show_map_unit;
724 Boolean check_cyto;
725 Uint1 bsptype = 0;
726 BioseqPtr bsp = NULL;
727 ValNodePtr global_bsp_data = NULL;
728 GeneDataPtr gdata_p = NULL;
729 Boolean is_circle = FALSE;
730 GlobalDrawPtr gdraw_p;
731 GlobalBspPtr gbp;
732 SeqLocPtr m_loc;
733 Int4 min_inconsist_sp; /*mininal space between the inconsistent marks*/
734 Boolean show_repeats;
735
736
737 if(msp_list == NULL)
738 return NULL;
739
740 /*get all the Bioseqs and equiv-aligns in Seq-entry*/
741 for(vnp = msp_list; vnp != NULL; vnp = vnp->next)
742 {
743 msp = (MuskSepPtr)(vnp->data.ptrvalue);
744 make_Bioseq_list (msp->sep, &bsp_list, &e_align);
745 }
746 if(bsp_list == NULL)
747 return NULL;
748 if(ext_align != NULL)
749 ValNodeLink(&e_align, ext_align);
750
751
752 /*load the landmark genes*/
753 min_inconsist_sp = -1;
754 if(for_picture)
755 {
756 for(vnp = msp_list; vnp != NULL; vnp = vnp->next)
757 {
758 msp = (MuskSepPtr)(vnp->data.ptrvalue);
759 new = LoadLandMarkGene(msp->sep);
760 ValNodeLink(&landmarks, new);
761 }
762 if(user_list != NULL) /*link the user-supplied list of landmarks to the end*/
763 ValNodeLink(&landmarks, user_list);
764 if(landmarks != NULL)
765 {
766 gdata_p = create_gene_data (msp_list, landmarks);
767 /*set the minimal space required for displaying the inconsistent marks*/
768 if(bsp_list != NULL && equiv_align_option == EQUIV_ALIGN_DEFAULT)
769 {
770 bsp = (BioseqPtr)(bsp_list->data.ptrvalue);
771 min_inconsist_sp = (bsp->length/5);
772 }
773 else
774 min_inconsist_sp = -1;
775
776 collect_equiv_align_for_landmark(gdata_p, e_align, min_inconsist_sp);
777 if(user_list != NULL)
778 separate_vnp_list(&landmarks, user_list);
779 if(landmarks != NULL)
780 ValNodeFreeData(landmarks);
781 }
782 }
783
784
785 /*load data for individual Bioseq*/
786 for(vnp = bsp_list; vnp != NULL; vnp = vnp->next)
787 {
788 bsp = (BioseqPtr)(vnp->data.ptrvalue);
789 bsptype = get_Bioseq_type (bsp);
790 switch(bsptype)
791 {
792 case RESTRICTION_MAP:
793 show_map_unit = FALSE;
794 check_cyto = FALSE;
795 break;
796 case CYTO_MAP:
797 show_map_unit = FALSE;
798 check_cyto = TRUE;
799 break;
800 default:
801 show_map_unit = TRUE;
802 check_cyto = FALSE;
803 break;
804 }
805 if(GlobalDataNew(bsp, bsptype, show_map_unit, check_cyto, gdata_p, &global_bsp_data, (Uint2)(vnp->choice)))
806 is_circle = TRUE;
807 }
808 ValNodeFree(bsp_list);
809
810 gdraw_p = MemNew(sizeof(GlobalDraw));
811 gdraw_p->gbp_list = global_bsp_data;
812 gdraw_p->ext_align = ext_align;
813 gdraw_p->equiv_align_list = e_align;
814 gdraw_p->msp_list = msp_list;
815 gdraw_p->free_data = need_free;
816 gdraw_p->g_data = gdata_p;
817 gdraw_p->g_list = user_list;
818 gdraw_p->is_circle = is_circle;
819
820 /*collect the repeats and alignments for global display */
821 if(!is_circle && for_picture)
822 {
823 gbp = find_bsp_for_repeat_align(gdraw_p->gbp_list, &show_repeats);
824 if(gbp != NULL)
825 {
826 m_loc = SeqLocIntNew(0, gbp->bsp->length-1, Seq_strand_plus, SeqIdFindBest(gbp->bsp->id, 0));
827 if(show_repeats)
828 collect_repeats_and_align (m_loc, &(gbp->rrp_list), &(gbp->arp_list), 0, msp->sep, &(gbp->align_has_status));
829 else
830 collect_repeats_and_align (m_loc, NULL, &(gbp->arp_list), 0, msp->sep, &(gbp->align_has_status));
831 SeqLocFree(m_loc);
832 }
833 }
834
835 return gdraw_p;
836
837 }
838
839
840 /***************************************************************************
841 *
842 * functions related to the layout of GlobalDrawPtr
843 *
844 * LayoutGlobalDrawData(gdraw_p, pan_width, pan_height)
845 * gdraw_p: the GlobalDrawPtr
846 * pan_width: the width of the viewer
847 * pan_height: the height of the viewer
848 *
849 ****************************************************************************/
850
851 static Int4 get_max_len(ValNodePtr bsp_data)
852 {
853 GlobalBspPtr gbp;
854 Int4 len = 0;
855
856 while(bsp_data)
857 {
858 gbp = (GlobalBspPtr)(bsp_data->data.ptrvalue);
859 if(gbp && gbp->hide == FALSE)
860 len = MAX(len, gbp->bsp->length);
861 bsp_data = bsp_data->next;
862 }
863 return len;
864 }
865
866 static Int2 get_curr_right(Int4 bsp_len, Int4 max_len, Int2 left, Int2 right)
867 {
868 FloatHi tmp_1;
869
870 if(bsp_len == max_len)
871 return right;
872 tmp_1 = (FloatHi)(bsp_len)/(FloatHi)(max_len);
873 tmp_1 *= (FloatHi)(right - left);
874
875 return (left + (Int2)tmp_1);
876 }
877
878 static Int4 get_max_label_len(ValNodePtr gbp_list)
879 {
880 Uint4 max_len = 0;
881 CharPtr seq_label = NULL;
882 GlobalBspPtr gbp;
883 FonT font;
884 Char label[21];
885 Uint1 format;
886 Int2 label_size;
887
888 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
889 SelectFont(font);
890
891 format = (Uint1)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_STYLE);
892 label_size = MIN(20, (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_LABEL, MSM_NUM));
893 while(gbp_list)
894 {
895 gbp = gbp_list->data.ptrvalue;
896 if(gbp && gbp->hide == FALSE )
897 {
898 if(gbp->label != NULL)
899 gbp->label = MemFree(gbp->label);
900 if(MuskSeqIdWrite (gbp->bsp->id, label, label_size, format, TRUE, FALSE))
901 {
902 gbp->label = StringSave(label);
903 if(StringLen(gbp->label) > max_len)
904 {
905 seq_label = gbp->label;
906 max_len = StringLen(gbp->label);
907 }
908 }
909 }
910 gbp_list = gbp_list->next;
911 }
912 if(seq_label != NULL)
913 return StringWidth(seq_label);
914 else
915 return 0;
916 }
917
918
919 /* space for the Font plus the length of the tick mark. That is the
920 immediate lines after the sequence */
921 static Int4 get_minimal_spacing(void)
922 {
923 FonT font;
924 Int4 font_height;
925
926 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
927 SelectFont(font);
928 font_height= FontHeight();
929
930 return (font_height + TICK_LEN);
931 }
932
933
934 /***********************************************************************
935 *
936 * calculate the maximum vertical space needed for displaying the
937 * alignment globally (for powblast application)
938 *
939 ***********************************************************************/
940 static Int4 get_max_alignment_yspace(ValNodePtr arp_list, Boolean is_fish_align)
941 {
942 Int4 line_space = 6;
943 AlignRegionPtr arp;
944 Int4 max_space = 0, c_space;
945 Int4 pen_width;
946 Int4 displayOrder;
947 Int4 groupNum, group_space;
948 Boolean has_prev;
949 FonT font;
950 Int4 font_height;
951
952 displayOrder = 0;
953 has_prev = FALSE;
954 c_space = 0;
955 groupNum = 0;
956 while(arp_list)
957 {
958 arp = arp_list->data.ptrvalue;
959 if(has_prev == FALSE || arp->displayOrder != displayOrder)
960 {
961 max_space += c_space;
962 c_space = 0;
963 displayOrder = arp->displayOrder;
964 has_prev = TRUE;
965 ++groupNum;
966 }
967 c_space = MAX(c_space, arp->line);
968 arp_list = arp_list->next;
969 }
970 max_space += c_space;
971 if(is_fish_align)
972 {
973 pen_width = 1;
974 ++max_space;
975 return ((max_space +1) * line_space*pen_width);
976 }
977 else
978 {
979 if(groupNum > 1)
980 {
981 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
982 SelectFont(font);
983 font_height = FontHeight();
984 group_space = font_height * groupNum + 2 * groupNum * line_space;
985 }
986 else
987 group_space = 0;
988 pen_width = MAX(1, GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_PENWIDTH));
989 return ((max_space +1) * line_space*pen_width + group_space);
990 }
991 }
992
993 static Int4 get_legend_space (void)
994 {
995 Int4 font_height;
996 FonT font;
997
998 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
999 SelectFont(font);
1000 font_height = FontHeight();
1001 return (2*font_height + 2*GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT));
1002 }
1003
1004
1005 /*
1006 * show_align_legend: if TRUE, draw a colored bar representing the
1007 * status of the alignemnts
1008 */
1009 static Boolean LayoutLinearDrawing(ValNodePtr g_bsp_list, Int2 pan_width, Int2 pan_height, Boolean show_align_legend)
1010 {
1011 Int2 space;
1012 Int2 extra_space = 0;
1013 Int2 top, bottom, left, right, c_right;
1014 GlobalBspPtr gbp;
1015 ValNodePtr curr;
1016 Int2 num, lod_num;
1017 Int4 maxlen, max_label_len;
1018 Int2 box_height;
1019 Int2 maxHeight;
1020 Uint1 label_align;
1021 Int2 start_height =0;
1022 Int2 align_space;
1023 Int4 legend_space;
1024 Boolean align_has_status;
1025
1026
1027
1028 /*calculate the number of sequences*/
1029 num = 0;
1030 lod_num = 0;
1031 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1032 {
1033 gbp = curr->data.ptrvalue;
1034 if(gbp->hide == FALSE)
1035 {
1036 ++num;
1037 lod_num += (gbp->num_lod_score);
1038 }
1039 }
1040 if(num == 0)
1041 return FALSE;
1042 /*figure out the left and right margin*/
1043 label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_LABEL, MSM_STYLE);
1044 max_label_len = get_max_label_len(g_bsp_list);
1045 if(label_align == MSM_LABEL_RIGHT)
1046 {
1047 left = max_label_len/2;
1048 right = pan_width - (Int2)max_label_len;
1049 }
1050 else
1051 {
1052 left = (Int2)max_label_len;
1053 right = pan_width -max_label_len/2;
1054 }
1055 if(right - left < MIN_WIDTH)
1056 return FALSE;
1057 maxlen = get_max_len(g_bsp_list);
1058
1059 /*layout the alignemnts. Figure out the maximum space
1060 required for the alignments*/
1061 align_space = 0;
1062 align_has_status = FALSE;
1063 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1064 {
1065 gbp = curr->data.ptrvalue;
1066 if(gbp->hide == FALSE)
1067 {
1068 c_right = get_curr_right(gbp->bsp->length, maxlen, left, right);
1069 gbp->rec.left = left;
1070 gbp->rec.right = c_right;
1071 if(gbp->arp_list != NULL)
1072 {
1073 if(gbp->has_fish_align)
1074 align_has_status = FALSE;
1075 else
1076 align_has_status = gbp->align_has_status;
1077 layout_alignment_view(gbp->arp_list,
1078 gbp->bsp->length, left, c_right, align_has_status);
1079 align_space += (Int2)get_max_alignment_yspace(gbp->arp_list, gbp->has_fish_align);
1080 }
1081 }
1082 }
1083
1084 if(show_align_legend && align_has_status)
1085 {
1086 legend_space = get_legend_space ();
1087 }
1088 else
1089 legend_space = 0;
1090
1091 extra_space = (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1092 space = (Int2)get_minimal_spacing();
1093
1094
1095 box_height = (Int2)GetMuskCParam(MSM_SEQUENCE, MSM_SEGMENT, MSM_HEIGHT);
1096 if(box_height < 6)
1097 box_height = 6;
1098 maxHeight = num*( box_height + space * 2) + (num -1) * extra_space + align_space + legend_space + lod_num * (box_height + extra_space * 2);
1099 if(legend_space > 0 || g_bsp_list->next == NULL || pan_height <= maxHeight)
1100 start_height = 0;
1101 else
1102 start_height = (pan_height - maxHeight)/(num + 1);
1103
1104 top = (Int2)legend_space;
1105 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1106 {
1107 gbp = curr->data.ptrvalue;
1108 if(gbp->hide == FALSE)
1109 {
1110 top += (space + start_height);
1111 if(gbp->arp_list != NULL)
1112 align_space = (Int2)get_max_alignment_yspace(gbp->arp_list, gbp->has_fish_align);
1113 else
1114 align_space = 0;
1115
1116 bottom = top + box_height;
1117 gbp->rec.top = top;
1118 gbp->rec.bottom = bottom;
1119 top = bottom + space + extra_space + align_space;
1120
1121 if(gbp->num_lod_score > 0)
1122 {
1123 top += ((box_height + extra_space * 2)*gbp->num_lod_score);
1124 }
1125 }
1126 }
1127
1128 return TRUE;
1129 }
1130
1131 static Int2 get_circle_max_label(Int2 num)
1132 {
1133 Char label[21];
1134 Int2 i;
1135 FonT font;
1136
1137 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1138 SelectFont(font);
1139 num = MIN(20, num);
1140 for(i = 0; i<num; ++i)
1141 label[i] = 'X';
1142 label[i] = '\0';
1143 return (Int2)StringWidth(label);
1144 }
1145
1146
1147 static Boolean LayoutCircleDrawing(ValNodePtr g_bsp_list, Int2 pan_width, Int2 pan_height)
1148 {
1149 Int2 space, extra_space, max_space;
1150 Int2 radius;
1151 Int2 max_radius, min_radius;
1152 Int2 max_label_width;
1153 GlobalBspPtr gbp;
1154 Int2 num;
1155 ValNodePtr curr;
1156
1157 num = 0;
1158 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1159 {
1160 gbp = curr->data.ptrvalue;
1161 if(gbp->hide == FALSE)
1162 ++num;
1163 }
1164 if( num == 0)
1165 return FALSE;
1166
1167 max_label_width = get_circle_max_label(10);
1168 if(pan_width - max_label_width > pan_height)
1169 {
1170 pan_width = pan_height;
1171 max_radius = pan_height/2;
1172 }
1173 else
1174 {
1175 pan_width -= max_label_width;
1176 max_radius = pan_width/2;
1177 }
1178 if(pan_width < MIN_WIDTH)
1179 return FALSE;
1180 space = max_label_width/2 + TICK_LEN;
1181 extra_space = (Int2)GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1182
1183
1184 max_space = 0;
1185 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1186 {
1187 gbp = curr->data.ptrvalue;
1188 if(gbp->hide == FALSE)
1189 {
1190 if(gbp->show_map_unit)
1191 max_space += space *2;
1192 max_space += extra_space;
1193 }
1194 }
1195 if(max_space != 0) /*get rid of the last extra_space*/
1196 max_space -= extra_space;
1197 min_radius = max_radius - max_space;
1198 radius = MAX(min_radius, 20);
1199
1200
1201 for(curr = g_bsp_list; curr != NULL; curr = curr->next)
1202 {
1203 gbp = curr->data.ptrvalue;
1204 if(gbp->hide == FALSE)
1205 {
1206 if(gbp->show_map_unit)
1207 radius += space;
1208 gbp->radius = radius;
1209 if(gbp->show_map_unit)
1210 radius += space;
1211 radius += extra_space;
1212 }
1213 }
1214
1215 return TRUE;
1216 }
1217
1218
1219 Boolean LayoutGlobalDrawData(GlobalDrawPtr gdraw_p, Int2 pan_width, Int2 pan_height)
1220 {
1221
1222 if(gdraw_p == NULL)
1223 return FALSE;
1224 if(gdraw_p->is_circle)
1225 {
1226 if(!LayoutCircleDrawing(gdraw_p->gbp_list, pan_width, pan_height))
1227 return FALSE;
1228 gdraw_p->center.x = pan_width/2;
1229 gdraw_p->center.y = pan_height/2;
1230 }
1231 else
1232 return LayoutLinearDrawing(gdraw_p->gbp_list, pan_width, pan_height, gdraw_p->draw_align_legend);
1233
1234 return TRUE;
1235 }
1236
1237
1238
1239
1240 /************************************************************************
1241 *
1242 * Draw_Global_Linear(bsp, show_map_unit, marks, check_cyto, p, rec)
1243 * draw the global view of a linear molecule
1244 * bsp: the map Bioseq
1245 * show_map_unit: label the map unit
1246 * marks: label any marks, such as genes associated with the map
1247 * check_cyto: check if it is a cytogenetic map
1248 * p: the PaneL for drawing
1249 * rec: the Rectangle that contains the map Bioseq
1250 *
1251 ************************************************************************/
1252 static void draw_linear_seqmark(SegmenT seg, Int4 length, Int4 left, Int4 top, Int4 right, Int4 bottom, NumberingPtr np)
1253 {
1254 Int4 scale, ruler;
1255 Int4 i;
1256 Int4 pos, x_pos;
1257
1258 Char str[40];
1259 Int4 tick_len;
1260 Boolean use_kb;
1261 FonT font;
1262
1263
1264 scale = length/(right - left);
1265 if (length%(right - left) != 0)
1266 ++scale;
1267 ruler = calculate_ruler(scale)/10;
1268 use_kb = (ruler >= 200);
1269 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1270 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1271
1272 i=0;
1273 pos = 0;
1274 while(pos < length)
1275 { /**mark the scales**/
1276 tick_len = (i%5==0) ? TICK_LEN: TICK_LEN/2;
1277 x_pos = map_linear_xpos(pos, length, left, right);
1278 AddLine(seg, x_pos, bottom, x_pos, (bottom - tick_len), FALSE, 0);
1279 if(i%5 ==0) /*label the the interval*/
1280 {
1281 map_unit_label(pos, np, str, use_kb);
1282 AddTextLabel(seg, x_pos, (bottom - tick_len), str, font, 0, LOWER_CENTER, 0);
1283 }
1284
1285 ++i;
1286 pos += ruler;
1287 }
1288 }
1289
1290
1291 static Boolean label_linear_mark(SegmenT seg, Int4 seqlen, ValNodePtr marks, Int4 left, Int4 top, Int4 right, Int4 bottom, Boolean ck_overlap)
1292 {
1293 FonT font;
1294 MapMarkPtr mmp;
1295 Int4 tick_len = TICK_LEN;
1296 Int4 x_pos, p_pos;
1297 Boolean drawit;
1298 Int4 pwidth = -1, width;
1299
1300 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1301 SelectFont(font);
1302 p_pos = -1;
1303 while(marks)
1304 {
1305 mmp = marks->data.ptrvalue;
1306 x_pos = map_linear_xpos (mmp->pos, seqlen, left, right);
1307 drawit = TRUE;
1308 width = (Int2)StringWidth(mmp->label);
1309 if(p_pos != -1 && ck_overlap && pwidth != -1)
1310 drawit = ((x_pos - p_pos -2) > (pwidth + width)/2);
1311 if(drawit)
1312 {
1313 if(mmp->inward)
1314 {
1315 AddLine(seg, x_pos, bottom, x_pos, (bottom - TICK_LEN), FALSE, 0);
1316 AddTextLabel(seg, x_pos, (bottom - TICK_LEN), mmp->label, font, 0, LOWER_CENTER, 0);
1317 }
1318 else
1319 {
1320 AddLine(seg, x_pos, top, x_pos, (top + TICK_LEN), FALSE, 0);
1321 AddTextLabel(seg, x_pos, (top + TICK_LEN), mmp->label, font, 0, UPPER_CENTER, 0);
1322 }
1323 pwidth = width;
1324 p_pos = x_pos;
1325 }
1326
1327 marks = marks->next;
1328 }
1329
1330 return TRUE;
1331 }
1332
1333
1334
1335 static void DrawInterval(Int4 start, Int4 stop, Int4 length, Int4 left, Int4 right, Int4 top, Int4 bottom, Boolean fill, SegmenT seg)
1336 {
1337 Int4 c_left, c_right;
1338
1339 c_left = map_linear_xpos (start, length, left, right);
1340 c_right = map_linear_xpos (stop, length, left, right);
1341 AddRectangle(seg, c_left, top, c_right, bottom, NO_ARROW, fill, 0);
1342 }
1343
1344
1345
1346 static Boolean draw_human_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1347 {
1348 SeqFeatPtr sfp;
1349 UserObjectPtr uop;
1350 Int4 m_start, m_stop, length;
1351 Int2 i = 0;
1352 Uint1 band;
1353 Boolean draw_band;
1354 Uint1Ptr color;
1355 Uint1 shading;
1356
1357
1358 if(bsp->repr != Seq_repr_map)
1359 return FALSE;
1360 sfp = bsp->seq_ext;
1361 if(sfp->data.choice != 14)
1362 return FALSE;
1363
1364 length = bsp->length;
1365 for(sfp = bsp->seq_ext; sfp !=NULL; sfp = sfp->next)
1366 {
1367 ++i;
1368 if(sfp->data.choice == 14)
1369 {
1370 uop = sfp->data.value.ptrvalue;
1371 band = get_band_type(uop);
1372 draw_band = TRUE;
1373 switch(band)
1374 {
1375 case BAND_POINT:
1376 color = RED_COLOR;
1377 shading = SOLID_SHADING;
1378 break;
1379 case GIEMSA_POS:
1380 color = BLACK_COLOR;
1381 shading = SOLID_SHADING;
1382 break;
1383 case GIEMSA_NEG:
1384 color = WHITE_COLOR;
1385 shading = SOLID_SHADING;
1386 break;
1387 case ACRO_CENTRIC:
1388 color = BLACK_COLOR;
1389 shading = THICK_NWSE_SHADING;
1390 break;
1391 case VARIABLE_REG:
1392 color = BLACK_COLOR;
1393 shading = THIN_NESW_SHADING;
1394 break;
1395 default:
1396 draw_band = FALSE;
1397 break;
1398 }
1399 if(draw_band)
1400 {
1401 m_start = SeqLocStart(sfp->location);
1402 m_stop = SeqLocStop(sfp->location);
1403 AddAttribute (seg, SHADING_ATT | COLOR_ATT, color, 0, shading, 0, NO_MODE);
1404 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1405 }
1406 }
1407 }
1408
1409 return TRUE;
1410 }
1411
1412 static Boolean draw_fly_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1413 {
1414 SeqFeatPtr sfp;
1415 UserObjectPtr uop;
1416 UserFieldPtr ufp;
1417 Int4 m_start, m_stop, length;
1418 Char subdiv[100];
1419 CharPtr curdiv;
1420 Boolean newseg;
1421 Uint1 band_type, prev_band;
1422 Int4 div =0;
1423 Boolean has_prev;
1424 Uint1Ptr color;
1425 Uint1 shading;
1426 Int2 num_subdiv = 0;
1427
1428
1429 if(bsp->repr != Seq_repr_map)
1430 return FALSE;
1431 sfp = bsp->seq_ext;
1432 if(sfp->data.choice != 14)
1433 return FALSE;
1434
1435 length = bsp->length;
1436 subdiv[0] = '\0';
1437 has_prev = FALSE;
1438 div = 0;
1439 for(sfp = bsp->seq_ext; sfp !=NULL; sfp = sfp->next)
1440 {
1441 uop = sfp->data.value.ptrvalue;
1442 band_type = get_band_type(uop);
1443 if(band_type ==TEL || band_type ==CEN)
1444 {
1445 if(has_prev)
1446 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1447 AddAttribute (seg, SHADING_ATT | COLOR_ATT, RED_COLOR, NO_LINE_STYLE, SOLID_SHADING, 0, NO_MODE);
1448 m_start = SeqLocStart(sfp->location);
1449 m_stop = SeqLocStop(sfp->location);
1450 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1451 has_prev = FALSE;
1452 subdiv[0] = '\0';
1453 }
1454 else
1455 {
1456 if(has_prev)
1457 newseg = (prev_band != band_type);
1458 else
1459 newseg = TRUE;
1460
1461 for(ufp = uop->data; ufp!=NULL; ufp = ufp->next)
1462 {
1463 if(is_label_match(ufp->label, "Subdivision"))
1464 {
1465 curdiv = ufp->data.ptrvalue;
1466 if(StringCmp(subdiv, curdiv) !=0)
1467 newseg = TRUE;
1468 if(newseg)
1469 StringCpy(subdiv, curdiv);
1470 }
1471 if(is_label_match(ufp->label, "Division"))
1472 div = ufp->data.intvalue;
1473 }
1474 if(newseg)
1475 {
1476 if(has_prev)
1477 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1478 m_start = SeqLocStart(sfp->location);
1479 m_stop = SeqLocStop(sfp->location);
1480 has_prev = TRUE;
1481 prev_band = band_type;
1482 if(band_type == BND)
1483 {
1484 if(num_subdiv%2 == 0)
1485 shading = THIN_NESW_SHADING;
1486 else
1487 shading = THIN_NWSE_SHADING;
1488 color = get_seg_color((Int2)div);
1489 ++num_subdiv;
1490 }
1491 else /*for herterogen*/
1492 {
1493 shading = THIN_HORIZ_SHADING;
1494 color = BLACK_COLOR;
1495 }
1496 AddAttribute (seg, SHADING_ATT | COLOR_ATT, color, 0, shading, 0, NO_MODE);
1497 }
1498 else
1499 m_stop = SeqLocStop(sfp->location);
1500 }
1501 }
1502 if(has_prev)
1503 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
1504 return TRUE;
1505 }
1506
1507
1508 static Boolean draw_cyto_map(BioseqPtr bsp, Int4 left, Int4 top, Int4 right, Int4 bottom, SegmenT seg)
1509 {
1510 SeqFeatPtr sfp;
1511 Uint1 cyto_type;
1512
1513 if(bsp->repr == Seq_repr_map)
1514 {
1515 sfp = (SeqFeatPtr)(bsp->seq_ext);
1516 cyto_type = ck_cyto_type(sfp);
1517 switch(cyto_type)
1518 {
1519 case HUMAN_CYTO:
1520 draw_human_cyto_map(bsp, left, top, right, bottom, seg);
1521 break;
1522 case FLY_CYTO:
1523 draw_fly_cyto_map(bsp, left, top, right, bottom, seg);
1524 break;
1525 default:
1526 return FALSE;
1527 }
1528 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
1529 AddRectangle(seg, left, top, right, bottom, FALSE, FALSE, 0);
1530 return TRUE;
1531 }
1532
1533 return FALSE;
1534 }
1535
1536
1537 /**********************************************************
1538 *
1539 * add_alignment_to_global: add the arp_list to the
1540 * global drawing
1541 * bottom: the current y position of the picture
1542 * add_to_bottom: TRUE, add the alignment to the bottom
1543 * of the picture, such as the regular sequence alignment
1544 * FALSE: add to the top of the picture. ONLY for the FISH
1545 * mapping data
1546 * return the next available y position
1547 *
1548 ***********************************************************/
1549 static Int4 add_alignment_to_global(SegmenT seg, ValNodePtr arp_list,
1550 Int4 bottom, Boolean add_to_bottom, Int4 left, Int4 right, Int4 length)
1551 {
1552 Uint1 p_val;
1553 Int4 extra_space;
1554 Int4 line_count, maxline;
1555 Uint1 displayOrder;
1556 Int2 order;
1557 Boolean has_prev;
1558 FonT font;
1559 Int4 font_height;
1560 Int4 g_top, g_bottom;
1561 CharPtr annotDB;
1562 Int4 m_start, m_stop, center;
1563 Int4 h_bottom;
1564 AlignRegionPtr arp;
1565 Int4 y_pos;
1566 Int4 pen_width;
1567 Int4 c_left, c_right;
1568 ValNodePtr intervals;
1569 GatherRangePtr grp;
1570 Uint1Ptr color;
1571
1572 if(arp_list == NULL)
1573 return bottom;
1574
1575 extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1576 h_bottom = bottom;
1577 if(add_to_bottom)
1578 bottom -= (extra_space + get_minimal_spacing());
1579 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1580 SelectFont(font);
1581 font_height = FontHeight();
1582 if(add_to_bottom)
1583 pen_width = MAX(1, GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_PENWIDTH));
1584 else
1585 pen_width = 1;
1586
1587 p_val = 1;
1588 color = BLACK_COLOR;
1589 displayOrder = 0;
1590 has_prev = FALSE;
1591 order = 0;
1592 maxline = 0;
1593 line_count = 0;
1594
1595 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
1596 while(arp_list)
1597 {
1598 arp = arp_list->data.ptrvalue;
1599 if(has_prev == FALSE || arp->displayOrder != displayOrder)
1600 { /*start of a new Seq-align cluster */
1601 displayOrder = arp->displayOrder;
1602 if(has_prev && add_to_bottom)
1603 { /*add the AlignNode box to the previous box*/
1604 g_bottom = bottom - (maxline + line_count)* (6+pen_width-1) - 8;
1605 color = get_seg_color(order);
1606 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, color, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
1607 AddRectangle (seg, left, g_top, right, g_bottom, FALSE, FALSE, 0);
1608 if(annotDB[0] != 0)
1609 {
1610 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, WHITE_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
1611
1612 c_left = (left + right)/2 - StringWidth(annotDB)/2 -10;
1613 c_right = c_left + StringWidth(annotDB) + 10;
1614 AddRectangle (seg, c_left, g_top+font_height/2, c_right, g_top-font_height/2, FALSE, TRUE, 0);
1615
1616
1617 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, COPY_MODE);
1618 AddTextLabel(seg, (left+right)/2, g_top, annotDB, font, 0, MIDDLE_CENTER, 0);
1619 }
1620 p_val = 0;
1621 bottom -= 16;
1622 line_count += maxline;
1623 }
1624 has_prev = TRUE;
1625 annotDB = arp->annotDB;
1626 ++order;
1627 if(add_to_bottom)
1628 {
1629 /* add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD); */
1630 g_top = bottom - line_count * (6 + pen_width-1);
1631 if(annotDB[0] != '\0')
1632 {
1633 g_top -= font_height/2;
1634 bottom -= font_height;
1635 }
1636 bottom -= 8;
1637 }
1638 else
1639 {
1640 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, NO_MODE);
1641 bottom -= 6;
1642 }
1643 maxline = 0;
1644
1645 }
1646 maxline = MAX(maxline, arp->line);
1647
1648
1649 switch(arp->status)
1650 {
1651 case 0:
1652 color = BLACK_COLOR;
1653 break;
1654 case 1:
1655 color = BLUE_COLOR;
1656 break;
1657 case 2:
1658 color = GREEN_COLOR;
1659 break;
1660 case 3:
1661 color = MAGENTA_COLOR;
1662 break;
1663 default:
1664 color = RED_COLOR;
1665 break;
1666 }
1667 m_start = arp->g_left;
1668 m_stop = arp->g_right;
1669
1670 /* m_start = arp->gr.left;
1671 m_stop = arp->gr.right;
1672 m_start = map_linear_xpos (m_start, length, left, right);
1673 m_stop = map_linear_xpos (m_stop, length, left, right); */
1674 y_pos = bottom - (arp->line + line_count) *(6 + pen_width-1);
1675 if(add_to_bottom)
1676 { /*adding the info for the image maps*/
1677 arp->g_left = m_start;
1678 arp->g_right = m_stop;
1679 arp->g_top = y_pos;
1680 arp->g_bottom = arp->g_top - pen_width;
1681 }
1682 /*the sequence hits more than one region*/
1683 intervals = arp->intervals;
1684 if(add_to_bottom && (intervals != NULL && intervals->next != NULL))
1685 {
1686 if(pen_width == 1)
1687 {
1688 AddAttribute(seg, COLOR_ATT|SHADING_ATT|MODE_ATT, YELLOW_COLOR, 0, DARK_SHADING, 0, COPY_MODE);
1689 AddLine(seg, m_start, y_pos, m_stop, y_pos, 0, FALSE);
1690 }
1691 else
1692 {
1693 AddAttribute(seg, COLOR_ATT|SHADING_ATT|MODE_ATT, BLACK_COLOR, 0, THICK_NESW_SHADING, 0, COPY_MODE);
1694 AddRectangle (seg, m_start, y_pos, m_stop, y_pos-pen_width, FALSE, TRUE, 0);
1695 }
1696 }
1697
1698 AddAttribute(seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|MODE_ATT, color, SOLID_LINE , SOLID_SHADING, 0, COPY_MODE);
1699 while(intervals)
1700 {
1701 grp = intervals->data.ptrvalue;
1702 m_start = map_linear_xpos(grp->left, length, left, right);
1703 m_stop = map_linear_xpos(grp->right, length, left, right);
1704 if(pen_width == 1 || !add_to_bottom)
1705 AddLine(seg, m_start, y_pos, m_stop, y_pos, 0, FALSE);
1706 else
1707 AddRectangle (seg, m_start, y_pos, m_stop, y_pos-pen_width, FALSE, TRUE, 0);
1708 intervals = intervals->next;
1709 }
1710
1711
1712
1713 if(add_to_bottom == FALSE && y_pos != h_bottom)
1714 {
1715 /*add the lines to the FISH mapping */
1716 center = (m_start + m_stop)/2;
1717 AddLine(seg, center, y_pos, center, h_bottom, 0, FALSE);
1718 }
1719 /* if(p_val > 1)
1720 AddLine(seg, m_start, y_pos+1, m_stop, y_pos+1, 0, FALSE); */
1721 arp_list = arp_list->next;
1722 }
1723
1724 if(order > 1 && add_to_bottom)
1725 {
1726 g_bottom = bottom - extra_space - (maxline + line_count)* (6 + pen_width - 1) -8;
1727 color = get_seg_color(order);
1728 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, color, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
1729 AddRectangle (seg, left, g_top, right, g_bottom, FALSE, FALSE, 0);
1730 if(annotDB[0] != 0)
1731 {
1732 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, WHITE_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
1733
1734 c_left = (left + right)/2 - StringWidth(annotDB)/2 -10;
1735 c_right = c_left + StringWidth(annotDB) + 10;
1736 AddRectangle (seg, c_left, g_top+font_height/2, c_right, g_top-font_height/2, FALSE, TRUE, 0);
1737
1738 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, COPY_MODE);
1739 AddTextLabel(seg, (left+right)/2, g_top, annotDB, font, 0, MIDDLE_CENTER, 0);
1740 }
1741 return g_bottom;
1742 }
1743 else
1744 return (bottom - (maxline + line_count +1) * 6 );
1745
1746 }
1747
1748 static Boolean get_print_score(FloatHi min_score, FloatHi max_score, CharPtr label, Uint1 status)
1749 {
1750 FloatHi val;
1751
1752 if(min_score == max_score)
1753 return FALSE;
1754 if(status > 4)
1755 return FALSE;
1756
1757 switch(status)
1758 {
1759 case 0:
1760 val = min_score;
1761 break;
1762 case 4:
1763 val = max_score;
1764 break;
1765 default:
1766 val = min_score + (FloatHi)status * (max_score - min_score)/5.0;
1767 break;
1768 }
1769
1770 sprintf(label, "%.1lf", val);
1771 return TRUE;
1772 }
1773
1774
1775
1776 static void DrawAlignScoreLegend(SegmenT seg, Int4 left, Int4 right, FloatHi min_score, FloatHi max_score)
1777 {
1778 FonT font;
1779 Int4 font_height, t_right;
1780 Int4 y_pos, box_width, box_height;
1781 Char buf[101], label[101];
1782 Int4 width;
1783 Int2 i;
1784 Int4 extra_space;
1785
1786 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1787 SelectFont(font);
1788 font_height = FontHeight();
1789 /* box_height = (Int2)GetMuskCParam(MSM_SEQUENCE, MSM_SEGMENT, MSM_HEIGHT);
1790 box_height = MIN(font_height, box_height); */
1791 box_height = font_height;
1792 extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
1793 t_right = right;
1794
1795 StringCpy(buf, "Color Key for Alignment Scores");
1796 AddTextLabel(seg, (left+right)/2, 0, buf, font, 0, LOWER_CENTER, 0);
1797 y_pos = 0 - font_height - extra_space;
1798 width = 0;
1799 left += width/2;
1800 right -= width/2;
1801 box_width = (right - left)/5;
1802
1803 /* StringCpy(buf, "lowest");
1804 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1805 AddTextLabel(seg, left, y_pos-box_height/2, buf, font, 0, MIDDLE_LEFT, 0); */
1806
1807 for(i = 0; i<5; ++i)
1808 {
1809 right = left + box_width -1;
1810 switch(i)
1811 {
1812 case 0:
1813 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1814 StringCpy(label, "<40");
1815 break;
1816 case 1:
1817 AddAttribute(seg, COLOR_ATT, BLUE_COLOR, 0, 0, 0, 0);
1818 StringCpy(label, "40-50");
1819 break;
1820 case 2:
1821 StringCpy(label, "50-80");
1822 AddAttribute(seg, COLOR_ATT, GREEN_COLOR, 0, 0, 0, 0);
1823 break;
1824 case 3:
1825 StringCpy(label, "80-200");
1826 AddAttribute(seg, COLOR_ATT, MAGENTA_COLOR, 0, 0, 0, 0);
1827 break;
1828 default:
1829 StringCpy(label, ">=200");
1830 AddAttribute(seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
1831 break;
1832 }
1833 AddRectangle (seg, left, y_pos, right, y_pos-box_height, FALSE, TRUE, 0);
1834 switch(i)
1835 {
1836 case 0:
1837 case 1:
1838 AddAttribute(seg, COLOR_ATT, WHITE_COLOR, 0, 0, 0, 0);
1839 break;
1840 default:
1841 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1842 break;
1843 }
1844 AddTextLabel(seg, (left+right)/2, y_pos-box_height/2-3, label, font, 0, MIDDLE_CENTER, 0);
1845 left = right + 1;
1846 }
1847 AddAttribute(seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1848 AddLine(seg, 0, y_pos-font_height-extra_space, t_right, y_pos-font_height-extra_space, 0, FALSE);
1849 }
1850
1851
1852 static Boolean get_min_max_score (ValNodePtr arp_list, FloatHiPtr min_score, FloatHiPtr max_score)
1853 {
1854 AlignRegionPtr arp;
1855 ValNodePtr curr;
1856 Uint1 displayOrder;
1857 Boolean has_prev;
1858
1859 *min_score = -1.0;
1860 *max_score = -1.0;
1861 has_prev = FALSE;
1862 displayOrder = 0;
1863
1864 for(curr = arp_list; curr != NULL; curr = curr->next)
1865 {
1866 arp = curr->data.ptrvalue;
1867 if(!has_prev)
1868 {
1869 displayOrder = arp->displayOrder;
1870 has_prev = TRUE;
1871 }
1872 else if(displayOrder != arp->displayOrder) /*more than one group*/
1873 {
1874 *min_score = -1.0;
1875 *max_score = -1.0;
1876 return FALSE;
1877 }
1878
1879 if(*min_score == -1.0 || *min_score > arp->score)
1880 *min_score = arp->score;
1881 if(*max_score == -1.0 || *max_score < arp->score)
1882 *max_score = arp->score;
1883 }
1884
1885 return (*min_score < *max_score);
1886 }
1887
1888
1889 static Uint1Ptr MapLodScoreColor(SeqFeatPtr sfp)
1890 {
1891 Uint1 bit_val;
1892
1893 bit_val = GetLODScoreBitValue(sfp);
1894 switch(bit_val)
1895 {
1896 case 1:
1897 return BLUE_COLOR;
1898 case 2:
1899 return CYAN_COLOR;
1900 case 3:
1901 return GREEN_COLOR;
1902 case 4:
1903 return YELLOW_COLOR;
1904 case 5:
1905 return MAGENTA_COLOR;
1906 case 6:
1907 return RED_COLOR;
1908 default:
1909 return BLACK_COLOR;
1910 }
1911 }
1912
1913
1914
1915 static Boolean Draw_Global_Linear(GlobalBspPtr gbp, SegmenT seg, Boolean draw_align_legend)
1916 {
1917 BioseqPtr bsp;
1918 Boolean show_map_unit;
1919 Boolean check_cyto;
1920 FonT font;
1921 Uint1 label_align;
1922 Int4 middle;
1923 Uint1Ptr color;
1924
1925
1926 Int4 left, top, right, bottom;
1927 NumberingPtr np = NULL;
1928 Int4 length;
1929 Int2 i;
1930
1931 SeqLocPtr slp;
1932 Int4 m_start, m_stop, pos;
1933 Boolean is_gap = FALSE;
1934 SeqIdPtr maybe_mapid; /*a possible id for map*/
1935 BioseqPtr t_bsp;
1936
1937 /*for adding the repeat regions*/
1938 Uint1 p_val, shading;
1939 RepeatRegionPtr rrp;
1940 AlignRegionPtr arp;
1941 ValNodePtr curr;
1942 CharPtr label;
1943 Int4 seglen;
1944 Boolean skip;
1945
1946 ValNodePtr rrp_list;
1947 FloatHi min_score, max_score;
1948 ValNodePtr delta_node;
1949 SeqLitPtr slitp;
1950
1951 SeqAnnotPtr annot;
1952 SeqFeatPtr sfp;
1953 Int4 extra_space, space;
1954
1955
1956 if(gbp == NULL || gbp->bsp == NULL || gbp->hide)
1957 return FALSE;
1958 bsp = gbp->bsp;
1959 show_map_unit = gbp->show_map_unit;
1960 check_cyto = gbp->check_cyto;
1961 left = (Int4)(gbp->rec.left);
1962 right = (Int4)(gbp->rec.right);
1963 top = -(Int4)(gbp->rec.top);
1964 bottom = -(Int4)(gbp->rec.bottom);
1965 length = bsp->length;
1966
1967 /*draw the legend for alignment first*/
1968 if(gbp->has_fish_align == FALSE && gbp->arp_list != NULL)
1969 {
1970 if(draw_align_legend)
1971 {
1972 for(curr = gbp->arp_list; curr != NULL; curr = curr->next)
1973 {
1974 arp = curr->data.ptrvalue;
1975 if(arp->status > 0)
1976 {
1977 /*draw the legend for alignment score*/
1978 get_min_max_score (gbp->arp_list, &min_score, &max_score);
1979 DrawAlignScoreLegend(seg, left, right, min_score, max_score);
1980 break;
1981 }
1982 }
1983 }
1984 }
1985
1986
1987 if(gbp->has_fish_align && gbp->arp_list != NULL)
1988 {
1989 top = add_alignment_to_global(seg, gbp->arp_list, top, FALSE, left, right, length);
1990 bottom = top - ABS(gbp->rec.top - gbp->rec.bottom);
1991 }
1992
1993 /*add the sequence label*/
1994 label = gbp->label;
1995 if(label != NULL)
1996 {
1997 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
1998 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
1999 label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_SLABEL, MSM_STYLE);
2000 middle = (top + bottom)/2;
2001 if(label_align == MSM_LABEL_RIGHT)
2002 AddTextLabel(seg, right, middle, label, font, 0, MIDDLE_RIGHT, 0);
2003 else
2004 AddTextLabel(seg, left, middle, label, font, 0, MIDDLE_LEFT, 0);
2005 }
2006
2007 if(bsp->repr != Seq_repr_seg && bsp->repr !=Seq_repr_delta)
2008 /*not a segmented entry or delta seq*/
2009 {
2010 if(check_cyto)
2011 draw_cyto_map(bsp, left, top, right, bottom, seg);
2012 else
2013 {
2014 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2015 AddRectangle (seg, left, top, right, bottom, FALSE, TRUE, 0);
2016 if(GetMuskCParam(MSM_SEQUENCE, MSM_SEG_BORD, MSM_TRUEFALSE))
2017 {
2018 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2019 AddRectangle(seg, left, top, right, bottom, FALSE, FALSE, 0);
2020 }
2021 }
2022 }
2023 else if(bsp->repr == Seq_repr_seg)/*draw the segmented sequence*/
2024 {
2025 slp = bsp->seq_ext;
2026 maybe_mapid = figure_map_seqid(slp);
2027 m_start = 0;
2028 m_stop = -1;
2029 i = 0;
2030 while(slp)
2031 {
2032 ++i;
2033 if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2034 {
2035 seglen = SeqLocLen(slp);
2036 m_stop += seglen;
2037 if(seglen >10000 || (seglen * 10000 > bsp->length))
2038 {
2039 is_gap = is_map_segment(slp);
2040 if(!is_gap && maybe_mapid != NULL)
2041 is_gap = (SeqIdMatch(maybe_mapid, SeqLocId(slp)));
2042 if(!is_gap)
2043 {
2044 color = get_seg_color(i);
2045 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2046 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2047 }
2048 }
2049 m_start = m_stop + 1;
2050 }
2051 slp = slp->next;
2052 }
2053 skip = FALSE;
2054 if(maybe_mapid != NULL)
2055 {
2056 t_bsp = BioseqFind(maybe_mapid);
2057 if(t_bsp != NULL && t_bsp->repr == Seq_repr_map)
2058 skip = TRUE;
2059 }
2060 if(!skip)
2061 {
2062 /*add the gaps*/
2063 m_start = 0;
2064 m_stop = -1;
2065 for(slp = bsp->seq_ext; slp != NULL; slp = slp->next)
2066 {
2067 pos = -1;
2068 if(slp->choice == SEQLOC_NULL || slp->choice == SEQLOC_EMPTY)
2069 {
2070 pos = map_linear_xpos (m_start, length, left, right);
2071 }
2072 else
2073 {
2074 seglen = SeqLocLen(slp);
2075 m_stop += seglen;
2076 is_gap = is_map_segment(slp);
2077
2078 if(is_gap && seglen * (right - left)/length < 4)
2079 {
2080 pos = map_linear_xpos((m_start+m_stop)/2, length, left, right);
2081 }
2082 m_start = m_stop + 1;
2083 }
2084 if(pos != -1)
2085 AddSymbol(seg, pos, (top+bottom)/2, DIAMOND_SYMBOL, FALSE, MIDDLE_CENTER, 0);
2086 }
2087 }
2088
2089 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2090 AddRectangle (seg, left, top, right, bottom, FALSE, FALSE, 0);
2091 }
2092 else /*it is a delta seq*/
2093 {
2094 delta_node = bsp->seq_ext;
2095 m_start = 0;
2096 m_stop = -1;
2097 i = 0;
2098 while(delta_node)
2099 {
2100 is_gap = FALSE;
2101 if(delta_node->choice == 1)
2102 {
2103 slp = delta_node->data.ptrvalue;
2104 if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2105 seglen = SeqLocLen(slp);
2106 else
2107 is_gap = TRUE;
2108 }
2109 else /*it is a literal seq*/
2110 {
2111 slitp = delta_node->data.ptrvalue;
2112 if(slitp->length == 0 || slitp->seq_data == NULL)
2113 {
2114 is_gap = TRUE;
2115 if(slitp->length != 0)
2116 {
2117 m_stop += slitp->length;
2118 m_start = m_stop + 1;
2119 }
2120 }
2121 else
2122 seglen = slitp->length;
2123 }
2124
2125 if(!is_gap)
2126 {
2127 m_stop += seglen;
2128 color = get_seg_color(i);
2129 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2130 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2131 ++i;
2132 m_start = m_stop + 1;
2133 }
2134 delta_node = delta_node->next;
2135 }
2136
2137 /*looking into small gaps*/
2138 m_start = 0;
2139 m_stop = -1;
2140 delta_node = (ValNodePtr)(bsp->seq_ext);
2141 while(delta_node)
2142 {
2143 is_gap = FALSE;
2144 if(delta_node->choice == 1)
2145 {
2146 slp = delta_node->data.ptrvalue;
2147 if(slp->choice != SEQLOC_NULL && slp->choice != SEQLOC_EMPTY)
2148 seglen = SeqLocLen(slp);
2149 else
2150 is_gap = TRUE;
2151 }
2152 else /*it is a literal seq*/
2153 {
2154 slitp = delta_node->data.ptrvalue;
2155 if(slitp->length == 0 || slitp->seq_data == NULL)
2156 {
2157 is_gap = TRUE;
2158 if(slitp->length != 0)
2159 {
2160 if(slitp->length * (right - left)/length >= 4)
2161 is_gap = FALSE;
2162 m_stop += slitp->length;
2163 m_start = m_stop + 1;
2164 }
2165 }
2166 else
2167 seglen = slitp->length;
2168 }
2169
2170 if(is_gap)
2171 {
2172 pos = map_linear_xpos (m_start, length, left, right);
2173 AddSymbol(seg, pos, (top+bottom)/2, DIAMOND_SYMBOL, FALSE, MIDDLE_CENTER, 0);
2174 }
2175 else
2176 {
2177 m_stop += seglen;
2178 m_start = m_stop + 1;
2179 }
2180 delta_node = delta_node->next;
2181 }
2182 }
2183
2184
2185 AddAttribute (seg, COLOR_ATT|STYLE_ATT|SHADING_ATT|WIDTH_ATT, BLACK_COLOR, SOLID_LINE, SOLID_SHADING, 1, COPY_MODE);
2186 if(show_map_unit)
2187 {
2188 np = getBioseqNumbering(bsp);
2189 draw_linear_seqmark(seg, length, left, top, right, bottom, np);
2190 }
2191
2192 if(gbp->cyto_marks != NULL)
2193 {
2194 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2195 label_linear_mark(seg, length, gbp->cyto_marks, left, top, right, bottom, TRUE);
2196 }
2197 if(gbp->l_marks != NULL)
2198 {
2199 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2200 label_linear_mark(seg, length, gbp->l_marks, left, top, right, bottom, TRUE);
2201 }
2202 if(gbp->g_marks != NULL) /*user selected marks*/
2203 {
2204 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
2205 label_linear_mark(seg, length, gbp->g_marks, left, top, right, bottom, FALSE);
2206 }
2207
2208 /*add the repeat unit*/
2209 if(gbp->rrp_list)
2210 {
2211 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2212 shading = LIGHT_SHADING;
2213 AddAttribute(seg, SHADING_ATT, 0, 0, shading, 0, 0);
2214 p_val = 0;
2215 rrp_list = gbp->rrp_list;
2216 while(rrp_list)
2217 {
2218 rrp = rrp_list->data.ptrvalue;
2219 if(rrp_list->choice != p_val)
2220 {
2221 p_val = rrp_list->choice;
2222 /*shading = p_val%4 + 6;
2223 shading = LIGHT_SHADING;
2224 AddAttribute(seg, SHADING_ATT, 0, 0, shading, 0, 0); */
2225 }
2226 m_start = rrp->gr.left;
2227 m_stop = rrp->gr.right;
2228 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2229 rrp_list = rrp_list->next;
2230 }
2231 }
2232
2233 /*add the global alignment as a result from powblast*/
2234 if(gbp->has_fish_align == FALSE && gbp->arp_list != NULL)
2235 top = add_alignment_to_global(seg, gbp->arp_list, top, TRUE, left, right, length);
2236
2237
2238 /*add the LOD score plot*/
2239 if(gbp->num_lod_score > 0)
2240 {
2241 extra_space = GetMuskCParam(MSM_TOPSTYLE, MSM_SPACE, MSM_HEIGHT);
2242 space = get_minimal_spacing();
2243 bottom -= space;
2244 for(annot = bsp->annot; annot != NULL; annot = annot->next)
2245 {
2246 if(is_lod_score_annot(annot))
2247 {
2248 top = bottom - 2* extra_space;
2249 bottom = top - (gbp->rec.bottom - gbp->rec.top);
2250 for(sfp = annot->data; sfp != NULL; sfp = sfp->next)
2251 {
2252 color = MapLodScoreColor(sfp);
2253 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2254 m_start = SeqLocStart(sfp->location);
2255 m_stop = SeqLocStop(sfp->location);
2256 DrawInterval(m_start, m_stop, length, left, right, top, bottom, TRUE, seg);
2257 }
2258 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEG_BORD);
2259 AddRectangle (seg, left, top, right, bottom, FALSE, FALSE, 0);
2260
2261 label = GetAnnotTitle(annot);
2262 if(label != NULL)
2263 {
2264 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2265 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2266 label_align = (Uint1)GetMuskCParam(MSM_TOPSTYLE, MSM_SLABEL, MSM_STYLE);
2267 middle = (top + bottom)/2;
2268 if(label_align == MSM_LABEL_RIGHT)
2269 AddTextLabel(seg, right, middle, label, font, 0, MIDDLE_RIGHT, 0);
2270 else
2271 AddTextLabel(seg, left, middle, label, font, 0, MIDDLE_LEFT, 0);
2272 }
2273 }
2274 }
2275 }
2276
2277 return TRUE;
2278 }
2279
2280
2281 /*************************************************************************
2282 *
2283 * Boolean Draw_Global_Circle(bsp, show_map_unit, marks, p, radius, center)
2284 * draw the global view of a circular genome.
2285 * bsp: the map Bioseq
2286 * show_map_unit: display the map unit or not
2287 * marks: the marks, such as genes, to be displayed on the map
2288 * p: the drawing PaneL
2289 * radius: the radius of the physical map
2290 * center: the center of the circle
2291 *
2292 **************************************************************************/
2293 static FloatHi cal_angle_on_circle(Int4 pos, Int4 length)
2294 {
2295 return (FloatHi)pos/length * (FloatHi)2 * PI;
2296 }
2297
2298 static Int4 cal_angle_with_mm_degree(Int4 pos, Int4 length)
2299 {
2300 FloatHi percent;
2301 Int4 angle;
2302
2303 percent = (FloatHi)pos/(FloatHi)(length-1) * (FloatHi) 360000;
2304 angle = 90L * 1000L - (Int4)percent;
2305 if(angle < 0)
2306 angle = 360000 + angle;
2307 return angle;
2308 }
2309
2310 static void find_point_on_circle(FloatHi angle, PoinT center, Int2 radius, PointPtr c_pos)
2311 {
2312 FloatHi temp;
2313
2314 temp = (FloatHi)radius * sin(angle);
2315 c_pos->x = center.x + (Int2)temp;
2316 temp = (FloatHi)radius * cos(angle);
2317 c_pos->y = center.y - (Int2)temp;
2318 }
2319
2320
2321 static FloatHi cal_mark_pos(Int4 pos, Int4 length, Int2 radius, PoinT center, Int2 tick_len, PointPtr p_start, PointPtr p_stop, Boolean inward)
2322 {
2323 FloatHi angle;
2324
2325 angle = cal_angle_on_circle(pos, length);
2326 find_point_on_circle(angle, center, radius, p_start);
2327 if(inward)
2328 radius -=tick_len;
2329 else
2330 radius += tick_len;
2331
2332 find_point_on_circle(angle, center, radius, p_stop);
2333 return angle;
2334 }
2335
2336
2337 static Uint1 get_circle_label_align(FloatHi angle, Boolean inward)
2338 {
2339 Uint1 align;
2340
2341 if((angle >= 0 && angle <= (PI*0.25)) || (angle >= (PI*1.75) && angle <= (PI *2.0)))
2342 align = inward ? LOWER_CENTER : UPPER_CENTER;
2343 if(angle > (PI * 0.25) && angle <= (PI * 0.75))
2344 align = inward ? MIDDLE_LEFT : MIDDLE_RIGHT;
2345 if(angle > (PI * 0.75) && angle <= (PI * 1.25))
2346 align = inward ? UPPER_CENTER : LOWER_CENTER;
2347 if(angle > (PI * 1.25) && angle <= (PI * 1.75))
2348 align = inward ? MIDDLE_RIGHT: MIDDLE_LEFT;
2349 return align;
2350 }
2351
2352
2353 static void draw_circle_seqmark(SegmenT seg, Int4 length, PoinT center, Int2 radius, NumberingPtr np)
2354 {
2355 FloatHi temp;
2356 Int4 circle_len, scale, ruler;
2357 Boolean use_kb;
2358 Int4 i;
2359 Int4 pos;
2360
2361 PoinT p_start, p_stop;
2362 FonT font;
2363 Char str[40];
2364 FloatHi angle;
2365 Int2 tick_len;
2366
2367 Int4 left, top, right, bottom;
2368 Uint1 label_align;
2369
2370
2371 temp = 2.0 * PI * (FloatHi)radius;
2372 circle_len = (Int4)temp;
2373 scale = length/circle_len;
2374 if (length%circle_len!= 0)
2375 ++scale;
2376 ruler = calculate_ruler(scale)/10;
2377 use_kb = (ruler >= 200);
2378 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2379 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2380
2381 i=0;
2382 pos = 0;
2383 while(pos < length)
2384 { /**mark the scales**/
2385 tick_len = (i%5==0) ? TICK_LEN: TICK_LEN/2;
2386 angle = cal_mark_pos(pos, length, radius, center, tick_len, &p_start, &p_stop, TRUE);
2387 left = (Int4)(p_stop.x);
2388 right = (Int4)(p_start.x);
2389 top = - (Int4)(p_stop.y);
2390 bottom = - (Int4)(p_start.y);
2391 AddLine(seg, left, top, right, bottom, 0, FALSE);
2392 if(i%5 ==0) /*label the the interval*/
2393 {
2394 map_unit_label(pos, np, str, use_kb);
2395 label_align = get_circle_label_align(angle, TRUE);
2396 AddTextLabel(seg, left, top, str, font, 0, label_align, 0);
2397 }
2398
2399 ++i;
2400 pos += ruler;
2401 }
2402 }
2403
2404 static Boolean label_circle_mark(SegmenT seg, Int4 seqlen, ValNodePtr marks, PoinT center, Int2 radius, Boolean ck_overlap)
2405 {
2406 FonT font;
2407 MapMarkPtr mmp;
2408 Int2 tick_len = TICK_LEN;
2409 PoinT p_start, p_stop;
2410 FloatHi angle;
2411 Int4 p_top = -1, p_width = -1, p_left = -1;
2412 Int4 first_top, first_width, first_left; /*first marker*/
2413 Int4 left, right, top, bottom;
2414 Int4 width;
2415 Int4 font_height;
2416 Boolean drawit;
2417 Uint1 label_align, p_align, first_align;
2418 Boolean has_prev = FALSE;
2419 Int4 t_width;
2420
2421
2422 font = (FonT)GetMuskCParam(MSM_SEQUENCE, MSM_SLABEL, MSM_FONT);
2423 SelectFont(font);
2424 font_height = FontHeight();
2425
2426 while(marks)
2427 {
2428 mmp = marks->data.ptrvalue;
2429 angle = cal_mark_pos(mmp->pos, seqlen, radius, center, tick_len, &p_start, &p_stop, mmp->inward);
2430 width = StringWidth(mmp->label);
2431 left = (Int4)(p_stop.x);
2432 right = (Int4)(p_start.x);
2433 top = - (Int4)(p_stop.y);
2434 bottom = - (Int4)(p_start.y);
2435 drawit = TRUE;
2436 label_align = get_circle_label_align(angle, mmp->inward);
2437
2438 if(ck_overlap && has_prev)
2439 {
2440 t_width = (p_width + width)/2;
2441 if(label_align != p_align)
2442 {
2443 if(p_top != -1)
2444 if(ABS(p_top - top )< (font_height+3))
2445 if(ABS(p_left - left) < (t_width +3))
2446 drawit = FALSE;
2447 }
2448 else
2449 {
2450 switch(label_align)
2451 {
2452 case LOWER_CENTER :
2453 case UPPER_CENTER :
2454 if(ABS(p_left - left) < (t_width +3))
2455 drawit = FALSE;
2456 break;
2457 case MIDDLE_LEFT :
2458 case MIDDLE_RIGHT:
2459 if(ABS(p_top - top )< (font_height+3))
2460 drawit = FALSE;
2461 break;
2462 default:
2463 break;
2464 }
2465 }
2466
2467 if(drawit && marks->next == NULL)
2468 {
2469 t_width = (first_width + width)/2;
2470 if(label_align != first_align)
2471 {
2472 if(first_top != -1)
2473 if(ABS(first_top - top )< (font_height+3))
2474 if(ABS(first_left - left) < (t_width +3))
2475 drawit = FALSE;
2476 }
2477 else
2478 {
2479 switch(label_align)
2480 {
2481 case LOWER_CENTER :
2482 case UPPER_CENTER :
2483 if(ABS(first_left - left) < (t_width +3))
2484 drawit = FALSE;
2485 break;
2486 case MIDDLE_LEFT :
2487 case MIDDLE_RIGHT:
2488 if(ABS(first_top - top )< (font_height+3))
2489 drawit = FALSE;
2490 break;
2491 default:
2492 break;
2493 }
2494 }
2495 }
2496 }
2497 if(drawit)
2498 {
2499 p_top = top;
2500 p_left = left;
2501 p_width = width;
2502 AddLine(seg, left, top, right, bottom, 0, FALSE);
2503 AddTextLabel(seg, left, top, mmp->label, font, 0, label_align, 0);
2504 p_align = label_align;
2505 if(!has_prev)
2506 {
2507 first_top = top;
2508 first_left = left;
2509 first_width = width;
2510 first_align = label_align;
2511 }
2512 has_prev = TRUE;
2513 }
2514 marks = marks->next;
2515 }
2516
2517 return TRUE;
2518 }
2519
2520
2521
2522 static Boolean Draw_Global_Circle(GlobalBspPtr gbp, SegmenT seg, PoinT center)
2523 {
2524 BioseqPtr bsp;
2525 Boolean show_map_unit;
2526 Int2 radius;
2527
2528 NumberingPtr np = NULL;
2529 Int4 length;
2530 Int4 start_angle, stop_angle;
2531
2532 SeqLocPtr slp;
2533 Int4 m_start, m_stop;
2534 Boolean is_gap;
2535 Int2 i;
2536 Uint1Ptr color;
2537 SeqIdPtr maybe_mapid; /*a possible id for map*/
2538 Int4 center_x, center_y;
2539
2540
2541
2542 if(gbp == NULL || gbp->bsp == NULL || gbp->hide)
2543 return FALSE;
2544 bsp = gbp->bsp;
2545 show_map_unit = gbp->show_map_unit;
2546 radius = gbp->radius;
2547 length = bsp->length;
2548 add_attribute_pen(seg, MSM_SEQUENCE, MSM_SEGMENT);
2549
2550 center_x = (Int4)(center.x);
2551 center_y = -(Int4)(center.y);
2552 if(bsp->repr != Seq_repr_seg) /*not a segmented entry*/
2553 AddOval(seg, center_x, center_y, radius, radius, FALSE, 0);
2554 else /*draw the segmented sequence*/
2555 {
2556 slp = bsp->seq_ext;
2557 maybe_mapid = figure_map_seqid(slp);
2558 m_start = 0;
2559 m_stop = -1;
2560 i = 0;
2561 while(slp)
2562 {
2563 ++i;
2564 m_stop += SeqLocLen(slp);
2565 is_gap = is_map_segment(slp);
2566 if(!is_gap && maybe_mapid != NULL)
2567 is_gap = (SeqIdMatch(maybe_mapid, SeqLocId(slp)));
2568 if(!is_gap)
2569 {
2570 start_angle = cal_angle_with_mm_degree(m_stop, length);
2571 stop_angle = cal_angle_with_mm_degree(m_start, length);
2572 if(start_angle == stop_angle)
2573 {
2574 if(slp == bsp->seq_ext)
2575 {
2576 start_angle = 0;
2577 stop_angle = 360000;
2578 }
2579 }
2580 color = get_seg_color(i);
2581 AddAttribute (seg, COLOR_ATT, color, 0, 0, 0, 0);
2582 AddArc(seg, center_x, center_y, radius, radius, start_angle, stop_angle, FALSE, i);
2583 }
2584 m_start = m_stop +1;
2585 slp = slp->next;
2586 }
2587 }
2588
2589 if(show_map_unit)
2590 {
2591 np = getBioseqNumbering(bsp);
2592 draw_circle_seqmark(seg, length, center, radius, np);
2593 }
2594
2595 if(gbp->l_marks != NULL)
2596 {
2597 AddAttribute (seg, COLOR_ATT, BLACK_COLOR, 0, 0, 0, 0);
2598 label_circle_mark(seg, length, gbp->l_marks, center, radius, TRUE);
2599 }
2600 if(gbp->g_marks != NULL)
2601 {
2602 AddAttribute (seg, COLOR_ATT, RED_COLOR, 0, 0, 0, 0);
2603 label_circle_mark(seg, length, gbp->g_marks, center, radius, FALSE);
2604 }
2605
2606 return TRUE;
2607 }
2608
2609
2610
2611 static void AddGeneEquivAlign(GeneDataPtr gdp, ValNodePtr gbsp_list, Boolean is_circle, PoinT center, SegmenT seg, Uint1 type)
2612 {
2613 StdSegPtr ssp;
2614 SeqLocPtr locs;
2615 SeqIdPtr sip;
2616 ValNodePtr curr;
2617 GlobalBspPtr gbsp;
2618 Int2 j;
2619 FloatHi angle;
2620 Int4 start, stop;
2621 Int4 length;
2622 Int4 left, right, top, bottom;
2623 PoinT pt;
2624 AlignPos ap;
2625
2626
2627 while(gdp)
2628 {
2629 if(gdp->align_seg != NULL && gdp->align_seg->choice == type)
2630 {
2631 ssp = (StdSegPtr)(gdp->align_seg->data.ptrvalue);
2632 j =0;
2633 for(locs = ssp->loc; locs != NULL; locs = locs->next)
2634 {
2635 sip = SeqLocId(locs);
2636 start = SeqLocStart(locs);
2637 stop = SeqLocStop(locs);
2638 for(curr = gbsp_list; curr != NULL; curr = curr->next)
2639 {
2640 gbsp = curr->data.ptrvalue;
2641 if(BioseqMatch(gbsp->bsp, sip))
2642 {
2643 length = gbsp->bsp->length;
2644 if(is_circle)
2645 {
2646 angle = cal_angle_on_circle(start, length);
2647 find_point_on_circle(angle, center, gbsp->radius, &pt);
2648 ap.left[j] = (Int4)(pt.x);
2649 ap.top[j] = 0 - (Int4)(pt.y);
2650
2651 angle = cal_angle_on_circle(stop, length);
2652 find_point_on_circle(angle, center, gbsp->radius, &pt);
2653 ap.right[j] = (Int4)(pt.x);
2654 ap.bottom[j] = 0- (Int4)(pt.y);
2655 }
2656 else
2657 {
2658 left = (Int4)(gbsp->rec.left);
2659 right = (Int4)(gbsp->rec.right);
2660 top = - (Int4)(gbsp->rec.top);
2661 bottom = - (Int4)(gbsp->rec.bottom);
2662 ap.left[j] = map_linear_xpos (start, length, left, right);
2663 ap.top[j] = top;
2664 ap.right[j] = map_linear_xpos (stop, length, left, right);
2665 ap.bottom[j] = bottom;
2666 }
2667 ++j;
2668 break;
2669 }
2670 }
2671 }
2672 if(j >1)
2673 {
2674 SortAlignPosition(&ap, j);
2675 draw_one_align(ap, j, 0, seg);
2676 }
2677 }
2678 gdp = gdp->next;
2679 }
2680 }
2681
2682 static GlobalBspPtr find_global_bsp(GlobalDrawPtr gdraw_p, SeqIdPtr sip)
2683 {
2684 ValNodePtr curr;
2685 GlobalBspPtr gbp;
2686
2687 for(curr = gdraw_p->gbp_list; curr != NULL; curr = curr->next)
2688 {
2689 gbp = curr->data.ptrvalue;
2690 if(gbp && gbp->bsp != NULL)
2691 {
2692 if(BioseqMatch(gbp->bsp, sip))
2693 return gbp;
2694 }
2695 }
2696 return NULL;
2697 }
2698
2699
2700 /*******************************************************************
2701 *
2702 * map the selected regions into Points that will be used
2703 * for drawing the Polygons
2704 *
2705 *******************************************************************/
2706 static PntPtr map_selected_points(ValNodePtr slp_list, GlobalDrawPtr gdraw_p, Int2Ptr num)
2707 {
2708 PntPtr points;
2709 Int2 n;
2710 SeqLocPtr slp;
2711 PntPtr pnt;
2712 GlobalBspPtr gbp;
2713
2714 if(gdraw_p->is_circle)
2715 return NULL;
2716
2717 n = get_vnp_num(slp_list);
2718 if(n == 0)
2719 return NULL;
2720 ++n; /*for the last point*/
2721 points = MemNew((size_t)2*n * sizeof(PntInfo));
2722
2723 n = 0;
2724 while(slp_list)
2725 {
2726 slp = slp_list->data.ptrvalue;
2727 gbp = find_global_bsp(gdraw_p, SeqLocId(slp));
2728 if(gbp != NULL)
2729 {
2730 if(gdraw_p->is_circle == FALSE)
2731 {
2732 pnt = &(points[n]);
2733 pnt->x = map_linear_xpos(SeqLocStart(slp),
2734 gbp->bsp->length, gbp->rec.left, gbp->rec.right);
2735 pnt->y = -(Int4)(gbp->rec.top);
2736 ++n;
2737
2738 pnt = &(points[n]);
2739 pnt->x = map_linear_xpos(SeqLocStop(slp),
2740 gbp->bsp->length, gbp->rec.left, gbp->rec.right);
2741 pnt->y = -(Int4)(gbp->rec.top);
2742 ++n;
2743
2744 if(slp_list->next == NULL) /*add the last one*/
2745 {
2746 /*the last point*/
2747 pnt = &(points[n]);
2748 pnt->x = points[n-2].x;
2749 pnt->y = -(Int4)(gbp->rec.bottom);
2750
2751 ++n;
2752 pnt = &(points[n]);
2753 pnt->x = points[n-2].x;
2754 pnt->y = -(Int4)(gbp->rec.bottom);
2755 ++n;
2756 }
2757 }
2758 }
2759
2760 slp_list = slp_list->next;
2761 }
2762
2763 *num = n;
2764 return points;
2765 }
2766
2767 /************************************************************************
2768 *
2769 * Draw_Global(gdraw_p)
2770 * return a picture created from GlobalDrawPtr
2771 *
2772 ************************************************************************/
2773 SegmenT Draw_Global(GlobalDrawPtr gdraw_p)
2774 {
2775 SegmenT pic;
2776 Boolean is_circle;
2777 GlobalBspPtr g_bsp;
2778 ValNodePtr gbp_list;
2779 PntPtr points;
2780 PntInfo pi[4];
2781 Int2 num, i;
2782
2783 if(gdraw_p == NULL)
2784 {
2785 Message(MSG_ERROR, "No Input Data");
2786 return NULL;
2787 }
2788
2789 pic = CreatePicture();
2790
2791
2792
2793 /*draw the high-light of the selected region*/
2794 is_circle = gdraw_p->is_circle;
2795 if(gdraw_p->slp_list != NULL && !is_circle)
2796 {
2797 points = map_selected_points(gdraw_p->slp_list, gdraw_p, &num);
2798 if(points && num >= 4)
2799 {
2800 /* AddAttribute(pic, COLOR_ATT|STYLE_ATT|WIDTH_ATT, YELLOW_COLOR, DASHED_LINE, 0, 4, 0); */
2801 AddAttribute(pic, COLOR_ATT, YELLOW_COLOR, 0, 0, 0, 0);
2802 /* for(i = 0; i<(num/2-1); ++i)
2803 {
2804 pnt_1 = &(points[2*i]);
2805 pnt_2 = &(points[2*(i+1)]);
2806 AddLine(pic, pnt_1->x, pnt_1->y, pnt_2->x, pnt_2->y, FALSE, 0);
2807 pnt_1 = &(points[2*i+1]);
2808 pnt_2 = &(points[2*(i+1)+1]);
2809 AddLine(pic, pnt_1->x, pnt_1->y, pnt_2->x, pnt_2->y, FALSE, 0);
2810 } */
2811 for(i = 0; i<(num/2-1); ++i)
2812 {
2813 MemCopy(&(pi[0]), points+2*i, sizeof(PntInfo));
2814 MemCopy(&(pi[1]), points+2*i+1, sizeof(PntInfo));
2815 MemCopy(&(pi[2]), points+2*i+3, sizeof(PntInfo));
2816 MemCopy(&(pi[3]), points+2*i+2, sizeof(PntInfo));
2817 AddPolygon(pic, 4, (PntPtr)pi, TRUE, 0);
2818 }
2819 }
2820 if(points)
2821 MemFree(points);
2822 }
2823
2824 /*draw the green lines first*/
2825 add_attribute_pen(pic, MSM_ALIGNMENT, MSM_ALINE);
2826 AddAttribute(pic, STYLE_ATT, 0, SOLID_LINE, 0, 0, 0);
2827 AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 1);
2828 AddAttribute(pic, COLOR_ATT|STYLE_ATT, RED_COLOR, DOTTED_LINE, 0, 0, 0);
2829 AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 2);
2830
2831 AddAttribute(pic, COLOR_ATT|STYLE_ATT, BLACK_COLOR, SOLID_LINE, 0, 0, 0);
2832 AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic, 4);
2833
2834 for(gbp_list = gdraw_p->gbp_list; gbp_list != NULL; gbp_list = gbp_list->next)
2835 {
2836 g_bsp = gbp_list->data.ptrvalue;
2837 if(is_circle)
2838 Draw_Global_Circle(g_bsp, pic, gdraw_p->center);
2839 else
2840 Draw_Global_Linear(g_bsp, pic, gdraw_p->draw_align_legend);
2841 }
2842
2843 /* add_attribute_pen(pic, MSM_ALIGNMENT, MSM_ALINE);
2844 AddGeneEquivAlign(gdraw_p->g_data, gdraw_p->gbp_list, is_circle, gdraw_p->center, pic);*/
2845
2846 return pic;
2847
2848
2849
2850 }
2851
2852
2853 SegmenT MuskGlobalPicture(ValNodePtr msp_list, ValNodePtr ext_align, Boolean need_free, Int2 panel_width, Int2 panel_height, ValNodePtr user_list, GlobalDrawPtr PNTR vwr_extra, Uint1 equiv_align_option, Boolean draw_align_legend)
2854 {
2855 GlobalDrawPtr gdraw_p;
2856 SegmenT pic;
2857
2858 gdraw_p = CreateGlobalDrawData (msp_list, ext_align, user_list, need_free, TRUE, equiv_align_option);
2859 if(gdraw_p == NULL)
2860 return NULL;
2861
2862 gdraw_p->draw_align_legend = draw_align_legend;
2863 if(!LayoutGlobalDrawData (gdraw_p, panel_width, panel_height))
2864 return NULL;
2865 pic = Draw_Global (gdraw_p);
2866
2867 if(vwr_extra != NULL)
2868 *vwr_extra = gdraw_p;
2869 else
2870 {
2871 gdraw_p->free_data = FALSE;
2872 free_global_draw (gdraw_p);
2873 }
2874
2875 return pic;
2876 }
2877
2878
2879 SegmenT SequinGlobalPicture (SeqEntryPtr sep, Int2 panel_width, Int2 panel_height, ValNodePtr user_list, GlobalDrawPtr PNTR vwr_extra, Boolean draw_align_legend)
2880 {
2881 MuskSepPtr msp;
2882 ValNodePtr msp_list = NULL;
2883 SegmenT pic;
2884
2885 msp = MemNew(sizeof(MuskSep));
2886 msp->sep = sep;
2887 msp->is_bin = TRUE;
2888 StringCpy(msp->file_name, "local.asn");
2889 ValNodeAddPointer(&msp_list, 0, (Pointer)msp);
2890
2891 pic = MuskGlobalPicture(msp_list, NULL, FALSE, panel_width, panel_height, user_list, vwr_extra, 0, draw_align_legend);
2892
2893 if(pic == NULL)
2894 ValNodeFreeData(msp_list);
2895
2896 return pic;
2897 }
2898
2899
2900 SegmenT GlobalPictureUpdate(GlobalDrawPtr gdraw_p, ValNodePtr new_gene_list, Int2 panel_width, Int2 panel_height)
2901 {
2902 GeneDataPtr g_data;
2903 GlobalBspPtr gbp;
2904 ValNodePtr curr;
2905
2906 if(gdraw_p == NULL)
2907 return NULL;
2908
2909 if(gdraw_p->gbp_list != NULL && gdraw_p->msp_list != NULL)
2910 {
2911 curr = gdraw_p->gbp_list;
2912 g_data = create_gene_data (gdraw_p->msp_list, new_gene_list);
2913
2914 if(g_data != NULL)
2915 {
2916 while(curr)
2917 {
2918 gbp = (GlobalBspPtr)(curr->data.ptrvalue);
2919 gbp->g_marks = ValNodeFreeData(gbp->g_marks);
2920 add_genedata_to_GlobalBsp(gbp, g_data);
2921 curr = curr->next;
2922 }
2923 GeneDataFree(g_data);
2924 } else {
2925 while(curr)
2926 {
2927 gbp = (GlobalBspPtr)(curr->data.ptrvalue);
2928 gbp->g_marks = ValNodeFreeData(gbp->g_marks);
2929 curr = curr->next;
2930 }
2931 }
2932 gdraw_p->g_list = new_gene_list;
2933 if(!LayoutGlobalDrawData (gdraw_p, panel_width, panel_height))
2934 return NULL;
2935 return Draw_Global (gdraw_p);
2936 }
2937
2938 return NULL;
2939
2940 }
2941
2942
2943 /**********************************************************************
2944 *
2945 *
2946 * Boolean find_map_pos(m_start, m_stop, start, stop, bsp_data, center)
2947 * map the two points start, stop selected by rubber-band to an interval
2948 * on the sequence (m_start, m_stop). If selected region contains the
2949 * zero point across a circular molecule, *m_start > *m_stop
2950 * bsp_data provide the mapping info. center is the center of a
2951 * circle.
2952 * return TRUE for success, FALSE for fail.
2953 *
2954 ************************************************************************/
2955 static Boolean check_linear_pnt(PoinT start, PoinT stop, RecT rec)
2956 {
2957 /*Int2 y_max, y_min;
2958
2959 y_max = MAX(start.y, stop.y);
2960 y_min = MIN(start.y, stop.y);
2961
2962 if(y_min > rec.top || y_max < rec.bottom)
2963 return FALSE;
2964 else
2965 return TRUE;*/
2966 if((start.x >= rec.right) && (stop.x >= rec.right))
2967 return FALSE;
2968 if((start.x <= rec.left) && (stop.x <= rec.left))
2969 return FALSE;
2970 return TRUE;
2971 }
2972
2973 static Int4 convert_pnt_linear(PoinT pnt, RecT rec, Int4 seq_len)
2974 {
2975 Int2 x;
2976 Int2 start, stop, length;
2977 FloatHi temp;
2978
2979 start = rec.left;
2980 stop = rec.right;
2981 length = stop - start;
2982 x = pnt.x;
2983 if(pnt.x < start)
2984 x = start;
2985 if(pnt.x > stop)
2986 x = stop;
2987 temp = (FloatHi)(x - start)/(FloatHi)length * (FloatHi)seq_len;
2988 return (Int4)temp;
2989 }
2990
2991
2992 static Int4 circle_pnt_to_map(FloatHi x_pos, FloatHi y_pos, Int2 radius, Int4 seq_len, PoinT center)
2993 {
2994
2995 FloatHi angle;
2996 FloatHi temp;
2997 FloatHi center_x, center_y;
2998 Boolean x_minus, y_minus;
2999
3000 center_x = (FloatHi)(center.x);
3001 center_y = (FloatHi)(center.y);
3002 x_minus = ((x_pos - center_x) < 0.0);
3003 y_minus = ((y_pos - center_y) < 0.0);
3004 temp = (x_pos - center_x)/(FloatHi)radius;
3005 if(x_minus)
3006 temp = 0.0 - temp;
3007 angle = asin(temp);
3008 if(x_minus && y_minus)
3009 angle = 2.0 * PI - angle;
3010 if(x_minus && !y_minus)
3011 angle = PI + angle;
3012 if(!x_minus && !y_minus)
3013 angle = PI - angle;
3014 temp = (FloatHi)seq_len * angle/((FloatHi)2.0 * PI);
3015 return (Int4)temp;
3016 }
3017
3018
3019 static Boolean get_cross_point(Int2 pos, Int2 border_1, Int2 border_2, Int4Ptr val_1, Int4Ptr val_2, Boolean is_x, Int2Ptr num_cross, Int2 radius, PoinT center, Int4 seq_len)
3020 {
3021 FloatHi val;
3022 FloatHi cross_offset;
3023 FloatHi x_pos, y_pos;
3024 FloatHi cross_val[2], cur_pos;
3025 FloatHi temp;
3026 Int2 i;
3027 Int4 map_pos;
3028
3029
3030 if(*num_cross == 2)
3031 return TRUE;
3032
3033 if(is_x)
3034 {
3035 if(pos < (center.x - radius) || pos > (center.x + radius))
3036 return FALSE;
3037 val = (FloatHi)(pos - center.x);
3038 }
3039 else
3040 {
3041 if(pos < (center.y - radius) || pos > (center.y + radius))
3042 return FALSE;
3043 val = (FloatHi)(pos - center.y);
3044 }
3045 temp = (FloatHi)radius * radius;
3046 cross_offset = sqrt(temp - val*val);
3047 if(cross_offset == 0.0)
3048 Message(MSG_OK, "radius is %d, val is %lf", radius, val);
3049 if(is_x)
3050 {
3051 cross_val[0] = (FloatHi)center.y + cross_offset;
3052 cross_val[1] = (FloatHi)center.y - cross_offset;
3053 }
3054 else
3055 {
3056 cross_val[0] = (FloatHi)center.x + cross_offset;
3057 cross_val[1] = (FloatHi)center.x - cross_offset;
3058 }
3059
3060
3061
3062
3063 for(i = 0; i<2 && (*num_cross <2); ++i)
3064 {
3065 cur_pos = cross_val[i];
3066 if(cur_pos >= (FloatHi)border_1 && cur_pos <= (FloatHi)border_2)
3067 {
3068 x_pos = is_x ? (FloatHi)pos : cur_pos;
3069 y_pos = is_x ? cur_pos : (FloatHi)pos;
3070 map_pos = circle_pnt_to_map(x_pos, y_pos, radius, seq_len, center);
3071 if(*num_cross == 0)
3072 {
3073 *val_1 = map_pos;
3074 ++ (*num_cross);
3075 }
3076 else
3077 {
3078 if(map_pos != *val_1)
3079 {
3080 *val_2 = map_pos;
3081 ++ (*num_cross);
3082 }
3083 }
3084 }
3085 }
3086
3087 return TRUE;
3088
3089 }
3090
3091
3092 static Boolean get_point_on_circle(PoinT start, PoinT stop, Int4Ptr val_1, Int4Ptr val_2, Int2 radius, PoinT center, Int4 seq_len)
3093 {
3094 Int2 num =0;
3095 Int2 x_start, x_stop, y_start, y_stop;
3096
3097 x_start = MIN(start.x, stop.x);
3098 x_stop = MAX(start.x, stop.x);
3099 y_start = MIN(start.y, stop.y);
3100 y_stop = MAX(start.y, stop.y);
3101
3102 get_cross_point(x_start, y_start, y_stop, val_1, val_2, TRUE, &num, radius, center, seq_len);
3103 get_cross_point(x_stop, y_start, y_stop, val_1, val_2, TRUE, &num, radius, center, seq_len);
3104 get_cross_point(y_start, x_start, x_stop, val_1, val_2, FALSE, &num, radius, center, seq_len);
3105 get_cross_point(y_stop, x_start, x_stop, val_1, val_2, FALSE, &num, radius, center, seq_len);
3106
3107
3108 return (num ==2); /*if two points on the circle are found or not*/
3109
3110 }
3111
3112
3113 static Int4 get_min_size(Int4 seq_len)
3114 {
3115 if(seq_len <= 350000)
3116 return seq_len;
3117
3118 return MAX(350000, seq_len/8);
3119 }
3120
3121 static SeqLocPtr load_seq_loc(Int4 val_1, Int4 val_2, Int4 seq_len, Boolean has_zero, SeqIdPtr sip, BoolPtr show_msg, Boolean add_interval)
3122 {
3123 Int4 m_start, m_stop;
3124 Uint1 m_strand = Seq_strand_plus;
3125 SeqLocPtr slp = NULL, loc;
3126 Int4 min_len;
3127 Int4 temp;
3128 Int4 len;
3129
3130 min_len = get_min_size(seq_len);
3131
3132
3133 if(has_zero)
3134 {
3135 if(val_1 < val_2)
3136 {
3137 temp = val_2;
3138 val_2 = val_1;
3139 val_1 = temp;
3140 }
3141 if(add_interval)
3142 {
3143 val_1 -= seq_len/20;
3144 val_2 += seq_len/20;
3145 }
3146 len = (seq_len - 1 - val_1 +1 + val_2 +1);
3147 if(len > min_len)
3148 {
3149 if(*show_msg)
3150 Message(MSG_OK, "The selected region is too large. Reduced to %ld base pairs", min_len);
3151 val_1 = seq_len - 1 - min_len/2;
3152 val_2= min_len/2 -1;
3153 }
3154 m_start = val_1;
3155 m_stop = seq_len -1;
3156 loc = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3157 m_start = 0;
3158 m_stop = val_2;
3159 loc->next = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3160 slp = loc;
3161 }
3162 else
3163 {
3164 m_start = MIN(val_1, val_2);
3165 m_start = MAX(0, m_start);
3166
3167 m_stop = MAX(val_1, val_2);
3168 m_stop = MIN(seq_len-1, m_stop);
3169 len = m_stop - m_start + 1;
3170 if(add_interval)
3171 {
3172 len += seq_len/10;
3173 m_start = MAX(0, (m_start - seq_len/20));
3174 m_stop = m_start + len -1;
3175 }
3176
3177 /* if(len > min_len)
3178 {
3179 if(*show_msg)
3180 Message(MSG_OK, "The selected region is too large. Reduced to %ld base pairs", min_len);
3181 center = (m_start + m_stop)/2;
3182 m_start = center - min_len/2;
3183 m_stop = m_start + min_len -1;
3184 } */
3185 slp = SeqLocIntNew(m_start, m_stop, m_strand, sip);
3186 }
3187 *show_msg = FALSE;
3188 return slp;
3189 }
3190
3191 static Boolean select_whole_circle(PoinT start, PoinT stop, PoinT center, Int2 r)
3192 {
3193 if(start.x < (center.x -r) && start.y < (center.y -r))
3194 {
3195 if(stop.x > (center.x +r) && stop.y >(center.y+r))
3196 return TRUE;
3197 }
3198
3199 if(stop.x < (center.x -r) && stop.y < (center.y -r))
3200 {
3201 if(start.x > (center.x +r) && start.y >(center.y+r))
3202 return TRUE;
3203 }
3204
3205 return FALSE;
3206 }
3207
3208
3209 static Boolean check_two_point(PoinT start, PoinT stop)
3210 {
3211 if(ABS(start.x - stop.x) < 3 && ABS(start.y - stop.y) < 3)
3212 return TRUE;
3213 else
3214 return FALSE;
3215 }
3216
3217 static ValNodePtr find_circle_pos(PoinT start, PoinT stop, ValNodePtr gbp_list, PoinT center)
3218 {
3219
3220 RecT or;
3221 PoinT zero_pnt;
3222 Int4 val_1, val_2;
3223 FloatHi percent_1, percent_2;
3224 FloatHi temp;
3225
3226 ValNodePtr curr;
3227 GlobalBspPtr gbp;
3228 BioseqPtr bsp;
3229 Int4 seq_len;
3230 Boolean is_found = FALSE;
3231 Boolean has_zero = FALSE;
3232 SeqLocPtr slp;
3233 ValNodePtr slp_list = NULL;
3234 Boolean show_msg = TRUE;
3235 Boolean add_interval;
3236
3237
3238 add_interval = check_two_point(start, stop);
3239 for(curr = gbp_list; curr !=NULL && !is_found; curr = curr->next)
3240 {
3241 gbp = curr->data.ptrvalue;
3242 bsp = gbp->bsp;
3243 seq_len = bsp->length;
3244 if(select_whole_circle(start, stop, center, gbp->radius))
3245 {
3246 is_found = TRUE;
3247 val_1 =0;
3248 val_2 = seq_len -1;
3249 }
3250 else
3251 {
3252 zero_pnt.x = center.x;
3253 zero_pnt.y = center.y - gbp->radius;
3254 LoadRect (&or, start.x, start.y, stop.x, stop.y);
3255 has_zero = PtInRect(zero_pnt, &or);
3256 is_found = get_point_on_circle(start, stop, &val_1, &val_2, gbp->radius, center, seq_len);
3257 }
3258 }
3259
3260
3261 if(is_found)
3262 {
3263 percent_1 = (FloatHi)(val_1)/(FloatHi)(seq_len);
3264 percent_2 = (FloatHi)(val_2)/(FloatHi)(seq_len);
3265
3266 for(curr = gbp_list; curr !=NULL; curr = curr->next)
3267 {
3268 gbp = curr->data.ptrvalue;
3269 bsp = gbp->bsp;
3270 seq_len = bsp->length;
3271 temp = percent_1 * (FloatHi)seq_len;
3272 val_1 = (Int4)temp;
3273 temp = percent_2 * (FloatHi)seq_len;
3274 val_2 = (Int4)temp;
3275
3276 slp = load_seq_loc(val_1, val_2, seq_len, has_zero, bsp->id, &show_msg, add_interval);
3277 if(slp != NULL)
3278 ValNodeAddPointer((Pointer)(&slp_list), 0, slp);
3279 }
3280 }
3281 return slp_list;
3282 }
3283
3284
3285 /*********************************************************************
3286 *
3287 *
3288 * find_map_pos(convert the start_pnt, stop_pnt into a list of
3289 * Seq-locs)
3290 *
3291 *********************************************************************/
3292 ValNodePtr find_map_pos(GlobalDrawPtr gdraw_p, PntInfo start_info, PntInfo stop_info)
3293 {
3294
3295 Int4 val_1, val_2;
3296 ValNodePtr gbp_list;
3297 PoinT center;
3298 ValNodePtr curr;
3299 GlobalBspPtr gbp;
3300 BioseqPtr bsp;
3301 Int4 seq_len;
3302 SeqLocPtr slp;
3303 ValNodePtr slp_list = NULL;
3304 Boolean show_msg = TRUE;
3305 Boolean add_interval;
3306 PoinT start_pnt, stop_pnt;
3307
3308
3309 if(gdraw_p == NULL)
3310 return NULL;
3311 start_pnt.x = (Int2)(start_info.x);
3312 start_pnt.y = (Int2)(start_info.y);
3313 stop_pnt.x = (Int2)(stop_info.x);
3314 stop_pnt.y = (Int2)(stop_info.y);
3315 start_pnt.y = ABS(start_pnt.y);
3316 stop_pnt.y = ABS(stop_pnt.y);
3317
3318 gbp_list = gdraw_p->gbp_list;
3319 center = gdraw_p->center;
3320 if(gdraw_p->is_circle)
3321 return find_circle_pos(start_pnt, stop_pnt, gbp_list, center);
3322
3323 add_interval = check_two_point(start_pnt, stop_pnt);
3324 for(curr = gbp_list; curr !=NULL; curr = curr->next)
3325 {
3326 gbp = curr->data.ptrvalue;
3327 bsp = gbp->bsp;
3328 seq_len = bsp->length;
3329 if(check_linear_pnt(start_pnt, stop_pnt, gbp->rec))
3330 {
3331 val_1 = convert_pnt_linear(start_pnt, gbp->rec, seq_len);
3332 val_2 = convert_pnt_linear(stop_pnt, gbp->rec, seq_len);
3333 slp = load_seq_loc(val_1, val_2, seq_len, FALSE, SeqIdFindBest(bsp->id, 0), &show_msg, add_interval);
3334 if(slp != NULL)
3335 ValNodeAddPointer((Pointer)&slp_list, (Uint1)(gbp->priority), slp);
3336 }
3337 }
3338 return slp_list;
3339 }
3340
3341 /*
3342 *
3343 * if there is a Bioseq in the list that records the cytogenetic
3344 * band, return the Bioseq
3345 *
3346 */
3347 BioseqPtr has_cyto_map (GlobalDrawPtr gdraw_p)
3348 {
3349 ValNodePtr curr;
3350 GlobalBspPtr gbp;
3351
3352 for(curr = gdraw_p->gbp_list; curr != NULL; curr = curr->next)
3353 {
3354 gbp = curr->data.ptrvalue;
3355 if(gbp->bsp != NULL && gbp->map_type == CYTO_MAP)
3356 return gbp->bsp;
3357 }
3358 return NULL;
3359 }
3360
3361
3362
3363 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |