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