1 
2 /*   jzmisc.c
3 *
4 * File Name:  jzmisc.c
5 *
6 * Author: Jinghui Zhang
7 *
8 * Version Creation Date:   2/10/93
9 *
10 * File Description:
11 *
12 * Modifications:
13 * --------------------------------------------------------------------------
14 * Date     Name        Description of modification
15 * -------  ----------  -----------------------------------------------------
16 * 11/2/93		A suite of general functions used in pup and
17 *			chromoscope
18 *
19 * ==========================================================================
20 */
21 
22 
23 #include <jzmisc.h>
24 #include <edutil.h>
25 #include <gather.h>
26 /*************************************************************************
27 ***
28 *	gb_id_make(): make the Seq-id for Genbank with tsip->name = name
29 *	tsip->acc.
30 *
31 *************************************************************************
32 ***/
gb_id_make(CharPtr name,CharPtr acc)33 NLM_EXTERN SeqIdPtr gb_id_make(CharPtr name, CharPtr acc)
34 {
35    SeqIdPtr new_id;
36    TextSeqIdPtr tsip;
37 
38 	   new_id= (SeqIdPtr)ValNodeNew(NULL);
39 	   new_id->choice = SEQID_GENBANK;
40 	   tsip = TextSeqIdNew();
41 	   if(name)
42 	   {
43 	   if(StringLen(name) >3 && IS_ALPHA(name[0]))
44 	     tsip->name = StringSave(name);
45 	   }
46 	   if(acc)
47 	   {
48 	   if(StringLen(acc) >3 && IS_ALPHA(acc[0]))
49 	     tsip->accession = StringSave(acc);
50 	   }
51 	   new_id->data.ptrvalue = tsip;
52 	   return new_id;
53 }
54 
55 
56 
57 
58 /**************************************************************************
59 ***
60 *	bb_sort(): bubble sort to the accending order of starts
61 *
62 ***************************************************************************
63 ***/
bb_sort(Int4Ptr start,Int2 num)64 NLM_EXTERN void bb_sort(Int4Ptr start, Int2 num)
65 {
66     Int4 hold;
67     Int2 j, pass;
68     Boolean swithed = TRUE;
69 
70 	for(pass = 0; pass < num-1 && swithed == TRUE; ++pass){
71 	   swithed = FALSE;
72 	   for(j=0; j<num - pass -1; ++j){
73 	     if(start[j] > start[j+1]){
74 		swithed = TRUE;
75 		hold = start[j];
76 		start[j] = start[j+1];
77 		start[j+1] = hold;
78 	      }/**end of if**/
79 	    }
80 	}
81 }
82 
83 
get_synonym(ValNodePtr head,CharPtr syn)84 NLM_EXTERN Boolean get_synonym(ValNodePtr head, CharPtr syn)
85 {
86 
87 	if(head == NULL)
88 	  return FALSE;
89 
90 	StringCpy(syn, head->data.ptrvalue);
91 	head = head->next;
92 
93 	while(head){
94 	   StringCat(syn, "  ");
95 	   StringCat(syn, head->data.ptrvalue);
96 	   head = head->next;
97 	}
98 
99 	return TRUE;
100 
101 }
102 
103 /******************************************************************
104 ***
105 *	general_id_make(): make SeqIdPtr with SEQID_LOCAL choice
106 *
107 *******************************************************************
108 ***/
general_id_make(CharPtr name,CharPtr dbase)109 NLM_EXTERN SeqIdPtr general_id_make(CharPtr name, CharPtr dbase)
110 {
111    SeqIdPtr new_id;
112    ObjectIdPtr obj_id;
113    DbtagPtr db_tag;
114 
115 
116 	new_id=(SeqIdPtr)ValNodeNew(NULL);
117 	new_id->choice = SEQID_GENERAL;
118 	db_tag = DbtagNew();
119 	db_tag->db = StringSave(dbase);
120 
121 	obj_id = ObjectIdNew();
122 	obj_id->str = StringSave(name);
123 	db_tag->tag = obj_id;
124 
125 	new_id->data.ptrvalue = db_tag;
126 
127 	return new_id;
128 }
129 
130 
131 
find_synonym(SeqFeatPtr sfp,CharPtr syn)132 NLM_EXTERN Boolean find_synonym(SeqFeatPtr sfp, CharPtr syn)
133 {
134    GeneRefPtr grp;
135 
136 	if(sfp->data.choice != 1)
137 	   return FALSE;
138 
139 	grp = sfp->data.value.ptrvalue;
140 	return get_synonym(grp->syn, syn);
141 
142 }
143 
check_syn(ValNodePtr syn,CharPtr symbol)144 NLM_EXTERN Boolean check_syn(ValNodePtr syn, CharPtr symbol)
145 {
146 
147 	if(syn == NULL)
148 	   return FALSE;
149 
150 	while(syn){
151 	  if(StringICmp(syn->data.ptrvalue, symbol)==0)
152 	    return TRUE;
153 	  syn = syn->next;
154 	}
155 
156 	return FALSE;
157 
158 }
159 
160 
161 
find_sip(SeqIdPtr sip)162 NLM_EXTERN SeqIdPtr find_sip(SeqIdPtr sip)
163 {
164   Uint1  order [NUM_SEQID];
165 
166   SeqIdBestRank (order, NUM_SEQID);
167   order [SEQID_LOCAL] = 2;
168   order [SEQID_GENBANK] = 5;
169   order [SEQID_EMBL] = 5;
170   order [SEQID_PIR] = 5;
171   order [SEQID_SWISSPROT] = 5;
172   order [SEQID_DDBJ] = 5;
173   order [SEQID_PRF] = 5;
174   order [SEQID_PDB] = 5;
175   order [SEQID_TPG] = 5;
176   order [SEQID_TPE] = 5;
177   order [SEQID_TPD] = 5;
178   order [SEQID_GPIPE] = 9;
179   order [SEQID_NAMED_ANNOT_TRACK] = 9;
180   order [SEQID_PATENT] = 10;
181   order [SEQID_OTHER] = 1;
182   order [SEQID_GENERAL] = 10;
183   order [SEQID_GIBBSQ] = 15;
184   order [SEQID_GIBBMT] = 15;
185   order [SEQID_GIIM] = 20;
186   order [SEQID_GI] = 20;
187   return SeqIdSelect (sip, order, NUM_SEQID);
188 }
189 
get_seq_name(SeqIdPtr hsip,CharPtr name,CharPtr acc,CharPtr dbase,Boolean check_chain)190 NLM_EXTERN Boolean  get_seq_name(SeqIdPtr hsip, CharPtr name, CharPtr acc, CharPtr dbase, Boolean check_chain)
191 {
192   TextSeqIdPtr tsip;
193   ObjectIdPtr obj_id;
194   DbtagPtr db_tag;
195   GiimPtr giim;
196   SeqIdPtr sip;
197 
198 
199 	if(check_chain)
200 		sip = find_sip(hsip);
201 	else
202 		sip = hsip;
203 	if(sip == NULL)
204 		return FALSE;
205 	switch(sip->choice){
206 	   case 11:
207 	      db_tag = sip->data.ptrvalue;
208 	      obj_id = db_tag->tag;
209 	      StringCpy(acc, obj_id->str);
210 	      StringCpy(name, obj_id->str);
211 	      StringCpy(dbase, db_tag->db);
212 	      return TRUE;
213 	    case 5:
214 	      StringCpy(dbase, "GenBank");
215 	       tsip = sip->data.ptrvalue;
216 	       StringCpy(acc, tsip->accession);
217 	       if(tsip->name == NULL)
218 			StringCpy(name, acc);
219 	       else
220 	       		StringCpy(name, tsip->name);
221 	       return TRUE;
222 	    case 6:
223 	      StringCpy(dbase, "EMBL");
224 	       tsip = sip->data.ptrvalue;
225 	       StringCpy(acc, tsip->accession);
226 	       StringCpy(name, tsip->name);
227 	       return TRUE;
228 	    case 8:
229 	      StringCpy(dbase, "SwissProt");
230 	       tsip = sip->data.ptrvalue;
231 	       StringCpy(acc, tsip->accession);
232 	       StringCpy(name, tsip->name);
233 	       return TRUE;
234 	    case 13:
235 	       StringCpy(dbase, "DDBJ");
236 	       tsip = sip->data.ptrvalue;
237 	       StringCpy(acc, tsip->accession);
238 	       StringCpy(name, tsip->name);
239 	       return TRUE;
240 	    case 4:
241 	       giim = sip->data.ptrvalue;
242 	       if(giim->db)
243 		 StringCpy(dbase, giim->db);
244 	       else
245 		 StringCpy(dbase, "NCBI");
246 	       sprintf(acc, "giim%ld", (long)(giim->id));
247 	       sprintf(name, "giim%ld", (long)(giim->id));
248 	       return TRUE;
249 	    default:
250 	       return FALSE;
251 	  }
252 }
253 
254 
get_sip_comment(SeqIdPtr sip,CharPtr comment)255 NLM_EXTERN Boolean get_sip_comment(SeqIdPtr sip, CharPtr comment)
256 {
257   Char dbase[20], name[20], acc[20];
258 
259 	if(get_seq_name(sip, name, acc, dbase, TRUE)){
260 	   if(sip->choice == SEQID_GENERAL)
261 	  	sprintf(comment, "Dbase %s; Name %s", dbase, acc);
262 	   else
263 		sprintf(comment, "Dbase %s; Name %s; Accession %s", dbase, name, acc);
264 	   return TRUE;
265 	}
266 	else
267 	   return FALSE;
268 }
269 
270 
271 /**make num empty space in the array**/
make_empty(CharPtr empty,Int2 num)272 NLM_EXTERN void make_empty(CharPtr empty, Int2 num)
273 {
274 	Int2 i;
275 
276 	for(i=0; i<(num); ++i)
277 	{
278 	   *empty = ' ';
279 	   ++empty;
280 	}
281 	*empty = '\0';
282 }
283 
284 
is_sequenced(SeqLocPtr slp)285 NLM_EXTERN Boolean is_sequenced(SeqLocPtr slp)
286 {
287 	IntFuzzPtr ifp;
288 	SeqPntPtr spp;
289 
290 	if(slp->choice == SEQLOC_PNT)
291 	{
292 		spp = slp->data.ptrvalue;
293 		ifp = spp->fuzz;
294 		if(ifp)
295 		{
296 			if(ifp->choice ==4 && ifp->a ==0)
297 				return FALSE;
298 		}
299 	}
300 
301 	return TRUE;
302 
303 }
304 
305 
fuzz_loc(Int4 start,Int4 stop,Uint1 strand,SeqIdPtr sip,Boolean is_from,Boolean is_to)306 NLM_EXTERN SeqLocPtr fuzz_loc(Int4 start, Int4 stop, Uint1 strand, SeqIdPtr sip, Boolean is_from, Boolean is_to)
307 {
308    SeqLocPtr new;
309    IntFuzzPtr fuzz;
310    SeqIntPtr sint;
311 
312 	   new = SeqLocIntNew(start, stop, strand, sip);
313 
314 	   sint = (SeqIntPtr)new->data.ptrvalue;
315 	   if(is_from){
316 	   	sint->if_from = IntFuzzNew();
317 	   	fuzz = sint->if_from;
318 	   	fuzz->choice = 4;
319 	   	fuzz->a =2;
320 	   }
321 	   if(is_to){
322 	     	sint->if_to = IntFuzzNew();
323 	     	fuzz = sint->if_to;
324 	     	fuzz->choice =4;
325 	     	fuzz->a =1;
326 	   }
327 	   return new;
328 }
329 
330 
331 
link_loc(SeqLocPtr new,SeqLocPtr head)332 NLM_EXTERN SeqLocPtr link_loc(SeqLocPtr new, SeqLocPtr head)
333 {
334   Int4 start, stop;
335   SeqLocPtr update_seq_loc(Int4, Int4, Uint1, SeqLocPtr );
336 
337 	if(new == NULL)
338 	   return head;
339 	if(head == NULL)
340 	   return new;
341 
342 	while(head->next != NULL)
343 	   head = head->next;
344 	if(SeqIdForSameBioseq(SeqLocId(new), SeqLocId(head))){
345 	   if(SeqLocStop(head) == (SeqLocStart(new) -1)){
346 	       if(SeqLocStrand(new) == SeqLocStrand(head)){
347 		  start = SeqLocStart(head);
348 		  stop = SeqLocStop(new);
349 		  update_seq_loc(start, stop, SeqLocStrand(head), head);
350 		  SeqLocFree(new);
351 		  return head;
352 		}
353 	     }
354 	}
355 
356 	head->next = new;
357 	return new;
358 }
359 
360 
s_witch(Int4Ptr x,Int4Ptr y)361 NLM_EXTERN void s_witch(Int4Ptr x, Int4Ptr y)
362 {
363 	Int4 temp;
364 
365 	temp = *x;
366 	*x = *y;
367 	*y=temp;
368 }
369 
swap(Int4Ptr x,Int4Ptr y)370 NLM_EXTERN void swap(Int4Ptr x, Int4Ptr y)
371 {
372   Int4 temp;
373 
374 	if((*x) > (*y)){
375 	  temp = *x;
376 	  *x = *y;
377 	  *y = temp;
378 	}
379 }
380 
381 
get_r_strand(SeqLocPtr seq_loc,SeqLocPtr f_loc)382 NLM_EXTERN Uint1 get_r_strand(SeqLocPtr seq_loc, SeqLocPtr f_loc)
383 {
384 	if(SeqLocStrand(seq_loc) != Seq_strand_minus)
385 	   return SeqLocStrand(f_loc);
386 	else{
387 	   if(SeqLocStrand(f_loc) == Seq_strand_minus)
388 	      return Seq_strand_plus;
389 	   else
390 	      return Seq_strand_minus;
391 	}
392 
393 }
394 
fit_this_line(Int4 start,Int4 stop,Int4Ptr p_pos,Int2 i,Int4 space)395 static Boolean fit_this_line(Int4 start, Int4 stop, Int4Ptr p_pos, Int2 i, Int4 space)
396 {
397 	if(p_pos[2*i] == 0 && p_pos[2*i+1] == 0)
398 		return TRUE;
399 
400 	if(start > (p_pos[2*i+1] + space))
401 		return TRUE;
402 
403 	if(stop < (p_pos[2*i] - space))
404 		return TRUE;
405 
406 	return FALSE;
407 }
408 
find_f_pos(Int4 start,Int4 stop,Int4Ptr p_pos,Int4 space,Int2 num)409 NLM_EXTERN Int2 find_f_pos(Int4 start, Int4 stop, Int4Ptr p_pos, Int4 space, Int2 num)
410 {
411 
412   	Int2 i =0;
413 
414 	for(i =0; i<num; ++i)
415 	{
416 		if(fit_this_line(start, stop, p_pos, i, space))
417 		{
418 			if(p_pos[2*i] == 0 && p_pos[2*i+1] == 0)
419 			{
420 				p_pos[2*i] = start;
421 				p_pos[2*i+1] = stop;
422 			}
423 			else
424 			{
425 				p_pos[2*i] = MIN(start, p_pos[2*i]);
426 				p_pos[2*i +1] = MAX(stop, p_pos[2*i+1]);
427 			}
428 			return i;
429 		}
430 	}
431 
432 	return -1;
433 }
434 
find_group_pos(Int4Ptr p_pos,Int4 space,Int2 num,Int2 group_size,Int4Ptr group_value)435 NLM_EXTERN Int2 find_group_pos(Int4Ptr p_pos, Int4 space, Int2 num, Int2 group_size, Int4Ptr group_value)
436 {
437 
438   Int2 i =0, j;
439   Boolean found;
440   Int4 start, stop;
441 
442 	if(num < group_size)
443 		return -1;
444 	for(i =0; i<= (num - group_size); ++i)
445 	{
446 	   found = TRUE;
447 	   for(j =0; j<group_size; ++j)
448 	   {
449 		start = group_value[2*j];
450 		stop = group_value[2*j+1];
451 		if(!fit_this_line(start, stop, p_pos, (Int2)(i+j), space))
452 		{
453 			found = FALSE;
454 			break;
455 		}
456 	   }
457 	   if(found)
458 	   {
459 		for(j =0; j<group_size; ++j)
460 		{
461 			start = group_value[2*j];
462 			stop = group_value[2*j+1];
463 			if(p_pos[2* (i+j)] == 0 && p_pos[2*(i+j)+1] == 0)
464 			{
465 				p_pos[2* (i+j)] = start;
466 				p_pos[2*(i+j)+1] = stop;
467 			}
468 			else
469 			{
470 				p_pos[2* (i+j)] = MIN(start, p_pos[2*(i+j)]);
471 				p_pos[2*(i+j)+1] = MAX(stop, p_pos[2*(i+j)+1]);
472 			}
473 		}
474 		return i;
475 	   }
476 	}
477 
478 	Message(MSG_ERROR, "Fail in find_group_pos");
479 	return -1;
480 }
481 
482 
add_name_partial(CharPtr name,Boolean trunc5,Boolean trunc3)483 static void add_name_partial(CharPtr name, Boolean trunc5, Boolean trunc3)
484 {
485    Char temp[100];
486 
487 	if(!trunc5 && !trunc3)
488 	    return;
489 
490 	if(trunc5)
491 	  sprintf(temp, "\'%s", name);
492 	else
493 	  StringCpy(temp, name);
494 
495 	if(trunc3)
496 	   StringCat(temp, "'");
497 
498 	StringCpy(name, temp);
499 	return;
500 
501 }
502 
503 
504 /************************************************************************
505 ***
506 *	get the citation label from a Pub-equiv
507 *
508 ************************************************************************
509 ***/
get_cit_edit(CharPtr fmark,Int2 order,ValNodePtr head)510 static Boolean get_cit_edit(CharPtr fmark, Int2 order, ValNodePtr head)
511 {
512 
513   ValNodePtr vnp, tmp;
514   CitArtPtr cap;
515   CitBookPtr cbp;
516   CitSubPtr csp;
517   CitGenPtr cgp;
518   AuthListPtr alp = NULL;
519 
520 	       vnp = head;
521 	       while(vnp){
522 		 if(vnp->choice == 4){
523 		   sprintf(fmark, "muid %ld", (long)(vnp->data.intvalue));
524 		   return TRUE;
525 		  }
526 		  vnp = vnp->next;
527 	        }
528 		vnp = head;
529 
530 		alp = NULL;
531 		while(vnp){
532 		   if(vnp->choice ==5){
533 		     cap = vnp->data.ptrvalue;
534 		     if(cap)
535 			alp = cap->authors;
536 		   }
537 		   if(vnp->choice == 2){
538 		      csp = vnp->data.ptrvalue;
539 		      if(csp)
540 			 alp = csp->authors;
541 		   }
542 		   if(vnp->choice ==7){
543 		      cbp = vnp->data.ptrvalue;
544 		      if(cbp)
545 			 alp = cbp->authors;
546 		    }
547 		    if(vnp->choice ==1){
548 		       cgp = (CitGenPtr)vnp->data.ptrvalue;
549 		       if(cgp)
550 			  alp = cgp->authors;
551 		    }
552 
553 		    if(alp){
554 			   if(alp->names){
555 			      tmp= alp->names;
556 			      if(tmp->choice ==3){
557 			      sprintf(fmark, "%s", (CharPtr) tmp->data.ptrvalue);
558 			      return TRUE;
559 			      }
560 			   }
561 		     }/*alp*/
562 
563 		   vnp = vnp->next;
564 		}
565 
566 		StringCpy(fmark, "Pub");
567 		return TRUE;
568 }
569 
myStringNCpy(CharPtr target,CharPtr source,Int2 n)570 static void myStringNCpy(CharPtr target, CharPtr source, Int2 n)
571 {
572 	Int2 i;
573 
574 	n = MIN(n, (Int2)StringLen(source));
575 	for(i = 0; i<n; ++i)
576 		target[i] = source[i];
577 	target[i] = '\0';
578 }
579 
label_feature(SeqFeatPtr sfp,CharPtr fmark,Int2 order,Boolean use_locus)580 NLM_EXTERN Uint1 label_feature(SeqFeatPtr sfp, CharPtr fmark, Int2 order, Boolean use_locus)
581 {
582   GeneRefPtr grp;
583   SeqLocPtr slp;
584   SeqIntPtr sint;
585   Boolean trunc5, trunc3;
586   OrgRefPtr org;
587 
588   CdRegionPtr crp;
589   SeqIdPtr sip;
590 
591   ProtRefPtr prp;
592   ValNodePtr vnp, dbase;
593   Char temp[200];
594   RnaRefPtr rrp;
595   ImpFeatPtr ifp;
596   RsiteRefPtr rrf;
597   TxinitPtr tp;
598   PubdescPtr pdp;
599 
600   Char name[100];
601   BioseqPtr bsp;
602   Uint1 val;
603   Boolean is_done, is_end;
604 
605      slp = sfp->location;
606      trunc5 = FALSE;
607      trunc3 = FALSE;
608      if(slp->choice == SEQLOC_INT){
609 	sint = slp->data.ptrvalue;
610 	if(sint->if_from){
611 	   if(SeqLocStrand(slp) == Seq_strand_minus)
612 	     trunc3 = TRUE;
613 	   else
614 	     trunc5 = TRUE;
615 	 }
616 	 if(sint->if_to){
617 	   if(SeqLocStrand(slp) == Seq_strand_minus)
618 	      trunc5 = TRUE;
619 	   else
620 	      trunc3 = TRUE;
621 	  }
622       }
623 
624 	switch(sfp->data.choice){
625 	  case 1:
626 	    grp = sfp->data.value.ptrvalue;
627 	    if(grp && grp->locus)
628 	       myStringNCpy(fmark, grp->locus, 20);
629 	    else
630 	       StringCpy(fmark, "gene");
631 	    add_name_partial(fmark, trunc5, trunc3);
632 	    return TRUE;
633 
634 	  case 2:
635 	    org = sfp->data.value.ptrvalue;
636 	    if(org && org->taxname)
637 	      StringCpy(fmark, org->taxname);
638 	    else{
639 	      if(org && org->common)
640 	         StringCpy(fmark, org->common);
641 	      else
642 	         StringCpy(fmark, "Org");
643 	    }
644 	    add_name_partial(fmark, trunc5, trunc3);
645 	    return TRUE;
646 
647 	  case 3:
648 	    val = 1;
649 	    crp = sfp->data.value.ptrvalue;
650 	    if(crp && sfp->product){
651 	      sip = SeqLocId(sfp->product);
652 	      if((bsp = BioseqFind(sip))!= NULL)
653 		 seqid_name(bsp->id, name, use_locus, TRUE);
654 	       else
655 		 seqid_name(sip, name, use_locus, TRUE);
656 
657 	       if(crp->orf)
658 		  sprintf(fmark, " ORF %s", name);
659 		else
660 		  StringCpy(fmark, name);
661 
662 	    }
663 	    else{
664 		StringCpy(fmark, "CDregion");
665 		val =2;
666 	    }
667 
668 	    add_name_partial(fmark, trunc5, trunc3);
669 	    return val;
670 
671 	   case 4:
672 	     prp = sfp->data.value.ptrvalue;
673 	     vnp = prp->name;
674 	     dbase = prp->db;
675 	     if(vnp && dbase){
676 	       sprintf(temp, "%s %s", (CharPtr) dbase->data.ptrvalue, (CharPtr) vnp->data.ptrvalue);
677 	       myStringNCpy(fmark, temp, 20);
678 	       add_name_partial(fmark, trunc5, trunc3);
679 	       return TRUE;
680 	     }
681 	     if(dbase){
682 	       StringCpy(fmark, dbase->data.ptrvalue);
683 	       add_name_partial(fmark, trunc5, trunc3);
684 	       return TRUE;
685 	     }
686 	     if(vnp){
687 	       StringCpy(fmark, vnp->data.ptrvalue);
688 	       add_name_partial(fmark, trunc5, trunc3);
689 	       return TRUE;
690 	     }
691 
692 	     StringCpy(fmark, "ProRef");
693 	     add_name_partial(fmark, trunc5, trunc3);
694 	     return TRUE;
695 	   case 5:
696 	     rrp = sfp->data.value.ptrvalue;
697 	     if(rrp->type == 0){
698 	       StringCpy(fmark, "Unknown");
699 	       add_name_partial(fmark, trunc5, trunc3);
700 	       return TRUE;
701 	     }
702 	     if(rrp->type == 1){
703 	       StringCpy(fmark, "Premsg");
704 	       add_name_partial(fmark, trunc5, trunc3);
705 	       return TRUE;
706 	     }
707 	     if(rrp->type == 2){
708 	       StringCpy(fmark, "mRNA");
709 	       add_name_partial(fmark, trunc5, trunc3);
710 	       return TRUE;
711 	     }
712 	     if(rrp->type == 3){
713 	       StringCpy(fmark, "tRNA");
714 	       add_name_partial(fmark, trunc5, trunc3);
715 	       return TRUE;
716 	     }
717 	     if(rrp->type == 4){
718 	       StringCpy(fmark, "rRNA");
719 	       add_name_partial(fmark, trunc5, trunc3);
720 	       return TRUE;
721 	     }
722 	     if(rrp->type == 5){
723 	       StringCpy(fmark, "snRNA");
724 	       add_name_partial(fmark, trunc5, trunc3);
725 	       return TRUE;
726 	     }
727 	     if(rrp->type == 6){
728 	       StringCpy(fmark, "scRNA");
729 	       add_name_partial(fmark, trunc5, trunc3);
730 	       return TRUE;
731 	     }
732 	     if(rrp->type == 7){
733 	       StringCpy(fmark, "snoRNA");
734 	       add_name_partial(fmark, trunc5, trunc3);
735 	       return TRUE;
736 	     }
737 	     if(rrp->type == 255){
738 	       StringCpy(fmark, "Other");
739 	       add_name_partial(fmark, trunc5, trunc3);
740 	       return TRUE;
741 	     }
742 	     StringCpy(fmark, "RNA");
743 	     add_name_partial(fmark, trunc5, trunc3);
744 	     return TRUE;
745 	   case 6:
746 	     pdp = sfp->data.value.ptrvalue;
747 	     vnp = pdp->pub;
748 	     return get_cit_edit(fmark, order, vnp);
749 
750 	   case 7:
751 	      sip = SeqLocId(sfp->data.value.ptrvalue);
752 	      seqid_name(sip, fmark, use_locus, TRUE);
753 	      add_name_partial(fmark, trunc5, trunc3);
754 	      return TRUE;
755 
756 	   case 8:
757 	      ifp = sfp->data.value.ptrvalue;
758 	      is_done = FALSE;
759 	      if(ifp->descr){
760 		StringCpy(temp, ifp->descr);
761 		myStringNCpy(fmark, temp, 20);
762 		is_done = TRUE;
763 	       }
764 	      if(ifp->key && !is_done){
765 		StringCpy(temp, ifp->key);
766 		myStringNCpy(fmark, temp, 20);
767 		is_done = TRUE;
768 	      }
769 	      if(!is_done)
770 	       	StringCpy(fmark, "Import");
771 	      is_end = FALSE;
772 	      if(sfp->cit != NULL){
773 		 if (sfp->cit->choice ==1){
774 		      vnp = (sfp->cit->data.ptrvalue);
775 		      while(vnp && !is_end){
776 			 if(vnp->choice == PUB_Muid)
777 		       		is_end = get_cit_edit(temp, order, vnp);
778 			 if(vnp->choice == PUB_Equiv)
779 			    	is_end = get_cit_edit(temp, order, vnp->data.ptrvalue);
780 			  vnp = vnp->next;
781 		       }
782 		       if(is_end)
783 		           StringCpy(fmark, temp);
784 		   }
785 	       }
786 	       if(!is_end)
787 	          add_name_partial(fmark, trunc5, trunc3);
788 	       return TRUE;
789 
790 	    case 9:
791 	      if(sfp->data.value.ptrvalue){
792 		StringCpy(temp, sfp->data.value.ptrvalue);
793 		if(StringLen(temp) > 20)
794 		   myStringNCpy(fmark, temp, 20);
795 	        else
796 		   StringCpy(fmark, temp);
797 	        add_name_partial(fmark, trunc5, trunc3);
798 		return TRUE;
799 	      }
800 	      StringCpy(fmark, "Region");
801 	      add_name_partial(fmark, trunc5, trunc3);
802 	      return TRUE;
803 	    case 10:
804 	       StringCpy(fmark, "Comment");
805 	       add_name_partial(fmark, trunc5, trunc3);
806 	       return TRUE;
807 	    case 11:
808 	      if(sfp->data.value.intvalue ==1){
809 		StringCpy(fmark, "Disulfide");
810 	        add_name_partial(fmark, trunc5, trunc3);
811 		return TRUE;
812 	      }
813 	      if(sfp->data.value.intvalue ==2){
814 		StringCpy(fmark, "Thiolester");
815 	        add_name_partial(fmark, trunc5, trunc3);
816 		return TRUE;
817 	      }
818 	      if(sfp->data.value.intvalue ==3){
819 		StringCpy(fmark, "Xlink");
820 	        add_name_partial(fmark, trunc5, trunc3);
821 		return TRUE;
822 	      }
823 	      if(sfp->data.value.intvalue ==255){
824 		StringCpy(fmark, "Disulfide");
825 	        add_name_partial(fmark, trunc5, trunc3);
826 		return TRUE;
827 	      }
828 
829 	      StringCpy(fmark, "bond");
830 	       add_name_partial(fmark, trunc5, trunc3);
831 	      return TRUE;
832 
833 	    case 12:
834 	      if(sfp->data.value.intvalue ==1){
835 		StringCpy(fmark, "Active");
836 	       add_name_partial(fmark, trunc5, trunc3);
837 		return TRUE;
838 	      }
839 	      if(sfp->data.value.intvalue ==2){
840 		StringCpy(fmark, "Binding");
841 	       add_name_partial(fmark, trunc5, trunc3);
842 		return TRUE;
843 	      }
844 	      if(sfp->data.value.intvalue ==3){
845 		StringCpy(fmark, "Cleavage");
846 	       add_name_partial(fmark, trunc5, trunc3);
847 		return TRUE;
848 	      }
849 	      if(sfp->data.value.intvalue ==4){
850 		StringCpy(fmark, "Inhibit");
851 	       add_name_partial(fmark, trunc5, trunc3);
852 		return TRUE;
853 	      }
854 	      if(sfp->data.value.intvalue ==5){
855 		StringCpy(fmark, "Modified");
856 	       add_name_partial(fmark, trunc5, trunc3);
857 		return TRUE;
858 	      }
859 
860 	      if(sfp->data.value.intvalue ==6){
861 		StringCpy(fmark, "Glycosylation");
862 	       add_name_partial(fmark, trunc5, trunc3);
863 		return TRUE;
864 	      }
865 
866 
867 	      if(sfp->data.value.intvalue ==7){
868 		StringCpy(fmark, "Myristoylation");
869 	       add_name_partial(fmark, trunc5, trunc3);
870 		return TRUE;
871 	      }
872 
873 
874 	      if(sfp->data.value.intvalue ==8){
875 		StringCpy(fmark, "Mutagenized");
876 	       add_name_partial(fmark, trunc5, trunc3);
877 		return TRUE;
878 	      }
879 
880 
881 	      if(sfp->data.value.intvalue ==9){
882 		StringCpy(fmark, "Metal-binding");
883 	       add_name_partial(fmark, trunc5, trunc3);
884 		return TRUE;
885 	      }
886 
887 
888 	      if(sfp->data.value.intvalue ==10){
889 		StringCpy(fmark, "Phosphorylation");
890 	       add_name_partial(fmark, trunc5, trunc3);
891 		return TRUE;
892 	      }
893 
894 
895 	      if(sfp->data.value.intvalue ==11){
896 		StringCpy(fmark, "Aceylation");
897 	       add_name_partial(fmark, trunc5, trunc3);
898 		return TRUE;
899 	      }
900 
901 
902 	      if(sfp->data.value.intvalue ==12){
903 		StringCpy(fmark, "Amidation");
904 	       add_name_partial(fmark, trunc5, trunc3);
905 		return TRUE;
906 	      }
907 
908 
909 	      if(sfp->data.value.intvalue ==13){
910 		StringCpy(fmark, "Methylation");
911 	       add_name_partial(fmark, trunc5, trunc3);
912 		return TRUE;
913 	      }
914 
915 
916 	      if(sfp->data.value.intvalue ==14){
917 		StringCpy(fmark, "Hydroxylation");
918 	       add_name_partial(fmark, trunc5, trunc3);
919 		return TRUE;
920 	      }
921 
922 
923 	      if(sfp->data.value.intvalue ==16){
924 		StringCpy(fmark, "Oxidative-deamination");
925 	       add_name_partial(fmark, trunc5, trunc3);
926 		return TRUE;
927 	      }
928 
929 
930 	      if(sfp->data.value.intvalue ==15){
931 		StringCpy(fmark, "Sulfataion");
932 	       add_name_partial(fmark, trunc5, trunc3);
933 		return TRUE;
934 	      }
935 
936 
937 	      if(sfp->data.value.intvalue ==17){
938 		StringCpy(fmark, "Pyrrolidone-carbosylic-acid");
939 	       add_name_partial(fmark, trunc5, trunc3);
940 		return TRUE;
941 	      }
942 
943 
944 	      if(sfp->data.value.intvalue ==18){
945 		StringCpy(fmark, "Gamma-carboxyglutamic-acid");
946 	       add_name_partial(fmark, trunc5, trunc3);
947 		return TRUE;
948 	      }
949 
950 
951 	      if(sfp->data.value.intvalue ==19){
952 		StringCpy(fmark, "Blocked");
953 	       add_name_partial(fmark, trunc5, trunc3);
954 		return TRUE;
955 	      }
956 
957 
958 	      if(sfp->data.value.intvalue ==20){
959 		StringCpy(fmark, "Lipid-binding");
960 	       add_name_partial(fmark, trunc5, trunc3);
961 		return TRUE;
962 	      }
963 
964 
965 	      if(sfp->data.value.intvalue ==21){
966 		StringCpy(fmark, "np-binding");
967 	       add_name_partial(fmark, trunc5, trunc3);
968 		return TRUE;
969 	      }
970 
971 
972 	      if(sfp->data.value.intvalue ==22){
973 		StringCpy(fmark, "dna-binding");
974 	       add_name_partial(fmark, trunc5, trunc3);
975 		return TRUE;
976 	      }
977 
978 	      if(sfp->data.value.intvalue ==255){
979 		StringCpy(fmark, "Other");
980 		add_name_partial(fmark, trunc5, trunc3);
981 		return TRUE;
982 	      }
983 
984 	      StringCpy(fmark, "Site");
985 	       add_name_partial(fmark, trunc5, trunc3);
986 	      return TRUE;
987 	     case 13:
988 	       rrf = sfp->data.value.ptrvalue;
989 	       if(rrf->choice ==1){
990 		 StringCpy(fmark, rrf->data.ptrvalue);
991 	          add_name_partial(fmark, trunc5, trunc3);
992 		 return TRUE;
993 	       }
994 	      StringCpy(fmark, "Rsite");
995 	       add_name_partial(fmark, trunc5, trunc3);
996 	      return TRUE;
997 
998 	     case 14:
999 	      StringCpy(fmark, "User");
1000 	       add_name_partial(fmark, trunc5, trunc3);
1001 	      return TRUE;
1002 
1003 	     case 15:
1004 	       tp = sfp->data.value.ptrvalue;
1005 	       if(tp->name){
1006 		 StringCpy(temp, tp->name);
1007 		 myStringNCpy(fmark, temp, 20);
1008 	       add_name_partial(fmark, trunc5, trunc3);
1009 		 return TRUE;
1010 	       }
1011 	      StringCpy(fmark, "Txinit");
1012 	       add_name_partial(fmark, trunc5, trunc3);
1013 	      return TRUE;
1014 
1015 	    case 16:
1016 	      StringCpy(fmark, "Numbering");
1017 	       add_name_partial(fmark, trunc5, trunc3);
1018 	      return TRUE;
1019 
1020 	    case 17:
1021 	      if(sfp->data.value.intvalue ==1){
1022 		StringCpy(fmark, "Helix");
1023 	       add_name_partial(fmark, trunc5, trunc3);
1024 		return TRUE;
1025 	      }
1026 	      if(sfp->data.value.intvalue ==2){
1027 		StringCpy(fmark, "Sheet");
1028 	       add_name_partial(fmark, trunc5, trunc3);
1029 		return TRUE;
1030 	      }
1031 	      if(sfp->data.value.intvalue ==3){
1032 		StringCpy(fmark, "Turn");
1033 	       add_name_partial(fmark, trunc5, trunc3);
1034 		return TRUE;
1035 	      }
1036 	      StringCpy(fmark, "Psec");
1037 	       add_name_partial(fmark, trunc5, trunc3);
1038 	      return TRUE;
1039 
1040 	     case 18:
1041 	      if(sfp->data.value.ptrvalue){
1042 		StringCpy(temp, sfp->data.value.ptrvalue);
1043 		myStringNCpy(fmark, temp, 20);
1044 	       add_name_partial(fmark, trunc5, trunc3);
1045 		return TRUE;
1046 	      }
1047 	      StringCpy(fmark, "NstdRes");
1048 	       add_name_partial(fmark, trunc5, trunc3);
1049 	      return TRUE;
1050 
1051 	     case 19:
1052 	      if(sfp->data.value.ptrvalue){
1053 		StringCpy(temp, sfp->data.value.ptrvalue);
1054 		myStringNCpy(fmark, temp, 20);
1055 	       add_name_partial(fmark, trunc5, trunc3);
1056 		return TRUE;
1057 	      }
1058 	      StringCpy(fmark, "Heterogen");
1059 	       add_name_partial(fmark, trunc5, trunc3);
1060 	      return TRUE;
1061 
1062 	      default:
1063 		return FALSE;
1064 
1065 	     }
1066 
1067 }
1068 
1069 
1070 
loc_offset(SeqLocPtr seq_loc,SeqLocPtr f_loc,Int4Ptr left,Int4Ptr right,BoolPtr l_trunc,BoolPtr r_trunc)1071 NLM_EXTERN Int1 loc_offset(SeqLocPtr seq_loc, SeqLocPtr f_loc, Int4Ptr left, Int4Ptr right, BoolPtr l_trunc, BoolPtr r_trunc)
1072 {
1073 	Boolean temp;
1074 
1075 
1076 	if(SeqLocCompare(seq_loc, f_loc) == SLC_NO_MATCH)
1077 		return -1;
1078 
1079 	*l_trunc = FALSE;
1080 	*r_trunc = FALSE;
1081 	*left = GetOffsetInLoc(f_loc, seq_loc, SEQLOC_LEFT_END);
1082 	if(*left == -1)
1083 	{
1084 	   *l_trunc = TRUE;
1085 	   if(SeqLocStrand(seq_loc) == Seq_strand_minus)
1086 	      *left = SeqLocLen(seq_loc) -1;
1087 	   else
1088 	     *left = 0;
1089 	}
1090 
1091 	*right = GetOffsetInLoc(f_loc, seq_loc, SEQLOC_RIGHT_END);
1092 	if(*right == -1)
1093 	{
1094 	   *r_trunc = TRUE;
1095 	   if(SeqLocStrand(seq_loc) == Seq_strand_minus)
1096 	      *right = 0;
1097 	   else
1098 	     *right = SeqLocLen(seq_loc) -1;
1099 	}
1100 
1101 	if(*right < *left)
1102 	{
1103 	   temp = *l_trunc;
1104 	   *l_trunc = *r_trunc;
1105 	   *r_trunc = temp;
1106 	   swap(left, right);
1107 	}
1108 
1109 	return (Int1)get_r_strand(seq_loc, f_loc);
1110 
1111 }
1112 
1113 
tloc_offset(SeqLocPtr seq_loc,SeqLocPtr f_loc,Int4Ptr left,Int4Ptr right)1114 NLM_EXTERN Int1 tloc_offset(SeqLocPtr seq_loc, SeqLocPtr f_loc, Int4Ptr left, Int4Ptr right)
1115 {
1116   Int4 t_start, t_stop;
1117 
1118 
1119 	if(SeqLocCompare(seq_loc, f_loc) == SLC_NO_MATCH)
1120 	   return -1;
1121 
1122 	t_start = MAX(SeqLocStart(f_loc), SeqLocStart(seq_loc));
1123 	t_stop = MIN(SeqLocStop(f_loc), SeqLocStop(seq_loc));
1124 	if(SeqLocStrand(seq_loc) != Seq_strand_minus){
1125 	*left = t_start - SeqLocStart(seq_loc);
1126 	*right = t_stop - SeqLocStart(seq_loc);
1127 	}
1128 	else{
1129 	*left = SeqLocStop(seq_loc) - t_stop;
1130 	*right = SeqLocStop(seq_loc) - t_start;
1131 	}
1132 	swap (left, right);
1133 
1134 	return (Int1)get_r_strand(seq_loc, f_loc);
1135 
1136 }
1137 
lr_offset_in_slp(SeqLocPtr slp,Int4 t_start,Int4 t_stop,Int4Ptr l_offset,Int4Ptr r_offset)1138 NLM_EXTERN Boolean lr_offset_in_slp(SeqLocPtr slp, Int4 t_start, Int4 t_stop, Int4Ptr l_offset, Int4Ptr r_offset)
1139 {
1140 	Int4 start, stop;
1141 
1142 	start = SeqLocStart(slp);
1143 	stop = SeqLocStop(slp);
1144 	if(t_start> stop || t_stop < start)
1145 		return FALSE;
1146 	t_start = MAX(t_start, start);
1147 	t_stop = MIN(t_stop, stop);
1148 
1149 	if(SeqLocStrand(slp) == Seq_strand_minus)
1150 	{
1151 		*l_offset = stop - t_stop;
1152 		*r_offset = stop - t_start;
1153 	}
1154 	else
1155 	{
1156 		*l_offset = t_start - start;
1157 		*r_offset = t_stop - start;
1158 	}
1159 
1160 	return TRUE;
1161 }
1162 
1163 /**************************************************************************
1164 ***
1165 *	make_range(): initiate the range on the genome for (start, stop)
1166 *	if(cross 0), have two slp, otherwise have only one segment
1167 *
1168 ***************************************************************************
1169 ***/
make_range(Int4 start,Int4 stop,Int4 end,SeqIdPtr sip,ValNodePtr PNTR g_start)1170 NLM_EXTERN SeqLocPtr make_range(Int4 start, Int4 stop, Int4 end, SeqIdPtr sip, ValNodePtr PNTR g_start)
1171 {
1172    SeqLocPtr slp;
1173    ValNodePtr vnp, next;
1174 
1175 	if(start <0)
1176 		start += end;
1177 	if(stop <0)
1178 		stop += end;
1179 
1180 	if(start <= stop){
1181 	  slp = SeqLocIntNew(start, stop, Seq_strand_plus, sip);
1182 	  slp->next = NULL;
1183 
1184 	  vnp = ValNodeNew(NULL);
1185 	  vnp->next = NULL;
1186 	  vnp->choice =0;
1187 	  vnp->data.intvalue =0;
1188 	}
1189 
1190 	else{		/*for circular molecules which cross the circle*/
1191 	  slp = SeqLocIntNew(start, end, Seq_strand_plus, sip);
1192 	  slp->next = SeqLocIntNew(0, stop, Seq_strand_plus, sip);
1193 	  vnp = ValNodeNew(NULL);
1194 	  vnp->choice =1;
1195 	  vnp->data.intvalue =0;
1196 
1197 	  next = ValNodeNew(vnp);
1198 	  next->choice =1;
1199 	  next->data.intvalue = SeqLocLen(slp);
1200 
1201 	}
1202 
1203 	*g_start = vnp;
1204 	return slp;
1205 }
1206 
1207 
1208 /******************************************************************************
1209 ***
1210 *	make_ext_feat(): return Seq-feat from bsp->seq_ext
1211 *
1212 *******************************************************************************
1213 ***/
make_ext_feat(BioseqPtr biosp)1214 NLM_EXTERN SeqFeatPtr make_ext_feat(BioseqPtr biosp)
1215 {
1216 
1217 
1218 	   if(biosp == NULL)
1219 	      return NULL;
1220 
1221 	   if(biosp->repr != Seq_repr_map)/**No physical Map**/
1222 	     return NULL;
1223 
1224 	   if(biosp->seq_ext_type ==3)
1225 	     return (SeqFeatPtr)(biosp->seq_ext);
1226 
1227 	   return NULL;
1228 }
1229 
1230 /*****************************************************************************
1231 ***
1232 *	get_bsp_feat(): make Seq-feat from Bioseq from bsp->annot
1233 *
1234 ******************************************************************************
1235 ***/
get_bsp_feat(BioseqPtr bsp)1236 NLM_EXTERN SeqFeatPtr get_bsp_feat(BioseqPtr bsp)
1237 {
1238   SeqAnnotPtr annot;
1239 
1240 	if(bsp == NULL)
1241 	  return NULL;
1242 
1243 	annot = bsp->annot;
1244 	if(annot == NULL)
1245 	  return NULL;
1246 
1247 	while(annot){
1248 	  if(annot->type == 1)
1249 	    return (SeqFeatPtr)annot->data;
1250 	  annot = annot->next;
1251 	}
1252 
1253 	return NULL;
1254 }
1255 
1256 
1257 
find_nth_align(SeqAlignPtr align,Int2 num)1258 NLM_EXTERN SeqAlignPtr find_nth_align(SeqAlignPtr align, Int2 num)
1259 {
1260    Int2 i;
1261 
1262 	i =0;
1263 	while(align){
1264 	  ++i;
1265 	  if(num == i)
1266 	     return align;
1267 	   align = align->next;
1268 	}
1269 
1270 	return NULL;
1271 
1272 
1273 }
1274 
1275 
1276 /******************************************************************************
1277 ***
1278 *	get the Seq-align from Seq-annot in a Bioseq
1279 *
1280 *******************************************************************************
1281 ***/
get_bsp_align(BioseqPtr bsp)1282 NLM_EXTERN SeqAlignPtr get_bsp_align(BioseqPtr bsp)
1283 {
1284   SeqAnnotPtr annot;
1285 
1286 	if(bsp == NULL)
1287 	  return NULL;
1288 
1289 	annot = bsp->annot;
1290 	if(annot == NULL)
1291 	  return NULL;
1292 
1293 	while(annot){
1294 	  if(annot->type == 2)
1295 	    return (SeqAlignPtr)annot->data;
1296 	  annot = annot->next;
1297 	}
1298 
1299 	return NULL;
1300 }
1301 
get_sep_align(SeqEntryPtr sep)1302 NLM_EXTERN SeqAlignPtr get_sep_align(SeqEntryPtr sep)
1303 {
1304   BioseqSetPtr bssp;
1305   BioseqPtr bsp;
1306   SeqAnnotPtr annot;
1307 
1308 	if(sep->choice ==1){
1309 	  bsp = sep->data.ptrvalue;
1310 	  return get_bsp_align(bsp);
1311 	}
1312 
1313 	else{
1314 	  bssp = sep->data.ptrvalue;
1315 	  annot = bssp->annot;
1316 	}
1317 
1318 	if(annot == NULL)
1319 	   return NULL;
1320 
1321 	while(annot){
1322 	  if(annot->type == 2)
1323 	    return (SeqAlignPtr)annot->data;
1324 	  annot = annot->next;
1325 	}
1326 
1327 	return NULL;
1328 
1329 }
1330 
1331 
1332 /*************************************************************************
1333 ****
1334 *	get_align_id(): get SeqIdPtr from SeqAlignPtr.
1335 *	order is the order of the aligned seq in SeqAlignPtr
1336 *	in SeqIdPtr, can be 0 or 1 for 2-D alignment.
1337 *
1338 **************************************************************************
1339 ****/
get_align_id(SeqAlignPtr sap_p,Int2 order)1340 NLM_EXTERN SeqIdPtr get_align_id(SeqAlignPtr sap_p, Int2 order)
1341 {
1342     DenseSegPtr  dsp;
1343     StdSegPtr    ssp;
1344     DenseDiagPtr ddp;
1345     SeqAlignPtr  sap;
1346     Int2         i;
1347     SeqIdPtr     sip;
1348     SeqLocPtr    loc;
1349 
1350     i =0;
1351     switch(sap_p->segtype) {
1352     case 1:		/*Dense Diag*/
1353         ddp = sap_p->segs;
1354         sip = ddp->id;
1355         for(; sip!=NULL; sip = sip->next, ++i)
1356             if(order == i)
1357                 return sip;
1358         return NULL;
1359     case 2:		/*Dense Seg*/
1360         dsp = sap_p->segs;
1361         sip = dsp->ids;
1362         for(; sip!=NULL; sip = sip->next, ++i)
1363             if(order == i)
1364                 return sip;
1365         return NULL;
1366     case 3:
1367         ssp = sap_p->segs;
1368         loc = ssp->loc;
1369         for(; loc != NULL; loc = loc->next, ++i)
1370             if(order == i)
1371                 return SeqLocId(loc);
1372         return NULL;
1373     case 5: /* Discontinuous alignment */
1374         sap = (SeqAlignPtr) sap_p->segs;
1375         sip = get_align_id(sap, order);
1376         return  sip;
1377 
1378     default:
1379         return NULL;
1380     }
1381 }
1382 
1383 
1384 /**************************************************************************
1385 ***
1386 *	get_align_strand(): get the strand of an aligned sequence
1387 *
1388 **************************************************************************
1389 ***/
get_align_strand(SeqAlignPtr sap_p,Int2 order)1390 NLM_EXTERN Uint1 get_align_strand(SeqAlignPtr sap_p, Int2 order)
1391 {
1392     DenseSegPtr dsp;
1393     StdSegPtr   ssp;
1394     DenseDiagPtr ddp;
1395     SeqLocPtr loc;
1396     Int2 i;
1397     SeqAlignPtr sap;
1398 
1399     switch(sap_p->segtype) {
1400     case 1:		/*Dense Diag*/
1401         ddp = sap_p->segs;
1402         order = order%(ddp->dim);
1403         if(ddp->strands)
1404             return ddp->strands[order];
1405         return 0;
1406     case 2:		/*Dense Seg*/
1407         dsp = sap_p->segs;
1408         order = order%(dsp->dim);
1409         if(dsp->strands)
1410             return dsp->strands[order];
1411         return 0;
1412     case 3:
1413         ssp = sap_p->segs;
1414         loc = ssp->loc;
1415         for(i = 0; loc != NULL; loc = loc->next, ++i)
1416             if(order == i)
1417                 return SeqLocStrand(loc);
1418         return 0;
1419     case 5: /* Discontinuous alignment */
1420 
1421         sap = (SeqAlignPtr) sap_p->segs;
1422         return get_align_strand(sap, order);
1423 
1424     default:
1425         return 0;
1426     }
1427 }
1428 
1429 /************************************************************************
1430 ****
1431 *	m_id_match(): check if the SeqAlign contains the sequence of
1432 *	match_id, return the order of the sequence in the alignment
1433 *************************************************************************
1434 ****/
m_id_match(SeqAlignPtr sap_p,SeqIdPtr match_id)1435 NLM_EXTERN Int2 m_id_match(SeqAlignPtr sap_p, SeqIdPtr match_id)
1436 {
1437     DenseSegPtr dsp;
1438     StdSegPtr   ssp;
1439     DenseDiagPtr ddp;
1440 
1441     Int2 i;
1442     SeqIdPtr sip;
1443     SeqLocPtr loc;
1444     SeqAlignPtr sap;
1445 
1446     i =0;
1447     switch(sap_p->segtype) {
1448     case 1:		/*Dense Diag*/
1449         ddp = sap_p->segs;
1450         sip = ddp->id;
1451         for(; sip!=NULL; sip = sip->next, ++i)
1452             if(SeqIdForSameBioseq(sip, match_id))
1453                 return i;
1454         return -1;
1455     case 2:		/*Dense Seg*/
1456         dsp = sap_p->segs;
1457         sip = dsp->ids;
1458         for(; sip!=NULL; sip = sip->next, ++i)
1459             if(SeqIdForSameBioseq(sip, match_id))
1460                 return i;
1461         return -1;
1462     case 3:
1463         ssp = sap_p->segs;
1464         loc = ssp->loc;
1465         for(; loc != NULL; loc = loc->next, ++i)
1466             if(SeqIdForSameBioseq(SeqLocId(loc), match_id))
1467                 return i;
1468         return -1;
1469     case 5: /* Discontinuous alignment */
1470 
1471         sap = (SeqAlignPtr) sap_p->segs;
1472         return m_id_match(sap, match_id);
1473 
1474     default:
1475         return -1;
1476     }
1477 }
1478 
1479 
1480 
1481 /*****************************************************************************
1482 ***
1483 *	get_clone_type(): determine if a clone is a YAC, a SEQUENCE or a CLONE
1484 *	(cosmid library)
1485 *
1486 ******************************************************************************
1487 ***/
get_clone_type(SeqIdPtr sip)1488 NLM_EXTERN Uint1 get_clone_type(SeqIdPtr sip)
1489 {
1490    Char acc[100], name[100], dbase[100];
1491 
1492 
1493 	get_seq_name(sip, name, acc, dbase, TRUE);
1494 	if(StringNICmp(dbase, "Yac", 3) ==0)
1495 	  return IS_YAC;
1496 
1497 	if(strstr(dbase, "clone") )
1498 	  return IS_CLONE;
1499 
1500 	if(StringCmp(dbase, "GenBank") ==0)
1501 	  return  IS_SEQ;
1502 
1503 	if(StringCmp(dbase, "EMBL") ==0)
1504 	  return  IS_SEQ;
1505 
1506 	if(StringCmp(dbase, "DDBJ") ==0)
1507 	  return  IS_SEQ;
1508 
1509 
1510 	if(StringCmp(dbase, "ACEDB") == 0)	/**it is not a clone**/
1511 	  return IS_SEQ;
1512 
1513 	return IS_CLONE;
1514 
1515 
1516 }
1517 
1518 
check_match(Char a,Char b)1519 NLM_EXTERN Boolean  check_match(Char a, Char b)
1520 {
1521 
1522 	if(a == b)
1523 	   return TRUE;
1524 
1525 	switch (a){
1526 	  case 'A':
1527 	    if(StringChr("DHMNRVW", b))
1528 	       return TRUE;
1529 	    else
1530 	      return FALSE;
1531 	   case 'B':
1532 	     if(StringChr("GTC", b))
1533 		return TRUE;
1534 	     else
1535 		return FALSE;
1536 	   case 'C':
1537 	     if(StringChr("BHMNSVY", b))
1538 		return TRUE;
1539 	     else
1540 		return FALSE;
1541 	   case 'D':
1542 	     if(StringChr("GAT", b))
1543 		return TRUE;
1544 	     else
1545 		return FALSE;
1546 	   case 'G':
1547 	     if(StringChr("BDKNRSV", b))
1548 		return TRUE;
1549 	     else
1550 		return FALSE;
1551 	   case 'H':
1552 	     if(StringChr("ACT", b))
1553 		return TRUE;
1554 	     else
1555 		return FALSE;
1556 	   case 'K':
1557 	     if(StringChr("GT", b))
1558 		return TRUE;
1559 	     else
1560 		return FALSE;
1561 	   case 'M':
1562 	     if(StringChr("AC", b))
1563 		return TRUE;
1564 	     else
1565 		return FALSE;
1566 	   case 'N':
1567 	     if(StringChr("AGTC", b))
1568 		return TRUE;
1569 	     else
1570 		return FALSE;
1571 	   case 'R':
1572 	     if(StringChr("GA", b))
1573 		return TRUE;
1574 	     else
1575 		return FALSE;
1576 	   case 'S':
1577 	     if(StringChr("GC", b))
1578 		return TRUE;
1579 	     else
1580 		return FALSE;
1581 	   case 'T':
1582 	     if(StringChr("BDHKNWY", b))
1583 		return TRUE;
1584 	     else
1585 		return FALSE;
1586 	   case 'V':
1587 	     if(StringChr("GCA", b))
1588 		return TRUE;
1589 	     else
1590 		return FALSE;
1591 	   case 'W':
1592 	     if(StringChr("AT", b))
1593 		return TRUE;
1594 	     else
1595 		return FALSE;
1596 	   case 'Y':
1597 	     if(StringChr("TC", b))
1598 		return TRUE;
1599 	     else
1600 		return FALSE;
1601 	   default :
1602 	      return FALSE;
1603 	}
1604 
1605 }
1606 
1607 
ReComputerNumObj(ValNodePtr desc,Int4 old_len,Int4 new_len)1608 static Boolean ReComputerNumObj(ValNodePtr desc, Int4 old_len, Int4 new_len)
1609 {
1610    NumberingPtr num;
1611    NumRealPtr nrp;
1612    FloatHi val;
1613 
1614 	if(old_len == new_len)
1615 		return FALSE;
1616 
1617 	if(desc == NULL)
1618 		return FALSE;
1619 
1620 	if(desc->choice != Seq_descr_num)
1621 		return FALSE;
1622 
1623 	num = (NumberingPtr)(desc->data.ptrvalue);
1624 	if(num->choice != Numbering_real)
1625 		return FALSE;
1626 
1627 	if(new_len == 0)
1628 		return FALSE;
1629 	nrp = (NumRealPtr)(num->data.ptrvalue);
1630 	val = (FloatHi) old_len * (nrp->a) /(FloatHi)new_len;
1631 	nrp->a = val;
1632 	num->data.ptrvalue = nrp;
1633 	return TRUE;
1634 }
1635 
get_numbering_desc(ValNodePtr desc,Uint1 type)1636 static ValNodePtr get_numbering_desc(ValNodePtr desc, Uint1 type)
1637 {
1638 	while(desc)
1639 	{
1640 		if(desc->choice == type)
1641 			return desc;
1642 		desc = desc->next;
1643 	}
1644 	return NULL;
1645 }
1646 
1647 
SeqLocReplace(SeqIdPtr s_id,Int4 s_start,Int4 s_stop,Uint1 s_strand,SeqIdPtr t_id,Int4 t_start,Int4 t_stop,Uint1 t_strand)1648 NLM_EXTERN Boolean SeqLocReplace(SeqIdPtr s_id, Int4 s_start, Int4 s_stop, Uint1 s_strand, SeqIdPtr t_id, Int4 t_start, Int4 t_stop, Uint1 t_strand)
1649 {
1650   BioseqPtr source_bsp, target_bsp;
1651   Int4 pos;
1652   Boolean adj_feat;
1653   Int4 old_len, new_len;
1654   ValNodePtr num_desc;
1655 
1656 	source_bsp = BioseqFind(s_id);
1657 	target_bsp = BioseqFind(t_id);
1658 	old_len = BioseqGetLen(target_bsp);
1659 
1660 	if(target_bsp->repr == Seq_repr_map && source_bsp->repr != Seq_repr_map)
1661 	{
1662 		Message(MSG_ERROR, "Incorrect type of bioseq for map insertion");
1663 		return FALSE;
1664 	}
1665 	else{
1666 		pos = t_start;
1667 		adj_feat = FALSE;
1668 		if(s_stop - s_start != t_stop - t_start)
1669 			adj_feat = TRUE;
1670 		s_id = find_sip(source_bsp->id);
1671 		if(s_id->choice == SEQID_OTHER)
1672 			s_id = source_bsp->id;
1673 		if(BioseqDelete(t_id, t_start, t_stop, adj_feat, FALSE))
1674 		{
1675 
1676 			if(BioseqInsert(s_id, s_start, s_stop, s_strand, t_id, pos, FALSE, adj_feat, FALSE))
1677 			{
1678 				new_len = BioseqGetLen(target_bsp);
1679 				if(old_len != new_len)
1680 				{
1681 					num_desc = get_numbering_desc(target_bsp->descr, Seq_descr_num);
1682 					ReComputerNumObj(num_desc, old_len, new_len);
1683 				}
1684 				return TRUE;
1685 			 }
1686 
1687 
1688 		}
1689 		return FALSE;
1690 	}
1691 
1692 
1693 }
1694 
1695 
get_pnt_val(SeqLocPtr slp,Int4Ptr pos,Uint1Ptr strand,BoolPtr fuzz)1696 NLM_EXTERN Boolean get_pnt_val(SeqLocPtr slp, Int4Ptr pos, Uint1Ptr strand, BoolPtr fuzz)
1697 {
1698 	SeqPntPtr spp;
1699 	if(slp->choice != SEQLOC_PNT)
1700 		return FALSE;
1701 
1702 	*pos = SeqLocStart(slp);
1703 	*strand = SeqLocStrand(slp);
1704 	spp = (SeqPntPtr)(slp->data.ptrvalue);
1705 	if(spp->fuzz != NULL)
1706 		*fuzz = TRUE;
1707 	else
1708 		*fuzz = FALSE;
1709 	return TRUE;
1710 }
1711 
get_gene_syn(SeqFeatPtr sfp,CharPtr name,BoolPtr has_name,CharPtr syn,BoolPtr has_syn)1712 NLM_EXTERN Boolean get_gene_syn(SeqFeatPtr sfp, CharPtr name, BoolPtr has_name, CharPtr syn, BoolPtr has_syn)
1713 {
1714 	GeneRefPtr grp;
1715 	ValNodePtr vnp;
1716 	Boolean has_prev;
1717 	Char tmp[20];
1718 
1719 	if(sfp->data.choice != 1)
1720 		return FALSE;
1721 
1722 	*has_name = FALSE;
1723 	*has_syn = FALSE;
1724 	grp = sfp->data.value.ptrvalue;
1725 	if(grp->locus)
1726 	{
1727 		*has_name = TRUE;
1728 		StringCpy(name, grp->locus);
1729 	}
1730 
1731 	if(grp->syn)
1732 	{
1733 		*has_syn = TRUE;
1734 		vnp= grp->syn;
1735 		has_prev = FALSE;
1736 		while(vnp)
1737 		{
1738 			if(has_prev)
1739 			{
1740 				sprintf(tmp, " %s", (CharPtr) vnp->data.ptrvalue);
1741 				StringCat(syn, tmp);
1742 			}
1743 			else
1744 				StringCpy(syn, vnp->data.ptrvalue);
1745 			vnp = vnp->next;
1746 			has_prev = TRUE;
1747 		}
1748 	}
1749 
1750 	return TRUE;
1751 
1752 }
1753 
1754 
get_feat_id(SeqFeatPtr sfp,CharPtr featId,BoolPtr has_fid,CharPtr dbase,BoolPtr has_db)1755 NLM_EXTERN Boolean get_feat_id(SeqFeatPtr sfp, CharPtr featId, BoolPtr has_fid, CharPtr dbase, BoolPtr has_db)
1756 {
1757 	DbtagPtr db_tag;
1758 	ObjectIdPtr oip;
1759 
1760 
1761 	*has_fid = FALSE;
1762 	*has_db = FALSE;
1763 	if(sfp->id.choice != 4 && sfp->id.choice != 3)
1764 		return FALSE;
1765 
1766 	if(sfp->id.choice == 3)
1767 	{
1768 		*has_db = FALSE;
1769 		oip = sfp->id.value.ptrvalue;
1770 		*has_fid = TRUE;
1771 		StringCpy(featId, oip->str);
1772 	}
1773 
1774 	if(sfp->id.choice == 4)
1775 	{
1776 		db_tag = sfp->id.value.ptrvalue;
1777 		oip = db_tag->tag;
1778 		*has_db = TRUE;
1779 		StringCpy(dbase, db_tag->db);
1780 		*has_fid = TRUE;
1781 		StringCpy(featId, oip->str);
1782 	}
1783 
1784 	return TRUE;
1785 
1786 }
1787 
DelNthFeat(SeqFeatPtr PNTR head,Int2 num)1788 NLM_EXTERN Boolean DelNthFeat(SeqFeatPtr PNTR head, Int2 num)
1789 {
1790 	SeqFeatPtr curr, prev;
1791 	Int2 i;
1792 
1793 	i =0;
1794 	curr = *head;
1795 	prev = NULL;
1796 
1797 	while(curr)
1798 	{
1799 		++i;
1800 		if(num ==i)
1801 		{
1802 			if(prev == NULL)
1803 				*head = curr->next;
1804 			else
1805 				prev->next = curr->next;
1806 			curr->next = NULL;
1807 			SeqFeatFree(curr);
1808 			return TRUE;
1809 		}
1810 		prev = curr;
1811 		curr = curr->next;
1812 	}
1813 
1814 	return FALSE;
1815 
1816 }
1817 
1818 
PackSeqPntInsert(PackSeqPntPtr head,Int4 pos)1819 NLM_EXTERN Boolean PackSeqPntInsert(PackSeqPntPtr head, Int4 pos)
1820 {
1821 	Int4 c_pos;
1822 	Uint1 i, cnt;
1823 	PackSeqPntPtr pspp, new;
1824 
1825 	pspp = head;
1826 	while(pspp)
1827 	{
1828 		cnt = pspp->used;
1829 		for(i =0; i<pspp->used; ++i)
1830 		{
1831 			if(pos < pspp->pnts[i])
1832 			{
1833 				c_pos = pspp->pnts[i];
1834 				pspp->pnts[i] = pos;
1835 				pspp->used = i+1;
1836 
1837 				new = PackSeqPntNew();
1838 				for(; i<cnt; ++i)
1839 				{
1840 					if(new->used ==0)
1841 						new->pnts[new->used] = c_pos;
1842 					else
1843 						new->pnts[new->used] = pspp->pnts[i];
1844 					++new->used;
1845 				}
1846 				new->next = pspp->next;
1847 				pspp->next = new;
1848 				return TRUE;
1849 			}
1850 
1851 		}
1852 		pspp = pspp->next;
1853 	}
1854 
1855 	return PackSeqPntPut(head, pos);
1856 }
1857 
insert_new_rsite(BioseqPtr r_bsp,CharPtr enz,Int4 pos)1858 NLM_EXTERN Boolean insert_new_rsite(BioseqPtr r_bsp, CharPtr enz, Int4 pos)
1859 {
1860 	SeqFeatPtr sfp;
1861 	RsiteRefPtr rrp;
1862 	CharPtr name;
1863 	SeqLocPtr slp;
1864 	PackSeqPntPtr pspp;
1865 
1866 
1867 	if(r_bsp == NULL)
1868 		return FALSE;
1869 
1870 	sfp = make_ext_feat(r_bsp);
1871 	if(sfp->data.choice != 13)
1872 		return FALSE;
1873 
1874 	while(sfp)
1875 	{
1876 		rrp = sfp->data.value.ptrvalue;
1877 		name = rrp->data.ptrvalue;
1878 		if(StringICmp(name, enz) ==0)
1879 		{
1880 			slp = sfp->location;
1881 			pspp = (PackSeqPntPtr)(slp->data.ptrvalue);
1882 			return PackSeqPntInsert(pspp, pos);
1883 		}
1884 		sfp = sfp->next;
1885 	}
1886 
1887 	return FALSE;
1888 
1889 }
1890 
1891 
PackSeqPntDelete(PackSeqPntPtr PNTR head,Int2 index)1892 NLM_EXTERN Boolean PackSeqPntDelete(PackSeqPntPtr PNTR head, Int2 index)
1893 {
1894 	PackSeqPntPtr pspp, prev;
1895 	Int2 j, i;
1896 
1897 	if(index < 0)
1898 		return FALSE;
1899 	pspp = *head;
1900 	j =0;
1901 	prev = NULL;
1902 	while(pspp)
1903 	{
1904 		if(index < (Int2)(j + (pspp->used)))
1905 		{
1906 			if(pspp->used == 1)
1907 			{
1908 				if(prev != NULL)
1909 					prev->next = pspp->next;
1910 				else
1911 					*head = pspp->next;
1912 				pspp->next = NULL;
1913 				PackSeqPntFree(pspp);
1914 				return TRUE;
1915 			}
1916 			else
1917 			{
1918 				for(i=index-j; i<(Int2)(pspp->used -1); ++i)
1919 					pspp->pnts[i] = pspp->pnts[i+1];
1920 				--(pspp->used);
1921 				return TRUE;
1922 			}
1923 		}
1924 		j += pspp->used;
1925 		pspp = pspp->next;
1926 	}
1927 
1928 	return FALSE;
1929 }
1930 
1931 
1932 
1933 
delete_rsite(BioseqPtr r_bsp,Int2 order,Int2 index)1934 NLM_EXTERN Boolean delete_rsite(BioseqPtr r_bsp, Int2 order, Int2 index)
1935 {
1936 	SeqFeatPtr sfp, prev;
1937 	SeqLocPtr slp;
1938 	PackSeqPntPtr pspp;
1939 	Int2 i;
1940 
1941 
1942 	if(r_bsp == NULL)
1943 		return FALSE;
1944 
1945 	sfp = make_ext_feat(r_bsp);
1946 	if(sfp->data.choice != 13)
1947 		return FALSE;
1948 
1949 	i =0;
1950 	prev = NULL;
1951 	while(sfp)
1952 	{
1953 		++i;
1954 		if(i == order)
1955 		{
1956 			slp = sfp->location;
1957 			if(slp->choice != SEQLOC_PACKED_PNT)
1958 				return FALSE;
1959 			pspp = slp->data.ptrvalue;
1960 			if(PackSeqPntDelete(&pspp, index))
1961 			{
1962 				if(pspp == NULL)
1963 				{
1964 					if(prev)
1965 						prev->next = sfp->next;
1966 					else
1967 						r_bsp->seq_ext = sfp->next;
1968 					sfp->next = NULL;
1969 					SeqFeatFree(sfp);
1970 				}
1971 				else
1972 					slp->data.ptrvalue = pspp;
1973 				return TRUE;
1974 			}
1975 		}
1976 		prev = sfp;
1977 		sfp = sfp->next;
1978 	}
1979 	return FALSE;
1980 
1981 }
1982 
DeleteNthAlign(SeqAlignPtr PNTR head,Int2 order)1983 NLM_EXTERN Boolean DeleteNthAlign(SeqAlignPtr PNTR head, Int2 order)
1984 {
1985 	SeqAlignPtr curr, prev;
1986 	Int2 num;
1987 
1988 	curr = *head;
1989 	num =0;
1990 	prev = NULL;
1991 	while(curr)
1992 	{
1993 		++num;
1994 		if(order == num)
1995 		{
1996 			if(prev == NULL)
1997 				*head = curr->next;
1998 			else
1999 				prev->next = curr->next;
2000 			curr->next = NULL;
2001 			SeqAlignFree(curr);
2002 			return TRUE;
2003 		}
2004 		prev = curr;
2005 		curr = curr->next;
2006 	}
2007 	return FALSE;
2008 }
2009 
2010 
Is_Local_Seq(SeqIdPtr hsip)2011 NLM_EXTERN Boolean Is_Local_Seq(SeqIdPtr hsip)
2012 {
2013 
2014 	SeqIdPtr sip;
2015 
2016 	sip = find_sip(hsip);
2017 	return (sip->choice == SEQID_LOCAL || sip->choice == SEQID_GENERAL || sip->choice == SEQID_OTHER);
2018 
2019 }
2020 
2021 
write_out_put(SeqEntryPtr sep,CharPtr file_name,Boolean bin)2022 NLM_EXTERN void write_out_put(SeqEntryPtr sep, CharPtr file_name, Boolean bin)
2023 {
2024    AsnIoPtr aip;
2025 
2026         aip = AsnIoOpen(file_name, (bin? "wb" : "w"));
2027         SeqEntryAsnWrite(sep, aip, NULL);
2028         AsnIoClose(aip);
2029 }
2030 
2031 
2032 /***********************************************************************
2033 ***
2034 *	functions for redrawing the Scaler for sequence
2035 *
2036 ************************************************************************
2037 ***/
slp_list_len(SeqLocPtr slp)2038 NLM_EXTERN Int4 slp_list_len(SeqLocPtr slp)
2039 {
2040 	Int4 seq_len;
2041 
2042 	for(seq_len = 0; slp!= NULL; slp = slp->next)
2043 		seq_len += SeqLocLen(slp);
2044 	return seq_len;
2045 }
2046 
get_node_num(ValNodePtr vnp)2047 NLM_EXTERN Int4 get_node_num(ValNodePtr vnp)
2048 {
2049 	Int4 i;
2050 
2051 	for(i =0; vnp!=NULL; vnp = vnp->next)
2052 		++i;
2053 	return i;
2054 }
2055 
2056 
BioseqHasFeature(BioseqPtr bsp)2057 NLM_EXTERN Boolean BioseqHasFeature(BioseqPtr bsp)
2058 {
2059 	SeqAnnotPtr annot;
2060 	SeqFeatPtr sfp;
2061 	SeqIdPtr sip;
2062 
2063 	if(bsp == NULL || bsp->annot == NULL)
2064 		return FALSE;
2065 	for(annot = bsp->annot; annot != NULL; annot = annot->next)
2066 		if(annot->type == 1)
2067 			if(annot->data != NULL)
2068 			{
2069 				sfp = annot->data;
2070 				if(sfp != NULL && sfp->location != NULL)
2071 				{
2072 					sip = SeqLocId(sfp->location);
2073 					if(sip != NULL && BioseqMatch(bsp, sip))
2074 						return TRUE;
2075 				}
2076 				return FALSE;
2077 			}
2078 
2079 	return FALSE;
2080 }
2081 
2082 
get_vnp_num(ValNodePtr vnp)2083 NLM_EXTERN Int2 get_vnp_num(ValNodePtr vnp)
2084 {
2085 	Int2 num =0;
2086 
2087 	while(vnp)
2088 	{
2089 		++num;
2090 		vnp = vnp->next;
2091 	}
2092 
2093 	return num;
2094 }
2095 
2096 
2097 
2098 /*###################################################################
2099 #
2100 #	functions related to find a default master sequence in Seq-align
2101 #	which will be used to display multiple pairwise alignment
2102 #
2103 ###################################################################*/
2104 typedef struct seqid_count{
2105 	SeqIdPtr sip;
2106 	Uint4 count;
2107 }SeqIdCount, PNTR SeqIdCountPtr;
2108 
find_repeat(ValNodePtr head,SeqIdPtr sip)2109 static ValNodePtr find_repeat(ValNodePtr head, SeqIdPtr sip)
2110 {
2111 	ValNodePtr vnp;
2112 	SeqIdCountPtr sicp;
2113 
2114 	for(vnp = head; vnp !=NULL; vnp = vnp->next)
2115 	{
2116 		sicp = vnp->data.ptrvalue;
2117 		if(SeqIdMatch(sicp->sip, sip))
2118 		{
2119 			++(sicp->count);
2120 			return head;
2121 		}
2122 	}
2123 	sicp = MemNew(sizeof(SeqIdCount));
2124 	sicp->sip = sip;
2125 	sicp->count = 1;
2126 	ValNodeAddPointer(&head, 0, (Pointer)sicp);
2127 	return head;
2128 }
2129 
2130 
find_max(ValNodePtr vnp)2131 static SeqIdPtr find_max(ValNodePtr vnp)
2132 {
2133 	Uint4 max;
2134 	SeqIdPtr sip= NULL;
2135 	SeqIdCountPtr sicp;
2136 
2137 
2138 	max =0;
2139 	while(vnp !=NULL)
2140 	{
2141 		sicp = vnp->data.ptrvalue;
2142 		if(sicp->count >max)
2143 		{
2144 	    		max = sicp->count;
2145 	    		sip = sicp->sip;
2146 		}
2147 	  	vnp = vnp->next;
2148 	}
2149 
2150 	return sip;
2151 }
2152 
2153 
2154 /*******************************************************************
2155 *
2156 *	make_master(sap_p)
2157 *	return the Seq-id of the sequence with the highest appearance
2158 *	frequency in a list of Seq-align
2159 *	sap_p: a list of Seq-align
2160 *	the return the Seq-id will be treated as the master in a
2161 *	multiple pairwise alignment
2162 *
2163 *******************************************************************/
make_master(SeqAlignPtr sap_p)2164 NLM_EXTERN SeqIdPtr make_master( SeqAlignPtr sap_p)
2165 {
2166     ValNodePtr vnp= NULL;   /*record the frequency of Seq-ids in alignment**/
2167     SeqIdPtr sip;
2168     DenseSegPtr dsp;
2169     DenseDiagPtr ddp;
2170     StdSegPtr ssp;
2171     SeqLocPtr slp;
2172     SeqAlignPtr sap;
2173 
2174     while(sap_p !=NULL) {
2175         switch(sap_p->segtype) {
2176         case 1:
2177             ddp = (DenseDiagPtr)(sap_p->segs);
2178             while(ddp) {
2179                 for(sip = ddp->id; sip!=NULL; sip = sip->next)
2180                     vnp = find_repeat(vnp, sip);
2181                 ddp = ddp->next;
2182             }
2183             break;
2184 
2185         case 2:
2186             dsp = (DenseSegPtr)(sap_p->segs);
2187             for(sip = dsp->ids; sip!=NULL; sip = sip->next)
2188                 vnp = find_repeat(vnp, sip);
2189             break;
2190 
2191         case 3:
2192             ssp = (StdSegPtr)(sap_p->segs);
2193             for(slp = ssp->loc; slp != NULL; slp = slp->next) {
2194                 sip = SeqLocId(slp);
2195                 vnp = find_repeat(vnp, sip);
2196             }
2197             break;
2198         case 5:
2199             for(sap = sap_p->segs; sap != NULL; sap = sap->next) {
2200                 sip = make_master(sap);
2201                 vnp = find_repeat(vnp, sip);
2202             }
2203             break;
2204 
2205         default:
2206             break;
2207         }
2208         sap_p = sap_p->next;
2209     }
2210 
2211     sip = find_max(vnp);
2212     ValNodeFreeData(vnp);
2213     return sip;
2214 }
2215 
use_multiple_dimension(SeqAlignPtr align)2216 NLM_EXTERN Boolean use_multiple_dimension(SeqAlignPtr align)
2217 {
2218 	DenseDiagPtr ddp;
2219 
2220 	if(align->next != NULL)
2221 		return FALSE;
2222 
2223 	if(align->segtype == 1)
2224 	{
2225 		ddp = align->segs;
2226 		return (ddp->next == NULL);
2227 	}
2228 	else
2229 		return TRUE;
2230 }
2231 
2232 
get_boundary(SeqIdPtr m_sip,Int4Ptr start,Int4Ptr stop,SeqAlignPtr align)2233 NLM_EXTERN void get_boundary(SeqIdPtr m_sip, Int4Ptr start, Int4Ptr stop, SeqAlignPtr align)
2234 {
2235 	Uint1 m_strand;
2236 	Int4 m_start, m_stop;
2237 
2238 	*start = -1;
2239 	*stop = -1;
2240 	while(align!=NULL)
2241 	{
2242 		get_align_ends(align, m_sip, &m_start, &m_stop, &m_strand);
2243 		if(*start == -1)
2244 		{
2245 			*start = m_start;
2246 			*stop = m_stop;
2247 		}
2248 		else
2249 		{
2250 			*start = MIN(m_start, (*start));
2251 			*stop = MAX(m_stop, (*stop));
2252 		}
2253 		align = align->next;
2254 	}
2255 }
2256 
2257 
2258 /*attach the information about the blast or the alignment type */
AddAlignInfoToSeqAnnotEx(SeqAnnotPtr annot,Uint1 align_type,CharPtr label)2259 NLM_EXTERN void AddAlignInfoToSeqAnnotEx(SeqAnnotPtr annot, Uint1 align_type, CharPtr label)
2260 {
2261 	UserObjectPtr uop, b_uop;
2262 	UserFieldPtr ufp;
2263 	ObjectIdPtr oip;
2264 
2265 	if(annot == NULL || annot->type != 2)
2266 		return;
2267 
2268 	oip = ObjectIdNew();
2269 	oip->str = StringSave("Hist Seqalign");
2270 	uop = UserObjectNew();
2271 	uop->type = oip;
2272 
2273 	oip = ObjectIdNew();
2274 	oip->str = StringSave("Hist Seqalign");
2275 	ufp = UserFieldNew();
2276 	ufp->choice = 4;
2277 	ufp->data.boolvalue = TRUE;
2278 	ufp->label = oip;
2279 
2280 	uop->data = ufp;
2281 
2282 
2283 	ufp = UserFieldNew();
2284 	oip = ObjectIdNew();
2285 	if(label == NULL)
2286 	{
2287 		switch(align_type)
2288 		{
2289 			case 1:
2290 				oip->str = StringSave("BLASTN");
2291 				break;
2292 			case 3:
2293 				oip->str = StringSave("BLASTX");
2294 				break;
2295 			case 2:
2296 				oip->str = StringSave("BLASTP");
2297 				break;
2298 			case 4:
2299 				oip->str = StringSave("TBLASTN");
2300 				break;
2301 			default:
2302 				break;
2303 		}
2304 	}
2305 	else
2306 		oip->str = StringSave(label);
2307 	ufp->label = oip;
2308 	ufp->choice = 2;
2309 	ufp->data.intvalue = (Int4)align_type;
2310 
2311 	oip = ObjectIdNew();
2312 	oip->str = StringSave("Blast Type");
2313 	b_uop = UserObjectNew();
2314 	b_uop->type = oip;
2315 	b_uop->data = ufp;
2316 
2317 	/* uop->next = b_uop; */
2318 	ValNodeAddPointer(&(annot->desc), Annot_descr_user, (Pointer)uop);
2319 	ValNodeAddPointer(&(annot->desc), Annot_descr_user, (Pointer)b_uop);
2320 }
2321 
AddAlignInfoToSeqAnnot(SeqAnnotPtr annot,Uint1 align_type)2322 NLM_EXTERN void AddAlignInfoToSeqAnnot(SeqAnnotPtr annot, Uint1 align_type)
2323 {
2324 	AddAlignInfoToSeqAnnotEx(annot, align_type, NULL);
2325 }
2326 
SortValNode(ValNodePtr list,int (LIBCALLBACK * compar)PROTO ((Nlm_VoidPtr,Nlm_VoidPtr)))2327 NLM_EXTERN ValNodePtr SortValNode (ValNodePtr list, int (LIBCALLBACK *compar )PROTO ((Nlm_VoidPtr, Nlm_VoidPtr )))
2328 {
2329 	ValNodePtr tmp, PNTR head;
2330 	Int4 count, i;
2331 
2332 	if(list == NULL)
2333 		return NULL;
2334 
2335 	count = get_node_num(list);
2336 	head = MemNew(((size_t)count+1) * sizeof (ValNodePtr));
2337 	for(tmp = list, i=0; tmp !=NULL && i<count; ++i)
2338 	{
2339 		head[i] = tmp;
2340 		tmp = tmp->next;
2341 	}
2342 
2343 	HeapSort(head, (size_t)count, sizeof(ValNodePtr), compar);
2344 	for(i =0; i<count; ++i)
2345 	{
2346 		tmp = head[i];
2347 		tmp->next = head[i+1];
2348 	}
2349 	list = head[0];
2350 	MemFree(head);
2351 
2352 	return list;
2353 }
2354 
get_align_score(SeqAlignPtr sap,FloatHiPtr score)2355 static Boolean get_align_score(SeqAlignPtr sap, FloatHiPtr score)
2356 {
2357 
2358         ScorePtr scp;
2359 
2360         if(sap->score == NULL || score == NULL)
2361                 return FALSE;
2362 	*score = 0;
2363         scp = sap->score;
2364 	if(scp->choice == 2)
2365 	{
2366         	*score = scp->value.realvalue;
2367         	return TRUE;
2368 	}
2369 	else
2370 		return FALSE;
2371 }
2372 
2373 typedef struct align_score {
2374 	SeqAlignPtr align;
2375 	FloatHi score;
2376 }AlignScore, PNTR AlignScorePtr;
2377 
AlignScoreCompProc(VoidPtr ptr1,VoidPtr ptr2)2378 static int LIBCALLBACK AlignScoreCompProc(VoidPtr ptr1, VoidPtr ptr2)
2379 {
2380   ValNodePtr   vnp1;
2381   ValNodePtr   vnp2;
2382   AlignScorePtr asp1, asp2;
2383 
2384   if (ptr1 != NULL && ptr2 != NULL) {
2385     vnp1 = *((ValNodePtr PNTR) ptr1);
2386     vnp2 = *((ValNodePtr PNTR) ptr2);
2387     if (vnp1 != NULL && vnp2 != NULL) {
2388       asp1 = (AlignScorePtr) vnp1->data.ptrvalue;
2389       asp2 = (AlignScorePtr) vnp2->data.ptrvalue;
2390       if (asp1 != NULL && asp2 != NULL) {
2391 	if(asp1->score > asp2->score)
2392 		return -1;
2393 	else if(asp1->score < asp2->score)
2394 		return 1;
2395 	else
2396 		return 0;
2397    }
2398   }
2399   }
2400   return 0;
2401 }
2402 
2403 
sort_align_by_score(SeqAlignPtr PNTR halign)2404 NLM_EXTERN SeqAlignPtr sort_align_by_score(SeqAlignPtr PNTR halign)
2405 {
2406 	ValNodePtr list, curr;
2407 	AlignScorePtr asp;
2408 	Int4 score;
2409 	FloatHi bit_score, evalue;
2410 	Int4 number;
2411 	Boolean comp = FALSE;
2412 	SeqAlignPtr align, prev;
2413 
2414 	list = NULL;
2415 	align = *halign;
2416 	while(align)
2417 	{
2418 		asp = MemNew(sizeof(AlignScore));
2419 		asp->align = align;
2420 		if(GetScoreAndEvalue(align, &score, &bit_score, &evalue, &number))
2421 			asp->score = (FloatHi)score;
2422 		else
2423 			get_align_score(align, &(asp->score));
2424 		if(asp->score > 0.0)
2425 			comp = TRUE;
2426 		ValNodeAddPointer(&list, 0, asp);
2427 		align = align->next;
2428 	}
2429 	if(list == NULL)
2430 		return NULL;
2431 	if(list->next == NULL || !comp)
2432 	{
2433 		ValNodeFreeData(list);
2434 		return (*halign);
2435 	}
2436 
2437 	list = SortValNode(list, AlignScoreCompProc);
2438 	prev = NULL;
2439 	for(curr = list; curr != NULL; curr = curr->next)
2440 	{
2441 		asp = curr->data.ptrvalue;
2442 		asp->align->next = NULL;
2443 		if(prev == NULL)
2444 		{
2445 			*halign = asp->align;
2446 		}
2447 		else
2448 			prev->next = asp->align;
2449 		prev = asp->align;
2450 	}
2451 	ValNodeFreeData(list);
2452 	return (*halign);
2453 }
2454 
2455 
2456