~ubuntu-branches/ubuntu/intrepid/ncbi-tools6/intrepid

« back to all changes in this revision

Viewing changes to desktop/salsa.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2006-12-07 15:02:17 UTC
  • mfrom: (1.1.6 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20061207150217-dhkefi84mxhwof0l
Tags: 6.1.20061015-1ubuntu1
* Re-sync with Debian
* Re-add .desktop files from Phil Bull (Closes Malone: #36384)

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
*
29
29
* Version Creation Date:   1/27/96
30
30
*
31
 
* $Revision: 6.169 $
 
31
* $Revision: 6.177 $
32
32
*
33
33
* File Description: 
34
34
*
68
68
#include <alignmgr.h>
69
69
#include <alignmgr2.h>
70
70
#include <seqpanel.h>
 
71
#include <blastpri.h>
 
72
#include <spidey.h>
71
73
 
72
74
/******/
73
75
#include <pgppop.h>
132
134
  InsetRect (prc, HRZ_BORDER_WIDTH, VER_BORDER_WIDTH);
133
135
}
134
136
 
135
 
static Int2 getsize_seqids (ValNodePtr sloc, Uint2 printid)
 
137
static Int2 getsize_seqids (ValNodePtr sloc, Uint1 printid)
136
138
{
137
139
  ValNodePtr  vnp;
138
140
  SeqLocPtr   slp;
474
476
}
475
477
 
476
478
 
477
 
static EditAlignDataPtr EditAlignDataInit (SelStructPtr master, Int2 width, Int2 height, Int2 marginleft, Int2 columnpcell, Handle font, Boolean size_pixel, Uint1 display_panel)
 
479
static EditAlignDataPtr EditAlignDataInit (SelStructPtr master, Int2 width, Int2 height, Int2 marginleft, Uint1 columnpcell, Handle font, Boolean size_pixel, Uint1 display_panel)
478
480
{
479
481
  EditAlignDataPtr adp;
480
482
 
2039
2041
  ValNodePtr       vnp;
2040
2042
  SeqLocPtr        slp;
2041
2043
  AlignNodePtr     anp;
2042
 
  Uint2            ei, ii;
 
2044
  Uint2            ei;
 
2045
  Uint4            ii;
2043
2046
  Boolean          first = TRUE;
2044
2047
 
2045
2048
  if ( ( pnl= GetPanelFromWindow ((WindoW)ParentWindow (i)) ) == NULL) return;
2128
2131
  Int2             seqnumber,
2129
2132
                   nalgline,
2130
2133
                   j;
2131
 
  Uint2            eID, iID;
 
2134
  Uint2            eID;
 
2135
  Uint4            iID;
2132
2136
  Boolean          goOn= FALSE,
2133
2137
                   sel = FALSE,
2134
2138
                   first=TRUE;
2296
2300
}
2297
2301
 
2298
2302
 
2299
 
static void changeseqid (PaneL pnl, Uint2 choice)
 
2303
static void changeseqid (PaneL pnl, Uint1 choice)
2300
2304
{
2301
2305
  WindoW           temport;
2302
2306
  EditAlignDataPtr adp;
2720
2724
                subtype = ompp->subinputtype;
2721
2725
                if (subtype == fdp->featdef_key &&
2722
2726
                    subtype != FEATDEF_PUB &&
 
2727
                    subtype != FEATDEF_IMP &&
2723
2728
                    subtype != FEATDEF_Imp_CDS &&
2724
2729
                    subtype != FEATDEF_misc_RNA &&
2725
2730
                    subtype != FEATDEF_precursor_RNA &&
3532
3537
  return TRUE;
3533
3538
}
3534
3539
 
3535
 
static void SeqAlignBioseqRegister (SeqAlignPtr salp, Uint2 *entityID, Uint2 *itemID)
 
3540
static void SeqAlignBioseqRegister (SeqAlignPtr salp, Uint2 *entityID, Uint4 *itemID)
3536
3541
{
3537
3542
  SeqAlignPtr tmp;
3538
3543
  SeqIdPtr    sip;
3539
3544
  Int2        j;
3540
 
  Uint2       eID=0, iID=0;
 
3545
  Uint2       eID=0;
 
3546
  Uint4       iID=0;
3541
3547
  Boolean     first=TRUE;
3542
3548
 
3543
3549
  for (tmp=salp; tmp!=NULL; tmp=tmp->next)
3655
3661
  SetPanelExtra (pnl, &adp); 
3656
3662
}
3657
3663
 
3658
 
extern Boolean FindIdsInSalsaPanel (PaneL pnl, PoinT pt, Uint2 *entityID, Uint2 *itemID, Uint2 *itemtype)
 
3664
extern Boolean FindIdsInSalsaPanel (PaneL pnl, PoinT pt, Uint2 *entityID, Uint4 *itemID, Uint2 *itemtype)
3659
3665
{
3660
3666
  EditAlignDataPtr adp;
3661
3667
  RecT             rp;
3662
3668
  Int4             pos;
3663
3669
  Int2             line;
3664
 
  Uint2            iID, eID, itype, isubtype;
 
3670
  Uint4            iID;
 
3671
  Uint2            eID, itype, isubtype;
3665
3672
  Uint1            what;
3666
3673
  SeqAlignPtr      salp;
3667
3674
 
3740
3747
  SeqAlignPtr      salp = NULL;
3741
3748
  RecT             rp;
3742
3749
  Int2             height, width;
3743
 
  Uint2            entityID, itemID;
 
3750
  Uint2            entityID;
 
3751
  Uint4            itemID;
3744
3752
  SeqEditViewProcsPtr  svpp;
3745
3753
 
3746
3754
  if (sep == NULL)
4462
4470
  PropaStructPtr     psp;
4463
4471
  SeqIdPtr           target_id,
4464
4472
                     source_id;
4465
 
  Uint2              entityID, itemID;
 
4473
  Uint2              entityID;
 
4474
  Uint4              itemID;
4466
4475
  Boolean            val = FALSE;
4467
4476
  
4468
4477
  w = (WindoW)ParentWindow (b);
5032
5041
FinishOpeningEditAlignmentWindow 
5033
5042
(SeqAlignPtr salp,
5034
5043
 Uint2       input_entityID,
5035
 
 Uint2       input_itemID,
 
5044
 Uint4       input_itemID,
5036
5045
 Uint2       input_itemtype,
5037
5046
 Uint2       procid,
5038
5047
 Uint2       proctype)
5118
5127
  ValNodePtr   seq_annot_list;
5119
5128
  SeqAnnotPtr  sap;
5120
5129
  SeqAlignPtr  salp = NULL;
5121
 
  Boolean      rval;
 
5130
  Int2         rval;
5122
5131
 
5123
5132
#ifdef WIN_MAC
5124
5133
  bfp = currentFormDataPtr;
5642
5651
}
5643
5652
 
5644
5653
 
 
5654
static SeqAlignPtr LIBCALL SeqAlignBestHit (SeqAlignPtr salp, BioseqPtr bsp1, BioseqPtr bsp2, Int4 threshold, CharPtr PNTR message, Int4Ptr nonly)
 
5655
{
 
5656
   AMFreqPtr         afp;
 
5657
   Int4              alln;
 
5658
   AMAlignIndex2Ptr  amaip;
 
5659
   Int4              beg;
 
5660
   Int4              ctr;
 
5661
   Int4              end;
 
5662
   Boolean           found;
 
5663
   Int4              gaps;
 
5664
   Int4              i;
 
5665
   Int4              j;
 
5666
   Int4              last;
 
5667
   Int4              len;
 
5668
   Int4              n;
 
5669
   Int4              nctr;
 
5670
   Char              newstr[256];
 
5671
   Int4              mismatches;
 
5672
   Uint1             res;
 
5673
   SeqAlignPtr       sap;
 
5674
   SeqAlignPtr       sap_new;
 
5675
   SeqAlignPtr       sap_new2;
 
5676
   SeqAlignPtr       sap_orig;
 
5677
   SeqPortPtr        spp;
 
5678
   Int4              start1;
 
5679
   Int4              start2;
 
5680
   Int4              stop1;
 
5681
   Int4              stop2;
 
5682
   Uint1             strand;
 
5683
 
 
5684
   if (salp == NULL)
 
5685
      return NULL;
 
5686
   sap = NULL;
 
5687
   if (salp->next != NULL)
 
5688
   {
 
5689
      sap_orig = SeqAlignDup(salp);
 
5690
      AlnMgr2IndexLite(salp);
 
5691
      AlnMgr2SortAlnSetByNthRowPos(salp, 1);
 
5692
      SPI_RemoveInconsistentAlnsFromSet(salp, 10, 1, SPI_LEFT);
 
5693
      amaip = (AMAlignIndex2Ptr)(salp->saip);
 
5694
      last = 0;
 
5695
      sap_new = NULL;
 
5696
      for (i=0; i<amaip->numsaps-1; i++)
 
5697
      {
 
5698
         amaip->saps[i]->next = NULL;
 
5699
         AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], 1, &start1, &stop1);
 
5700
         AlnMgr2GetNthSeqRangeInSA(amaip->saps[i+1], 1, &start2, &stop2);
 
5701
         strand = AlnMgr2GetNthStrand(amaip->saps[i], 1);
 
5702
         if (strand == Seq_strand_minus)
 
5703
         {
 
5704
            if (start1 <= stop2)
 
5705
               AlnMgr2TruncateSeqAlign(amaip->saps[i], stop2+1, start1, 1);
 
5706
            SeqAlignFree(amaip->saps[i]->next);
 
5707
            amaip->saps[i]->next = NULL;
 
5708
         } else
 
5709
         {
 
5710
            if (stop1 >= start2)
 
5711
               AlnMgr2TruncateSeqAlign(amaip->saps[i], start1, start2-1, 1);
 
5712
            SeqAlignFree(amaip->saps[i]->next);
 
5713
            amaip->saps[i]->next = NULL;
 
5714
         }
 
5715
      }
 
5716
      amaip->saps[amaip->numsaps-1]->next = NULL;
 
5717
      for (i=0; i<amaip->numsaps-1; i++)
 
5718
      {
 
5719
         if (sap_new == NULL)
 
5720
            sap_new = SeqAlignDup(amaip->saps[i]);
 
5721
         sap_new2 = AlnMgr2MergeTwoAlignments(sap_new, amaip->saps[i+1]);
 
5722
         if (sap_new2 == NULL)
 
5723
            sap_new = amaip->saps[i];
 
5724
         else
 
5725
         {
 
5726
            SeqAlignFree(sap_new);
 
5727
            sap_new = sap_new2;
 
5728
            sap_new2 = NULL;
 
5729
         }
 
5730
      }
 
5731
      AlnMgr2IndexSingleChildSeqAlign(sap_new);
 
5732
      if (AlnMgr2GetAlnLength(sap_orig, FALSE) >= AlnMgr2GetAlnLength(sap_new, FALSE))
 
5733
      {
 
5734
         SeqAlignFree(sap_new);
 
5735
         sap_new = SeqAlignDup(sap_orig);
 
5736
      }
 
5737
      salp = sap_new;
 
5738
   }
 
5739
   sap = salp;
 
5740
   AlnMgr2IndexSingleChildSeqAlign(sap);
 
5741
   AlnMgr2ExtendToCoords(sap, 0, -1, 1);
 
5742
   AlnMgr2GetNthSeqRangeInSA(sap, 1, &start1, &stop1);
 
5743
   len = stop1 - start1 + 1; /* the actual length of sequence1 covered by aln */
 
5744
   afp = AlnMgr2ComputeFreqMatrix(sap, 0, -1, 0);
 
5745
   gaps = 0;
 
5746
   mismatches = n = 0;
 
5747
   alln = 0;
 
5748
   for (i=0; i<afp->len; i++)
 
5749
   {
 
5750
      if (afp->freq[5][i] > 0)
 
5751
         alln++;
 
5752
      found = FALSE;
 
5753
      for (j=0; !found && j<afp->size; j++)
 
5754
      {
 
5755
         if (afp->freq[0][i] > 0)
 
5756
         {
 
5757
            gaps++;
 
5758
            found = TRUE;
 
5759
         } else if (afp->freq[j][i] == 1 && afp->freq[5][i] == 0)
 
5760
         {
 
5761
            mismatches++;
 
5762
            found = TRUE;
 
5763
         } else if (afp->freq[j][i] == 1 && afp->freq[5][i] == 1)
 
5764
         {
 
5765
            n++;
 
5766
            found = TRUE;
 
5767
         }
 
5768
      }
 
5769
   }
 
5770
   if (alln > 0 && (gaps>0 || mismatches>0 || n > 0))
 
5771
   {
 
5772
      spp = SeqPortNew(bsp1, 0, bsp1->length-1, Seq_strand_plus, Seq_code_ncbi4na);
 
5773
      beg = end = 0;
 
5774
      ctr = 0;
 
5775
      nctr = 0;
 
5776
      while ((res = SeqPortGetResidue(spp)) != SEQPORT_EOF)
 
5777
      {
 
5778
         if (res == 15)
 
5779
         {
 
5780
            if (beg == ctr)
 
5781
               beg++;
 
5782
            else
 
5783
            {
 
5784
               end++;
 
5785
               nctr++;
 
5786
            }
 
5787
         } else
 
5788
            end = 0;
 
5789
         ctr++;
 
5790
      }
 
5791
      nctr = nctr - end;
 
5792
      if (beg > 0 || end > 0)
 
5793
      {
 
5794
         sprintf(newstr, "The local sequence has %d terminal N%s. ", beg+end, beg+end!=1?"s":"");
 
5795
         StringCat(*message, newstr);
 
5796
      }
 
5797
      if (nctr > 0)
 
5798
      {
 
5799
         sprintf(newstr, "The local sequence has %d internal N%s. ", nctr, nctr!=1?"s":"");
 
5800
         StringCat(*message, newstr);
 
5801
      }
 
5802
      SeqPortFree(spp);
 
5803
   }
 
5804
   if ((*message[0] != '\0') && len == bsp1->length && gaps == 0 && mismatches == 0)
 
5805
   {
 
5806
      if (nctr > 0)
 
5807
         *nonly = nctr+beg+end;
 
5808
      else
 
5809
         *nonly = -(beg+end);
 
5810
      sprintf(newstr, "\nThere are no other differences between the local and database sequences.");
 
5811
      StringCat(*message, newstr);
 
5812
      return sap;
 
5813
   } else
 
5814
      *nonly = 0;
 
5815
   if (len < bsp1->length)
 
5816
   {
 
5817
      sprintf(newstr, "%sThe alignment to the database sequence does not cover all of the local sequence. ", *message[0]=='\0'?"":"\n");
 
5818
      StringCat(*message, newstr);
 
5819
      spp = SeqPortNew(bsp1, len, bsp1->length-1, Seq_strand_plus, Seq_code_ncbi4na);
 
5820
      alln = TRUE;
 
5821
      while (alln && (res = SeqPortGetResidue(spp)) != SEQPORT_EOF)
 
5822
      {
 
5823
         if (res != 15)
 
5824
            alln = FALSE;
 
5825
      }
 
5826
      if (alln)
 
5827
         sprintf(newstr, "\nThe unaligned sequence consists only of Ns. ");
 
5828
      else
 
5829
         sprintf(newstr, "\nThere are non-N residues in the unaligned sequence. ");
 
5830
      StringCat(*message, newstr);
 
5831
      SeqPortFree(spp);
 
5832
   }
 
5833
   if (gaps > 0 || mismatches > 0 || n > 0)
 
5834
   {
 
5835
      sprintf(newstr, "%sThe alignment to the database sequence has %d gap%s, %d mismatch%s, and %d N-mismatch%s. ", afp->len<bsp1->length?"\n":"", gaps, (gaps!=1?"s":""), mismatches, (mismatches!=1?"es":""), n, (n!=1?"es":""));
 
5836
      StringCat(*message, newstr);
 
5837
   }
 
5838
   return sap;
 
5839
}
 
