1 /* salprop.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: salprop.c
27 *
28 * Author: Colombe Chappey
29 *
30 * Version Creation Date: 8/20/99
31 *
32 * File Description:
33 *
34 * Modifications:
35 * --------------------------------------------------------------------------
36 * Date Name Description of modification
37 * ------- ---------- -----------------------------------------------------
38 *
39 *
40 * ==========================================================================
41 */
42 #include <salprop.h>
43 #include <salutil.h>
44 #include <salstruc.h>
45 #include <salsap.h>
46 #include <sqnutils.h>
47 #include <satutil.h>
48 #include <explore.h>
49
50 /**********************************************************************
51 *** PropagateFeatureProc
52 *** build features taking one selected feature as template
53 ***
54 ***
55 LIST starts with 15
56 ***********************************************************************/
57
58 #define ADD_TITLE 1
59 #define ADD_RRNA 2
60 #define ADD_CDS 3
61 #define ADD_PROT 4
62 #define ADD_IMP 5
63 #define ADD_PUB 6
64 #define ADD_GENE 7
65 #define ADD_REGION 8
66 #define ADD_BOND 9
67 #define ADD_SITE 10
68
69 typedef struct applyformdata {
70 Int2 type;
71 Boolean noLeft;
72 Boolean noRight;
73 CharPtr geneName;
74 ValNodePtr protName;
75 CharPtr featcomment;
76 CharPtr defline;
77 Uint2 input_entityID;
78 } ApplyFormData, PNTR ApplyFormPtr;
79
80 typedef struct partials {
81 Boolean p3, p5;
82 } ParTials, PNTR ParTialsPtr;
83
84 typedef struct ccid {
85 SeqIdPtr sip;
86 SeqEntryPtr sep;
87 BioseqPtr bsp;
88 Boolean found;
89 } CcId, PNTR CcIdPtr;
90
91
FindSeqEntryForSeqIdCallback(SeqEntryPtr sep,Pointer mydata,Int4 index,Int2 indent)92 static void FindSeqEntryForSeqIdCallback (SeqEntryPtr sep, Pointer mydata,
93 Int4 index, Int2 indent)
94 {
95 BioseqPtr bsp;
96 SeqIdPtr sip;
97 CcIdPtr cip;
98 Uint1 val;
99
100 if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
101 cip = (CcIdPtr)mydata;
102 if (!(cip->found) && IS_Bioseq(sep)) {
103 bsp = (BioseqPtr) sep->data.ptrvalue;
104 if (bsp!=NULL) {
105 for (sip = bsp->id; sip!=NULL; sip=sip->next)
106 {
107 if ((val=SeqIdComp(cip->sip, sip)) == SIC_YES) {
108 cip->sep = sep;
109 cip->bsp = bsp;
110 cip->found = TRUE;
111 break;
112 }
113 }
114 }
115 }
116 }
117 }
118
is_id_unique(Uint2 entityID,SeqIdPtr sip)119 static Boolean is_id_unique (Uint2 entityID, SeqIdPtr sip)
120 {
121 SeqEntryPtr sep;
122 CcId ci;
123
124 sep = GetTopSeqEntryForEntityID (entityID);
125 ci.sip = SeqIdDup (sip);
126 ci.sep = NULL;
127 ci.bsp=NULL;
128 ci.found=FALSE;
129 SeqEntryExplore(sep,(Pointer)&ci, FindSeqEntryForSeqIdCallback);
130 SeqIdFree (ci.sip);
131 ci.sep=NULL;
132 ci.bsp=NULL;
133 return (!(ci.found));
134 }
135
stringhasnotext(CharPtr str)136 static Boolean stringhasnotext (CharPtr str)
137
138 {
139 Char ch;
140
141 if (str != NULL) {
142 ch = *str;
143 while (ch != '\0') {
144 if (ch > ' ' && ch <= '~') {
145 return FALSE;
146 }
147 str++;
148 ch = *str;
149 }
150 }
151 return TRUE;
152
153 }
154
155 /**********************************************************
156 *** GetFeatureForEditor
157 ***
158 ***********************************************************/
is_newfeat(ValNodePtr feathead,Uint2 eID,Uint2 subtype,SeqLocPtr slp)159 static Boolean is_newfeat (ValNodePtr feathead, Uint2 eID, Uint2 subtype, SeqLocPtr slp)
160 {
161 SelEdStructPtr psp;
162 ValNodePtr vnp = NULL;
163
164 if (feathead == NULL) {
165 return TRUE;
166 }
167 for (vnp = feathead; vnp != NULL; vnp = vnp->next)
168 {
169 psp = (SelEdStructPtr) vnp->data.ptrvalue;
170 if (psp->entityID == eID && psp->itemsubtype == vnp->choice)
171 {
172 if (SeqLocCompare(slp, (SeqLocPtr) psp->region) == SLC_A_EQ_B) {
173 return FALSE;
174 }
175 }
176 }
177 return TRUE;
178 }
179
180
get_names_from_prot(ValNodePtr sfp_product)181 static ValNodePtr get_names_from_prot (ValNodePtr sfp_product)
182 {
183 BioseqPtr bsp;
184 SeqAnnotPtr annot;
185 SeqFeatPtr sfpp;
186 ProtRefPtr prp;
187 ValNodePtr vnp,
188 new_vnp=NULL;
189 CharPtr name;
190
191 bsp=BioseqLockById (SeqLocId(sfp_product));
192 if (bsp){
193 if (bsp->annot){
194 for (annot=bsp->annot;annot!=NULL;annot=annot->next){
195 if (annot->type==1){
196 sfpp=(SeqFeatPtr)annot->data;
197 if (sfpp->data.choice==SEQFEAT_PROT) {
198 prp=(ProtRefPtr)sfpp->data.value.ptrvalue;
199 for (vnp = prp->name;vnp!=NULL;vnp=vnp->next){
200 name = StringSave((CharPtr)vnp->data.ptrvalue);
201 ValNodeAddPointer(&new_vnp, 0, name);
202 }
203 }
204 }
205 }
206 }
207 BioseqUnlock(bsp);
208 }
209 return new_vnp;
210 }
211
212
PosInSeqLoc(Int4 position,SeqLocPtr location)213 static Int4 PosInSeqLoc (Int4 position, SeqLocPtr location)
214 {
215 SeqLocPtr slp;
216 Int4 start,
217 lens,
218 sum=0;
219 if (location ==NULL)
220 return -1;
221 start = SeqLocStart(location);
222 if (location->choice == 4)
223 {
224 position += start;
225 return position;
226 }
227 if (location->choice == 5) {
228 slp=(SeqLocPtr)location->data.ptrvalue;
229 for (; slp!=NULL; slp=slp->next)
230 {
231 if (slp->choice == 4) {
232 lens = SeqLocLen(slp);
233 if (position <= (sum+lens)) {
234 start = SeqLocStart(slp);
235 position = start + (position - sum);
236 return position;
237 }
238 sum += lens;
239 }
240 }
241 }
242 /****
243 while ((slp=SeqLocFindNext(location, slp))!=NULL)
244 {
245 lens = SeqLocLen(slp);
246 if (position <= (sum+lens)) {
247 start = SeqLocStart(slp);
248 position = start + (position - sum) -1;
249 return position;
250 }
251 sum += lens;
252 }
253 ***/
254 return -1;
255 }
256
257
FindSqFeatItem(GatherContextPtr gcp)258 static Boolean FindSqFeatItem (GatherContextPtr gcp)
259 {
260 SeqFeatPtr PNTR sfpp;
261
262 sfpp = (SeqFeatPtr PNTR) gcp->userdata;
263 if (sfpp != NULL && gcp->thistype == OBJ_SEQFEAT) {
264 *sfpp = (SeqFeatPtr) gcp->thisitem;
265 }
266 return TRUE;
267 }
268
269 /************************************************************
270 ***
271 *** CopySeqLocFromSeqAlign
272 *** map source_loc to the target sequence defined by target_sip.
273 *** Calls map_one_location, that maps one Seq-loc
274 *** with gap_choice == TAKE_GAP_CHOICE
275 *** because one SEQLOCINT seqloc has to be stoppped at gaps
276 *** when mapped, and returns SEQLOCMIX
277 ***
278 #define DEFAULT_GAP_CHOICE 0 * will split seqloc
279 * if gaps length > MAX_GAP_LEN_BY_DEFAULT *
280 #define IGNORE_GAP_CHOICE 1 * extends over gaps *
281 #define TAKE_GAP_CHOICE 2 * split at gaps *
282 #define MAX_GAP_LEN_BY_DEFAULT 10 *the maximum allowd length of gap*
283 ***
284 *************************************************************/
CopySeqLocFromSeqAlign(SeqFeatPtr source_sfp,SeqIdPtr target_id,SeqIdPtr s_id,SeqAlignPtr align,Uint1 gap_choice,Uint1 * frame)285 static SeqLocPtr CopySeqLocFromSeqAlign (SeqFeatPtr source_sfp, SeqIdPtr target_id, SeqIdPtr s_id, SeqAlignPtr align, Uint1 gap_choice, Uint1 *frame)
286 {
287 GatherRange gr;
288 SeqLocPtr slp, source_slp, c_slp;
289 SeqLocPtr process_slp, new_slp,
290 new_location;
291 Boolean check_gap;
292
293 SeqIdPtr sip, source_id;
294 Boolean map_to_source;
295 BioseqPtr source_bsp;
296 CdRegionPtr crp;
297 Int4 cds_len;
298 Int4 aa_start, aa_stop;
299 Int4 a_start, a_stop;
300 Int4 r_start, r_stop, e_start, e_stop;
301 Int4 frame_offset;
302 Int4 offset;
303 Uint1 new_frame;
304 Boolean stop_here;
305 Boolean had_first_seg;
306 Boolean p5, p3;
307
308 if(source_sfp == NULL || target_id == NULL || align == NULL)
309 return NULL;
310
311 if(source_sfp->location == NULL)
312 return NULL;
313
314 sip = SeqLocId(source_sfp->location);
315 if(sip == NULL)
316 return NULL;
317
318 if(s_id == NULL)
319 source_id = sip;
320 else
321 source_id = s_id;
322
323 source_bsp = BioseqLockById(source_id);
324
325 if(source_bsp == NULL)
326 {
327 return NULL;
328 }
329
330 map_to_source = FALSE; /*segmented sequence may have locations on different segment sequences*/
331
332 if(!BioseqMatch(source_bsp, sip))
333 {
334 ErrPostEx (SEV_ERROR, 0, 0, "Source Bioseq does not match the Seq-id of the Source Seq-feat");
335 BioseqUnlock(source_bsp);
336 return NULL;
337 }
338 else
339 map_to_source = TRUE;
340
341 source_slp = NULL;
342 if(!map_to_source)
343 source_slp = SeqLocIntNew(0, source_bsp->length-1, Seq_strand_plus, sip);
344 if(source_sfp->data.choice == 3)
345 crp = (CdRegionPtr)source_sfp->data.value.ptrvalue;
346 else
347 crp = NULL;
348
349 if(gap_choice == DEFAULT_GAP_CHOICE)
350 {
351 if(source_sfp->data.choice == SEQFEAT_CDREGION || source_sfp->data.choice == SEQFEAT_RNA)
352 check_gap = TRUE;
353 else
354 check_gap = FALSE;
355 }
356 else
357 check_gap = (Boolean) (gap_choice == TAKE_GAP_CHOICE);
358
359 slp = NULL;
360 process_slp = NULL;
361 cds_len = 0;
362 new_frame = 0;
363 a_start = -1;
364 a_stop = -1;
365 e_start = -1;
366 e_stop = -1;
367 stop_here = FALSE;
368 had_first_seg = FALSE;
369 while((slp = SeqLocFindNext(source_sfp->location, slp)) != NULL && !stop_here)
370 {
371 c_slp = NULL;
372 new_slp = NULL;
373
374 if(map_to_source == FALSE)
375 { /* map the location to the coordinates on the source */
376 if(SeqLocOffset(source_slp, slp, &gr, 0))
377 {
378 if(gr.l_trunc == FALSE && gr.r_trunc == FALSE)
379 c_slp = SeqLocIntNew(gr.left, gr.right, gr.strand, source_id);
380 }
381 }
382 else
383 c_slp = slp;
384
385 if(c_slp != NULL)
386 {
387
388 new_slp = map_one_location(c_slp, align, target_id, gap_choice, &r_start, &r_stop);
389 if(new_slp != NULL)
390 {
391 ValNodeLink(&process_slp, new_slp);
392 if(e_start == -1)
393 e_start = r_start;
394 else
395 e_start = MIN(e_start, r_start);
396 if(e_stop == -1)
397 e_stop = r_stop;
398 else
399 e_stop = MAX(e_stop, r_stop);
400
401 if(crp != NULL) /*for coding region features*/
402 {
403 /*calculate the frame for the first exon*/
404 if(!had_first_seg)
405 {
406 new_frame = (Int4)crp->frame;
407
408 /* JINGUI's CALCUL
409 THAT I do not understand ******************************
410 {{
411 Int4 c_frame_offset;
412 if(crp->frame > 1)
413 frame_offset = (Int4)crp->frame -1L;
414 else
415 frame_offset = 0L;
416
417 c_frame_offset = frame_offset;
418 if(cds_len > 0)
419 {
420 c_frame_offset = (cds_len - frame_offset)%3;
421 if(c_frame_offset > 0)
422 c_frame_offset = 3 - c_frame_offset;
423 }
424 if(SeqLocStrand(c_slp) == Seq_strand_minus)
425 frame_offset = (SeqLocStop(c_slp) - r_stop)%3;
426 else
427 frame_offset = (r_start - SeqLocStart(c_slp))%3;
428 if(frame_offset > 0)
429 c_frame_offset = (frame_offset + c_frame_offset)%3;
430 if(c_frame_offset > 1)
431 new_frame = (Uint1) (c_frame_offset + 1);
432 else
433 new_frame = 1;
434 }}
435 END of calcul of new_frame **/
436 }
437
438 /*calculate the position in the amino acid*/
439 if(SeqLocStrand(c_slp) == Seq_strand_minus)
440 offset = SeqLocStop(c_slp) - r_stop;
441 else
442 offset = r_start - SeqLocStart(c_slp);
443
444 if(crp->frame > 1)
445 frame_offset = (Int4)crp->frame -1L;
446 else
447 frame_offset = 0L;
448 aa_start = (cds_len + offset - frame_offset)/3;
449 if(aa_start < 0)
450 aa_start = 0 ;
451
452 if(SeqLocStrand(c_slp) == Seq_strand_minus)
453 offset = SeqLocStop(c_slp) - r_start;
454 else
455 offset = r_stop- SeqLocStart(c_slp);
456 aa_stop= (cds_len + offset - frame_offset)/3;
457 if(aa_stop < 0 )
458 aa_stop = 0;
459 if(a_start == -1)
460 a_start = aa_start;
461 else
462 a_start = MIN(a_start, aa_start);
463
464 if(a_stop == -1)
465 a_stop = aa_stop;
466 else
467 a_stop = MAX(a_stop, aa_stop);
468
469 }/*finishing processing the CDS region*/
470 had_first_seg = TRUE;
471
472 }
473 else
474 stop_here = TRUE;
475 }
476 else
477 stop_here = TRUE;
478 cds_len += SeqLocLen(c_slp);
479 if(c_slp != NULL && !map_to_source)
480 SeqLocFree(c_slp);
481 }
482 if(process_slp == NULL)
483 {
484 if(source_slp != NULL)
485 SeqLocFree(source_slp);
486 BioseqUnlock(source_bsp);
487 return NULL;
488 }
489 new_location = SeqLocPackage(process_slp);
490 CheckSeqLocForPartial (source_sfp->location, &p5, &p3);
491 SetSeqLocPartial (new_location, p5, p3);
492 BioseqUnlock(source_bsp);
493 *frame = new_frame;
494 return new_location;
495 }
496
497
498
499
500
CheckPartialInterval(SeqFeatPtr sfp,Int4 nbsp_length,Int4 stoptransl,Uint1 frame,Boolean include_stop,Boolean exon,ParTialsPtr ppp)501 static Boolean CheckPartialInterval (SeqFeatPtr sfp, Int4 nbsp_length, Int4 stoptransl,
502 Uint1 frame, Boolean include_stop, Boolean exon,
503 ParTialsPtr ppp)
504 {
505 ByteStorePtr bs;
506 CharPtr prot,
507 prot2;
508 SeqLocPtr sfp_location = sfp->location,
509 new_sfp_location = sfp_location;
510 SeqIdPtr sfp_sip;
511 Int4 strlens,
512 strlens2,
513 start,
514 stop,
515 j;
516 Boolean p5=FALSE,
517 p3=FALSE,
518 stop_codon_found = FALSE,
519 until_end=TRUE,
520 changed;
521
522 bs = ProteinFromCdRegion (sfp, include_stop);
523 if (bs==NULL)
524 return FALSE;
525 prot = (CharPtr)BSMerge (bs, NULL);
526 if (prot)
527 {
528 strlens = StringLen (prot);
529 p5 = (Boolean) (prot[(Int4)0] != 'M');
530 stop_codon_found = FALSE;
531 for (j=0; j<strlens; j++) {
532 if (prot[j] == '*') {
533 stop_codon_found=TRUE;
534 break;
535 }
536 }
537 until_end=TRUE;
538 if (!stop_codon_found)
539 {
540 stop = (Int4)(nbsp_length-1);
541 until_end = (Boolean) (stop==SeqLocStop(sfp_location));
542 }
543 if (stop_codon_found && j==strlens-1) /*------- same length (make sure !p3) */
544 {
545 p3=FALSE;
546 /*
547 prot [(Int4)(strlens-1)] = '\0';
548 bs = BSFree (bs);
549 bs = BSNew (StringLen (prot)+5);
550 BSWrite (bs, (VoidPtr) prot, (Int4) StringLen (prot));
551 */
552 }
553 else if (stop_codon_found && j<strlens-1) /*---- shorter */
554 {
555 if (stoptransl & PROPAG_SETSTOP)
556 {
557 prot [(Int4)(j)] = '\0';
558 strlens2 = StringLen (prot);
559 if (strlens2>1)
560 {
561 bs = BSFree (bs);
562 bs = BSNew (strlens2 +5);
563 BSWrite (bs, (VoidPtr) prot, (Int4) strlens2);
564 start = PosInSeqLoc (3*strlens2+2, sfp_location) +1;
565 if (frame > 1)
566 {
567 start += (frame-1);
568 }
569 stop = SeqLocStop (sfp_location);
570 sfp_sip = SeqLocId (sfp_location);
571 sfp_location = SeqLocDelete (sfp_location, sfp_sip, start, stop, FALSE, &changed);
572 p3=FALSE;
573 }
574 else {
575 ErrPostEx (SEV_ERROR, 0, 0, "New feature too short");
576 }
577 }
578 else {
579 p3=TRUE;
580 /*
581 prot [(Int4)(strlens-1)] = '\0';
582 bs = BSFree (bs);
583 bs = BSNew (StringLen (prot)+5);
584 BSWrite (bs, (VoidPtr) prot, (Int4) StringLen (prot));
585 */
586 }
587 }
588 else if (!stop_codon_found && until_end)
589 {
590 p3=TRUE;
591 /*
592 prot [(Int4)(strlens-1)] = '\0';
593 bs = BSFree (bs);
594 bs = BSNew (StringLen (prot)+5);
595 BSWrite (bs, (VoidPtr) prot, (Int4) StringLen (prot));
596 */
597 }
598 else if (!stop_codon_found && !until_end && exon)
599 {
600 p3=TRUE;
601 /*
602 prot [(Int4)(strlens-1)] = '\0';
603 bs = BSFree (bs);
604 bs = BSNew (StringLen (prot)+5);
605 BSWrite (bs, (VoidPtr) prot, (Int4) StringLen (prot));
606 */
607 }
608 else if (!stop_codon_found && !until_end && !(stoptransl & PROPAG_GETSTOP))
609 {
610 p3=TRUE;
611 /*
612 prot [(Int4)(strlens-1)] = '\0';
613 bs = BSFree (bs);
614 bs = BSNew (StringLen (prot)+5);
615 BSWrite (bs, (VoidPtr) prot, (Int4) StringLen (prot));
616 */
617 }
618 else /*------- longer */
619 {
620 j = stop - SeqLocStop(sfp_location);
621 if (j>1)
622 {
623 sfp_sip = SeqLocId (sfp_location);
624 stop = SeqLocStop (sfp_location);
625 new_sfp_location = (SeqLocPtr)AsnIoMemCopy ((Pointer) sfp_location, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
626 new_sfp_location = SeqLocInsert (new_sfp_location, sfp_sip, stop, j, FALSE, NULL);
627 sfp_location = new_sfp_location;
628 ValNodeFree (sfp->location);
629 sfp->location = sfp_location;
630 bs = BSFree (bs);
631 bs = ProteinFromCdRegion (sfp, FALSE);
632 if (bs)
633 {
634 j = 3*BSLen(bs)+2;
635 if (j <= SeqLocLen (sfp_location)) /*------- longer with * (!p3) */
636 {
637 start = PosInSeqLoc (j, sfp_location) +1;
638 if (frame > 1)
639 {
640 start += (frame-1);
641 }
642 stop = SeqLocStop (sfp_location);
643 sfp_location = SeqLocDelete (sfp_location, sfp_sip, start, stop, FALSE, &changed);
644 p3 = FALSE;
645 }
646 else { /*------- longer without * (p3) */
647 p3 = TRUE;
648 }
649 prot2 = (CharPtr)BSMerge (bs, NULL);
650 p5 = (Boolean) (prot2[(Int4)0] != 'M');
651 }
652 else
653 ErrPostEx (SEV_ERROR, 0, 0, "Propagate error [22]");
654 }
655 else {
656 ErrPostEx (SEV_ERROR, 0, 0, "Propagate error [33]");
657 }
658 }
659 sfp->location = sfp_location;
660 }
661 ppp->p3 = p3;
662 ppp->p5 = p5;
663 return 0;
664 }
665
666
ApplyBioFeatToSeqEntry(SeqEntryPtr sep,ApplyFormPtr afp,SeqLocPtr slp,Uint1 frame,Int4 stoptransl,SeqFeatPtr sfp_source,Boolean exon,SeqIdPtr prot_id)667 static Boolean ApplyBioFeatToSeqEntry (SeqEntryPtr sep, ApplyFormPtr afp, SeqLocPtr slp, Uint1 frame, Int4 stoptransl, SeqFeatPtr sfp_source, Boolean exon, SeqIdPtr prot_id)
668
669 {
670 CdRegionPtr crp;
671 GeneRefPtr grp;
672 SeqEntryPtr nsep;
673 ValNodePtr sdp;
674 SeqFeatPtr sfp;
675
676 Char string_id[128];
677 Boolean include_stop = TRUE,
678 sfp_p3, sfp_p5;
679 ParTials ppp;
680
681 if (sep == NULL || afp == NULL)
682 return FALSE;
683 nsep = FindNucSeqEntry (sep);
684 if (nsep == NULL)
685 return FALSE;
686 string_id[0]='\0';
687 if (afp->type == ADD_TITLE) {
688 if (! stringhasnotext(afp->defline)) {
689 sdp = CreateNewDescriptor (sep, Seq_descr_title);
690 if (sdp != NULL) {
691 sdp->data.ptrvalue = (Pointer) StringSave (afp->defline);
692 }
693 }
694 } else if (afp->type == ADD_GENE) {
695 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_GENE, sfp_source);
696 } else if (afp->type == ADD_CDS) {
697 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_CDREGION, sfp_source);
698 } else if (afp->type == ADD_RRNA) {
699 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_RNA, sfp_source);
700 } else if (afp->type == ADD_PUB) {
701 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_PUB, sfp_source);
702 } else if (afp->type == ADD_IMP) {
703 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_IMP, sfp_source);
704 } else if (afp->type == ADD_REGION) {
705 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_REGION, sfp_source);
706 } else if (afp->type == ADD_BOND) {
707 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_BOND, sfp_source);
708 } else if (afp->type == ADD_SITE) {
709 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_SITE, sfp_source);
710 }
711 if (sfp != NULL)
712 {
713 sfp->location = SeqLocFree (sfp->location);
714 sfp->location = (SeqLocPtr) AsnIoMemCopy ((Pointer) slp, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
715 if (! stringhasnotext(afp->featcomment)) {
716 sfp->comment = (CharPtr) StringSave (afp->featcomment);
717 }
718 SetSeqLocPartial (sfp->location, afp->noLeft, afp->noRight);
719 sfp->partial = (afp->noLeft || afp->noRight);
720
721 if (afp->type == ADD_CDS)
722 {
723 if (sfp->product!=NULL) {
724 ValNodeFree (sfp->product);
725 sfp->product=NULL;
726 }
727 crp = (CdRegionPtr) (sfp->data.value.ptrvalue);
728 if (crp!=NULL)
729 {
730 crp->frame = frame;
731 CheckPartialInterval (sfp, ((BioseqPtr)nsep->data.ptrvalue)->length, stoptransl, frame, include_stop, exon, &ppp);
732 CheckSeqLocForPartial (sfp->location, &sfp_p5, &sfp_p3);
733 if (!sfp_p5 && ppp.p5)
734 sfp_p5 = ppp.p5;
735 afp->noLeft = sfp_p5;
736 afp->noRight = ppp.p3;
737 SetSeqLocPartial (sfp->location, afp->noLeft, afp->noRight);
738 sfp->partial = (afp->noLeft || afp->noRight);
739
740 if (prot_id==NULL) {
741 prot_id = MakeNewProteinSeqId (sfp->location, NULL);
742 }
743 SeqIdWrite (prot_id, string_id , PRINTID_FASTA_LONG, 128);
744 AddQualifierToFeature (sfp, "protein_id", string_id);
745 if (afp->protName)
746 AddQualifierToFeature (sfp, "product", (CharPtr)afp->protName->data.ptrvalue);
747 }
748 }
749 if (afp->type==ADD_CDS || afp->type==ADD_RRNA || afp->type==ADD_IMP)
750 {
751 if (! stringhasnotext (afp->geneName)) {
752 grp = CreateNewGeneRef (afp->geneName, NULL, NULL, FALSE);
753 if (grp != NULL)
754 {
755 sfp = CreateNewFeature (nsep, NULL, SEQFEAT_GENE, NULL);
756 if (sfp != NULL)
757 {
758 sfp->data.value.ptrvalue = (Pointer) grp;
759 sfp->location = SeqLocFree (sfp->location);
760 sfp->location = (SeqLocPtr)AsnIoMemCopy ((Pointer) slp, (AsnReadFunc) SeqLocAsnRead, (AsnWriteFunc) SeqLocAsnWrite);
761 SetSeqLocPartial (sfp->location, afp->noLeft, afp->noRight);
762 sfp->partial = (afp->noLeft || afp->noRight);
763 }
764 }
765 }
766 }
767 }
768 return TRUE;
769 }
770
771
ApplyNewSeqFeat(ValNodePtr vnpfeat,Int4 stoptransl,Boolean keep_protID)772 static Boolean ApplyNewSeqFeat (ValNodePtr vnpfeat, Int4 stoptransl, Boolean keep_protID)
773 {
774 BioseqPtr target_bsp;
775 ValNodePtr vnpf;
776 ApplyFormData af;
777 SelEdStructPtr sesp;
778 SeqFeatPtr sfp;
779 SeqAnnotPtr sap;
780 SeqEntryPtr sep,
781 sep2,
782 sep_head;
783 SeqLocPtr new_slp;
784 SeqIdPtr protid = NULL;
785 Uint2 entityID;
786 CdRegionPtr crp;
787 CodeBreakPtr cbp;
788 CcId ci;
789 Int2 genCode;
790 Boolean val = FALSE,
791 val2,
792 p5,
793 p3,
794 exon;
795
796 if (vnpfeat!=NULL)
797 {
798 MemSet ((Pointer)(&af), 0, sizeof(ApplyFormData));
799 af.geneName = NULL;
800 af.protName = NULL;
801 af.featcomment = NULL;
802 af.defline = NULL;
803 for (vnpf=vnpfeat; vnpf!=NULL; vnpf=vnpf->next)
804 {
805 sesp = (SelEdStructPtr) vnpf->data.ptrvalue;
806 new_slp = (SeqLocPtr) sesp->region;
807 sep_head = GetTopSeqEntryForEntityID (sesp->entityID);
808
809 exon = FALSE;
810 val = FALSE;
811 sep2 = NULL;
812 ci.sip = SeqIdDup (SeqIdFindBest(SeqLocId(new_slp), 0));
813 ci.sep = NULL;
814 ci.bsp = NULL;
815 ci.found = FALSE;
816 SeqEntryExplore(sep_head,(Pointer)&ci, FindSeqEntryForSeqIdCallback);
817 if (ci.bsp!=NULL && ci.sep!=NULL)
818 {
819 af.input_entityID = SeqMgrGetEntityIDForSeqEntry(ci.sep);
820 sep2 = GetBestTopParentForData (af.input_entityID, ci.bsp);
821 SeqIdFree (ci.sip);
822 }
823 if (sep2 != NULL && vnpf!=NULL && new_slp!=NULL)
824 {
825 af.input_entityID = SeqMgrGetEntityIDForSeqEntry(sep2);
826 if (af.input_entityID != 0)
827 {
828 sep = GetTopSeqEntryForEntityID (af.input_entityID);
829 sfp = (SeqFeatPtr)(sesp->data->data.ptrvalue);
830 if (sep != NULL && sfp!=NULL)
831 {
832 if (sesp->itemsubtype == FEATDEF_GENE) {
833 af.type = ADD_GENE;
834 af.geneName = sesp->label;
835 }
836 else if (sesp->itemsubtype == FEATDEF_CDS) {
837 af.type = ADD_CDS;
838
839 {{
840 CheckSeqLocForPartial (new_slp, &p5, &p3);
841 if (p3) {
842 exon=(Boolean)(SeqLocStop(new_slp) < ci.bsp->length-1);
843 }
844 }}
845 /*
846 if (sfp->data.value.ptrvalue!=NULL){
847 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
848 af.geneName= StringSave (grp->locus);
849 }
850 */
851 if (sfp->data.choice == SEQFEAT_CDREGION) {
852 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
853 if (crp->code_break !=NULL) {
854 for (cbp=crp->code_break; cbp!=NULL; cbp=cbp->next)
855 cbp->loc = SeqLocReplaceID (cbp->loc, SeqLocId(new_slp));
856 }
857 if (sfp->product!=NULL)
858 {
859 af.protName = get_names_from_prot (sfp->product);
860 if (keep_protID) {
861 if ((val2=is_id_unique (entityID, SeqLocId(sfp->product))))
862 protid = SeqIdDup (SeqLocId(sfp->product));
863 }
864 }
865
866 }
867 if (af.protName==NULL && sesp->label)
868 ValNodeAddPointer (&(af.protName), 0, sesp->label);
869 }
870 else if (sesp->itemsubtype == FEATDEF_preRNA ) {
871 af.type = ADD_RRNA;
872 }
873 else if (sesp->itemsubtype == FEATDEF_mRNA ) {
874 af.type = ADD_RRNA;
875 }
876 else if (sesp->itemsubtype == FEATDEF_tRNA ) {
877 af.type = ADD_RRNA;
878 }
879 else if (sesp->itemsubtype == FEATDEF_rRNA ) {
880 af.type = ADD_RRNA;
881 }
882 else if (sesp->itemsubtype == FEATDEF_snRNA ) {
883 af.type = ADD_RRNA;
884 }
885 else if (sesp->itemsubtype == FEATDEF_scRNA ) {
886 af.type = ADD_RRNA;
887 }
888 else if (sesp->itemsubtype == FEATDEF_otherRNA ) {
889 af.type = ADD_RRNA;
890 }
891 else if (sesp->itemsubtype == FEATDEF_PUB ) {
892 af.type = ADD_PUB;
893 }
894 else if (sesp->itemsubtype == FEATDEF_REGION ) {
895 af.type = ADD_REGION;
896 }
897 else if (sesp->itemsubtype == FEATDEF_BOND ) {
898 af.type = ADD_BOND;
899 }
900 else if (sesp->itemsubtype == FEATDEF_SITE ) {
901 af.type = ADD_SITE;
902 }
903 else if (sesp->itemsubtype >= first_GBFeat && sesp->itemsubtype < number_GBFeat+first_GBFeat) {
904 af.type = ADD_IMP;
905 }
906 else af.type = 0;
907 if (af.type > 0) {
908 CheckSeqLocForPartial (new_slp, &p5, &p3);
909 af.noLeft = p5;
910 af.noRight = p3;
911 val = ApplyBioFeatToSeqEntry (sep2, &af, new_slp, sesp->codonstart, stoptransl, sfp, exon, protid);
912 entityID = ObjMgrGetEntityIDForPointer (ci.bsp);
913 target_bsp = BioseqLockById ((SeqIdPtr) SeqLocId(new_slp));
914 if (target_bsp)
915 {
916 genCode = SeqEntryToGeneticCode (sep2, NULL, NULL, 0);
917 sap = SeqAnnotNew ();
918 sap->type = 1;
919 sap->data = sfp;
920 SetEmptyGeneticCodes (sap, genCode);
921 sap->data= NULL;
922 SeqAnnotFree(sap);
923 PromoteXrefs (sfp, target_bsp, entityID);
924 BioseqUnlock (target_bsp);
925 }
926 }
927 }
928 }
929 }
930 }
931 }
932 return val;
933 }
934
935 /**********************************************************************
936 *** PropagateFeatureBySeqLock
937 *** propagates features (seqfeat) from a bioseq (source_bspitemID)
938 *** to another (target_sep)
939 ***
940 **********************************************************************/
941
PropagateFeatureBySeqLock(SeqAnnotPtr sap,Uint4 source_bspitemID,Uint2 target_entityID,SeqEntryPtr target_sep,ValNodePtr seqfeat,Uint1 gap_choice)942 NLM_EXTERN void PropagateFeatureBySeqLock (SeqAnnotPtr sap, Uint4 source_bspitemID, Uint2 target_entityID, SeqEntryPtr target_sep, ValNodePtr seqfeat, Uint1 gap_choice)
943 {
944 BioseqPtr target_bsp;
945 SeqFeatPtr source_sfp;
946 SeqAlignPtr salp;
947 SelEdStructPtr feat;
948 SeqIdPtr featsip;
949 SeqIdPtr target_sip;
950 SeqLocPtr featslp;
951 SeqLocPtr new_slp;
952 ValNodePtr vnpf;
953 Uint2 subtype;
954 Uint1 frame;
955 Uint1 gap_choice_subtype;
956 Boolean val;
957
958 if (sap != NULL && target_sep != NULL && seqfeat != NULL) {
959 if (sap != NULL)
960 {
961 target_bsp = (BioseqPtr) target_sep->data.ptrvalue;
962 salp = (SeqAlignPtr) sap->data;
963 for (vnpf= seqfeat; vnpf!=NULL; vnpf=vnpf->next)
964 {
965 feat = (SelEdStructPtr) vnpf->data.ptrvalue;
966 val = (Boolean)(feat->bsp_itemID == source_bspitemID);
967 if (val) {
968 featslp = (SeqLocPtr) feat->region;
969 featsip = SeqLocId (featslp);
970 subtype = vnpf->choice;
971 GatherItem (feat->entityID, feat->itemID, OBJ_SEQFEAT, (Pointer) (&source_sfp), FindSqFeatItem);
972 if (source_sfp != NULL) {
973 target_sip=target_bsp->id;
974 if (subtype == FEATDEF_GENE)
975 gap_choice_subtype = IGNORE_GAP_CHOICE;
976 else if (subtype == FEATDEF_PUB)
977 gap_choice_subtype = IGNORE_GAP_CHOICE;
978 else
979 gap_choice_subtype = gap_choice;
980 new_slp = CopySeqLocFromSeqAlign (source_sfp, target_sip, featsip, salp, gap_choice_subtype, &frame);
981 if (new_slp != NULL) {
982 if (is_newfeat (seqfeat, target_entityID, subtype, new_slp))
983 {
984 new_slp = SeqLocReplaceID(new_slp, SeqLocId(source_sfp->location));
985 SeqLocFree (source_sfp->location);
986 source_sfp->location = new_slp;
987 }
988 }
989 }
990 }
991 }
992 }
993 }
994 return;
995 }
996
PropagateFeatureByApply(PropaStructPtr psp)997 NLM_EXTERN void PropagateFeatureByApply (PropaStructPtr psp)
998 {
999 BioseqPtr target_bsp;
1000 SeqFeatPtr source_sfp,
1001 source_dup;
1002 SeqAlignPtr salp;
1003 SelEdStructPtr feat,
1004 sesp;
1005 SeqIdPtr featsip,
1006 target_sip;
1007 SeqLocPtr featslp,
1008 new_slp;
1009 ValNodePtr vnpf,
1010 vnpfeat = NULL;
1011 Uint2 subtype;
1012 Uint1 frame,
1013 gap_choice_subtype;
1014 Boolean val;
1015
1016 if (psp->target_sep != NULL && psp->source_seqfeat != NULL) {
1017 if (psp->sap != NULL)
1018 {
1019 target_bsp = (BioseqPtr) psp->target_sep->data.ptrvalue;
1020 salp = (SeqAlignPtr) psp->sap->data;
1021 for (vnpf= psp->source_seqfeat; vnpf!=NULL; vnpf=vnpf->next)
1022 {
1023 feat = (SelEdStructPtr) vnpf->data.ptrvalue;
1024 val = (Boolean)(feat->bsp_itemID == psp->source_bspitemID);
1025 if (val)
1026 {
1027 featslp = (SeqLocPtr) feat->region;
1028 featsip = SeqLocId (featslp);
1029 subtype = vnpf->choice;
1030 GatherItem (feat->entityID, feat->itemID, OBJ_SEQFEAT, (Pointer)
1031 (&source_sfp), FindSqFeatItem);
1032 if (source_sfp != NULL)
1033 {
1034 target_sip=target_bsp->id;
1035 if (subtype == FEATDEF_GENE)
1036 gap_choice_subtype = IGNORE_GAP_CHOICE;
1037 else if (subtype == FEATDEF_PUB)
1038 gap_choice_subtype = IGNORE_GAP_CHOICE;
1039 else
1040 gap_choice_subtype = psp->gap_choice;
1041 new_slp = CopySeqLocFromSeqAlign (source_sfp, target_sip,
1042 featsip, salp, gap_choice_subtype, &frame);
1043 if (new_slp != NULL)
1044 {
1045 new_slp = SeqLocReplaceID (new_slp, SeqIdFindBest(target_sip, 0));
1046 if (is_newfeat (psp->target_seqfeat, psp->target_entityID,
1047 subtype, new_slp))
1048 {
1049 source_dup = (SeqFeatPtr) AsnIoMemCopy((Pointer) source_sfp, (AsnReadFunc)SeqFeatAsnRead, (AsnWriteFunc)SeqFeatAsnWrite);
1050 sesp = new_seledstruct_fromseqloc (psp->target_entityID,
1051 psp->target_bsp_itemID, (Uint2)OBJ_SEQFEAT, subtype,
1052 psp->target_bsp_itemID, new_slp, feat->label,
1053 (Pointer)source_dup, 0, frame);
1054 if (sesp != NULL) {
1055 ValNodeAddPointer(&vnpfeat, 0, (Pointer) sesp);
1056 }
1057 }
1058 }
1059 }
1060 }
1061 }
1062 /* ************
1063 {{
1064 SeqEntryPtr top_source_sep;
1065 top_source_sep = GetTopSeqEntryForEntityID (psp->source_entityID);
1066 ObjMgrFree (OBJ_SEQENTRY, (Pointer)top_source_sep);
1067 }}
1068 ********** */
1069 ObjMgrFreeByEntityID (psp->source_entityID);
1070 val = ApplyNewSeqFeat (vnpfeat, psp->stoptransl, psp->keep_protID);
1071 }
1072 }
1073 return;
1074 }
1075
1076 /**********************************************************
1077 ***
1078 *** CopyFeatFunc
1079 ***
1080 ***********************************************************/
CreatePropaStruc(SeqIdPtr target_id,SeqIdPtr source_id,SeqAlignPtr salp)1081 NLM_EXTERN PropaStructPtr CreatePropaStruc (SeqIdPtr target_id,
1082 SeqIdPtr source_id, SeqAlignPtr salp)
1083 {
1084 SeqLocPtr source_slp,
1085 target_slp;
1086 BioseqPtr source_bsp = NULL;
1087 BioseqPtr target_bsp = NULL;
1088
1089 PropaStructPtr psp = NULL;
1090
1091 if (target_id==NULL || source_id == NULL)
1092 return NULL;
1093 source_bsp = BioseqLockById (source_id);
1094 target_bsp = BioseqLockById (target_id);
1095 if (source_bsp!=NULL && target_bsp!=NULL)
1096 {
1097 psp = (PropaStructPtr) MemNew (sizeof (PropaStruct));
1098 psp->sap=SeqAnnotForSeqAlign(salp);
1099 psp->source_sep = SeqMgrGetSeqEntryForData ((Pointer)source_bsp);
1100 psp->source_entityID = SeqMgrGetEntityIDForSeqEntry (psp->source_sep);
1101 psp->source_bspitemID = GetItemIDGivenPointer (psp->source_entityID,
1102 OBJ_BIOSEQ, source_bsp);
1103
1104 psp->target_sep = SeqMgrGetSeqEntryForData ((Pointer)target_bsp);
1105 psp->target_entityID = SeqMgrGetEntityIDForSeqEntry (psp->target_sep);
1106 psp->target_bsp_itemID = GetItemIDGivenPointer (psp->target_entityID,
1107 OBJ_BIOSEQ, target_bsp);
1108
1109 source_slp = SeqLocIntNew (0, source_bsp->length-1, Seq_strand_plus, source_id);
1110 psp->source_seqfeat = NULL;
1111 psp->source_seqfeat = CollectFeatureForEditor (source_slp,
1112 psp->source_seqfeat, psp->source_entityID,
1113 psp->source_bspitemID, NULL, TRUE);
1114 target_slp = SeqLocIntNew (0, target_bsp->length-1, Seq_strand_plus,
1115 target_id);
1116 psp->target_seqfeat = NULL;
1117 psp->target_seqfeat = CollectFeatureForEditor (target_slp,
1118 psp->target_seqfeat, psp->target_entityID,
1119 psp->target_bsp_itemID, NULL, TRUE);
1120 BioseqUnlock (target_bsp);
1121 BioseqUnlock (source_bsp);
1122 /*** TODO free source_slp, target_slp ********/
1123 }
1124 return psp;
1125 }
1126
1127
1128 /**********************************************************
1129 ***
1130 *** MergeFunc
1131 ***
1132 ***********************************************************/
FreeSourceBsp(SeqIdPtr source_id)1133 static void FreeSourceBsp (SeqIdPtr source_id)
1134 {
1135 BioseqPtr bsp;
1136 SeqEntryPtr sep=NULL;
1137 Uint2 entityID;
1138
1139 bsp=BioseqLockById (source_id);
1140 if (bsp) {
1141 sep = SeqMgrGetSeqEntryForData (bsp);
1142 entityID = SeqMgrGetEntityIDForSeqEntry (sep);
1143 /* sep = GetTopSeqEntryForEntityID (entityID); */
1144 BioseqUnlock (bsp);
1145 ObjMgrFreeByEntityID (entityID);
1146 }
1147 /*
1148 if (sep)
1149 ObjMgrFree (OBJ_SEQENTRY, (Pointer)sep); */
1150
1151 }
1152
AddQualToSourceSeqFeat(BioseqPtr source_bsp,SeqIdPtr target_id,Uint2 entityID,Boolean keep_protid)1153 static void AddQualToSourceSeqFeat (BioseqPtr source_bsp, SeqIdPtr target_id, Uint2 entityID, Boolean keep_protid)
1154 {
1155 SeqAnnotPtr sap;
1156 SeqFeatPtr sfp;
1157 ValNodePtr protName=NULL;
1158 SeqIdPtr prot_id=NULL;
1159 Char string_id[128];
1160 Boolean val;
1161
1162 for (sap=source_bsp->annot; sap!=NULL; sap=sap->next)
1163 {
1164 if (sap->type==1) {
1165 for(sfp = (SeqFeatPtr)sap->data;sfp!=NULL; sfp=sfp->next)
1166 {
1167 if (sfp->data.choice==SEQFEAT_CDREGION) {
1168 if (sfp->product)
1169 {
1170 if (keep_protid) {
1171 if ((val=is_id_unique (entityID, SeqLocId(sfp->product)))) {
1172 prot_id = SeqIdDup (SeqLocId(sfp->product));
1173 }
1174 }
1175 if (prot_id==NULL) {
1176 prot_id = MakeNewProteinSeqId (NULL, target_id);
1177 }
1178 SeqIdWrite (prot_id, string_id , PRINTID_FASTA_LONG, 128);
1179 AddQualifierToFeature (sfp, "protein_id", string_id);
1180
1181 protName = get_names_from_prot (sfp->product);
1182 if (protName)
1183 AddQualifierToFeature (sfp, "product", (CharPtr)protName->data.ptrvalue);
1184 sfp->product = NULL;
1185 }
1186 }
1187 }
1188 }
1189 }
1190 }
1191
PromoteTargetBsp(BioseqPtr target_bsp,Uint2 entityID,Int2 genCode)1192 static void PromoteTargetBsp (BioseqPtr target_bsp, Uint2 entityID, Int2 genCode)
1193 {
1194 SeqAnnotPtr sap;
1195 SeqFeatPtr sfp;
1196
1197 for (sap=target_bsp->annot; sap!=NULL; sap=sap->next)
1198 {
1199 if (sap->type==1) {
1200 SetEmptyGeneticCodes (sap, genCode);
1201 sfp = (SeqFeatPtr)sap->data;
1202 PromoteXrefs (sfp, target_bsp, entityID);
1203 }
1204 }
1205 }
1206
map_position_seqalign(SeqAlignPtr salp,Int4 pos,ValNodePtr sqlocs)1207 static Int4 map_position_seqalign (SeqAlignPtr salp, Int4 pos, ValNodePtr sqlocs)
1208 {
1209 SeqIdPtr sip1, sip2;
1210 Int4 tmp_pos,
1211 froms;
1212 Int2 chklocp ;
1213
1214 sip1 = SeqAlignId (salp, 0);
1215 sip2 = SeqAlignId (salp, 1);
1216 chklocp = chkloc (sip2, pos, sqlocs, &froms);
1217 tmp_pos = SeqCoordToAlignCoord (pos, sip2, salp, 0, chklocp);
1218 tmp_pos = (Int4) AlignCoordToSeqCoord2 (tmp_pos, sip1, salp, sqlocs, 0);
1219 return tmp_pos;
1220 }
1221
1222
MergeFunc(SeqIdPtr target_id,SeqIdPtr source_id,SeqIdPtr merge_id,SeqAlignPtr salp,Int4 fromseq2,Int4 toseq2,ValNodePtr sqlocs,Boolean spliteditmode,Boolean keep_protID)1223 NLM_EXTERN Boolean MergeFunc (SeqIdPtr target_id, SeqIdPtr source_id, SeqIdPtr merge_id, SeqAlignPtr salp, Int4 fromseq2, Int4 toseq2, ValNodePtr sqlocs, Boolean spliteditmode, Boolean keep_protID)
1224 {
1225 SeqEntryPtr sep;
1226 BioseqPtr merge_bsp,
1227 target_bsp;
1228 SeqLocPtr target_slp;
1229 Int4 fromseq1, toseq1,
1230 from1seq1, to1seq1,
1231 from_overlapp, to_overlapp;
1232 Int4 caret = -1,
1233 overlapp=0;
1234 Int2 genCode;
1235 Uint2 target_entityID;
1236 Boolean ok = TRUE;
1237
1238 if (target_id==NULL || source_id==NULL || merge_id==NULL || toseq2 < fromseq2)
1239 return FALSE;
1240 merge_bsp = BioseqLockById (merge_id);
1241 if (merge_bsp!=NULL)
1242 {
1243 target_bsp = BioseqLockById (target_id);
1244 if (target_bsp!=NULL)
1245 {
1246 fromseq1= map_position_seqalign(salp,fromseq2, sqlocs);
1247 toseq1 = map_position_seqalign(salp,toseq2, sqlocs);
1248 from1seq1= map_position_seqalign(salp,fromseq2-1, sqlocs);
1249 to1seq1 = map_position_seqalign(salp,toseq2+1, sqlocs);
1250 overlapp = 0;
1251 if (toseq1>-1) {
1252 if (fromseq1>-1) {
1253 overlapp=toseq1-fromseq1 + 1;
1254 from_overlapp = fromseq1;
1255 to_overlapp = toseq1;
1256 } else {
1257 overlapp=toseq1 + 1;
1258 from_overlapp = 0;
1259 to_overlapp = toseq1;
1260 }
1261 }
1262 else if (to1seq1 > -1) {
1263 if (fromseq1>-1) {
1264 overlapp = to1seq1 - fromseq1;
1265 from_overlapp = fromseq1;
1266 to_overlapp = to1seq1-1;
1267 } else if (from1seq1>-1) {
1268 overlapp = to1seq1 - from1seq1 -1;
1269 from_overlapp = from1seq1+1;
1270 to_overlapp = to1seq1-1;
1271 }
1272 }
1273 else if (toseq1==-2 && to1seq1 ==-2)
1274 {
1275 if (fromseq1 > -1 || from1seq1 > -1) {
1276 if (fromseq1 < 0)
1277 fromseq1 = from1seq1+1;
1278 if (target_bsp->length > fromseq1+1) {
1279 overlapp = target_bsp->length - fromseq1;
1280 from_overlapp = fromseq1;
1281 to_overlapp = target_bsp->length-1;
1282 }
1283 }
1284 else ok = FALSE;
1285 }
1286 if (to1seq1 == -2)
1287 caret = -2;
1288 else if (to1seq1 == 0)
1289 caret = 0;
1290 else if (overlapp <= to1seq1) {
1291 if (overlapp == 0)
1292 caret = to1seq1;
1293 else
1294 caret = to1seq1 - overlapp;
1295 }
1296 if (ok) {
1297 if (overlapp > 0)
1298 {
1299 target_slp=SeqLocIntNew (from_overlapp, to_overlapp, Seq_strand_plus, target_id);
1300 SeqDeleteByLoc (target_slp, TRUE, spliteditmode);
1301 SeqLocFree (target_slp);
1302 }
1303 target_entityID = ObjMgrGetEntityIDForPointer (target_bsp);
1304 if (target_entityID)
1305 {
1306 AddQualToSourceSeqFeat (merge_bsp, target_id, target_entityID, keep_protID);
1307 FreeSourceBsp (source_id);
1308 ok = BioseqInsert (merge_bsp->id, FIRST_RESIDUE, LAST_RESIDUE, Seq_strand_plus, target_id, caret, TRUE, TRUE, spliteditmode);
1309 sep = GetBestTopParentForData (target_entityID, target_bsp);
1310 genCode = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
1311 PromoteTargetBsp (target_bsp, target_entityID, genCode);
1312 }
1313 }
1314 BioseqUnlock (target_bsp);
1315 }
1316 BioseqUnlock (merge_bsp);
1317 }
1318 return ok;
1319 }
1320
FeatListToProp(EditAlignDataPtr adp,ValNodePtr vnpfeat)1321 NLM_EXTERN Boolean FeatListToProp (EditAlignDataPtr adp, ValNodePtr vnpfeat)
1322 {
1323 SeqLocPtr featslp;
1324 SeqIdPtr featsip,
1325 bsp_id;
1326 ValNodePtr vnp,
1327 pre,
1328 next,
1329 datavnp;
1330 SeqLocPtr new_slp;
1331 SelEdStructPtr sesp;
1332 SeqFeatPtr source_sfp=NULL,
1333 source_dup;
1334 SeqAnnotPtr sap;
1335 SeqAlignPtr salp;
1336 Uint4 feat_itemID;
1337 Uint1 frame;
1338 Boolean val,
1339 keep_sesp;
1340
1341 vnp=vnpfeat;
1342 pre = NULL;
1343 while (vnp!=NULL)
1344 {
1345 next = vnp->next;
1346 keep_sesp = FALSE;
1347 sesp=(SelEdStructPtr) vnp->data.ptrvalue;
1348 feat_itemID = sesp->itemtype;
1349
1350 /**/
1351 GatherItem (sesp->entityID, sesp->itemID, OBJ_SEQFEAT, (Pointer) (&source_sfp), FindSqFeatItem);
1352 /**/
1353 /**
1354 SeqMgrIndexFeatures (sesp->entityID, NULL);
1355 SeqMgrExploreFeatures (bsp, (Pointer)stdin, GetCDSCB, NULL, NULL, NULL);
1356 SeqMgrClearFeatureIndexes (sesp->entityID, NULL);
1357 **/
1358 if (source_sfp != NULL)
1359 {
1360 featslp = (SeqLocPtr) sesp->region;
1361 featsip = SeqLocId (featslp);
1362 bsp_id = (SeqIdPtr) sesp->data->data.ptrvalue;
1363 sap = SeqAnnotBoolSegToDenseSeg (adp->sap_align);
1364 salp = (SeqAlignPtr)sap->data;
1365 new_slp = CopySeqLocFromSeqAlign (source_sfp, bsp_id, featsip, salp, adp->gap_choice, &frame);
1366 if (new_slp != NULL) {
1367 if (is_newfeat (adp->seqfeat, sesp->entityID, sesp->itemsubtype, new_slp) )
1368 {
1369 source_dup = (SeqFeatPtr) AsnIoMemCopy((Pointer) source_sfp, (AsnReadFunc)SeqFeatAsnRead, (AsnWriteFunc)SeqFeatAsnWrite);
1370 sesp->data->data.ptrvalue = ValNodeFree (sesp->data->data.ptrvalue);
1371 sesp->data = MemFree (sesp->data);
1372 datavnp = ValNodeNew (NULL);
1373 datavnp->choice = 0;
1374 datavnp->data.ptrvalue = (Pointer)source_dup;
1375 sesp->data = datavnp;
1376 sesp->codonstart = frame;
1377 sesp->itemID = sesp->bsp_itemID;
1378 ValNodeFree((ValNodePtr)sesp->region);
1379 sesp->region = new_slp;
1380 keep_sesp = TRUE;
1381 }
1382 }
1383 }
1384 if (!keep_sesp) {
1385 vnp->next = NULL;
1386 sesp->data->data.ptrvalue = ValNodeFree (sesp->data->data.ptrvalue);
1387 sesp->data = ValNodeFree (sesp->data);
1388 sesp->region = ValNodeFree((ValNodePtr)sesp->region);
1389 vnp->data.ptrvalue = MemFree (sesp);
1390 vnp = ValNodeFree (vnp);
1391 if (pre==NULL) {
1392 vnpfeat = next;
1393 }
1394 else
1395 pre->next = next;
1396 }
1397 else
1398 pre = vnp;
1399 vnp = next;
1400 }
1401 val = ApplyNewSeqFeat (vnpfeat, adp->stoptransl, FALSE);
1402 for (vnp=vnpfeat; vnp!=NULL;vnp=vnp->next) {
1403 sesp=(SelEdStructPtr) vnp->data.ptrvalue;
1404 sesp->data->data.ptrvalue = NULL;
1405 sesp->data = ValNodeFree (sesp->data);
1406 sesp->region = ValNodeFree((ValNodePtr)sesp->region);
1407 vnp->data.ptrvalue = MemFree (sesp);
1408 }
1409 ValNodeFree (vnpfeat);
1410 return val;
1411 }
1412