5840
 
 
5841
static void SeqAlignStartUpdate (SeqAlignPtr salp, SeqIdPtr target_sip, Int4 offset, Int4 len, Uint1 strand)
 
5842
{
 
5843
  SeqAlignPtr salptmp;
 
5844
  DenseSegPtr dsp;
 
5845
  SeqIdPtr    pre, sip, next;
 
5846
  Int4Ptr     lenp,
 
5847
              startp;
 
5848
  Uint1Ptr    strandp;
 
5849
  Int4        len_sum,
 
5850
              start;
 
5851
  Int2        index, k, j;
 
5852
 
 
5853
  if (salp==NULL || offset<=0)
 
5854
     return;
 
5855
  for (salptmp=salp; salptmp!=NULL; salptmp=salptmp->next)
 
5856
  {
 
5857
     if (salptmp->segtype == 2)
 
5858
     {
 
5859
        dsp = (DenseSegPtr) salptmp->segs;
 
5860
        pre = NULL;
 
5861
        index=0;
 
5862
        sip=dsp->ids;
 
5863
        while (sip)
 
5864
        {
 
5865
           next=sip->next;
 
5866
           if (SeqIdForSameBioseq(target_sip, sip))
 
5867
           {
 
5868
              if (strand == Seq_strand_minus)
 
5869
              {
 
5870
                 strandp=dsp->strands;
 
5871
                 if (strandp != NULL) {
 
5872
                   strandp+=index;
 
5873
                   for (j=0; j < dsp->numseg; j++)
 
5874
                   {
 
5875
                      if (*strandp == Seq_strand_minus)
 
5876
                         *strandp = Seq_strand_plus;
 
5877
                      else if (*strandp == Seq_strand_plus)
 
5878
                         *strandp = Seq_strand_minus;
 
5879
                      strandp+=dsp->dim;
 
5880
                   }
 
5881
                } else
 
5882
                {
 
5883
                   dsp->strands = (Uint1Ptr)MemNew(dsp->dim*dsp->numseg*sizeof(Uint1));
 
5884
                   for (j=0; j<dsp->dim*dsp->numseg; j++)
 
5885
                      dsp->strands[j] = Seq_strand_plus;
 
5886
                   for(j=0; j<dsp->numseg; j++)
 
5887
                      dsp->strands[j*dsp->dim + index] = Seq_strand_minus;
 
5888
                }
 
5889
                 lenp=dsp->lens;
 
5890
                 startp=dsp->starts;
 
5891
                 start=startp[index];
 
5892
                 len_sum=0;
 
5893
                 j=dsp->dim*dsp->numseg-dsp->dim;
 
5894
                 k=dsp->numseg-1;
 
5895
                 for (j=0; j<dsp->numseg; j++) {
 
5896
                   if (startp[j*dsp->dim + index]>=0) {
 
5897
                       startp[j*dsp->dim + index]=len-startp[j*dsp->dim + index]-dsp->lens[j]+1;
 
5898
                   }
 
5899
                 }
 
5900
              } else
 
5901
              {
 
5902
                 for (j=0; j<dsp->numseg; j++) {
 
5903
                    if (dsp->starts[dsp->dim*j+index] != -1)
 
5904
                        dsp->starts[dsp->dim*j+index] += offset;
 
5905
                 }
 
5906
              }
 
5907
           }
 
5908
           pre=sip;
 
5909
           sip=next;
 
5910
           index++;
 
5911
        }
 
5912
     }
 
5913
  }
 
5914
}
 
5915
 
 
5916
 
 
5917
static SeqIdPtr SWSeqIdReplaceID(SeqIdPtr sip_head, SeqIdPtr sip1, SeqIdPtr sip2)
 
5918
{
 
5919
   Boolean   found;
 
5920
   SeqIdPtr  sip;
 
5921
   SeqIdPtr  sip_prev;
 
5922
 
 
5923
   sip = sip_head;
 
5924
   sip_prev = NULL;
 
5925
   found = FALSE;
 
5926
   while (sip != NULL && !found)
 
5927
   {
 
5928
      if (SeqIdComp(sip, sip1) == SIC_YES)
 
5929
         found = TRUE;
 
5930
      else
 
5931
      {
 
5932
         sip_prev = sip;
 
5933
         sip = sip->next;
 
5934
      }
 
5935
   }
 
5936
   if (!found)
 
5937
      return sip_head;
 
5938
   if (sip_prev == NULL)
 
5939
   {
 
5940
      sip2->next = sip_head->next;
 
5941
      SeqIdFree(sip_head);
 
5942
      return sip2;
 
5943
   } else
 
5944
   {
 
5945
      sip_prev->next = sip2;
 
5946
      sip2->next = sip->next;
 
5947
      SeqIdFree(sip);
 
5948
      return sip_head;
 
5949
   }
 
5950
}
 
5951
 
 
5952
/**********************************************************************
 
5953
 * 
 
5954
 * nrSeqIdIsInValNodeList (vnp, sip)
 
5955
 * 
 
5956
 * This function checks to see if SeqIdPtr sip points to the same Bioseq
 
5957
 * as the SeqIdPtr values in ValNode list vnp's data.ptrvalues.
 
5958
 *
 
5959
 * Return values:
 
5960
 *       TRUE if a match was found
 
5961
 *       FALSE if no match was found
 
5962
 **********************************************************************/
 
5963
static Boolean nrSeqIdIsInValNodeList (ValNodePtr vnp, SeqIdPtr sip)
 
5964
{
 
5965
  ValNodePtr vnptmp=NULL;
 
5966
  SeqIdPtr   siptmp;
 
5967
  Boolean    rval = FALSE;
 
5968
 
 
5969
  if (sip == NULL)
 
5970
  {
 
5971
    return FALSE;
 
5972
  }
 
5973
  
 
5974
  for (vnptmp=vnp; vnptmp!=NULL && !rval; vnptmp=vnptmp->next) {
 
5975
    siptmp=(SeqIdPtr)vnptmp->data.ptrvalue;
 
5976
    if (SeqIdForSameBioseq(sip, siptmp))
 
5977
    {
 
5978
      rval = TRUE;
 
5979
    }
 
5980
  }
 
5981
 
 
5982
  return rval;
 
5983
}
 
5984
 
 
5985
 
 
5986
/**********************************************************************
 
5987
 * 
 
5988
 * nrSeqIdAdd (vnp, sip)
 
5989
 * 
 
5990
 * This function checks to see if SeqIdPtr sip points to the same Bioseq
 
5991
 * as the SeqIdPtr values in ValNode list vnp's data.ptrvalues.
 
5992
 * If not, sip is added to the list.
 
5993
 *
 
5994
 * Return value:
 
5995
 *       A ValNodeList pointing to SeqIDPtr values
 
5996
 **********************************************************************/
 
5997
static ValNodePtr nrSeqIdAdd (ValNodePtr vnp, SeqIdPtr sip)
 
5998
{
 
5999
  if (sip == NULL)
 
6000
  {
 
6001
    return vnp;
 
6002
  }
 
6003
  
 
6004
  if (!nrSeqIdIsInValNodeList (vnp, sip))
 
6005
  {
 
6006
    ValNodeAddPointer(&vnp, 0, sip);
 
6007
  }
 
6008
     
 
6009
  return vnp;
 
6010
}
 
6011
 
 
6012
 
 
6013
static Int4 CalculateAlignmentDisplayPosition (SeqAlignPtr sap, Int4 aln_pos, Int4 row)
 
6014
{
 
6015
  Int4 seq_pos;
 
6016
  
 
6017
  /* calculate alignment position */
 
6018
  if (sap == NULL)
 
6019
  {
 
6020
    return aln_pos;
 
6021
  }
 
6022
  seq_pos = AlnMgr2MapSeqAlignToBioseq(sap, aln_pos, row); 
 
6023
  while ((seq_pos == ALNMGR_GAP || seq_pos == ALNMGR_ROW_UNDEFINED) && aln_pos > 1) { /* count back if we in the gap */
 
6024
    aln_pos--;
 
6025
    seq_pos = AlnMgr2MapSeqAlignToBioseq(sap, aln_pos, 1);
 
6026
  }
 
6027
  if (seq_pos == ALNMGR_GAP || seq_pos == ALNMGR_ROW_UNDEFINED) 
 
6028
      seq_pos = 1;  /* Gap at the begining of the alignment */
 
6029
  return seq_pos;
 
6030
}
 
6031
 
 
6032
 
 
6033
static void SWPrintFarpointerAln(SeqAlignPtr sap, FILE *fp)
 
6034
{
 
6035
   Uint1Ptr    buf, seqbuf;
 
6036
   Char        dig [6];
 
6037
   Int4        i;
 
6038
   Int4        l;
 
6039
   Int4        len;
 
6040
   Int4        linesize = 70;
 
6041
   SeqIdPtr    sip;
 
6042
   SeqIdPtr    sip2;
 
6043
   Int4        alnbuflen;
 
6044
   Uint1       strand1, strand2;
 
6045
   Char        textid1[16];
 
6046
   Char        textid2[16];
 
6047
   Int4        seq_pos;
 
6048
 
 
6049
   if (sap == NULL || fp == NULL)
 
6050
      return;
 
6051
   if (sap->saip == NULL)
 
6052
      AlnMgr2IndexSingleChildSeqAlign(sap);
 
6053
   buf = (Uint1Ptr)MemNew(linesize * sizeof(Uint1));
 
6054
   seqbuf = (Uint1Ptr)MemNew(linesize * sizeof(Uint1));
 
6055
 
 
6056
   for (i=0; i<16; i++)
 
6057
   {
 
6058
      textid1[i] = textid2[i] = ' ';
 
6059
   }
 
6060
   sip = AlnMgr2GetNthSeqIdPtr(sap, 1);
 
6061
   SeqIdWrite(sip, textid1, PRINTID_TEXTID_ACC_VER, 15);
 
6062
   sip2 = AlnMgr2GetNthSeqIdPtr(sap, 2);
 
6063
   SeqIdWrite(sip2, textid2, PRINTID_TEXTID_ACC_VER, 15);
 
6064
   for (i=0; i<15; i++)
 
6065
   {
 
6066
      if (textid1[i] == '\0')
 
6067
         textid1[i] = ' ';
 
6068
      if (textid2[i] == '\0')
 
6069
         textid2[i] = ' ';
 
6070
   }
 
6071
   textid1[15] = '\0';
 
6072
   textid2[15] = '\0';
 
6073
   
 
6074
   len = AlnMgr2GetAlnLength(sap, FALSE);
 
6075
   strand1 = AlnMgr2GetNthStrand(sap, 1);
 
6076
   strand2 = AlnMgr2GetNthStrand(sap, 2);
 
6077
   
 
6078
   for (l = 0; l < len; l+= linesize)
 
6079
   {
 
6080
     alnbuflen = linesize;
 
6081
     AlignmentIntervalToString (sap, 1, l, l + linesize - 1, 1, FALSE, seqbuf, buf, &alnbuflen, TRUE);
 
6082
     StringUpper ((char *)buf);
 
6083
     seq_pos = CalculateAlignmentDisplayPosition (sap, l, 1);
 
6084
     sprintf (dig, "%5d", seq_pos + 1);
 
6085
     
 
6086
     fprintf(fp, "%s%c%s %s\n", textid1, strand1 == Seq_strand_plus?'>':'<', dig, buf);
 
6087
     alnbuflen = linesize;
 
6088
     AlignmentIntervalToString (sap, 2, l, l + linesize - 1, 1, FALSE, seqbuf, buf, &alnbuflen, TRUE);
 
6089
     StringUpper ((char *)buf);
 
6090
     seq_pos = CalculateAlignmentDisplayPosition (sap, l, 2);
 
6091
     sprintf (dig, "%5d", seq_pos + 1);
 
6092
     fprintf(fp, "%s%c%s %s\n", textid2, strand2 == Seq_strand_plus?'>':'<', dig, buf);  
 
6093
     fprintf (fp, "\n");   
 
6094
   }
 
6095
 
 
6096
   sip = SeqIdFree(sip);
 
6097
   sip2 = SeqIdFree (sip2);
 
6098
   buf = MemFree(buf);
 
6099
   seqbuf = MemFree (seqbuf);
 
6100
}
 
6101
 
 
6102
 
 
6103
#if 1
 
6104
 
 
6105
typedef enum {
 
6106
    FARPOINTER_LOOKUP_NO_ERROR = 0,
 
6107
    FARPOINTER_LOOKUP_NOT_FOUND,
 
6108
    FARPOINTER_LOOKUP_NONLY,
 
6109
    FARPOINTER_LOOKUP_BAD_ALN
 
6110
} EFarPointerError;
 
6111
 
 
6112
typedef struct farpointer {
 
6113
  SeqIdPtr    sip_local;
 
6114
  SeqIdPtr    sip_db;
 
6115
  BioseqPtr   bsp_local;
 
6116
  BioseqPtr   bsp_db;
 
6117
  SeqAlignPtr salp;
 
6118
  Boolean     revcomp;
 
6119
  CharPtr     err_msg;
 
6120
  Int4        nonly;
 
6121
  EFarPointerError err_type;
 
6122
}FarPointerData, PNTR FarPointerPtr;
 
6123
 
 
6124
typedef struct farpointerwin 
 
6125
{
 
6126
  FORM_MESSAGE_BLOCK
 
6127
  
 
6128
  ParData ParFmt;
 
6129
  ColData ColFmt[3];  
 
6130
  
 
6131
  DoC        doc;
 
6132
  BoolPtr    selected;
 
6133
  Int2       lineheight;  
 
6134
  
 
6135
  FarPointerPtr far_pointer_list;
 
6136
  Int4          num_sequences;
 
6137
} FarPointerWinData, PNTR FarPointerWinPtr;
 
6138
 
 
6139
 
 
6140
static FarPointerPtr FreeFarPointerData (FarPointerPtr fpp, Int4 num)
 
6141
{
 
6142
  Int4 i;
 
6143
  
 
6144
  if (fpp != NULL) {
 
6145
    for (i = 0; i < num; i++) {
 
6146
      fpp[i].sip_local = SeqIdFree (fpp[i].sip_local);
 
6147
      fpp[i].sip_db = SeqIdFree (fpp[i].sip_db);
 
6148
      BioseqUnlock (fpp[i].bsp_local);
 
6149
      if (fpp[i].bsp_local != NULL) {
 
6150
        fpp[i].bsp_local->idx.deleteme = TRUE;
 
6151
      }
 
6152
      fpp[i].bsp_local = NULL;
 
6153
      BioseqUnlock (fpp[i].bsp_db);
 
6154
      fpp[i].bsp_db = NULL;
 
6155
      fpp[i].salp = SeqAlignFree (fpp[i].salp);
 
6156
      fpp[i].err_msg = MemFree (fpp[i].err_msg);
 
6157
    }
 
6158
    fpp = MemFree (fpp);
 
6159
  }
 
6160
  return fpp;
 
6161
}
 
6162
 
 
6163
static void CleanupFarPointerWinProc (GraphiC g, Pointer data)
 
6164
{
 
6165
  FarPointerWinPtr fpwp;
 
6166
  
 
6167
  if (data != NULL)  
 
6168
  {
 
6169
    fpwp = (FarPointerWinPtr) data;
 
6170
    fpwp->selected = MemFree (fpwp->selected);
 
6171
    fpwp = MemFree (fpwp);
 
6172
  }
 
6173
}
 
6174
 
 
6175
static Int4 GetDisplayGroupNum (FarPointerPtr fpp)
 
6176
{
 
6177
  if (fpp == NULL) return -1;
 
6178
  else if (fpp->sip_db == NULL) return 4;
 
6179
  else if (fpp->bsp_db == NULL) return 3;
 
6180
  else if (fpp->nonly < 0) return 1;
 
6181
  else if (fpp->err_msg != NULL) return 0;
 
6182
  else return 2;
 
6183
}
 
6184
 
 
6185
static Int4 GetSeqNumFromListPos (Int4 list_pos, FarPointerPtr fpp, Int4 num)
 
6186
{
 
6187
  Int4       seq_num, list_offset = 0, group_num;
 
6188
  
 
6189
  if (fpp == NULL || num < list_pos)
 
6190
  {
 
6191
    return 0;
 
6192
  }
 
6193
 
 
6194
  /* TO DO: sort items by how they are listed */
 
6195
  
 
6196
  for (group_num = 0; group_num < 5; group_num++) {
 
6197
    for (seq_num = 0; seq_num < num; seq_num++) {
 
6198
      if (GetDisplayGroupNum(fpp + seq_num) == group_num) {
 
6199
        if (list_offset == list_pos) {
 
6200
          return seq_num;
 
6201
        }
 
6202
        list_offset++;
 
6203
      }
 
6204
    }
 
6205
  }
 
6206
  return 0;
 
6207
}
 
6208
 
 
6209
static void ReleaseFarPointer (DoC d, PoinT pt)
 
6210
 
 
6211
{
 
6212
  Int2            col;
 
6213
  FarPointerWinPtr  fpwp;
 
6214
  Int2            item;
 
6215
  RecT            rct;
 
6216
  Int2            row;
 
6217
  Int4            seq_num, group_num;
 
6218
 
 
6219
  fpwp = (FarPointerWinPtr) GetObjectExtra (d);
 
6220
  if (fpwp != NULL && fpwp->selected != NULL) {
 
6221
    MapDocPoint (d, pt, &item, &row, &col, &rct);
 
6222
    rct.left += 1;
 
6223
    rct.right = rct.left + fpwp->lineheight;
 
6224
    rct.bottom = rct.top + (rct.right - rct.left);
 
6225
    if (row == 1 && col == 3 && PtInRect (pt, &rct))
 
6226
    {
 
6227
      seq_num = GetSeqNumFromListPos (item - 1, fpwp->far_pointer_list, fpwp->num_sequences);
 
6228
      if (seq_num > -1 && seq_num < fpwp->num_sequences)
 
6229
      {
 
6230
        group_num = GetDisplayGroupNum(fpwp->far_pointer_list + seq_num);
 
6231
        if (group_num == 3 || group_num == 4) {
 
6232
          /* can never replace non-far pointers */
 
6233
          fpwp->selected[seq_num] = FALSE;
 
6234
        } else if (fpwp->selected [seq_num]) {
 
6235
          fpwp->selected [seq_num] = FALSE;
 
6236
        } else {
 
6237
          fpwp->selected [seq_num] = TRUE;
 
6238
        }
 
6239
        InsetRect (&rct, -1, -1);
 
6240
        InvalRect (&rct);
 
6241
        Update ();
 
6242
      }
 
6243
    }
 
6244
  }
 
6245
}
 
6246
 
 
6247
static void DrawFarPointer (DoC d, RectPtr r, Int2 item, Int2 firstLine)
 
6248
 
 
6249
{
 
6250
  FarPointerWinPtr fpwp;
 
6251
  RecT             rct;
 
6252
  RecT             doc_rect;
 
6253
  Int4             seq_num, group_num;
 
6254
 
 
6255
  fpwp = (FarPointerWinPtr) GetObjectExtra (d);
 
6256
  
 
6257
  if (fpwp == NULL || r == NULL 
 
6258
      || item < 1 || item > fpwp->num_sequences 
 
6259
      || firstLine != 0)
 
6260
  {
 
6261
    return;
 
6262
  }
 
6263
  
 
6264
  rct = *r;
 
6265
  rct.right --;
 
6266
  rct.left = rct.right - fpwp->lineheight;
 
6267
  rct.bottom = rct.top + (rct.right - rct.left);
 
6268
  
 
6269
  /* make sure we don't draw a box where we aren't drawing text */
 
6270
  ObjectRect (fpwp->doc, &doc_rect);
 
6271
  InsetRect (&doc_rect, 4, 4);
 
6272
  if (rct.bottom > doc_rect.bottom)
 
6273
  {
 
6274
    return;
 
6275
  }
 
6276
 
 
6277
  seq_num = GetSeqNumFromListPos (item - 1, fpwp->far_pointer_list, fpwp->num_sequences);
 
6278
  if (seq_num > -1 && seq_num < fpwp->num_sequences) {
 
6279
    group_num = GetDisplayGroupNum(fpwp->far_pointer_list + seq_num);
 
6280
    if (group_num != 3 && group_num != 4) {
 
6281
      FrameRect (&rct);
 
6282
  
 
6283
      if (fpwp->selected != NULL && fpwp->selected [seq_num]) {
 
6284
        MoveTo (rct.left, rct.top);
 
6285
        LineTo (rct.right - 1, rct.bottom - 1);
 
6286
        MoveTo (rct.left, rct.bottom - 1);
 
6287
        LineTo (rct.right - 1, rct.top);
 
6288
      }
 
6289
    }
 
6290
  }
 
6291
}
 
6292
 
 
6293
static void GetTextForOneFarPointerData (FarPointerPtr fpp, CharPtr doc_line)
 
6294
{
 
6295
  CharPtr      cp;
 
6296
 
 
6297
  if (fpp == NULL || doc_line == NULL) return;
 
6298
  
 
6299
  SeqIdWrite (fpp->sip_local, doc_line, PRINTID_TEXTID_ACC_ONLY, 255);
 
6300
  if (fpp->sip_db == NULL) {
 
6301
    StringCat (doc_line, "\tNot a far pointer\t\n");
 
6302
  } else if (fpp->bsp_db == NULL) {
 
6303
    StringCat (doc_line, "\tNot found in GenBank\t\n");
 
6304
  } else if (fpp->err_msg != NULL) {
 
6305
    /* replace carriage returns with spaces */
 
6306
    cp = StringChr (fpp->err_msg, '\n');
 
6307
    while (cp != NULL) {
 
6308
      *cp = ' ';
 
6309
      cp = StringChr (cp + 1, '\n');
 
6310
    }
 
6311
    /* replace tabs with spaces */
 
6312
    cp = StringChr (fpp->err_msg, '\t');
 
6313
    while (cp != NULL) {
 
6314
      *cp = ' ';
 
6315
      cp = StringChr (cp + 1, '\t');
 
6316
    }
 
6317
    
 
6318
    StringCat (doc_line, "\t");
 
6319
    StringCat (doc_line, fpp->err_msg);
 
6320
    StringCat (doc_line, "\t\n");
 
6321
  } else {
 
6322
    StringCat (doc_line, "\t\t\n");
 
6323
  }
 
6324
}
 
6325
 
 
6326
static void RedrawFarPointerWin (FarPointerWinPtr fpwp)
 
6327
{
 
6328
  Int4         i, group_num;
 
6329
  Char         doc_line [500];
 
6330
  
 
6331
  if (fpwp == NULL)
 
6332
  {
 
6333
    return;
 
6334
  }
 
6335
 
 
6336
  Reset (fpwp->doc);
 
6337
  
 
6338
  for (group_num = 0; group_num < 5; group_num++) {
 
6339
    for (i = 0; i < fpwp->num_sequences; i++) {
 
6340
      if (GetDisplayGroupNum(fpwp->far_pointer_list + i) == group_num) {
 
6341
        GetTextForOneFarPointerData (fpwp->far_pointer_list + i, doc_line);
 
6342
        AppendText (fpwp->doc, doc_line, &(fpwp->ParFmt), fpwp->ColFmt, Nlm_programFont);
 
6343
        if (group_num == 2) {
 
6344
          fpwp->selected [i] = TRUE;
 
6345
        } else {
 
6346
          fpwp->selected [i] = FALSE;
 
6347
        }
 
6348
      }
 
6349
    }
 
6350
  }
 
6351
  
 
6352
 
 
6353
  UpdateDocument (fpwp->doc, 0, 0);  
 
6354
}
 
6355
 
 
6356
static void ExportBadAlignments (ButtoN b)
 
6357
{
 
6358
  FarPointerWinPtr   fpwp;
 
6359
  Char               path [PATH_MAX];
 
6360
  FILE               *fp;
 
6361
  Int4               i;
 
6362
  Char               str[50];
 
6363
  
 
6364
  fpwp = (FarPointerWinPtr) GetObjectExtra (b);
 
6365
  if (fpwp == NULL) return;
 
6366
  
 
6367
  if (GetOutputFileName (path, sizeof (path), NULL)) {
 
6368
    fp = FileOpen (path, "w");
 
6369
    if (fp == NULL) {
 
6370
      Message (MSG_ERROR, "Unable to open %s", path);
 
6371
      return;
 
6372
    }
 
6373
    for (i = 0; i < fpwp->num_sequences; i++) {
 
6374
      if (fpwp->far_pointer_list[i].salp != NULL 
 
6375
          && fpwp->far_pointer_list[i].err_msg != NULL) {
 
6376
        SeqIdWrite (fpwp->far_pointer_list[i].sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
 
6377
        fprintf (fp, "%s\n", str);
 
6378
        fprintf (fp, "%s\n", fpwp->far_pointer_list[i].err_msg);
 
6379
        WriteAlignmentInterleaveToFileEx (fpwp->far_pointer_list[i].salp, fp,
 
6380
                                        60, TRUE, TRUE);
 
6381
      }
 
6382
    }
 
6383
  }
 
6384
  FileClose (fp);
 
6385
}
 
6386
 
 
6387
 
 
6388
static void ExportFASTAForUnselectedUpdates (ButtoN b)
 
6389
{
 
6390
  FarPointerWinPtr   fpwp;
 
6391
  Char               path [PATH_MAX];
 
6392
  FILE               *fp;
 
6393
  Int4               i;
 
6394
  
 
6395
  fpwp = (FarPointerWinPtr) GetObjectExtra (b);
 
6396
  if (fpwp == NULL) return;
 
6397
  
 
6398
  if (GetOutputFileName (path, sizeof (path), NULL)) {
 
6399
    fp = FileOpen (path, "w");
 
6400
    if (fp == NULL) {
 
6401
      Message (MSG_ERROR, "Unable to open %s", path);
 
6402
      return;
 
6403
    }
 
6404
    for (i = 0; i < fpwp->num_sequences; i++) {
 
6405
      if (fpwp->far_pointer_list[i].bsp_db != NULL 
 
6406
          && !fpwp->selected[i]) {
 
6407
        EditBioseqToFasta (fpwp->far_pointer_list[i].bsp_db, fp, 0, fpwp->far_pointer_list[i].bsp_db->length - 1);                
 
6408
      }
 
6409
    }
 
6410
  }
 
6411
  FileClose (fp);
 
6412
}
 
6413
 
 
6414
static void ExportFarPointerErrorMessages (ButtoN b)
 
6415
{
 
6416
  FarPointerWinPtr   fpwp;
 
6417
  Char               path [PATH_MAX];
 
6418
  FILE               *fp;
 
6419
  Int4               i;
 
6420
  Char               str[50];
 
6421
  
 
6422
  fpwp = (FarPointerWinPtr) GetObjectExtra (b);
 
6423
  if (fpwp == NULL) return;
 
6424
 
 
6425
  TmpNam (path);  
 
6426
  fp = FileOpen (path, "w");
 
6427
  if (fp == NULL) {
 
6428
    Message (MSG_ERROR, "Unable to open %s", path);
 
6429
    return;
 
6430
  }
 
6431
  for (i = 0; i < fpwp->num_sequences; i++) {
 
6432
    if (fpwp->far_pointer_list[i].err_msg != NULL 
 
6433
        && fpwp->far_pointer_list[i].sip_local != NULL) {
 
6434
        SeqIdWrite (fpwp->far_pointer_list[i].sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
 
6435
        fprintf (fp, "%s\t%s\n", str, fpwp->far_pointer_list[i].err_msg);        
 
6436
    }
 
6437
  }
 
6438
  FileClose (fp);
 
6439
  LaunchGeneralTextViewer (path, "FarPointer Errors");
 
6440
  FileRemove (path);
 
6441
}
 
6442
 
 
6443
 
 
6444
static Boolean DisplayFarPointerData (FarPointerPtr fpp, Int4 num)
 
6445
{
 
6446
  WindoW w;
 
6447
  ModalAcceptCancelData acd;
 
6448
  FarPointerWinPtr   fpwp;
 
6449
  ButtoN             b;
 
6450
  GrouP              h, g, c;
 
6451
  RecT               r;
 
6452
  Int4               i;
 
6453
  
 
6454
  if (fpp == NULL) {
 
6455
    return FALSE;
 
6456
  }
 
6457
  
 
6458
  fpwp = (FarPointerWinPtr) MemNew (sizeof (FarPointerWinData));
 
6459
  
 
6460
  fpwp->far_pointer_list = fpp;
 
6461
  fpwp->num_sequences = num;
 
6462
  fpwp->selected = (BoolPtr) MemNew (sizeof(Boolean) * num);
 
6463
  
 
6464
  /* initialize document paragraph format */
 
6465
  fpwp->ParFmt.openSpace = FALSE;
 
6466
  fpwp->ParFmt.keepWithNext = FALSE;
 
6467
  fpwp->ParFmt.keepTogether = FALSE;
 
6468
  fpwp->ParFmt.newPage = FALSE;
 
6469
  fpwp->ParFmt.tabStops = FALSE;
 
6470
  fpwp->ParFmt.minLines = 0;
 
6471
  fpwp->ParFmt.minHeight = 0;
 
6472
  
 
6473
  /* initialize document column format */
 
6474
  fpwp->ColFmt[0].pixWidth = 0;
 
6475
  fpwp->ColFmt[0].pixInset = 0;
 
6476
  fpwp->ColFmt[0].charWidth = 80;
 
6477
  fpwp->ColFmt[0].charInset = 0;
 
6478
  fpwp->ColFmt[0].font = NULL;
 
6479
  fpwp->ColFmt[0].just = 'l';
 
6480
  fpwp->ColFmt[0].wrap = TRUE;
 
6481
  fpwp->ColFmt[0].bar = FALSE;
 
6482
  fpwp->ColFmt[0].underline = FALSE;
 
6483
  fpwp->ColFmt[0].left = FALSE;
 
6484
  fpwp->ColFmt[0].last = FALSE;
 
6485
  fpwp->ColFmt[1].pixWidth = 0;
 
6486
  fpwp->ColFmt[1].pixInset = 0;
 
6487
  fpwp->ColFmt[1].charWidth = 80;
 
6488
  fpwp->ColFmt[1].charInset = 0;
 
6489
  fpwp->ColFmt[1].font = NULL;
 
6490
  fpwp->ColFmt[1].just = 'l';
 
6491
  fpwp->ColFmt[1].wrap = TRUE;
 
6492
  fpwp->ColFmt[1].bar = FALSE;
 
6493
  fpwp->ColFmt[1].underline = FALSE;
 
6494
  fpwp->ColFmt[1].left = FALSE;
 
6495
  fpwp->ColFmt[1].last = FALSE;
 
6496
  fpwp->ColFmt[2].pixWidth = 0;
 
6497
  fpwp->ColFmt[2].pixInset = 0;
 
6498
  fpwp->ColFmt[2].charWidth = 80;
 
6499
  fpwp->ColFmt[2].charInset = 0;
 
6500
  fpwp->ColFmt[2].font = NULL;
 
6501
  fpwp->ColFmt[2].just = 'l';
 
6502
  fpwp->ColFmt[2].wrap = TRUE;
 
6503
  fpwp->ColFmt[2].bar = FALSE;
 
6504
  fpwp->ColFmt[2].underline = FALSE;
 
6505
  fpwp->ColFmt[2].left = FALSE;
 
6506
  fpwp->ColFmt[2].last = TRUE;  
 
6507
  
 
6508
  w = MovableModalWindow (50, 33, -10, -10, "Far Pointer Sequences", NULL);
 
6509
  SetObjectExtra (w, fpwp, CleanupFarPointerWinProc);
 
6510
  fpwp->form = (ForM) w;
 
6511
  
 
6512
  h = HiddenGroup (w, -1, 0, NULL);
 
6513
  SetGroupSpacing (h, 10, 10);
 
6514
  
 
6515
  fpwp->doc = DocumentPanel (h, stdCharWidth * 50, stdLineHeight * 20);
 
6516
  SetObjectExtra (fpwp->doc, fpwp, NULL);
 
6517
  SetDocAutoAdjust (fpwp->doc, TRUE);
 
6518
  SetDocProcs (fpwp->doc, NULL, NULL, ReleaseFarPointer, NULL); 
 
6519
  SetDocShade (fpwp->doc, DrawFarPointer, NULL, NULL, NULL);
 
6520
 
 
6521
  SelectFont (Nlm_programFont);
 
6522
  fpwp->lineheight = LineHeight ();
 
6523
  
 
6524
  ObjectRect (fpwp->doc, &r);
 
6525
  InsetRect (&r, 4, 4);
 
6526
  fpwp->ColFmt[0].pixWidth = (r.right - r.left - fpwp->lineheight) / 2;
 
6527
  fpwp->ColFmt[1].pixWidth = (r.right - r.left - fpwp->lineheight) / 2;
 
6528
  fpwp->ColFmt[2].pixWidth = fpwp->lineheight;
 
6529
  
 
6530
  g = HiddenGroup (h, 4, 0, NULL);
 
6531
  b = PushButton (g, "Export Bad Alignments", ExportBadAlignments);
 
6532
  SetObjectExtra (b, fpwp, NULL);
 
6533
  Disable (b);
 
6534
  for (i = 0; i < fpwp->num_sequences; i++) {
 
6535
    if (fpwp->far_pointer_list[i].salp != NULL && fpwp->far_pointer_list[i].err_msg != NULL) {
 
6536
      Enable (b);
 
6537
      break;
 
6538
    }
 
6539
  }
 
6540
  b = PushButton (g, "Export FASTA for Unselected Sequences", ExportFASTAForUnselectedUpdates);
 
6541
  SetObjectExtra (b, fpwp, NULL);
 
6542
  
 
6543
  b = PushButton (g, "Export FarPointer Error Messages", ExportFarPointerErrorMessages);
 
6544
  SetObjectExtra (b, fpwp, NULL);
 
6545
 
 
6546
  c = HiddenGroup (h, 2, 0, NULL);
 
6547
  b = PushButton (c, "Replace Selected Sequences", ModalAcceptButton);
 
6548
  SetObjectExtra (b, &acd, NULL);
 
6549
  b = PushButton (c, "Cancel", ModalCancelButton);
 
6550
  SetObjectExtra (b, &acd, NULL);
 
6551
 
 
6552
  AlignObjects (ALIGN_CENTER, (HANDLE) fpwp->doc,
 
6553
                              (HANDLE) g,
 
6554
                              (HANDLE) c,
 
6555
                              NULL);  
 
6556
  RedrawFarPointerWin (fpwp);
 
6557
  Show (w);
 
6558
  Select (w);
 
6559
  ArrowCursor();
 
6560
  Update ();
 
6561
 
 
6562
  acd.accepted = FALSE;
 
6563
  acd.cancelled = FALSE;
 
6564
  while (!acd.accepted && ! acd.cancelled)
 
6565
  {
 
6566
    ProcessExternalEvent ();
 
6567
    Update ();
 
6568
  }
 
6569
  ProcessAnEvent ();
 
6570
 
 
6571
  if (acd.accepted)
 
6572
  {
 
6573
    Hide (w);
 
6574
    for (i = 0; i < num; i++) {
 
6575
      if (!fpwp->selected[i]) {
 
6576
        fpp[i].salp = SeqAlignFree (fpp[i].salp);
 
6577
        BioseqUnlock (fpp[i].bsp_db);
 
6578
        fpp[i].bsp_db = NULL;
 
6579
        fpp[i].sip_db = SeqIdFree (fpp[i].sip_db);
 
6580
        /* make sure local sequence is not deleted */
 
6581
        BioseqUnlock (fpp[i].bsp_local);
 
6582
        fpp[i].bsp_local = NULL;
 
6583
      }
 
6584
    }
 
6585
        
 
6586
  }
 
6587
  Remove (w);
 
6588
  WatchCursor();
 
6589
  Update();
 
6590
  return acd.accepted;
 
6591
}
 
6592
 
 
6593
/* This function will replace a sequence in an alignment record with one
 
6594
 * downloaded from GenBank.  It will also adjust the alignment starts
 
6595
 * for that sequence if the GenBank sequence is not identical to the
 
6596
 * sequence in the alignment (salp).
 
6597
 * vnp is a ValNodePtr to a list of sequence IDs for Bioseqs to be deleted
 
6598
 * later.
 
6599
 */
 
6600
static ValNodePtr CCNormalizeSeqAlignId (SeqAlignPtr salp, ValNodePtr vnp)
 
6601
{
 
6602
  Int4 num_rows, i;
 
6603
  CharPtr tmp, id_start, dot_pos;
 
6604
  Char    str [52];
 
6605
  FarPointerPtr far_pointer_list = NULL;
 
6606
  Int4          num_missing = 0, num_found = 0;
 
6607
  CharPtr       missing_cont_fmt = "The alignment contains %s that can not be found in GenBank.\nPlease check the accession number.\nContinue anyway?\n";
 
6608
  CharPtr       missing_fmt = "The alignment contains %s that can not be found in GenBank.\nPlease check the accession number.\n";
 
6609
  Int4                gi = 0;
 
6610
  Int4                version;
 
6611
  BLAST_OptionsBlkPtr options;
 
6612
  SeqAlignPtr         tmp_salp;
 
6613
  DenseSegPtr         dsp;
 
6614
  Int4                offset, len, start1, start2, stop1, stop2;
 
6615
  SeqIdPtr            sip, presip;
 
6616
  Uint1               strand;
 
6617
  
 
6618
  if (salp == NULL || salp->segtype != 2) {
 
6619
    return vnp;
 
6620
  }
 
6621
  
 
6622
  dsp = (DenseSegPtr) salp->segs;
 
6623
  
 
6624
  AlnMgr2IndexSingleChildSeqAlign(salp);
 
6625
  num_rows = AlnMgr2GetNumRows(salp);
 
6626
  
 
6627
  far_pointer_list = (FarPointerPtr) MemNew (num_rows * sizeof (FarPointerData)); 
 
6628
 
 
6629
  for (i = 0; i < num_rows; i++) {
 
6630
    far_pointer_list[i].sip_local = AlnMgr2GetNthSeqIdPtr(salp, i + 1);
 
6631
    far_pointer_list[i].sip_db = NULL;
 
6632
    far_pointer_list[i].bsp_local = NULL;
 
6633
    far_pointer_list[i].bsp_db = NULL;
 
6634
    far_pointer_list[i].salp = NULL;
 
6635
    far_pointer_list[i].revcomp = FALSE;
 
6636
    far_pointer_list[i].nonly = 0;
 
6637
    far_pointer_list[i].err_type = FARPOINTER_LOOKUP_NO_ERROR;
 
6638
 
 
6639
    /* is this a farpointer ID? */
 
6640
    SeqIdWrite (far_pointer_list[i].sip_local, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
 
6641
    tmp = StringISearch (str, "acc");
 
6642
    if (tmp!=NULL) {
 
6643
      tmp += 3;
 
6644
      if (*tmp == '|')
 
6645
         tmp++;   
 
6646
      id_start = tmp;
 
6647
      
 
6648
      /* look for next pipe char, carriage return, or end of string */
 
6649
      while (*tmp!='\0' && *tmp != '|' && *tmp!='\n')
 
6650
        tmp++;
 
6651
      *tmp = '\0';
 
6652
      
 
6653
      /* check for version */
 
6654
      version = 0;
 
6655
      dot_pos = StringChr (id_start, '.');
 
6656
      if (dot_pos != NULL) {
 
6657
        *dot_pos = '\0';
 
6658
        version = atoi (dot_pos + 1);
 
6659
      }
 
6660
      if (StringSpn (id_start, "0123456789") == StringLen (id_start)) {
 
6661
        /* all numbers, is GI */
 
6662
        gi = (Int4)atol(id_start);
 
6663
        if (gi>0) {
 
6664
          far_pointer_list[i].sip_db = ValNodeNew (NULL);
 
6665
          if (far_pointer_list[i].sip_db) {
 
6666
            far_pointer_list[i].sip_db->choice = SEQID_GI;
 
6667
            far_pointer_list[i].sip_db->data.intvalue = (Int4)gi;
 
6668
          }
 
6669
        }
 
6670
      } else if (IS_ntdb_accession(id_start) || IS_protdb_accession(id_start)) {
 
6671
        far_pointer_list[i].sip_db = SeqIdFromAccession (id_start, version, NULL);
 
6672
      }
 
6673
      if (far_pointer_list[i].sip_db != NULL) {
 
6674
        far_pointer_list[i].bsp_local = BioseqLockById(far_pointer_list[i].sip_local);
 
6675
        far_pointer_list[i].bsp_db = BioseqLockById(far_pointer_list[i].sip_db);
 
6676
        if (far_pointer_list[i].bsp_local != NULL 
 
6677
            && far_pointer_list[i].bsp_db != NULL 
 
6678
            && far_pointer_list[i].bsp_local->length > 0 
 
6679
            && far_pointer_list[i].bsp_db->length > 0) {
 
6680
          options = BLASTOptionNew("blastn", TRUE);
 
6681
          options->filter_string = StringSave("m L;R");
 
6682
          tmp_salp = BlastTwoSequences (far_pointer_list[i].bsp_local, far_pointer_list[i].bsp_db, "blastn", options);
 
6683
          options = BLASTOptionDelete(options);
 
6684
          far_pointer_list[i].err_msg = (CharPtr) MemNew (sizeof(Char) * 1000);
 
6685
          far_pointer_list[i].salp = SeqAlignBestHit (tmp_salp, 
 
6686
                                                      far_pointer_list[i].bsp_local, 
 
6687
                                                      far_pointer_list[i].bsp_db, 
 
6688
                                                      100, &(far_pointer_list[i].err_msg),
 
6689
                                                      &(far_pointer_list[i].nonly));
 
6690
          if (far_pointer_list[i].err_msg[0] == '\0')
 
6691
            far_pointer_list[i].err_msg = MemFree (far_pointer_list[i].err_msg);
 
6692
          else if (far_pointer_list[i].nonly < 0)
 
6693
            far_pointer_list[i].err_type = FARPOINTER_LOOKUP_NONLY;
 
6694
          else
 
6695
            far_pointer_list[i].err_type = FARPOINTER_LOOKUP_BAD_ALN;
 
6696
                                                            
 
6697
          num_found++;
 
6698
        } else {
 
6699
          num_missing++;
 
6700
        }
 
6701
      }
 
6702
    }
 
6703
  }
 
6704
 
 
6705
  if (DisplayFarPointerData (far_pointer_list, num_rows)) {
 
6706
    /* for each entry that still has a bioseq, do the replacement */
 
6707
    presip = NULL;
 
6708
    for (i = 0, sip = dsp->ids; i < num_rows && sip != NULL; i++, sip = sip->next) {
 
6709
      if (far_pointer_list[i].bsp_db == NULL) {
 
6710
        continue;
 
6711
      }
 
6712
      offset = SeqAlignStart(far_pointer_list[i].salp, 1)-SeqAlignStart(far_pointer_list[i].salp, 0);
 
6713
      if ((SeqAlignStrand(far_pointer_list[i].salp, 0)==Seq_strand_minus && SeqAlignStrand(far_pointer_list[i].salp, 1) != Seq_strand_minus) 
 
6714
          || (SeqAlignStrand(far_pointer_list[i].salp, 1)==Seq_strand_minus && SeqAlignStrand(far_pointer_list[i].salp, 0) != Seq_strand_minus))
 
6715
      {
 
6716
        /* strand is reversed */
 
6717
        strand=Seq_strand_minus;
 
6718
        AlnMgr2IndexSingleChildSeqAlign(far_pointer_list[i].salp);
 
6719
        AlnMgr2GetNthSeqRangeInSA(far_pointer_list[i].salp, 1, &start1, &stop1);
 
6720
        AlnMgr2GetNthSeqRangeInSA(far_pointer_list[i].salp, 2, &start2, &stop2);
 
6721
        len = stop2 + start1;
 
6722
        if (offset < 0)
 
6723
        {
 
6724
          offset = 0 - offset;
 
6725
        }
 
6726
      } else
 
6727
        strand=Seq_strand_plus;
 
6728
      SeqAlignStartUpdate (far_pointer_list[i].salp, far_pointer_list[i].sip_local, abs(offset), len, strand);
 
6729
      dsp->ids = SWSeqIdReplaceID(dsp->ids, far_pointer_list[i].sip_local, far_pointer_list[i].sip_db);
 
6730
      /* set to NULL so that we don't free it later */
 
6731
      far_pointer_list[i].sip_db = NULL;
 
6732
 
 
6733
      if (presip)
 
6734
        sip = presip->next;
 
6735
      else
 
6736
        sip = dsp->ids;
 
6737
      /* We add the ID of the sequence we are replacing to a list
 
6738
       * of sequences that will be deleted later.
 
6739
       * We can't delete the sequence now, in case it is present
 
6740
       * in more than one alignment for this record.
 
6741
       */
 
6742
      vnp = nrSeqIdAdd (vnp, far_pointer_list[i].sip_local);
 
6743
      /* set to NULL so that we don't free it later */
 
6744
      far_pointer_list[i].sip_local = NULL;
 
6745
    }
 
6746
  } else {
 
6747
    for (i = 0, sip = dsp->ids; i < num_rows && sip != NULL; i++, sip = sip->next) {
 
6748
      if (far_pointer_list[i].bsp_db != NULL) {
 
6749
        BioseqUnlock (far_pointer_list[i].bsp_db);
 
6750
        far_pointer_list[i].bsp_db->idx.deleteme = TRUE;
 
6751
      }
 
6752
      if (far_pointer_list[i].bsp_local != NULL) {
 
6753
        BioseqUnlock (far_pointer_list[i].bsp_local);
 
6754
        far_pointer_list[i].bsp_local = NULL;
 
6755
      }
 
6756
    }
 
6757
  }
 
6758
  
 
6759
  far_pointer_list = FreeFarPointerData(far_pointer_list, num_rows);
 
6760
  
 
6761
  return vnp;
 
6762
}
 
6763
#else
 
6764
static ValNodePtr CCNormalizeSeqAlignId (SeqAlignPtr salp, ValNodePtr vnp)
 
6765
{
 
6766
  BLAST_OptionsBlkPtr options;
 
6767
  MsgAnswer           ans;
 
6768
  DenseSegPtr         dsp;
 
6769
  SeqIdPtr            sip,
 
6770
                      dbsip = NULL,
 
6771
                      lclsip,
 
6772
                      presip, 
 
6773
                      next,
 
6774
                      tmpsip;
 
6775
  SeqAlignPtr         seqalign = NULL;
 
6776
  SeqAlignPtr         bestsalp = NULL;
 
6777
  CharPtr             TmpBuff, tmp;
 
6778
  Char                str [52];
 
6779
  Int4                gi = 0,
 
6780
                      offset,
 
6781
                      totlenlcl = 0, totlendb = 0;
 
6782
  Int4                i, j, k, len = 0, n;
 
6783
  Int4                num_not_asked;
 
6784
  Int2                index;
 
6785
  Uint1               strand;
 
6786
  Boolean             ok, 
 
6787
                      found;
 
6788
  
 
6789
  Char                strLog[50];
 
6790
  BioseqPtr           bsp1, bsp2;
 
6791
  Int4                start1, start2, stop1, stop2;
 
6792
  CharPtr             errstr;
 
6793
  Int4                nonly;
 
6794
  BestHitPtr          hip, hip_prev, hip_head;
 
6795
  BestHitPtr          PNTR hiparray;
 
6796
  Char                messagestr[1500];
 
6797
  Int4                numhips;
 
6798
  FILE                *ofp;
 
6799
  Int4                version;
 
6800
 
 
6801
  hip_prev = hip_head = NULL;
 
6802
  errstr = (CharPtr)MemNew(500*sizeof(Char));
 
6803
  if (salp!=NULL) {
 
6804
     if (salp->segtype == 2) {
 
6805
        dsp = (DenseSegPtr) salp->segs;
 
6806
        presip = NULL;
 
6807
        sip = dsp->ids;
 
6808
        index = 0;
 
6809
        found = FALSE;
 
6810
        while (sip != NULL) 
 
6811
        {
 
6812
           next = sip->next;
 
6813
           lclsip = SeqIdDup (sip);
 
6814
           SeqIdWrite (lclsip, str, PRINTID_FASTA_LONG, 50);
 
6815
           tmp = StringStr (str, "acc");
 
6816
           if (tmp==NULL) 
 
6817
           {
 
6818
              tmp = StringStr (str, "ACC");
 
6819
           }
 
6820
           if (tmp!=NULL) {
 
6821
              tmp++; tmp++; tmp++;
 
6822
              if (*tmp == '|')
 
6823
                 tmp++;   
 
6824
              TmpBuff = tmp;
 
6825
              while (*tmp!='\0' && *tmp != '|' && *tmp!='\n')
 
6826
                 tmp++;
 
6827
              *tmp = '\0';
 
6828
              /* check for version */
 
6829
              tmp = TmpBuff;
 
6830
              version = 0;
 
6831
              while (*tmp != 0 && *tmp != '.')
 
6832
              {
 
6833
                *tmp++;
 
6834
              }
 
6835
              if (*tmp == '.')
 
6836
              {
 
6837
                *tmp = 0;
 
6838
                version = atoi (tmp + 1);
 
6839
              }
 
6840
 
 
6841
              ok = FALSE;
 
6842
              j = StringLen (TmpBuff);
 
6843
              for(k =0; k < j; k++) {
 
6844
                 if(!isdigit(TmpBuff[k])) {
 
6845
                    break;
 
6846
                 }
 
6847
              }
 
6848
              dbsip=NULL;
 
6849
              if(k != j) {
 
6850
                 
 
6851
                 ok=(IS_ntdb_accession(TmpBuff) || IS_protdb_accession(TmpBuff));
 
6852
                 if (ok) {
 
6853
                    dbsip = SeqIdFromAccession (TmpBuff, version, NULL);
 
6854
                 }
 
6855
              }
 
6856
              else {
 
6857
                 gi = (Int4)atol(TmpBuff);
 
6858
                 if (gi>0) {
 
6859
                    dbsip = ValNodeNew (NULL);
 
6860
                    if (dbsip) {
 
6861
                       dbsip->choice = SEQID_GI;
 
6862
                       dbsip->data.intvalue = (Int4)gi;
 
6863
                    }
 
6864
                 }
 
6865
              }
 
6866
              if (dbsip!=NULL) {
 
6867
                 bsp1 = BioseqLockById(lclsip);
 
6868
                 bsp2 = BioseqLockById(dbsip);
 
6869
                 if ( bsp1 != NULL && bsp2 != NULL && bsp1->length > 0 && bsp2->length > 0) {
 
6870
                 options = BLASTOptionNew("blastn", TRUE);
 
6871
                 options->filter_string = StringSave("m L;R");
 
6872
                 seqalign = BlastTwoSequences (bsp1, bsp2, "blastn", options);
 
6873
                 if (errstr != NULL)
 
6874
                    MemFree(errstr);
 
6875
                 errstr = (CharPtr)MemNew(1000*sizeof(Char));
 
6876
                 bestsalp = SeqAlignBestHit (seqalign, bsp1, bsp2, 100, &errstr, &nonly);
 
6877
                 hip = (BestHitPtr)MemNew(sizeof(BestHit));
 
6878
                 hip->sap = bestsalp;
 
6879
                 hip->sip1 = lclsip;
 
6880
                 if (dbsip->choice != SEQID_GI && bsp2->id != NULL) {
 
6881
                   /* recreate sip to get correct version number */
 
6882
                   for (tmpsip = bsp2->id; tmpsip != NULL; tmpsip = tmpsip->next) {
 
6883
                     if (tmpsip->choice == dbsip->choice) break;
 
6884
                   }
 
6885
                   if (tmpsip != NULL) {
 
6886
                     dbsip = SeqIdFree (dbsip);
 
6887
                     dbsip = SeqIdStripLocus (SeqIdDup (tmpsip));
 
6888
                   }
 
6889
                 }
 
6890
                 hip->sip2 = dbsip;
 
6891
                 hip->bsp1 = bsp1;
 
6892
                 hip->bsp2 = bsp2;
 
6893
                 hip->errstr = StringSave(errstr);
 
6894
                 hip->nonly = nonly;
 
6895
                 if (*hip->errstr == '\0')
 
6896
                    hip->errtype = 0;
 
6897
                 else if (nonly < 0)
 
6898
                    hip->errtype = 1;
 
6899
                 else
 
6900
                    hip->errtype = 2;
 
6901
                 if (hip_head != NULL)
 
6902
                 {
 
6903
                    hip_prev->next = hip;
 
6904
                    hip_prev = hip;
 
6905
                 } else
 
6906
                    hip_head = hip_prev = hip;
 
6907
             } else {
 
6908
                 if (totlendb == 0) {
 
6909
                    SeqIdWrite(dbsip, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
6910
                    sprintf(errstr, "This alignment contains \"%s\" that can not be found in GenBank.\nPlease check the accession number.\n", strLog);
 
6911
                   sip->next = next;
 
6912
                 } else if (totlenlcl == 0) {
 
6913
                   SeqIdWrite (lclsip, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
6914
                   sprintf(errstr, "This alignment contains \"%s\" that can not be found.\nPlease check the accession number.\n", strLog);
 
6915
                   sip->next = next;
 
6916
                 }
 
6917
                 hip = (BestHitPtr)MemNew(sizeof(BestHit));
 
6918
                 hip->sap = bestsalp;
 
6919
                 hip->sip1 = lclsip;
 
6920
                 hip->sip2 = dbsip;
 
6921
                 hip->errstr = StringSave(errstr);
 
6922
                 hip->nonly = 0;
 
6923
                 hip->errtype = 3;
 
6924
                 hip->bsp1 = NULL;
 
6925
                 hip->bsp2 = NULL;
 
6926
                 if (hip_head != NULL)
 
6927
                 {
 
6928
                    hip_prev->next = hip;
 
6929
                    hip_prev = hip;
 
6930
                 } else
 
6931
                    hip_head = hip_prev = hip;
 
6932
              }
 
6933
              } else {
 
6934
                 SeqIdWrite (sip, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
6935
                 sprintf(errstr, "This alignment contains \"%s\" that can not be found in GenBank.\nPlease check the accession number.\n", strLog);
 
6936
                 sip->next = next;
 
6937
                 hip = (BestHitPtr)MemNew(sizeof(BestHit));
 
6938
                 hip->sap = bestsalp;
 
6939
                 hip->sip1 = lclsip;
 
6940
                 hip->sip2 = dbsip;
 
6941
                 hip->errstr = StringSave(errstr);
 
6942
                 hip->nonly = 0;
 
6943
                 hip->errtype = 3;
 
6944
                 hip->bsp1 = NULL;
 
6945
                 hip->bsp2 = NULL;
 
6946
                 if (hip_head != NULL)
 
6947
                 {
 
6948
                    hip_prev->next = hip;
 
6949
                    hip_prev = hip;
 
6950
                 } else
 
6951
                    hip_head = hip_prev = hip;
 
6952
              }
 
6953
           }
 
6954
           presip = sip;
 
6955
           sip = next;
 
6956
           index++;
 
6957
           found = FALSE;
 
6958
        }
 
6959
        hip = hip_head;
 
6960
        numhips = 0;
 
6961
        while (hip != NULL)
 
6962
        {
 
6963
           numhips++;
 
6964
           hip = hip->next;
 
6965
        }
 
6966
        hiparray = (BestHitPtr PNTR)MemNew(numhips*sizeof(BestHitPtr));
 
6967
        hip = hip_head;
 
6968
        numhips = 0;
 
6969
        while (hip != NULL)
 
6970
        {
 
6971
           hiparray[numhips] = hip;
 
6972
           numhips++;
 
6973
           hip = hip->next;
 
6974
        }
 
6975
        HeapSort(hiparray, numhips, sizeof(BestHitPtr), OrderBestHits);
 
6976
        i = 0;
 
6977
        while (i<numhips && *hiparray[i]->errstr == '\0')
 
6978
        {
 
6979
           i++;
 
6980
        }
 
6981
        if (i > 0)
 
6982
        {
 
6983
           /* If there are sequences that can be treated as Far Pointers
 
6984
            * and are identical to the most recent version of the sequence
 
6985
            * in GenBank, ask the user if these sequences should be replace
 
6986
            * by the GenBank sequence.
 
6987
            */
 
6988
           messagestr[0] = '\0';
 
6989
           ans = ANS_OK;
 
6990
           num_not_asked = 0;
 
6991
           for (j=0; j<i; j++)
 
6992
           {
 
6993
             /* if we are looking at an alignment of segmented sets,
 
6994
              * and the far pointer points to something other than a
 
6995
              * segmented set, the sequence ID will be the same for
 
6996
              * the alignments for each segment.  We only want to ask
 
6997
              * about the same sequence once.
 
6998
              */
 
6999
             if (! nrSeqIdIsInValNodeList (vnp, hiparray[j]->sip1))
 
7000
             {
 
7001
               SeqIdWrite(hiparray[j]->sip2, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
7002
               StringCat(messagestr, strLog);
 
7003
               StringCat(messagestr, ", ");
 
7004
               ans = ANS_CANCEL;
 
7005
               num_not_asked ++;
 
7006
             }
 
7007
           }
 
7008
           if (ans == ANS_CANCEL)
 
7009
           {
 
7010
             ans = Message(MSG_OKC, 
 
7011
                           "This alignment contains %s that %s already in GenBank. \nDo you wish to replace %s?", 
 
7012
                           messagestr, num_not_asked > 1 ? "are":"is",
 
7013
                           num_not_asked > 1 ? "them":"it");
 
7014
           }
 
7015
           if (ans != ANS_CANCEL)
 
7016
           {
 
7017
              for (j=0; j<i; j++)
 
7018
              {
 
7019
                 offset = SeqAlignStart(hiparray[j]->sap, 1)-SeqAlignStart(hiparray[j]->sap, 0);
 
7020
                 if ((SeqAlignStrand(hiparray[j]->sap, 0)==Seq_strand_minus && SeqAlignStrand(hiparray[j]->sap, 1) != Seq_strand_minus) || (SeqAlignStrand(hiparray[j]->sap, 1)==Seq_strand_minus && SeqAlignStrand(hiparray[j]->sap, 0) != Seq_strand_minus))
 
7021
                 {
 
7022
                     strand=Seq_strand_minus;
 
7023
                     AlnMgr2IndexSingleChildSeqAlign(hiparray[j]->sap);
 
7024
                     AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 1, &start1, &stop1);
 
7025
                     AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 2, &start2, &stop2);
 
7026
                     len = stop2 + start1;
 
7027
                     if (offset < 0)
 
7028
                     {
 
7029
                      offset = 0 - offset;
 
7030
                     }
 
7031
                 } else
 
7032
                      strand=Seq_strand_plus;
 
7033
                 SeqAlignStartUpdate (salp, hiparray[j]->sip1, abs(offset), len, strand);
 
7034
                 dsp->ids = SWSeqIdReplaceID(dsp->ids, hiparray[j]->sip1, hiparray[j]->sip2);
 
7035
 
 
7036
                 if (presip)
 
7037
                    sip = presip->next;
 
7038
                 else
 
7039
                    sip = dsp->ids;
 
7040
                 
 
7041
                 /* We add the ID of the sequence we are replacing to a list
 
7042
                  * of sequences that will be deleted later.
 
7043
                  * We can't delete the sequence now, in case it is present
 
7044
                  * in more than one alignment for this record.
 
7045
                  */
 
7046
                 vnp = nrSeqIdAdd (vnp, hiparray[j]->sip1);
 
7047
                 found = TRUE;
 
7048
                 SeqAlignFree(hiparray[j]->sap);
 
7049
                 if (hiparray[j]->bsp1 != NULL) {
 
7050
                   BioseqUnlock (hiparray[j]->bsp1);
 
7051
                   hiparray[j]->bsp1->idx.deleteme = TRUE;
 
7052
                   hiparray[j]->bsp1 = NULL;
 
7053
                 }
 
7054
                 if (hiparray[j]->bsp2 != NULL) {
 
7055
                   BioseqUnlock (hiparray[j]->bsp2);
 
7056
                   hiparray[j]->bsp2 = NULL;
 
7057
                 }
 
7058
              }
 
7059
           } else /* need to ask one by one */
 
7060
           {
 
7061
              for (j=0; j<i; j++)
 
7062
              {
 
7063
                 SeqIdWrite(hiparray[j]->sip2, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
7064
                 ans = Message(MSG_OKC, "This alignment contains %s that is already in GenBank. \nDo you wish to replace it?", strLog);
 
7065
                 if (ans != ANS_CANCEL)
 
7066
                 {
 
7067
                    offset = SeqAlignStart(hiparray[j]->sap, 1)-SeqAlignStart(hiparray[j]->sap, 0);
 
7068
                    if ((SeqAlignStrand(hiparray[j]->sap, 0)==Seq_strand_minus && SeqAlignStrand(hiparray[j]->sap, 1) != Seq_strand_minus) || (SeqAlignStrand(hiparray[j]->sap, 1)==Seq_strand_minus && SeqAlignStrand(hiparray[j]->sap, 0) != Seq_strand_minus))
 
7069
                    {
 
7070
                        strand=Seq_strand_minus;
 
7071
                        AlnMgr2IndexSingleChildSeqAlign(hiparray[j]->sap);
 
7072
                        AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 1, &start1, &stop1);
 
7073
                        AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 2, &start2, &stop2);
 
7074
                        len = stop2 + start1;
 
7075
                        if (offset < 0)
 
7076
                        {
 
7077
                          offset = 0 - offset;
 
7078
                        }
 
7079
                    } else
 
7080
                         strand=Seq_strand_plus;
 
7081
                    SeqAlignStartUpdate (salp, hiparray[j]->sip1, offset, len, strand);
 
7082
                    dsp->ids = SWSeqIdReplaceID(dsp->ids, hiparray[j]->sip1, hiparray[j]->sip2);
 
7083
                    if (presip)
 
7084
                       sip = presip->next;
 
7085
                    else
 
7086
                       sip = dsp->ids;
 
7087
                    SeqAlignReplaceId (hiparray[j]->sip1, hiparray[j]->sip2, salp);
 
7088
                    vnp = nrSeqIdAdd (vnp, hiparray[j]->sip1);
 
7089
                    found = TRUE;
 
7090
                    if (hiparray[j]->bsp1 != NULL) {
 
7091
                      hiparray[j]->bsp1->idx.deleteme = TRUE;
 
7092
                    }
 
7093
                 }
 
7094
                 SeqAlignFree(hiparray[j]->sap);
 
7095
                 if (hiparray[j]->bsp1 != NULL) {
 
7096
                   BioseqUnlock (hiparray[j]->bsp1);
 
7097
                   hiparray[j]->bsp1 = NULL;
 
7098
                 }
 
7099
                 if (hiparray[j]->bsp2 != NULL) {
 
7100
                   BioseqUnlock (hiparray[j]->bsp2);
 
7101
                   hiparray[j]->bsp2 = NULL;
 
7102
                 }
 
7103
              }
 
7104
           }
 
7105
        }
 
7106
        n = i;
 
7107
        i = 0;
 
7108
        /* Replacement of sequences that are not exact matches */
 
7109
        for (j=n+i; j<numhips; j++)
 
7110
        {
 
7111
           if (hiparray[j]->errtype <3)
 
7112
           {
 
7113
               SeqIdWrite (hiparray[j]->sip2, strLog, PRINTID_TEXTID_ACCESSION, 50);
 
7114
               ans = Message (MSG_OKC, "This alignment contains \"%s\" that is already in GenBank.\n However, the local version is not identical to the most recent database version.\n %s \nDo you wish to replace it anyway ?\n If you cancel, the alignment of the local and the database versions \nof \"%s\" will be saved in the error file \"error.log\"", strLog, hiparray[j]->errstr, strLog);
 
7115
               if (ans != ANS_CANCEL)
 
7116
               {
 
7117
                  offset = SeqAlignStart(hiparray[j]->sap, 1)-SeqAlignStart(hiparray[j]->sap, 0);
 
7118
 
 
7119
                  if (SeqAlignStrand(hiparray[j]->sap, 0)==Seq_strand_minus || SeqAlignStrand(hiparray[j]->sap, 1)==Seq_strand_minus)
 
7120
                  {
 
7121
                     strand=Seq_strand_minus;
 
7122
                     AlnMgr2IndexSingleChildSeqAlign(hiparray[j]->sap);
 
7123
                     AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 1, &start1, &stop1);
 
7124
                     AlnMgr2GetNthSeqRangeInSA(hiparray[j]->sap, 2, &start2, &stop2);
 
7125
                     len = stop2 + start1;
 
7126
                     if (offset < 0)
 
7127
                     {
 
7128
                       offset = 0 - offset;
 
7129
                     }                    
 
7130
                  }                  
 
7131
                  else
 
7132
                     strand=Seq_strand_plus;
 
7133
                  SeqAlignStartUpdate (salp, hiparray[j]->sip1, offset, len, strand);
 
7134
                  dsp->ids = SWSeqIdReplaceID(dsp->ids, hiparray[j]->sip1, hiparray[j]->sip2);
 
7135
                  if (presip)
 
7136
                     sip = presip->next;
 
7137
                  else
 
7138
                     sip = dsp->ids;
 
7139
                  SeqAlignReplaceId (hiparray[j]->sip1, hiparray[j]->sip2, salp);
 
7140
                  vnp = nrSeqIdAdd (vnp, hiparray[j]->sip1);
 
7141
                  found = TRUE;
 
7142
               }
 
7143
               else {
 
7144
                  ofp = FileOpen("error.log", "a");
 
7145
                  fprintf(ofp, "This alignment contains %s that is already in GenBank; \nhowever, the local version is not identical to the most recent database version.\n %s\n", strLog, hiparray[j]->errstr);
 
7146
                  FileClose(ofp);
 
7147
                  SWPrintFarpointerAln(hiparray[j]->sap, "error.log");
 
7148
               }
 
7149
            } else
 
7150
               Message(MSG_OK, "%s", hiparray[j]->errstr);
 
7151
         }
 
7152
     }
 
7153
  }
 
7154
  return vnp;  
 
7155
}
 
7156
#endif
 
7157
 
 
7158
static ValNodePtr errorp = NULL;
 
7159
 
 
7160
/******************************************************************
 
7161
Output error message according to code defined in alignval.h.  
 
7162
id refers to seqid of the sequence that causes the error 
 
7163
and idcontext refers to other sequences in the same segment.  
 
7164
Intvalue is used to indicate 1) the segment where the sequence 
 
7165
with error is, or 2) the segtype in case of segtype error.  
 
7166
Please note that not all errors report all three 
 
7167
parameters(id, idcontext, Intvalue)
 
7168
******************************************************************/ 
 
7169
static void ValMessage (Int1 MessageCode, ErrSev errlevel, SeqIdPtr id, SeqIdPtr idcontext , Int4 Intvalue) 
 
7170
{
 
7171
  
 
7172
  Char     buf[256], 
 
7173
           buf3[64],
 
7174
           string1[64],
 
7175
           string2[252];
 
7176
 
 
7177
  string1[0] = '\0';
 
7178
  string2[0] = '\0';
 
7179
  SeqIdWrite(id, buf, PRINTID_FASTA_LONG, sizeof(buf)-1);
 
7180
  switch(MessageCode)
 
7181
  {
 
7182
    case Err_SeqId:
 
7183
      sprintf(string1, "SeqId");
 
7184
      sprintf(string2, "Invalid Seq_id: %s\n", buf);
 
7185
      break;
 
7186
 
 
7187
    case Err_Strand_Rev:      
 
7188
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7189
      sprintf(string1, "Strand");
 
7190
      sprintf(string2, "Alignment strand is reversed in segment %d for Seq ID: %s in the context of%s\n", Intvalue, buf, buf3);
 
7191
      break;
 
7192
 
 
7193
    case Err_Denseg_Len_Start:
 
7194
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7195
      sprintf(string1, "Start/Length");
 
7196
      sprintf(string2, "Error in length and/or starts in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
 
7197
      break;
 
7198
 
 
7199
    case  Err_Start_Less_Than_Zero:
 
7200
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7201
      sprintf(string1, "Start");
 
7202
      sprintf(string2, "Start point is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
 
7203
      break;
 
7204
 
 
7205
    case Err_Start_More_Than_Biolen:      
 
7206
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7207
      sprintf(string1, "Start");
 
7208
      sprintf(string2, "Start point is greater than total bioseq length in segment %d for sequence ID: %s in the context of%s\n", Intvalue, buf, buf3);
 
7209
      break;
 
7210
 
 
7211
    case Err_End_Less_Than_Zero:
 
7212
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7213
      sprintf(string1, "Length");
 
7214
      sprintf(string2, "End point is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
 
7215
      break;
 
7216
 
 
7217
    case Err_End_More_Than_Biolen:
 
7218
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7219
      sprintf(string1, "Length");
 
7220
      sprintf(string2, "End point is greater than total bioseq length in segment %d for sequence ID: %s in the context of%s\n", Intvalue, buf, buf3);
 
7221
      break;
 
7222
 
 
7223
    case Err_Len_Less_Than_Zero:
 
7224
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7225
      sprintf(string1, "Length");
 
7226
      sprintf(string2, "Segment length is less than zero in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3); 
 
7227
      break;
 
7228
 
 
7229
    case Err_Len_More_Than_Biolen:
 
7230
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7231
      sprintf(string1, "Length");
 
7232
      sprintf(string2, "Segment length is greater than total bioseq length in segment %d for sequence ID: %s in the context of %s\n", Intvalue, buf, buf3);
 
7233
      break; 
 
7234
 
 
7235
    case Err_Sum_Len_Start:
 
7236
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7237
      sprintf(string1, "Start");
 
7238
      sprintf(string2, "Sum of start point and segment is greater than total bioseq length in segment %d  for sequence ID: %s in the context of %s\n",  Intvalue, buf, buf3); 
 
7239
      break;
 
7240
 
 
7241
    case Err_SeqAlign_DimSeqId_Not_Match:
 
7242
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7243
      sprintf(string1, "SeqId");
 
7244
      sprintf(string2, "The number of SeqId does not match the dimensions for sequence ID's %s\n", buf3); 
 
7245
      break;
 
7246
 
 
7247
    case Err_Segs_DimSeqId_Not_Match:
 
7248
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7249
      sprintf(string1, "SeqId");
 
7250
      sprintf(string2, "The number of SeqId does not match the dimensions in segment %d for  sequence ID's %s\n", Intvalue, buf3); 
 
7251
      break;
 
7252
 
 
7253
    case Err_Fastalike:
 
7254
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7255
      sprintf(string1, "Fasta");
 
7256
      sprintf(string2, "This may be a fasta-like alignment for SeqId: %s in the context of %s\n", buf, buf3); 
 
7257
      break;
 
7258
 
 
7259
    case Err_Null_Segs:
 
7260
      sprintf(string1, "Segs");
 
7261
      sprintf(string2, "This alignment contains a null segs\n");
 
7262
      break;
 
7263
 
 
7264
    case Err_Segment_Gap:
 
7265
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7266
      sprintf(string1, "Segs");
 
7267
      sprintf(string2, "Segment %d is a gap for all sequence with the following ID's: %s\n", Intvalue, buf3); 
 
7268
      break;
 
7269
 
 
7270
    case Err_Segs_Dim_One:
 
7271
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7272
      sprintf(string1, "Segs");
 
7273
      sprintf(string2, "There is only one dimension in segment %d for  sequence ID's %s\n", Intvalue, buf3); 
 
7274
      break;
 
7275
 
 
7276
    case Err_SeqAlign_Dim_One:
 
7277
      SeqIdWrite (idcontext, buf3, PRINTID_REPORT, sizeof (buf3));
 
7278
      sprintf(string1, "Dim");
 
7279
      sprintf(string2, "There is only one dimension for sequence ID's %s\n", buf3); 
 
7280
      break;
 
7281
 
 
7282
    case Err_Segtype :
 
7283
      sprintf(string1, "Segs");
 
7284
      sprintf(string2, "This alignment has a undefined or unsupported Seqalign segtype %d\n", Intvalue);
 
7285
      break;
 
7286
 
 
7287
    default:
 
7288
      break;
 
7289
  }
 
7290
  if (StringLen(string1) > 0)
 
7291
     errorp = BlastConstructErrorMessage (string1, string2, errlevel, &errorp);
 
7292
}
 
7293
 
 
7294
/******************************************************************
 
7295
validate each alignment sequentially.  
 
7296
This function will subject the seqalign to all validation functions
 
7297
******************************************************************/ 
 
7298
/*********************************************************/
 
7299
static void delete_bioseqs (ValNodePtr ids, Uint2 entityID)
 
7300
{
 
7301
  SeqEntryPtr  sep_top;
 
7302
  SeqEntryPtr  sep_del;
 
7303
  ValNodePtr   vnp;
 
7304
  SeqIdPtr     sip;
 
7305
  SeqLocPtr    slp;
 
7306
  BioseqPtr    bsp;
 
7307
  ObjMgrDataPtr  omdptop;
 
7308
  ObjMgrData     omdata;
 
7309
  Uint2          parenttype;
 
7310
  Pointer        parentptr;
 
7311
 
 
7312
  if (ids == NULL)
 
7313
     return;
 
7314
  sep_top = GetTopSeqEntryForEntityID (entityID);
 
7315
  SaveSeqEntryObjMgrData (sep_top, &omdptop, &omdata);
 
7316
  GetSeqEntryParent (sep_top, &parentptr, &parenttype);
 
7317
 
 
7318
  vnp=ids;
 
7319
  while (vnp!=NULL)
 
7320
  {
 
7321
     sip = (SeqIdPtr) vnp->data.ptrvalue;
 
7322
     if (sip!=NULL) {
 
7323
        slp = (SeqLocPtr)ValNodeNew (NULL);
 
7324
        slp->choice = SEQLOC_WHOLE;
 
7325
        slp->data.ptrvalue = sip;
 
7326
        bsp = GetBioseqGivenSeqLoc (slp, entityID);
 
7327
        if (bsp!=NULL) {
 
7328
           sep_del=GetBestTopParentForData (entityID, bsp);
 
7329
           RemoveSeqEntryFromSeqEntry (sep_top, sep_del, FALSE);
 
7330
        }
 
7331
        slp->data.ptrvalue = NULL;
 
7332
        SeqLocFree (slp);
 
7333
     }
 
7334
     vnp=vnp->next;
 
7335
  }
 
7336
  SeqMgrLinkSeqEntry (sep_top, parenttype, parentptr);
 
7337
  RestoreSeqEntryObjMgrData (sep_top, omdptop, &omdata);
 
7338
  RenormalizeNucProtSets (sep_top, TRUE);
 
7339
 
 
7340
  for (vnp=ids; vnp!=NULL; vnp=vnp->next) {
 
7341
     SeqIdFree ((SeqIdPtr) vnp->data.ptrvalue);
 
7342
     vnp->data.ptrvalue = NULL;
 
7343
  }
 
7344
  ValNodeFree (ids);
 
7345
  return;
 
7346
}
 
7347
 
 
7348
 
 
7349
static Boolean check_dbid_seqalign (SeqAlignPtr salp)
 
7350
{
 
7351
  DenseSegPtr dsp;
 
7352
  SeqIdPtr    sip, next;
 
7353
  Char        str [52];
 
7354
  CharPtr     TmpBuff, tmp;
 
7355
  Int4        j, k;
 
7356
  Boolean     found = FALSE;
 
7357
 
 
7358
  if (salp!=NULL) 
 
7359
  {
 
7360
     if (salp->segtype == 2) 
 
7361
     {
 
7362
        dsp = (DenseSegPtr) salp->segs;
 
7363
        sip = dsp->ids;
 
7364
        while (!found && sip != NULL) 
 
7365
        {
 
7366
           next = sip->next;
 
7367
           sip->next = NULL;
 
7368
           SeqIdWrite (sip, str, PRINTID_FASTA_LONG, 50);
 
7369
           sip->next = next;
 
7370
           tmp = StringStr (str, "acc");
 
7371
           if (tmp!=NULL) {
 
7372
              tmp++; tmp++; tmp++;
 
7373
              if (*tmp == '|')
 
7374
                 tmp++;
 
7375
              TmpBuff = tmp;
 
7376
              while (*tmp!='\0' && *tmp != '|' && *tmp!='\n' && *tmp != '.')
 
7377
                 tmp++;
 
7378
              *tmp = '\0';
 
7379
 
 
7380
              j = StringLen (TmpBuff);
 
7381
              for(k =0; k < j; k++) {
 
7382
                 if(!isdigit(TmpBuff[k])) {
 
7383
                    break;
 
7384
                 }
 
7385
              }
 
7386
              if(k != j) {
 
7387
                found=(IS_ntdb_accession(TmpBuff) || IS_protdb_accession(TmpBuff));
 
7388
              }
 
7389
           }  
 
7390
           sip = next;
 
7391
        }     
 
7392
     }
 
7393
  }     
 
7394
  return found;
 
7395
}
 
7396
 
 
7397
 
 
7398
/***************************************************************************************
 
7399
***
 
7400
***  ValidateSeqAlignandACC
 
7401
***     calls ValidateSeqAlign (in api directory)
 
7402
***     and tests for occurrence of ACC string in sequence ID.
 
7403
***     ACC|ACC# will be compared with the corresponding sequence (ACC#)
 
7404
***     in the database and replaced by a far pointer if the sequences
 
7405
***     are identical.
 
7406
***
 
7407
***************************************************************************************/
 
7408
typedef struct saval {
 
7409
  Boolean     message;
 
7410
  Boolean     msg_success;
 
7411
  Boolean     find_remote_bsp;
 
7412
  Boolean     find_acc_bsp;
 
7413
  Boolean     delete_salp;
 
7414
  Boolean     delete_bsp;
 
7415
  Boolean     retdel;
 
7416
  ValNodePtr  ids;
 
7417
  Uint2       entityID;
 
7418
  Boolean     dirty;
 
7419
} SaVal, PNTR SaValPtr;
 
7420
 
 
7421
 
 
7422
static Boolean 
 
7423
ValidateSeqAlignandACCEx 
 
7424
(SeqAlignPtr salp, Uint2 entityID, Boolean message,
 
7425
 Boolean msg_success, Boolean find_remote_bsp,Boolean find_acc_bsp,
 
7426
 Boolean delete_bsp, Boolean delete_salp, BoolPtr dirty,
 
7427
 ValNodePtr PNTR id_list) /* added id_list so that we could defer deleting bioseqs */
 
7428
{  
 
7429
  SeqAlignPtr  pre,
 
7430
               salptmp;
 
7431
  SaVal        sv;
 
7432
  SaValPtr     svp;
 
7433
  MsgAnswer    ans;
 
7434
  Int2         err_count=0,
 
7435
               salp_count=0;
 
7436
  Boolean      ok;
 
7437
 
 
7438
  if(salp!=NULL)
 
7439
  {
 
7440
    /* initialize SaVal structure */
 
7441
    sv.message = message;
 
7442
    sv.msg_success = msg_success;
 
7443
    sv.find_remote_bsp = find_remote_bsp;
 
7444
    sv.find_acc_bsp = find_acc_bsp;
 
7445
    sv.delete_salp = delete_salp;
 
7446
    sv.delete_bsp = delete_bsp;
 
7447
    sv.retdel = TRUE;
 
7448
    sv.ids = NULL;
 
7449
    sv.entityID = entityID; 
 
7450
    sv.dirty = FALSE;   
 
7451
    svp = &sv;
 
7452
    
 
7453
    pre=NULL;
 
7454
    salptmp=salp; 
 
7455
    while (salptmp)
 
7456
    {
 
7457
      salp_count++;
 
7458
      if(salp->segtype==5)
 
7459
      {
 
7460
        ValidateSeqAlignandACCEx ((SeqAlignPtr) (salptmp->segs), entityID, 
 
7461
                                  message, msg_success, find_remote_bsp, 
 
7462
                                  find_acc_bsp, delete_bsp, delete_salp, 
 
7463
                                  &svp->dirty, id_list);
 
7464
      } 
 
7465
      else if (salp->segtype<1 || salp->segtype>4)
 
7466
      {
 
7467
        ValMessage (Err_Segtype, SEV_ERROR, NULL, NULL, salptmp->segtype);
 
7468
      }
 
7469
      else 
 
7470
      {
 
7471
        ValidateSeqAlign (salptmp, svp->entityID, svp->message, 
 
7472
                          svp->msg_success, svp->find_remote_bsp, 
 
7473
                          svp->delete_bsp, svp->delete_salp, &svp->dirty);
 
7474
        if (svp->find_acc_bsp) 
 
7475
        {
 
7476
                ok = check_dbid_seqalign (salptmp);
 
7477
                if (ok) 
 
7478
                {
 
7479
                  if (id_list != NULL)
 
7480
                  {
 
7481
                    svp->ids = *id_list;
 
7482
                  }
 
7483
            svp->ids = CCNormalizeSeqAlignId (salptmp, svp->ids);
 
7484
            if (svp->ids!=NULL && svp->entityID > 0) {
 
7485
              if (svp->delete_bsp)
 
7486
              {
 
7487
                delete_bioseqs (svp->ids, svp->entityID);
 
7488
                svp->ids = NULL;
 
7489
              }
 
7490
              svp->dirty = TRUE;
 
7491
            }
 
7492
          }             
 
7493
        }
 
7494
      }         
 
7495
          if (errorp)
 
7496
          {
 
7497
        if(svp->message)
 
7498
            {
 
7499
          BlastErrorPrint (errorp);
 
7500
          errorp = BlastErrorChainDestroy (errorp);
 
7501
        }
 
7502
        if (svp->delete_salp)
 
7503
        {
 
7504
          if (pre==NULL) 
 
7505
          {
 
7506
            salp=salptmp->next;
 
7507
            salptmp->next = NULL;
 
7508
            SeqAlignFree (salptmp);
 
7509
            salptmp = salp;
 
7510
          }
 
7511
          else 
 
7512
          {
 
7513
            pre->next = salptmp->next;
 
7514
            salptmp->next = NULL;
 
7515
            SeqAlignFree (salptmp);
 
7516
            salptmp = pre->next;
 
7517
          }
 
7518
        }
 
7519
        else 
 
7520
        {
 
7521
                salptmp = salptmp->next;
 
7522
        }
 
7523
        err_count++;
 
7524
        svp->retdel=FALSE;
 
7525
      }
 
7526
      else 
 
7527
      {
 
7528
        salptmp = salptmp->next;
 
7529
      }
 
7530
    }
 
7531
    if (err_count==0 && svp->msg_success) 
 
7532
    {
 
7533
      if (salp_count>1)
 
7534
        ans = Message (MSG_OK, "Validation test of %d alignments succeded", salp_count);
 
7535
      else
 
7536
        ans = Message (MSG_OK, "Validation test of the alignment succeded");
 
7537
    }
 
7538
    if (dirty)
 
7539
      *dirty = svp->dirty;
 
7540
  }
 
7541
  if (id_list != NULL)
 
7542
  {
 
7543
    *id_list = svp->ids;
 
7544
  }
 
7545
  return svp->retdel;
 
7546
 
7547
 
 
7548
NLM_EXTERN Boolean ValidateSeqAlignandACC (SeqAlignPtr salp, Uint2 entityID, Boolean message,
 
7549
                         Boolean msg_success, Boolean find_remote_bsp,Boolean find_acc_bsp,
 
7550
                         Boolean delete_bsp, Boolean delete_salp, BoolPtr dirty)
 
7551
{
 
7552
  return ValidateSeqAlignandACCEx (salp, entityID, message, msg_success, 
 
7553
                                   find_remote_bsp, find_acc_bsp, delete_bsp, 
 
7554
                                   delete_salp, dirty, NULL);
 
7555
}
 
7556
 
 
7557
/***************************************************************************
 
7558
 *
 
7559
 * ValidateAllAlignmentsInAnnotList (sap, svp)
 
7560
 *
 
7561
 * This function validates all of the alignments in the annotation list
 
7562
 * (there may be multiple alignments, especially when there is an alignment
 
7563
 * of segmented sequences), and then deletes the local versions of sequences
 
7564
 * which have been replaced by farpointers.
 
7565
 * We wait to remove the sequences in case the sequence is used in more than
 
7566
 * one alignment, which may be the case if an alignment of segmented sets
 
7567
 * contains a far pointer, and that far pointer points to a sequence that is
 
7568
 * not actually a segmented set.
 
7569
 *
 
7570
 ***************************************************************************/
 
7571
static void ValidateAllAlignmentsInAnnotList (SeqAnnotPtr sap, SaValPtr svp)
 
7572
{
 
7573
  SeqAlignPtr salp;
 
7574
  ValNodePtr  id_list = NULL;
 
7575
  
 
7576
  if (svp == NULL)
 
7577
  {
 
7578
    return;
 
7579
  }
 
7580
  
 
7581
  while (sap != NULL)    
 
7582
  {
 
7583
    if (sap->type == 2 && sap->data != NULL)
 
7584
    {
 
7585
      salp = (SeqAlignPtr) sap->data;
 
7586
      ValidateSeqAlignandACCEx (salp, svp->entityID, svp->message, 
 
7587
                                svp->msg_success, svp->find_remote_bsp, 
 
7588
                                svp->find_acc_bsp, FALSE, 
 
7589
                                svp->delete_salp, &svp->dirty,
 
7590
                                &id_list);
 
7591
    }
 
7592
    sap = sap->next;
 
7593
  }
 
7594
  if (svp->delete_bsp)
 
7595
  {
 
7596
    delete_bioseqs (id_list, svp->entityID);
 
7597
  }
 
7598
}
 
7599
 
 
7600
 
 
7601
 
 
7602
/***************************************************************************
 
7603
 *
 
7604
 * ValidateSeqAlignandACCCallback (sep, mydata, index, indent)
 
7605
 *
 
7606
 * This function is a callback for SeqEntryExplore used by 
 
7607
 * ValidateSeqAlignandACCInSeqEntry.  It will validate the alignments
 
7608
 * found in the record.
 
7609
 * This function used to only validate the first alignment found on a
 
7610
 * SeqEntry.  It was repaired to validate all alignments on the SeqEntry
 
7611
 * on May 27, 2005 by Colleen Bollin.
 
7612
 *
 
7613
 ***************************************************************************/
 
7614
static void ValidateSeqAlignandACCCallback (SeqEntryPtr sep, Pointer mydata,
 
7615
                                          Int4 index, Int2 indent)
 
7616
{
 
7617
  BioseqPtr          bsp;
 
7618
  BioseqSetPtr       bssp;
 
7619
  SaValPtr           svp = NULL;
 
7620
  SeqAnnotPtr        sap = NULL;
 
7621
 
 
7622
  if (sep != NULL && sep->data.ptrvalue && mydata != NULL) {
 
7623
     svp = (SaValPtr)mydata;
 
7624
     if (IS_Bioseq(sep)) {
 
7625
        bsp = (BioseqPtr) sep->data.ptrvalue;
 
7626
        if (bsp!=NULL) {
 
7627
           sap = bsp->annot;
 
7628
        }
 
7629
     }   
 
7630
     else if(IS_Bioseq_set(sep)) {
 
7631
        bssp = (BioseqSetPtr)sep->data.ptrvalue;
 
7632
        if (bssp!=NULL) {
 
7633
           sap = bssp->annot;
 
7634
        }
 
7635
     }
 
7636
  }
 
7637
  ValidateAllAlignmentsInAnnotList (sap, svp);
 
7638
}
 
7639
 
 
7640
 
 
7641
NLM_EXTERN Boolean ValidateSeqAlignandACCInSeqEntry (SeqEntryPtr sep, Boolean message, 
 
7642
                                 Boolean msg_success, Boolean find_remote_bsp, Boolean find_acc_bsp,
 
7643
                                 Boolean delete_bsp, Boolean delete_salp)
 
7644
{
 
7645
  SeqEntryPtr      sep_head;
 
7646
  Uint2            entityID;
 
7647
  SaVal            sv;
 
7648
  Boolean          success=TRUE;
 
7649
 
 
7650
  entityID = ObjMgrGetEntityIDForChoice (sep);
 
7651
  if (entityID > 0) {
 
7652
     sep_head = GetTopSeqEntryForEntityID (entityID);
 
7653
     if (sep_head != NULL) {
 
7654
        sv.message = message;
 
7655
        sv.msg_success = msg_success;
 
7656
        sv.find_remote_bsp = find_remote_bsp;
 
7657
        sv.find_acc_bsp = find_acc_bsp;
 
7658
        sv.delete_salp = delete_salp;
 
7659
        sv.delete_bsp = delete_bsp;
 
7660
        sv.retdel = TRUE;
 
7661
        sv.ids = NULL;
 
7662
        sv.entityID = entityID; 
 
7663
        sv.dirty = FALSE;
 
7664
        SeqEntryExplore (sep_head, (Pointer)&sv, ValidateSeqAlignandACCCallback);
 
7665
        if (sv.dirty) {
 
7666
           ObjMgrSetDirtyFlag (entityID, TRUE);
 
7667
           ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
 
7668
        }
 
7669
        success = sv.retdel;
 
7670
     }
 
7671
  }
 
7672
  return success;
 
7673
}
 
7674
 
 
7675
 
 
7676
/* we need to iterate through the actual SeqEntries, because theoretically the
 
7677
 * same SeqID should appear in the SeqEntry with the new alignment and again
 
7678
 * in the SeqEntry of the original record.
 
7679
 */
 
7680
static BioseqPtr FindBioseqInSep (SeqEntryPtr sep, SeqIdPtr sip)
 
7681
{
 
7682
  BioseqPtr    bsp = NULL;
 
7683
  BioseqSetPtr bssp;
 
7684
  SeqEntryPtr  this_sep;
 
7685
  
 
7686
  if (sep == NULL || sip == NULL) return NULL;
 
7687
  
 
7688
  if (IS_Bioseq (sep))
 
7689
  {
 
7690
        bsp = (BioseqPtr) sep->data.ptrvalue;
 
7691
        if (! BioseqMatch(bsp, sip))
 
7692
        {
 
7693
          bsp = NULL;
 
7694
        }
 
7695
  }
 
7696
  else if (IS_Bioseq_set (sep))
 
7697
  {
 
7698
        bssp = (BioseqSetPtr) sep->data.ptrvalue;
 
7699
    for (this_sep = bssp->seq_set; this_sep != NULL && bsp == NULL; this_sep = this_sep->next)
 
7700
    {
 
7701
      bsp = FindBioseqInSep (this_sep, sip);
 
7702
    }
 
7703
  }
 
7704
  return bsp;
 
7705
}
 
7706
 
 
7707
 
 
7708
NLM_EXTERN void CalculateAlignmentOffsets (SeqEntryPtr sepnew, SeqEntryPtr sepold)
 
7709
{
 
7710
  SeqAlignPtr         salpnew;
 
7711
  DenseSegPtr         dsp;
 
7712
  SeqIdPtr            sip_temp, sip_next;
 
7713
  BioseqPtr           bsp1, bsp2;
 
7714
  BLAST_OptionsBlkPtr options;
 
7715
  SeqAlignPtr         seqalign = NULL;
 
7716
  SeqAlignPtr         bestsalp = NULL;
 
7717
  Int4                start1, start2, stop1, stop2;
 
7718
  CharPtr             errstr = NULL;
 
7719
  Uint1               strand;
 
7720
  Int4                offset, len, nonly;
 
7721
  BioseqPtr           copybsp1, copybsp2;
 
7722
  SeqIdPtr            tmp_id_1, tmp_id_2;
 
7723
  
 
7724
  if (sepnew == NULL || sepold == NULL)
 
7725
  {
 
7726
        return;
 
7727
  }
 
7728
  /* this function needs to look at the bioseqs we have created while reading in the
 
7729
   * alignment, align them with the existing bioseqs, and adjust the alignment start
 
7730
   * positions if necessary.
 
7731
   */
 
7732
 
 
7733
  salpnew = (SeqAlignPtr) FindSeqAlignInSeqEntry (sepnew, OBJ_SEQALIGN);
 
7734
  if (salpnew == NULL)
 
7735
  {
 
7736
        return;
 
7737
  }
 
7738
  
 
7739
  if (salpnew->segtype != 2) return;
 
7740
  dsp = (DenseSegPtr) salpnew->segs;
 
7741
  if (dsp == NULL) return;
 
7742
 
 
7743
  /* create IDs to use when copying Bioseqs.
 
7744
   * BioseqCopyEx makes a copy of these for the Bioseq it creates,
 
7745
   * so we can reuse them and then free them at the end of the for-next loop.
 
7746
   */
 
7747
  tmp_id_1 = MakeSeqID ("lcl|tmp_1_for_update");
 
7748
  tmp_id_2 = MakeSeqID ("lcl|tmp_2_for_update");
 
7749
  
 
7750
  for (sip_temp = dsp->ids; sip_temp != NULL; sip_temp = sip_next)
 
7751
  {
 
7752
        sip_next = sip_temp->next;
 
7753
        sip_temp->next = NULL;
 
7754
        
 
7755
        /* find bsp1 in sepnew, bsp2 in sepold */
 
7756
    bsp1 = FindBioseqInSep (sepnew, sip_temp);
 
7757
    bsp2 = FindBioseqInSep (sepold, sip_temp);
 
7758
    
 
7759
    if (bsp1 != NULL && bsp2 != NULL) 
 
7760
    {
 
7761
          /* create alignment between old and new bioseqs */
 
7762
          /* new bioseq will have same ID as old bioseq, so BLAST won't work
 
7763
           * because it's looking for IDs using indexing.
 
7764
           * Create a temporary copy of the two bioseqs with different IDS,
 
7765
           * add them to the BioseqIndex, BLAST them, then remove them 
 
7766
           * from the index and delete them.
 
7767
           */
 
7768
      copybsp1 = BioseqCopyEx (tmp_id_1, bsp1, 0, bsp1->length - 1, Seq_strand_plus, FALSE);
 
7769
      copybsp2 = BioseqCopyEx (tmp_id_2, bsp2, 0, bsp2->length - 1 , Seq_strand_plus, FALSE);
 
7770
      SeqMgrAddToBioseqIndex (copybsp1);
 
7771
      SeqMgrAddToBioseqIndex (copybsp2);
 
7772
           
 
7773
      options = BLASTOptionNew("blastn", TRUE);
 
7774
      options->filter_string = StringSave("m L;R");
 
7775
      seqalign = BlastTwoSequences (copybsp1, copybsp2, "blastn", options);
 
7776
      if (errstr != NULL)
 
7777
        MemFree(errstr);
 
7778
      errstr = (CharPtr)MemNew(1000*sizeof(Char));
 
7779
      bestsalp = SeqAlignBestHit (seqalign, copybsp1, copybsp2, 100, &errstr, &nonly);
 
7780
  
 
7781
      /* we don't need the copies after this, and we don't want them in the BioseqIndex
 
7782
       * (or BLAST might get confused the next time through the loop).
 
7783
       */       
 
7784
          copybsp1->idx.deleteme = TRUE;
 
7785
          copybsp2->idx.deleteme = TRUE;
 
7786
          SeqMgrDeleteFromBioseqIndex (copybsp1);
 
7787
          SeqMgrDeleteFromBioseqIndex (copybsp2);
 
7788
        
 
7789
          /* update start position in alignment */
 
7790
      offset = SeqAlignStart(bestsalp, 1)-SeqAlignStart(bestsalp, 0);
 
7791
      if ((SeqAlignStrand(bestsalp, 0)==Seq_strand_minus && SeqAlignStrand(bestsalp, 1) != Seq_strand_minus) || (SeqAlignStrand(bestsalp, 1)==Seq_strand_minus && SeqAlignStrand(bestsalp, 0) != Seq_strand_minus))
 
7792
      {
 
7793
        strand=Seq_strand_minus;
 
7794
        AlnMgr2IndexSingleChildSeqAlign(bestsalp);
 
7795
        AlnMgr2GetNthSeqRangeInSA(bestsalp, 1, &start1, &stop1);
 
7796
        AlnMgr2GetNthSeqRangeInSA(bestsalp, 2, &start2, &stop2);
 
7797
        len = stop2 + start1;
 
7798
        if (offset < 0)
 
7799
        {
 
7800
          offset = 0 - offset;
 
7801
        }                    
 
7802
      } 
 
7803
      else
 
7804
      {
 
7805
        strand=Seq_strand_plus;
 
7806
        len = offset;
 
7807
        offset = 0;
 
7808
      }
 
7809
      SeqAlignStartUpdate (salpnew, sip_temp, abs(offset), len, strand);                
 
7810
    }   
 
7811
        sip_temp->next = sip_next;
 
7812
  }
 
7813
  SeqIdFree (tmp_id_1);
 
7814
  SeqIdFree (tmp_id_2);
 
7815
    
 
7816
  if (errstr != NULL)
 
7817
  {
 
7818
        MemFree (errstr);
 
7819
  }
 
7820
}
 
7821
 
 
7822
 
 
7823
NLM_EXTERN Boolean CheckAlignmentSequenceLengths (SeqAlignPtr salp)
 
7824
{
 
7825
  Int4 i, num_rows, num_bad = 0;
 
7826
  Int4 from, to;
 
7827
  SeqIdPtr sip;
 
7828
  BioseqPtr bsp;
 
7829
  ValNodePtr sip_list = NULL, vnp;
 
7830
  Char       path [PATH_MAX];
 
7831
  FILE       *fp;
 
7832
  Char       str[50];
 
7833
  Boolean    retval = TRUE;
 
7834
  
 
7835
  if (salp == NULL) return FALSE;
 
7836
  
 
7837
  num_rows = AlnMgr2GetNumRows(salp);
 
7838
 
 
7839
  for (i = 0; i < num_rows; i++) {
 
7840
    AlnMgr2GetNthSeqRangeInSA(salp, i + 1, &from, &to);
 
7841
    sip = AlnMgr2GetNthSeqIdPtr(salp, i + 1);
 
7842
    bsp = BioseqFind (sip);
 
7843
    if (bsp != NULL) {
 
7844
      if (from > to) to = from;
 
7845
      if (bsp->length < to) {
 
7846
        ValNodeAddPointer (&sip_list, 0, sip);
 
7847
        num_bad++;
 
7848
      } else {
 
7849
        sip = SeqIdFree (sip);
 
7850
      }
 
7851
    }
 
7852
  }
 
7853
  if (sip_list != NULL) {
 
7854
    TmpNam (path);  
 
7855
    fp = FileOpen (path, "w");
 
7856
    if (fp == NULL) {
 
7857
      Message (MSG_ERROR, "Unable to open %s", path);
 
7858
    } else {
 
7859
      vnp = sip_list;
 
7860
      while (vnp != NULL) {
 
7861
        SeqIdWrite (vnp->data.ptrvalue, str, PRINTID_FASTA_LONG, sizeof (str) - 1);
 
7862
        fprintf (fp, "%s\n", str);       
 
7863
        vnp->data.ptrvalue = SeqIdFree (vnp->data.ptrvalue);
 
7864
        vnp = vnp->next;
 
7865
      }
 
7866
      FileClose (fp);
 
7867
      LaunchGeneralTextViewer (path, "Short Sequences");
 
7868
      FileRemove (path);
 
7869
    }
 
7870
    if (Message(MSG_YN, "%d sequence%s too short for this alignment.  Do you wish to continue?", 
 
7871
                num_bad, num_bad > 1 ? "s are" : " is") == ANS_NO) {
 
7872
      retval = FALSE;
 
7873
    }
 
7874
    sip_list = ValNodeFree (sip_list);
 
7875
  }
 
7876
  return retval;
 
7877
}
 
7878
 
 
7879
 
 
7880
/******************************************************************
 
7881
call back function for REGISTER_ALIGNVALIDATION defined in sequin4.c.  
 
7882
Starting point for seqalign validation if user clicked on 
 
7883
SeqalignValidation under menu Filer/Alignment.  
 
7884
Either individual alignment or alignment block 
 
7885
should be highlighted for this validation to work
 
7886
******************************************************************/ 
 
7887
 
 
7888
NLM_EXTERN Int2 LIBCALLBACK ValidateSeqAlignandACCFromData (Pointer data)
 
7889
 
7890
 
 
7891
  OMProcControlPtr  ompcp;
 
7892
  SeqAlignPtr       salp=NULL;
 
7893
  SeqAnnotPtr       sap=NULL;
 
7894
  SeqEntryPtr       sep=NULL;
 
7895
  
 
7896
  ompcp = (OMProcControlPtr) data;
 
7897
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
 
7898
  
 
7899
  if (ompcp->input_data == NULL) return OM_MSG_RET_ERROR;
 
7900
  
 
7901
  switch(ompcp->input_itemtype)
 
7902
    {
 
7903
    case OBJ_BIOSEQ :
 
7904
      sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
 
7905
      break;
 
7906
    case OBJ_BIOSEQSET :
 
7907
      sep = SeqMgrGetSeqEntryForData (ompcp->input_data);
 
7908
      break;
 
7909
      /*if clicked on alignment block*/
 
7910
    case OBJ_SEQANNOT:
 
7911
      sap=(SeqAnnotPtr) (ompcp->input_data);
 
7912
      break;
 
7913
      /*if clicked on individual alignment*/
 
7914
    case OBJ_SEQALIGN:
 
7915
      salp=(SeqAlignPtr) (ompcp->input_data);
 
7916
      break;
 
7917
    case 0 :
 
7918
      return OM_MSG_RET_ERROR;
 
7919
    default :
 
7920
      return OM_MSG_RET_ERROR;
 
7921
  }
 
7922
  
 
7923
  ErrSetMessageLevel(SEV_ERROR);
 
7924
  if(sap!=NULL)
 
7925
  {
 
7926
     salp=is_salp_in_sap(sap, 2);
 
7927
     ValidateSeqAlignandACC (salp, 0, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL);
 
7928
  }
 
7929
  if (salp!=NULL) {
 
7930
     ValidateSeqAlignandACC (salp, 0, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL);
 
7931
  }
 
7932
  if (sep!=NULL) {
 
7933
     ValidateSeqAlignandACCInSeqEntry (sep, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE);
 
7934
  }
 
7935
  return OM_MSG_RET_DONE;
 
7936
}
 
7937
 
 
7938
 
 
7939
 
5645
7940
 
5646
7941