~ubuntu-branches/debian/experimental/ncbi-tools6/experimental

« back to all changes in this revision

Viewing changes to sequin/sequin8.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2008-12-17 19:45:48 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081217194548-s86rrujnezfxr1pv
Tags: 6.1.20081116a-2
* debian/control: per Lintian's advice, depend on ${misc:Depends} across
  the board, in case Debhelper ever populates it.
* debian/{control,rules}: split newly added large BLAST databases into a
  new ncbi-rrna-data package to keep ncbi-data to a reasonable size.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*
30
30
* Version Creation Date:   2/3/98
31
31
*
32
 
* $Revision: 6.458 $
 
32
* $Revision: 6.516 $
33
33
*
34
34
* File Description: 
35
35
*
58
58
#include <spidey.h>
59
59
#include <blast.h>
60
60
#include <salpanel.h>
 
61
#include <seqpanel.h>
61
62
#include <edutil.h>
62
63
#include <tax3api.h>
63
64
#include <asn2gnbp.h> /* included for discrepancy report */
66
67
 
67
68
#include <macrodlg.h>
68
69
#include <macroapi.h>
 
70
#include <alignval.h>
69
71
 
70
72
#define DEFLINE_MAX_LEN          380
71
73
#define TEXT_MAX_LEN             64
4104
4106
          subtype != FEATDEF_mat_peptide &&
4105
4107
          subtype != FEATDEF_sig_peptide &&
4106
4108
          subtype != FEATDEF_transit_peptide &&
4107
 
          subtype != FEATDEF_Imp_CDS) {
 
4109
          subtype != FEATDEF_Imp_CDS &&
 
4110
          !IsUnwantedFeatureType(subtype)) {
4108
4111
        vnp = ValNodeNew (head);
4109
4112
        if (head == NULL) {
4110
4113
          head = vnp;
4559
4562
  GrouP         status;
4560
4563
  ButtoN        generated;
4561
4564
  TexT          curator;
 
4565
  TexT          url;
4562
4566
  TexT          source;
4563
4567
  Int2          indexer;
4564
4568
  DialoG        fields;
4785
4789
    str = (CharPtr) curr->data.ptrvalue;
4786
4790
    SetTitle (rdp->curator, str);
4787
4791
  }
 
4792
 
 
4793
  for (curr = uop->data; curr != NULL; curr = curr->next) {
 
4794
    oip = curr->label;
 
4795
    if (oip != NULL && StringICmp (oip->str, "CollaboratorURL") == 0) {
 
4796
      break;
 
4797
    }
 
4798
  }
 
4799
  if (curr != NULL && curr->choice == 1) {
 
4800
    str = (CharPtr) curr->data.ptrvalue;
 
4801
    SetTitle (rdp->url, str);
 
4802
  }
 
4803
 
4788
4804
  for (curr = uop->data; curr != NULL; curr = curr->next) {
4789
4805
    oip = curr->label;
4790
4806
    if (oip != NULL && StringICmp (oip->str, "GenomicSource") == 0) {
4861
4877
  TagListPtr            tlp;
4862
4878
  CharPtr               txt [6];
4863
4879
  UserObjectPtr         uop;
 
4880
  Char                  url [512];
4864
4881
  long int              val;
4865
4882
  ValNodePtr            vnp;
4866
4883
 
4903
4920
    AddCuratorToRefGeneTrackUserObject (uop, curator);
4904
4921
  }
4905
4922
 
 
4923
  GetTitle (rdp->url, url, sizeof (url));
 
4924
  if (! StringHasNoText (url)) {
 
4925
    AddCuratorURLToRefGeneTrackUserObject (uop, url);
 
4926
  }
 
4927
 
4906
4928
  if (rdp->indexer > 0) {
4907
4929
    AddIndexerToRefGeneTrackUserObject (uop, rdp->indexer);
4908
4930
  }
4968
4990
  TagListPtr            tlp;
4969
4991
  GrouP                 x;
4970
4992
  GrouP                 y;
 
4993
  GrouP                 z;
4971
4994
 
4972
4995
  p = HiddenGroup (g, -1, 0, NULL);
4973
4996
  SetGroupSpacing (p, 10, 10);
4996
5019
 
4997
5020
  y = HiddenGroup (p, 6, 0, NULL);
4998
5021
  rdp->generated = CheckBox (y, "Generated", NULL);
4999
 
  StaticPrompt (y, "Curator", 0, dialogTextHeight, programFont, 'l');
5000
 
  rdp->curator = DialogText (y, "", 14, NULL);
 
5022
  z = HiddenGroup (y, 2, 0, NULL);
 
5023
  StaticPrompt (z, "Curator", 0, dialogTextHeight, programFont, 'l');
 
5024
  rdp->curator = DialogText (z, "", 14, NULL);
 
5025
  StaticPrompt (z, "URL", 0, dialogTextHeight, programFont, 'r');
 
5026
  rdp->url = DialogText (z, "", 14, NULL);
5001
5027
  StaticPrompt (y, "Genomic Source", 0, dialogTextHeight, programFont, 'l');
5002
5028
  rdp->source = DialogText (y, "", 7, NULL);
5003
5029
 
5822
5848
        return SeqIdSelect (sip, order, NUM_SEQID);
5823
5849
}
5824
5850
 
 
5851
 
 
5852
static Boolean ValidateTPAHistAlign (BioseqPtr bsp, ValNodePtr PNTR errors)
 
5853
{
 
5854
  ValNodePtr new_errors;
 
5855
  Boolean    retval = TRUE;
 
5856
  SeqAlignPtr salp;
 
5857
 
 
5858
  if (bsp == NULL || bsp->hist == NULL || bsp->hist->assembly == NULL) {
 
5859
    return FALSE;
 
5860
  }
 
5861
 
 
5862
  for (salp = bsp->hist->assembly; salp != NULL; salp = salp->next) {
 
5863
    AlnMgr2IndexSingleChildSeqAlign(salp);
 
5864
  }
 
5865
 
 
5866
  new_errors = ReportCoverageForBioseqSeqHist (bsp);
 
5867
  if (new_errors != NULL) {
 
5868
    ValNodeLink (errors, new_errors);
 
5869
    retval = FALSE;
 
5870
  }
 
5871
  return retval;
 
5872
}
 
5873
 
 
5874
 
5825
5875
static Boolean CKA_ValidateSeqAlign(SeqAlignPtr sap, CKA_AccPtr acc_head, Int4 bioseqlen, ValNodePtr PNTR errors)
5826
5876
{
5827
5877
   CKA_AccPtr        acc;
5838
5888
   Int4              max;
5839
5889
   Int4              n;
5840
5890
   Int4              prev;
5841
 
   Boolean           retval;
 
5891
   Boolean           retval = TRUE;
5842
5892
   CharPtr           textid;
5843
5893
   Char              textid2[42];
5844
5894
   CharPtr           err_msg;
6118
6168
 
6119
6169
  for (vnp = errors; vnp != NULL; vnp = vnp->next)
6120
6170
  {
6121
 
    fprintf (lip->fp, vnp->data.ptrvalue);
 
6171
    fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
6122
6172
    lip->data_in_log = TRUE;
6123
6173
  }
6124
6174
  fprintf (lip->fp, "\n\n");
6212
6262
           acc = acc->next;
6213
6263
         }
6214
6264
 
6215
 
               if (CKA_ValidateSeqAlign(sap, acc_head, bsp->length, &err_list))
 
6265
         if (sap != NULL) {
 
6266
            AlnMgr2IndexLite(sap);
 
6267
            AlnMgr2SortAlnSetByNthRowPos(sap, 1);
 
6268
                  /* make seq-hist and add it to record */
 
6269
                  if (bsp->hist != NULL)
 
6270
                  {
 
6271
                      shp = bsp->hist;
 
6272
                      if (shp->assembly != NULL)
 
6273
                        SeqAlignSetFree(shp->assembly);
 
6274
                      shp->assembly = (SeqAlignPtr)(sap->segs);
 
6275
                  }
 
6276
            else
 
6277
                  {
 
6278
                      shp = SeqHistNew();
 
6279
                      shp->assembly = (SeqAlignPtr)(sap->segs);
 
6280
                      bsp->hist = shp;
 
6281
                  }
 
6282
         }
 
6283
      
 
6284
         if (ValidateTPAHistAlign(bsp, &err_list)) 
6216
6285
         {
6217
6286
            fprintf (lip->fp, "Alignments were successfully created and are being added to %s.\n", textid);
6218
6287
            lip->data_in_log = TRUE;
6240
6309
            err_list = ValNodeFreeData (err_list);
6241
6310
         }
6242
6311
 
6243
 
         AlnMgr2IndexLite(sap);
6244
 
         AlnMgr2SortAlnSetByNthRowPos(sap, 1);
6245
 
               /* make seq-hist and add it to record */
6246
 
               if (bsp->hist != NULL)
6247
 
               {
6248
 
                  shp = bsp->hist;
6249
 
                  if (shp->assembly != NULL)
6250
 
                    SeqAlignSetFree(shp->assembly);
6251
 
                  shp->assembly = (SeqAlignPtr)(sap->segs);
6252
 
               }
6253
 
         else
6254
 
               {
6255
 
                  shp = SeqHistNew();
6256
 
                  shp->assembly = (SeqAlignPtr)(sap->segs);
6257
 
                  bsp->hist = shp;
6258
 
               }
6259
 
         sap->segs = NULL;
6260
 
         SeqAlignFree(sap);
 
6312
         if (sap != NULL) {
 
6313
            sap->segs = NULL;
 
6314
            SeqAlignFree(sap);
 
6315
         }
6261
6316
             } 
6262
6317
     else
6263
6318
     {
6280
6335
  lip = FreeLog (lip);
6281
6336
}
6282
6337
 
6283
 
static void CKA_FindNuc(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
6284
 
{
6285
 
   BioseqPtr      bsp;
6286
 
   BioseqPtr      PNTR bspptr;
6287
 
 
6288
 
   bspptr = (BioseqPtr PNTR)data;
6289
 
   if (IS_Bioseq(sep))
6290
 
   {
6291
 
      bsp = (BioseqPtr)sep->data.ptrvalue;
6292
 
      if (ISA_na(bsp->mol))
6293
 
      {
6294
 
         *bspptr = bsp;
6295
 
      }
6296
 
   }
6297
 
}
6298
 
 
6299
 
static int LIBCALLBACK CKA_CompareAlns(VoidPtr ptr1, VoidPtr ptr2)
6300
 
{
6301
 
   Int4         len1;
6302
 
   Int4         len2;
6303
 
   SeqAlignPtr  sap1;
6304
 
   SeqAlignPtr  sap2;
6305
 
 
6306
 
   sap1 = *((SeqAlignPtr PNTR) ptr1);
6307
 
   sap2 = *((SeqAlignPtr PNTR) ptr2);
6308
 
   if (sap1 == NULL || sap2 == NULL)
6309
 
      return 0;
6310
 
   len1 = AlnMgr2GetAlnLength(sap1, FALSE);
6311
 
   len2 = AlnMgr2GetAlnLength(sap2, FALSE);
6312
 
   if (len1 < len2)
6313
 
      return 1;
6314
 
   if (len1 > len2)
6315
 
      return -1;
6316
 
   return 0;
6317
 
}
 
6338
 
 
6339
typedef struct seqalignrow {
 
6340
  Int4 start;
 
6341
  Int4 stop;
 
6342
  Uint1 strand;
 
6343
} SeqAlignRowData, PNTR SeqAlignRowPtr;
 
6344
 
 
6345
static SeqAlignRowPtr SeqAlignRowNew (Int4 start, Int4 stop, Uint1 strand)
 
6346
{
 
6347
  SeqAlignRowPtr r;
 
6348
  Int4 tmp;
 
6349
 
 
6350
  r = (SeqAlignRowPtr) MemNew (sizeof (SeqAlignRowData));
 
6351
  r->start = start;
 
6352
  r->stop = stop;
 
6353
 
 
6354
  if (r->start > r->stop) {
 
6355
    tmp = r->start;
 
6356
    r->start = r->stop;
 
6357
    r->stop = tmp;
 
6358
  }
 
6359
  r->strand = strand;
 
6360
  return r;
 
6361
}
 
6362
 
 
6363
 
 
6364
static SeqAlignRowPtr SeqAlignRowCopy (SeqAlignRowPtr orig)
 
6365
{
 
6366
  SeqAlignRowPtr r = NULL;
 
6367
 
 
6368
  if (orig != NULL) {
 
6369
    r = SeqAlignRowNew (orig->start, orig->stop, orig->strand);
 
6370
  }
 
6371
  return r;
 
6372
}
 
6373
 
 
6374
 
 
6375
static SeqAlignRowPtr SeqAlignRowFree (SeqAlignRowPtr r)
 
6376
{
 
6377
  r = MemFree (r);
 
6378
  return r;
 
6379
}
 
6380
 
 
6381
 
 
6382
static Int4 RowDiff (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
 
6383
{
 
6384
  Int4 diff = 0;
 
6385
 
 
6386
  if (r1 == NULL || r2 == NULL) {
 
6387
    return -1;
 
6388
  }
 
6389
 
 
6390
  diff = ABS(r1->start - r2->start) + ABS (r1->stop - r2->stop);
 
6391
  return diff;
 
6392
}
 
6393
 
 
6394
 
 
6395
static Int4 SeqAlignRowLen (SeqAlignRowPtr r) 
 
6396
{
 
6397
  Int4 len = 0;
 
6398
 
 
6399
  if (r != NULL) {
 
6400
    len = r->stop - r->start + 1;
 
6401
  }
 
6402
  return len;
 
6403
}
 
6404
 
 
6405
 
 
6406
typedef struct seqalignsort {
 
6407
  SeqAlignRowPtr row1;
 
6408
  SeqAlignRowPtr row2;
 
6409
  SeqAlignPtr salp;
 
6410
} SeqAlignSortData, PNTR SeqAlignSortPtr;
 
6411
 
 
6412
 
 
6413
static SeqAlignSortPtr SeqAlignSortNew (SeqAlignPtr salp)
 
6414
{
 
6415
  SeqAlignSortPtr s;
 
6416
 
 
6417
  if (salp == NULL) {
 
6418
    return NULL;
 
6419
  }
 
6420
 
 
6421
  s = (SeqAlignSortPtr) MemNew (sizeof (SeqAlignSortData));
 
6422
  s->salp = salp;
 
6423
 
 
6424
  AlnMgr2IndexSingleChildSeqAlign(salp);
 
6425
 
 
6426
  s->row1 = SeqAlignRowNew (SeqAlignStart (salp, 0), SeqAlignStop (salp, 0), SeqAlignStrand (salp, 0));
 
6427
  s->row2 = SeqAlignRowNew (SeqAlignStart (salp, 1), SeqAlignStop (salp, 1), SeqAlignStrand (salp, 1));
 
6428
 
 
6429
  return s;
 
6430
}
 
6431
 
 
6432
 
 
6433
static SeqAlignSortPtr SeqAlignSortFree (SeqAlignSortPtr s)
 
6434
{
 
6435
  if (s != NULL) {
 
6436
    s->row1 = SeqAlignRowFree (s->row1);
 
6437
    s->row2 = SeqAlignRowFree (s->row2);
 
6438
    s = MemFree (s);
 
6439
  }
 
6440
  return s;
 
6441
}
 
6442
 
 
6443
 
 
6444
static ValNodePtr SeqAlignSortListNew (SeqAlignPtr salp)
 
6445
{
 
6446
  ValNodePtr list = NULL;
 
6447
  SeqAlignPtr salp_next;
 
6448
 
 
6449
  while (salp != NULL) {
 
6450
    salp_next = salp->next;
 
6451
    salp->next = NULL;
 
6452
    ValNodeAddPointer (&list, 0, SeqAlignSortNew (salp));
 
6453
    salp = salp_next;
 
6454
  }
 
6455
  return list;
 
6456
}
 
6457
 
 
6458
 
 
6459
static ValNodePtr SeqAlignSortListFree (ValNodePtr vnp)
 
6460
{
 
6461
  ValNodePtr vnp_next;
 
6462
 
 
6463
  while (vnp != NULL) {
 
6464
    vnp_next = vnp->next;
 
6465
    vnp->next = NULL;
 
6466
    vnp->data.ptrvalue = SeqAlignSortFree (vnp->data.ptrvalue);
 
6467
    vnp = ValNodeFree (vnp);
 
6468
    vnp = vnp_next;
 
6469
  }
 
6470
  return vnp;
 
6471
}
 
6472
 
 
6473
 
 
6474
static SeqAlignRowPtr SeqAlignRowFromSeqAlignSort (SeqAlignSortPtr s, Int4 row)
 
6475
{
 
6476
  if (s == NULL) {
 
6477
    return NULL;
 
6478
  } else if (row == 1) {
 
6479
    return s->row1;
 
6480
  } else {
 
6481
    return s->row2;
 
6482
  }
 
6483
}
 
6484
 
 
6485
 
 
6486
static Uint1 SeqAlignSortRowStrand (SeqAlignSortPtr s, Int4 row)
 
6487
{
 
6488
  Uint1 strand = Seq_strand_plus;
 
6489
  SeqAlignRowPtr r;
 
6490
 
 
6491
  r = SeqAlignRowFromSeqAlignSort (s, row);
 
6492
  if (r != NULL) {
 
6493
    strand = r->strand;
 
6494
  }
 
6495
  return strand;
 
6496
}
 
6497
 
 
6498
 
 
6499
static Uint1 SeqAlignSortListFindBestStrand (ValNodePtr vnp, Int4 row)
 
6500
{
 
6501
  Int4 num_plus = 0, num_minus = 0;
 
6502
  SeqAlignSortPtr s;
 
6503
 
 
6504
  while (vnp != NULL) {
 
6505
    s = (SeqAlignSortPtr) vnp->data.ptrvalue;
 
6506
    if (s != NULL) {
 
6507
      if (SeqAlignSortRowStrand(s, row) == Seq_strand_minus) {
 
6508
        num_minus++;
 
6509
      } else {
 
6510
        num_plus++;
 
6511
      }
 
6512
    }
 
6513
    vnp = vnp->next;
 
6514
  }
 
6515
 
 
6516
  if (num_minus > num_plus) {
 
6517
    return Seq_strand_minus;
 
6518
  } else {
 
6519
    return Seq_strand_plus;
 
6520
  }
 
6521
}
 
6522
 
 
6523
 
 
6524
static void SeqAlignSortListMarkStrand (ValNodePtr vnp, Int4 row, Uint1 strand)
 
6525
{
 
6526
  while (vnp != NULL) {
 
6527
    if (SeqAlignSortRowStrand (vnp->data.ptrvalue, row) == strand) {
 
6528
      vnp->choice = 1;
 
6529
    }
 
6530
    vnp = vnp->next;
 
6531
  }
 
6532
}
 
6533
 
 
6534
 
 
6535
static ValNodePtr SeqAlignSortListRemoveAll (ValNodePtr list)
 
6536
{
 
6537
  ValNodePtr vnp;
 
6538
  SeqAlignSortPtr s;
 
6539
 
 
6540
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
6541
    s = vnp->data.ptrvalue;
 
6542
    if (s != NULL && s->salp != NULL) {
 
6543
      s->salp->next = NULL;
 
6544
      s->salp = SeqAlignFree (s->salp);
 
6545
    }
 
6546
  }
 
6547
 
 
6548
  list = SeqAlignSortListFree (list);
 
6549
  return list;
 
6550
}
 
6551
 
 
6552
 
 
6553
static void SeqAlignSortListRemoveMarked (ValNodePtr PNTR list)
 
6554
{
 
6555
  ValNodePtr remove_list;
 
6556
 
 
6557
  if (list == NULL) {
 
6558
    return;
 
6559
  }
 
6560
 
 
6561
  remove_list = ValNodeExtractList (list, 1);
 
6562
  remove_list = SeqAlignSortListRemoveAll (remove_list);
 
6563
}
 
6564
 
 
6565
 
 
6566
static Uint1 SeqAlignSortListRemoveConflictingStrands (ValNodePtr PNTR list, Int4 row)
 
6567
{
 
6568
  Uint1 strand;
 
6569
 
 
6570
  if (list == NULL) {
 
6571
    return Seq_strand_plus;
 
6572
  }
 
6573
 
 
6574
  strand = SeqAlignSortListFindBestStrand (*list, row);
 
6575
  if (strand == Seq_strand_plus) {
 
6576
    SeqAlignSortListMarkStrand (*list, row, Seq_strand_minus);
 
6577
  } else {
 
6578
    SeqAlignSortListMarkStrand (*list, row, Seq_strand_plus);
 
6579
  }
 
6580
 
 
6581
  SeqAlignSortListRemoveMarked (list);
 
6582
  return strand;
 
6583
}
 
6584
 
 
6585
 
 
6586
static SeqAlignPtr SeqAlignFromSeqAlignSortList (ValNodePtr vnp)
 
6587
{
 
6588
  SeqAlignPtr salp_list = NULL, salp_prev = NULL;
 
6589
  SeqAlignSortPtr s;
 
6590
 
 
6591
  while (vnp != NULL) {
 
6592
    s = (SeqAlignSortPtr) vnp->data.ptrvalue;
 
6593
    if (s != NULL && s->salp != NULL) {
 
6594
      s->salp->next = NULL;
 
6595
      if (salp_prev == NULL) {
 
6596
        salp_list = s->salp;
 
6597
      } else {
 
6598
        salp_prev->next = s->salp;
 
6599
      }
 
6600
      salp_prev = s->salp;
 
6601
      s->salp->next = NULL;
 
6602
    }
 
6603
    vnp = vnp->next;
 
6604
  }
 
6605
  return salp_list;
 
6606
}
 
6607
 
 
6608
 
 
6609
static int CompareSeqAlignRow (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
 
6610
{
 
6611
  int rval = 0;
 
6612
 
 
6613
  if (r1 == NULL && r2 == NULL) {
 
6614
    rval = 0;
 
6615
  } else if (r1 == NULL) {
 
6616
    rval = -1;
 
6617
  } else if (r2 == NULL) {
 
6618
    rval = 1;
 
6619
  } else if (r1->start < r2->start) {
 
6620
    rval = -1;
 
6621
  } else if (r1->start > r2->start) {
 
6622
    rval = 1;
 
6623
  } else if (r1->stop < r2->stop) {
 
6624
    rval = -1;
 
6625
  } else if (r1->stop > r2->stop) {
 
6626
    rval = 1;
 
6627
  } else if (r1->strand < r2->strand) {
 
6628
    rval = -1;
 
6629
  } else if (r1->strand > r2->strand) {
 
6630
    rval = 1;
 
6631
  }
 
6632
  return rval;
 
6633
}
 
6634
 
 
6635
 
 
6636
static int CompareSeqAlignSortPreferRow1 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
 
6637
{
 
6638
  int rval = 0;
 
6639
  if (s1 == NULL && s2 == NULL) {
 
6640
    rval = 0;
 
6641
  } else if (s1 == NULL) {
 
6642
    rval = -1;
 
6643
  } else if (s2 == NULL) {
 
6644
    rval = 1;
 
6645
  } else if ((rval = CompareSeqAlignRow (s1->row1,s2->row1)) == 0) {
 
6646
    rval = CompareSeqAlignRow (s1->row2, s2->row2);
 
6647
  }
 
6648
  return rval;
 
6649
}
 
6650
 
 
6651
 
 
6652
static int CompareSeqAlignSortPreferRow2 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
 
6653
{
 
6654
  int rval = 0;
 
6655
  if (s1 == NULL && s2 == NULL) {
 
6656
    rval = 0;
 
6657
  } else if (s1 == NULL) {
 
6658
    rval = -1;
 
6659
  } else if (s2 == NULL) {
 
6660
    rval = 1;
 
6661
  } else if ((rval = CompareSeqAlignRow (s1->row2,s2->row2)) == 0) {
 
6662
    rval = CompareSeqAlignRow (s1->row1, s2->row1);
 
6663
  }
 
6664
  return rval;
 
6665
}
 
6666
 
 
6667
 
 
6668
 
 
6669
static int LIBCALLBACK SortVnpBySeqAlignSortRow1 (VoidPtr ptr1, VoidPtr ptr2)
 
6670
 
 
6671
{
 
6672
  ValNodePtr  vnp1;
 
6673
  ValNodePtr  vnp2;
 
6674
 
 
6675
  if (ptr1 != NULL && ptr2 != NULL) {
 
6676
    vnp1 = *((ValNodePtr PNTR) ptr1);
 
6677
    vnp2 = *((ValNodePtr PNTR) ptr2);
 
6678
    if (vnp1 != NULL && vnp2 != NULL) {
 
6679
      return CompareSeqAlignSortPreferRow1 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
 
6680
    }
 
6681
  }
 
6682
  return 0;
 
6683
}
 
6684
 
 
6685
 
 
6686
static int LIBCALLBACK SortVnpBySeqAlignSortRow2 (VoidPtr ptr1, VoidPtr ptr2)
 
6687
 
 
6688
{
 
6689
  ValNodePtr  vnp1;
 
6690
  ValNodePtr  vnp2;
 
6691
 
 
6692
  if (ptr1 != NULL && ptr2 != NULL) {
 
6693
    vnp1 = *((ValNodePtr PNTR) ptr1);
 
6694
    vnp2 = *((ValNodePtr PNTR) ptr2);
 
6695
    if (vnp1 != NULL && vnp2 != NULL) {
 
6696
      return CompareSeqAlignSortPreferRow2 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
 
6697
    }
 
6698
  }
 
6699
  return 0;
 
6700
}
 
6701
 
 
6702
 
 
6703
static ValNodePtr SeqAlignSortListExtractRepeats (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
 
6704
{
 
6705
  ValNodePtr repeat_start, repeat_prev = NULL, vnp_prev = NULL, vnp;
 
6706
  ValNodePtr repeat_list = NULL;
 
6707
  SeqAlignSortPtr s1, s2;
 
6708
  SeqAlignRowPtr  interval, r2;
 
6709
  Int4            diff;
 
6710
  Boolean         is_repeat;
 
6711
 
 
6712
  if (list == NULL || *list == NULL || (*list)->next == NULL) {
 
6713
    return NULL;
 
6714
  }
 
6715
 
 
6716
  if (row == 1) {
 
6717
    *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow1);
 
6718
  } else {
 
6719
    *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow2);
 
6720
  }
 
6721
 
 
6722
  repeat_start = *list;
 
6723
  s1 = repeat_start->data.ptrvalue;
 
6724
  interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
 
6725
  vnp_prev = *list;
 
6726
  for (vnp = (*list)->next; vnp != NULL; vnp = vnp->next) {
 
6727
    s2 = vnp->data.ptrvalue;
 
6728
    is_repeat = FALSE;
 
6729
    r2 = SeqAlignRowFromSeqAlignSort (s2, row);
 
6730
 
 
6731
    if (interval->start <= r2->start && interval->stop >= r2->stop) {
 
6732
      /* contained */
 
6733
      is_repeat = TRUE;
 
6734
    } else if (r2->start <= interval->start && r2->stop >= interval->stop) {
 
6735
      /* contained */
 
6736
      is_repeat = TRUE;
 
6737
    } else if ((diff = RowDiff (interval, r2)) > -1 && diff < fuzz) {
 
6738
      is_repeat = TRUE;
 
6739
    }
 
6740
    if (is_repeat) {
 
6741
      vnp_prev = vnp;
 
6742
      if (interval->start > r2->start) {
 
6743
        interval->start = r2->start;
 
6744
      }
 
6745
      if (interval->stop < r2->stop) {
 
6746
        interval->stop = r2->stop;
 
6747
      }
 
6748
    } else {
 
6749
      if (repeat_start->next == vnp) {
 
6750
        repeat_prev = vnp_prev;
 
6751
        vnp_prev = vnp;
 
6752
      } else {
 
6753
        if (repeat_prev == NULL) {
 
6754
          *list = vnp;
 
6755
        } else {
 
6756
          repeat_prev->next = vnp;
 
6757
        }
 
6758
        if (vnp_prev != NULL) {
 
6759
          vnp_prev->next = NULL;
 
6760
        }
 
6761
        ValNodeAddPointer (&repeat_list, 0, repeat_start);
 
6762
        vnp_prev = vnp;
 
6763
      }
 
6764
      repeat_start = vnp;
 
6765
      s1 = vnp->data.ptrvalue;
 
6766
      interval = SeqAlignRowFree (interval);
 
6767
      interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
 
6768
    }
 
6769
  }
 
6770
 
 
6771
  if (repeat_start->next != NULL) {
 
6772
    if (repeat_prev == NULL) {
 
6773
      *list = NULL;
 
6774
    } else {
 
6775
      repeat_prev->next = NULL;
 
6776
    }
 
6777
    ValNodeAddPointer (&repeat_list, 0, repeat_start);
 
6778
  }
 
6779
 
 
6780
  interval = SeqAlignRowFree (interval);
 
6781
  return repeat_list;
 
6782
}
 
6783
 
 
6784
 
 
6785
static int SeqAlignRowFuzzyCompare (SeqAlignRowPtr r1, SeqAlignRowPtr r2, Int4 fuzz)
 
6786
{
 
6787
  if (r1 == NULL && r2 == NULL) {
 
6788
    return 0;
 
6789
  } else if (r1 == NULL) {
 
6790
    return -1;
 
6791
  } else if (r2 == NULL) {
 
6792
    return 1;
 
6793
  }
 
6794
 
 
6795
  if (r1->stop < r2->start || r1->stop - r2->start < fuzz) {
 
6796
    return -1;
 
6797
  } else if (r2->stop < r1->start || r2->stop - r1->start < fuzz) {
 
6798
    return 1;
 
6799
  } else {
 
6800
    return 0;
 
6801
  }
 
6802
}
 
6803
 
 
6804
 
 
6805
static int SeqAlignSortFuzzyCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
 
6806
{
 
6807
  if (s1 == NULL && s2 == NULL) {
 
6808
    return 0;
 
6809
  } else if (s1 == NULL) {
 
6810
    return -1;
 
6811
  } else if (s2 == NULL) {
 
6812
    return 1;
 
6813
  } else if (row == 1) {
 
6814
    return SeqAlignRowFuzzyCompare (s1->row1, s2->row1, fuzz);
 
6815
  } else {
 
6816
    return SeqAlignRowFuzzyCompare (s1->row2, s2->row2, fuzz);
 
6817
  }
 
6818
}
 
6819
 
 
6820
 
 
6821
static void SeqAlignSortListRemoveIntervalsOutOfOrder (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
 
6822
{
 
6823
  ValNodePtr vnp, vnp_prev = NULL;
 
6824
 
 
6825
  if (list == NULL) {
 
6826
    return;
 
6827
  }
 
6828
 
 
6829
  for (vnp = *list; vnp != NULL; vnp = vnp->next) {
 
6830
    if (vnp_prev != NULL && SeqAlignSortFuzzyCompare (vnp_prev->data.ptrvalue, vnp->data.ptrvalue, row, fuzz) != -1) {
 
6831
      vnp->choice = 1;
 
6832
    } else if (vnp->next != NULL && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->data.ptrvalue, row, fuzz) != -1) {
 
6833
      if (vnp->next->next != NULL 
 
6834
          && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) == -1
 
6835
          && SeqAlignSortFuzzyCompare (vnp->next->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) != -1) {
 
6836
        /* ok to keep this one, we'll toss the next one */
 
6837
      } else {
 
6838
        vnp->choice = 1;
 
6839
      }
 
6840
    }
 
6841
    if (vnp->choice == 0) {
 
6842
      vnp_prev = vnp;
 
6843
    }
 
6844
  }
 
6845
 
 
6846
  SeqAlignSortListRemoveMarked (list);
 
6847
}
 
6848
 
 
6849
 
 
6850
static Int4 GetRepeatIntervalFuzz (SeqAlignSortPtr s_repeat, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row)
 
6851
{
 
6852
  Int4 start_fuzz = 0, end_fuzz = 0;
 
6853
 
 
6854
  if (s_repeat == NULL) {
 
6855
    return -1;
 
6856
  }
 
6857
 
 
6858
  if (s_before != NULL) {
 
6859
    if (row == 1) {
 
6860
      start_fuzz = ABS (s_repeat->row1->start - s_before->row1->stop);
 
6861
    } else {
 
6862
      start_fuzz = ABS (s_repeat->row2->start - s_before->row2->stop);
 
6863
    }
 
6864
  }
 
6865
  if (s_after != NULL) {
 
6866
    if (row == 1) {
 
6867
      end_fuzz = ABS (s_after->row1->start - s_repeat->row1->stop);
 
6868
    } else {
 
6869
      end_fuzz = ABS (s_after->row2->start - s_repeat->row2->stop);
 
6870
    }
 
6871
  }
 
6872
 
 
6873
  return start_fuzz + end_fuzz;
 
6874
}
 
6875
 
 
6876
 
 
6877
static int StrandedSeqAlignSortRowCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
 
6878
{
 
6879
  SeqAlignRowPtr r1 = NULL, r2 = NULL;
 
6880
  int rval = 0;
 
6881
  Uint1 strand = Seq_strand_plus;
 
6882
 
 
6883
  if (s1 == NULL || s2 == NULL) {
 
6884
    return 0;
 
6885
  } 
 
6886
 
 
6887
  r1 = SeqAlignRowFromSeqAlignSort (s1, row);
 
6888
  r2 = SeqAlignRowFromSeqAlignSort (s2, row);
 
6889
  strand = r1->strand;
 
6890
 
 
6891
  if (strand == Seq_strand_minus) {
 
6892
    if (r1->start < r2->start - fuzz) {
 
6893
      rval = 1;
 
6894
    } else if (r1->start >r2->start + fuzz) {
 
6895
      rval = -1;
 
6896
    }
 
6897
  } else {
 
6898
    if (r1->start > r2->start + fuzz) {
 
6899
      rval = 1;
 
6900
    } else if (r1->stop < r2->stop - fuzz) {
 
6901
      rval = -1;
 
6902
    } 
 
6903
  }
 
6904
 
 
6905
  return rval;
 
6906
}
 
6907
 
 
6908
 
 
6909
static Boolean FindSeqAlignSortWithPoint (ValNodePtr list, Int4 point, Int4 row)
 
6910
{
 
6911
  ValNodePtr vnp;
 
6912
  SeqAlignRowPtr r;
 
6913
  SeqAlignSortPtr s;
 
6914
  Boolean found = FALSE;
 
6915
 
 
6916
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
6917
    s = vnp->data.ptrvalue;
 
6918
    r = SeqAlignRowFromSeqAlignSort (s, row);
 
6919
    if (point >= r->start && point <= r->stop) {
 
6920
      found = TRUE;
 
6921
    }
 
6922
  }
 
6923
  return found;
 
6924
}
 
6925
 
 
6926
 
 
6927
static ValNodePtr FindBestRepeat (ValNodePtr PNTR repeat_list, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row, Int4 fuzz)
 
6928
{
 
6929
  Int4       best_diff = -1, diff;
 
6930
  ValNodePtr vnp, vnp_best = NULL, vnp_best_prev = NULL, vnp_prev = NULL;
 
6931
  SeqAlignSortPtr s_this;
 
6932
 
 
6933
  if (repeat_list == NULL || *repeat_list == NULL) {
 
6934
    return NULL;
 
6935
  }
 
6936
 
 
6937
  for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
 
6938
    s_this = vnp->data.ptrvalue;
 
6939
 
 
6940
    if (StrandedSeqAlignSortRowCompare (s_this, s_before, row, fuzz) < 0
 
6941
      || StrandedSeqAlignSortRowCompare (s_this, s_after, row, fuzz) > 0) {
 
6942
      /* skip - already out of order */
 
6943
    } else {
 
6944
      diff = GetRepeatIntervalFuzz (vnp->data.ptrvalue, s_before, s_after, row);
 
6945
      if (diff > -1 && (best_diff < 0 || best_diff > diff)) {
 
6946
        vnp_best = vnp;
 
6947
        vnp_best_prev = vnp_prev;
 
6948
        best_diff = diff;
 
6949
      }
 
6950
    }
 
6951
    vnp_prev = vnp;
 
6952
  }
 
6953
 
 
6954
  if (vnp_best != NULL) {
 
6955
    if (vnp_best_prev == NULL) {
 
6956
      *repeat_list = vnp_best->next;
 
6957
    } else {
 
6958
      vnp_best_prev->next = vnp_best->next;
 
6959
    }
 
6960
    vnp_best->next = NULL;
 
6961
  }
 
6962
 
 
6963
  return vnp_best;
 
6964
}
 
6965
 
 
6966
 
 
6967
static void RemoveRepeatsCoincidingWithBest (ValNodePtr PNTR repeat_list, ValNodePtr best, Int4 row, Int4 fuzz)
 
6968
{
 
6969
  ValNodePtr vnp;
 
6970
  SeqAlignSortPtr s_best, s;
 
6971
  SeqAlignRowPtr r_best, r2;
 
6972
  Boolean        is_repeat;
 
6973
  Int4           diff;
 
6974
 
 
6975
  if (repeat_list == NULL || *repeat_list == NULL || best == NULL) {
 
6976
    return;
 
6977
  }
 
6978
 
 
6979
  s_best = best->data.ptrvalue;
 
6980
  r_best = SeqAlignRowFromSeqAlignSort (s_best, row);
 
6981
 
 
6982
  for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
 
6983
    s = vnp->data.ptrvalue;
 
6984
    r2 = SeqAlignRowFromSeqAlignSort (s, row);
 
6985
 
 
6986
    is_repeat = FALSE;
 
6987
    if (r_best->start <= r2->start && r_best->stop >= r2->stop) {
 
6988
      /* contained */
 
6989
      is_repeat = TRUE;
 
6990
    } else if (r2->start <= r_best->start && r2->stop >= r_best->stop) {
 
6991
      /* contained */
 
6992
      is_repeat = TRUE;
 
6993
    } else if (r2->stop < r_best->stop || r2->stop - r_best->stop < fuzz) {
 
6994
      is_repeat = TRUE;
 
6995
    } else if ((diff = RowDiff (r_best, r2)) > -1 && diff < fuzz) {
 
6996
      is_repeat = TRUE;
 
6997
    }
 
6998
 
 
6999
    if (is_repeat) {
 
7000
      vnp->choice = 1;
 
7001
    }
 
7002
  }
 
7003
  SeqAlignSortListRemoveMarked (repeat_list);
 
7004
}
 
7005
 
 
7006
 
 
7007
static ValNodePtr ExtractLongestSeqAlignRow (ValNodePtr PNTR list, Int4 row)
 
7008
{
 
7009
  ValNodePtr vnp, vnp_prev = NULL, rval = NULL;
 
7010
  Int4       longest = 0, len;
 
7011
  Boolean    found = FALSE;
 
7012
 
 
7013
  if (list == NULL || *list == NULL) {
 
7014
    return NULL;
 
7015
  }
 
7016
 
 
7017
  for (vnp = *list; vnp != NULL; vnp = vnp->next) {
 
7018
    len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
 
7019
    if (longest < len) {
 
7020
      longest = len;
 
7021
    }
 
7022
  }
 
7023
 
 
7024
  for (vnp = *list; vnp != NULL && !found; vnp = vnp->next) {
 
7025
    len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
 
7026
    if (len == longest) {
 
7027
      if (vnp_prev == NULL) {
 
7028
        *list = vnp->next;
 
7029
      } else {
 
7030
        vnp_prev->next = vnp->next;
 
7031
      }
 
7032
      vnp->next = NULL;
 
7033
      rval = vnp;
 
7034
      found = TRUE;
 
7035
    }
 
7036
    vnp_prev = vnp;
 
7037
  }
 
7038
  return rval;
 
7039
}
 
7040
 
 
7041
 
 
7042
static void InsertBestRepeat (ValNodePtr repeat_list, ValNodePtr PNTR sorted_list, Int4 row, Int4 fuzz)
 
7043
{
 
7044
  ValNodePtr vnp, vnp_prev = NULL, vnp_new;
 
7045
  SeqAlignSortPtr s_repeat, s, s_before = NULL;
 
7046
  Boolean         found = TRUE;
 
7047
  SeqAlignRowPtr  r1, r2;
 
7048
  Int4 other_row;
 
7049
 
 
7050
  if (repeat_list == NULL || sorted_list == NULL) {
 
7051
    return;
 
7052
  }
 
7053
 
 
7054
  if (row == 1) {
 
7055
    other_row = 2;
 
7056
  } else {
 
7057
    other_row = 1;
 
7058
  }
 
7059
  if (sorted_list == NULL || *sorted_list == NULL) {
 
7060
    /* keep longest, mark others for removal */
 
7061
    vnp = ExtractLongestSeqAlignRow (&repeat_list, row);
 
7062
    ValNodeLink (sorted_list,vnp);
 
7063
    repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7064
  } else {
 
7065
    s_repeat = repeat_list->data.ptrvalue;
 
7066
    found = FALSE;
 
7067
    vnp = *sorted_list;
 
7068
 
 
7069
    /* find first entry that is after this repeat, and insert before that */
 
7070
    while (vnp != NULL && !found) {
 
7071
      s = vnp->data.ptrvalue;
 
7072
      r1 = SeqAlignRowFromSeqAlignSort (s, row);
 
7073
      r2 = SeqAlignRowFromSeqAlignSort (s_repeat, row);
 
7074
 
 
7075
      if (r1->start > r2->start || r2->start - r1->start < fuzz) {
 
7076
        while (repeat_list != NULL) {
 
7077
          /* extract best repeat */
 
7078
          vnp_new = FindBestRepeat (&repeat_list, s_before, vnp->data.ptrvalue, other_row, fuzz);
 
7079
          if (vnp_new == NULL) {
 
7080
            repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7081
          } else {
 
7082
            RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
 
7083
            vnp_new->next = vnp;
 
7084
            if (vnp_prev == NULL) {
 
7085
              *sorted_list = vnp_new;
 
7086
            } else {
 
7087
              vnp_prev->next = vnp_new;
 
7088
            }
 
7089
            vnp_prev = vnp_new;
 
7090
            s_before = vnp_new->data.ptrvalue;
 
7091
          }
 
7092
        }
 
7093
        found = TRUE;
 
7094
      }
 
7095
      if (!found) {
 
7096
        s_before = vnp->data.ptrvalue;
 
7097
        vnp_prev = vnp;
 
7098
        vnp = vnp->next;
 
7099
      }
 
7100
    }
 
7101
    if (!found) {
 
7102
      while (repeat_list != NULL) {
 
7103
        /* extract best repeat */
 
7104
        vnp_new = FindBestRepeat (&repeat_list, s_before, NULL, other_row, fuzz);
 
7105
        if (vnp_new == NULL) {
 
7106
          repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7107
        } else {
 
7108
          RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
 
7109
          vnp_new->next = NULL;
 
7110
          if (vnp_prev == NULL) {
 
7111
            *sorted_list = vnp_new;
 
7112
          } else {
 
7113
            vnp_prev->next = vnp_new;
 
7114
          }
 
7115
          vnp_prev = vnp_new;
 
7116
          s_before = vnp_new->data.ptrvalue;
 
7117
        }
 
7118
      }
 
7119
    }
 
7120
  }
 
7121
 
 
7122
  SeqAlignSortListRemoveMarked (&repeat_list);
 
7123
  repeat_list = ValNodeFree (repeat_list);
 
7124
}
 
7125
 
 
7126
 
 
7127
static void SelectBestRepeatsFromList (SeqAlignPtr PNTR salp)
 
7128
{
 
7129
  ValNodePtr list, vnp;
 
7130
  ValNodePtr row1_repeats, row2_repeats;
 
7131
  Uint1 strand1, strand2;
 
7132
  SeqAlignPtr    tmp_salp;
 
7133
  Int4           fuzz = 15;
 
7134
 
 
7135
  Int4           missing = 600;
 
7136
 
 
7137
  if (salp == NULL || *salp == NULL || (*salp)->next == NULL) {
 
7138
    return;
 
7139
  }
 
7140
 
 
7141
  list = SeqAlignSortListNew (*salp);
 
7142
 
 
7143
  FindSeqAlignSortWithPoint (list, missing, 1);
 
7144
 
 
7145
  /* remove conflicting strands for row 1 */
 
7146
  strand1 = SeqAlignSortListRemoveConflictingStrands (&list, 1);
 
7147
 
 
7148
  /* remove conflicting strands for row 1 */
 
7149
  strand2 = SeqAlignSortListRemoveConflictingStrands (&list, 2);
 
7150
 
 
7151
  FindSeqAlignSortWithPoint (list, missing, 1);
 
7152
 
 
7153
  if (list != NULL && list->next != NULL) {
 
7154
    row1_repeats = SeqAlignSortListExtractRepeats (&list, 1, fuzz);
 
7155
    row2_repeats = SeqAlignSortListExtractRepeats (&list, 2, fuzz);
 
7156
 
 
7157
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7158
 
 
7159
    /* remove scaffold intervals that are out of order */
 
7160
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7161
    SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 1, fuzz);
 
7162
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
 
7163
    SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 2, fuzz);
 
7164
 
 
7165
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7166
 
 
7167
    /* Remove overlaps.*/
 
7168
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7169
    tmp_salp = SeqAlignFromSeqAlignSortList (list);
 
7170
    list = SeqAlignSortListFree (list);
 
7171
    ACT_RemoveInconsistentAlnsFromSet (tmp_salp, 1, 1);
 
7172
    list = SeqAlignSortListNew (tmp_salp);
 
7173
 
 
7174
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7175
 
 
7176
    /* for each repeat on row 1, we want to pick the most consistent interval for row 2 */
 
7177
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7178
    for (vnp = row1_repeats; vnp != NULL; vnp = vnp->next) {   
 
7179
      InsertBestRepeat (vnp->data.ptrvalue, &list, 1, fuzz);
 
7180
    }
 
7181
    row1_repeats = ValNodeFree (row1_repeats);
 
7182
 
 
7183
    /* for each repeat on row 2, we want to pick the most consistent interval for row 1 */
 
7184
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
 
7185
    for (vnp = row2_repeats; vnp != NULL; vnp = vnp->next) {   
 
7186
      InsertBestRepeat (vnp->data.ptrvalue, &list, 2, fuzz);
 
7187
    }
 
7188
    row2_repeats = ValNodeFree (row2_repeats);
 
7189
  }
 
7190
 
 
7191
  list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7192
  *salp = SeqAlignFromSeqAlignSortList (list);
 
7193
 
 
7194
  list = SeqAlignSortListFree (list);
 
7195
}
 
7196
 
6318
7197
 
6319
7198
static void amconssetfree(AMConsSetPtr acp)
6320
7199
{
6357
7236
      return 0;
6358
7237
}
6359
7238
 
 
7239
 
6360
7240
static void CKA_RemoveInconsistentAlnsFromSet(SeqAlignPtr sap_head, Int4 fuzz)
6361
7241
{
6362
7242
   AMConsSetPtr  acp;
6557
7437
   AlnMgr2IndexLite(sap_head);
6558
7438
}
6559
7439
 
 
7440
 
6560
7441
static BioseqPtr ReadFromTraceDb (CharPtr number)
6561
7442
 
6562
7443
{
6820
7701
      acc_new_head = NULL;
6821
7702
      if (acc->sap != NULL && acc->sap->next != NULL)
6822
7703
      {
 
7704
         if (!CKA_blast_allow_repeats) {
 
7705
           SelectBestRepeatsFromList (&(acc->sap));
 
7706
         }
6823
7707
         AlnMgr2IndexLite(acc->sap);
6824
7708
         if (!CKA_blast_allow_repeats) {
6825
7709
           CKA_RemoveInconsistentAlnsFromSet(acc->sap, -1);
7154
8038
typedef struct assemblyuserform {
7155
8039
  FEATURE_FORM_BLOCK
7156
8040
  SeqEntryPtr   sep;
 
8041
  SeqDescrPtr   orig_sdp;
7157
8042
} AssemblyUserForm, PNTR AssemblyUserFormPtr;
7158
8043
 
7159
8044
static void UserObjectPtrToAssemblyDialog (DialoG d, Pointer data)
7566
8451
}
7567
8452
 
7568
8453
 
 
8454
static void PopulateAssemblyIntervals (ButtoN b)
 
8455
{
 
8456
  AssemblyUserFormPtr  afp;
 
8457
  BioseqPtr            bsp;
 
8458
  UserObjectPtr        uop;
 
8459
  SeqAlignPtr          salp;
 
8460
  Char                 id_txt[355];
 
8461
  SeqIdPtr             sip;
 
8462
  Int4                 primary_start, primary_stop;
 
8463
 
 
8464
  afp = (AssemblyUserFormPtr) GetObjectExtra (b);
 
8465
  if (afp == NULL) {
 
8466
    return;
 
8467
  }
 
8468
 
 
8469
  bsp = GetSequenceForObject (OBJ_SEQDESC, afp->orig_sdp);
 
8470
  if (bsp != NULL && bsp->hist != NULL && bsp->hist->assembly != NULL) {
 
8471
    uop = CreateTpaAssemblyUserObject  ();
 
8472
    /* populate user object with intervals */
 
8473
    for (salp = bsp->hist->assembly; salp != NULL; salp = salp->next) {
 
8474
      AlnMgr2IndexSingleChildSeqAlign (salp); 
 
8475
      sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
8476
      SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
8477
      AlnMgr2GetNthSeqRangeInSA (salp, 2, &primary_start, &primary_stop);
 
8478
      AddAccessionToTpaAssemblyUserObject (uop, id_txt, primary_start, primary_stop);
 
8479
      sip = SeqIdFree (sip);
 
8480
    }
 
8481
 
 
8482
    PointerToDialog (afp->data, uop);
 
8483
    uop = UserObjectFree (uop);
 
8484
  }
 
8485
}
 
8486
 
 
8487
 
7569
8488
static ForM CreateAssemblyDescForm (Int2 left, Int2 top, Int2 width,
7570
8489
                                   Int2 height, CharPtr title, ValNodePtr sdp,
7571
8490
                                   SeqEntryPtr sep, FormActnFunc actproc)
7572
8491
 
7573
8492
{
7574
8493
  AssemblyUserFormPtr  afp;
7575
 
  ButtoN               b;
 
8494
  ButtoN               b, pop_btn = NULL;
7576
8495
  GrouP                c;
7577
8496
  GrouP                g;
7578
8497
  StdEditorProcsPtr    sepp;
7579
8498
  WindoW               w;
 
8499
  BioseqPtr            bsp;
7580
8500
 
7581
8501
  w = NULL;
7582
8502
  afp = (AssemblyUserFormPtr) MemNew (sizeof (AssemblyUserForm));
7601
8521
    g = HiddenGroup (w, -1, 0, NULL);
7602
8522
    afp->data = CreateAssemblyDialog (g);
7603
8523
 
 
8524
    if (sdp != NULL) {
 
8525
      bsp = GetSequenceForObject (OBJ_SEQDESC, sdp);
 
8526
      if (bsp != NULL && bsp->hist != NULL && bsp->hist->assembly != NULL) {
 
8527
        pop_btn = PushButton (g, "Populate Intervals from Assembly Alignment", PopulateAssemblyIntervals);
 
8528
        SetObjectExtra (pop_btn, afp, NULL);
 
8529
      }
 
8530
    }
 
8531
 
7604
8532
    c = HiddenGroup (w, 2, 0, NULL);
7605
8533
    b = DefaultButton (c, "Accept", TPAAssemblyFormAccept);
7606
8534
    SetObjectExtra (b, afp, NULL);
7607
8535
    PushButton (c, "Cancel", StdCancelButtonProc);
7608
 
    AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
8536
    AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, (HANDLE) pop_btn, NULL);
7609
8537
    RealizeWindow (w);
7610
8538
  }
7611
8539
  return (ForM) w;
7691
8619
    if (sdp != NULL) {
7692
8620
      PointerToDialog (afp->data, (Pointer) sdp->data.ptrvalue);
7693
8621
      SetClosestParentIfDuplicating ((BaseFormPtr) afp);
 
8622
      afp->orig_sdp = sdp;
7694
8623
    }
7695
8624
  }
7696
8625
  Show (w);
7699
8628
}
7700
8629
 
7701
8630
 
 
8631
/* advanced editor for Seq-hist assembly alignment */
 
8632
typedef struct assemblyalignmentdlg {
 
8633
  DIALOG_MESSAGE_BLOCK
 
8634
  DialoG intervals_dialog;
 
8635
 
 
8636
  
 
8637
} AssemblyAlignmentDlgData, PNTR AssemblyAlignmentDlgPtr;
 
8638
 
 
8639
Uint2 assmbly_aln_types [] = {
 
8640
  TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_POPUP
 
8641
};
 
8642
 
 
8643
Uint2 assmbly_aln_widths [] = {
 
8644
  16, 8, 8, 8, 8, 8, 0
 
8645
};
 
8646
 
 
8647
ENUM_ALIST(assmbly_aln_strand_alist)
 
8648
  {"Plus",  0},
 
8649
  {"Minus",    1},
 
8650
END_ENUM_ALIST
 
8651
 
 
8652
 
 
8653
 
 
8654
static EnumFieldAssocPtr assmbly_aln_alists[] = {
 
8655
  NULL, NULL, NULL, NULL, NULL, assmbly_aln_strand_alist
 
8656
};
 
8657
 
 
8658
 
 
8659
typedef struct assemblyalignmentinterval {
 
8660
  CharPtr prim_accession;
 
8661
  Int4    tpa_from;
 
8662
  Int4    tpa_to;
 
8663
  Int4    prim_from;
 
8664
  Uint1   prim_strand;
 
8665
  Uint2   percent_identity;
 
8666
} AssemblyAlignmentIntervalData, PNTR AssemblyAlignmentIntervalPtr;
 
8667
 
 
8668
 
 
8669
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFree (AssemblyAlignmentIntervalPtr interval)
 
8670
{
 
8671
  if (interval != NULL) {
 
8672
    interval->prim_accession = MemFree (interval->prim_accession);
 
8673
    interval = MemFree (interval);
 
8674
  }
 
8675
  return interval;
 
8676
}
 
8677
 
 
8678
 
 
8679
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromTagListString (CharPtr str)
 
8680
{
 
8681
  AssemblyAlignmentIntervalPtr interval;
 
8682
  CharPtr cp;
 
8683
  Int4    len, val;
 
8684
 
 
8685
  if (StringHasNoText (str)) {
 
8686
    return NULL;
 
8687
  }
 
8688
 
 
8689
  interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
 
8690
  MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
 
8691
 
 
8692
  cp = StringChr (str, '\t');
 
8693
  if (cp == NULL) {
 
8694
    interval->prim_accession = StringSave (str);
 
8695
  } else {
 
8696
    len = cp - str + 1;
 
8697
    interval->prim_accession = (CharPtr) MemNew (sizeof (Char) * len);
 
8698
    StringNCpy (interval->prim_accession, str, len - 1);
 
8699
    interval->prim_accession[len - 1] = 0;
 
8700
    str = cp + 1;
 
8701
    cp = StringChr (str, '\t');
 
8702
    interval->tpa_from = atoi (str);
 
8703
    if (cp != NULL) {
 
8704
      str = cp + 1;
 
8705
      cp = StringChr (str, '\t');
 
8706
      interval->tpa_to = atoi (str);
 
8707
      if (cp != NULL) {
 
8708
        str = cp + 1;
 
8709
        cp = StringChr (str, '\t');
 
8710
        interval->prim_from = atoi (str);
 
8711
        if (cp != NULL) {
 
8712
          cp = StringChr (cp + 1, '\t');
 
8713
          if (cp != NULL) {
 
8714
            val = atoi (cp + 1);
 
8715
            if (val == 1) {
 
8716
              interval->prim_strand = Seq_strand_minus;
 
8717
            } else {
 
8718
              interval->prim_strand = Seq_strand_plus;
 
8719
            }
 
8720
          }
 
8721
        }
 
8722
      }
 
8723
    }
 
8724
  }
 
8725
  return interval;
 
8726
}
 
8727
 
 
8728
 
 
8729
static CharPtr TagListStringFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
 
8730
{
 
8731
  CharPtr str, str_fmt = "%s\t%d\t%d\t%d\t%d (%d)\t%d\n";
 
8732
 
 
8733
  if (interval == NULL) {
 
8734
    return NULL;
 
8735
  }
 
8736
 
 
8737
  str = (CharPtr) MemNew (sizeof (Char) * (StringLen (str_fmt) + StringLen (interval->prim_accession) + 61));
 
8738
  sprintf (str, str_fmt, interval->prim_accession == NULL ? "" : interval->prim_accession,
 
8739
                         interval->tpa_from,
 
8740
                         interval->tpa_to,
 
8741
                         interval->prim_from,
 
8742
                         interval->prim_from + interval->tpa_to - interval->tpa_from,
 
8743
                         interval->percent_identity,
 
8744
                         interval->prim_strand == Seq_strand_minus ? 1 : 0);
 
8745
  return str;
 
8746
}
 
8747
 
 
8748
 
 
8749
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromSeqAlign (SeqAlignPtr salp)
 
8750
{
 
8751
  AssemblyAlignmentIntervalPtr interval;
 
8752
  DenseSegPtr dsp;
 
8753
  Char     id_txt[200];
 
8754
 
 
8755
  if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG) {
 
8756
    return NULL;
 
8757
  }
 
8758
 
 
8759
  dsp = (DenseSegPtr) salp->segs;
 
8760
  if (dsp == NULL || dsp->numseg != 1) {
 
8761
    return NULL;
 
8762
  }
 
8763
 
 
8764
  interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
 
8765
  MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
 
8766
 
 
8767
  /* first row is TPA, second row is primary */  
 
8768
  SeqIdWrite (dsp->ids->next, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
8769
  interval->prim_accession = StringSave (id_txt);
 
8770
 
 
8771
  interval->tpa_from = dsp->starts[0] + 1;
 
8772
  interval->tpa_to = dsp->starts[0] + dsp->lens[0];
 
8773
  interval->prim_from = dsp->starts[1] + 1;
 
8774
  if (dsp->strands == NULL) {
 
8775
    interval->prim_strand = Seq_strand_plus;
 
8776
  } else {
 
8777
    interval->prim_strand = dsp->strands[1];
 
8778
  }
 
8779
 
 
8780
  interval->percent_identity = AlignmentPercentIdentity (salp, FALSE);
 
8781
 
 
8782
  return interval;
 
8783
}
 
8784
 
 
8785
 
 
8786
static SeqAlignPtr SeqAlignFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
 
8787
{
 
8788
  SeqAlignPtr salp;
 
8789
  DenseSegPtr dsp;
 
8790
 
 
8791
  if (interval == NULL) {
 
8792
    return NULL;
 
8793
  }
 
8794
  dsp = DenseSegNew ();
 
8795
  dsp->dim = 2;
 
8796
  dsp->numseg = 1;
 
8797
  dsp->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
8798
  dsp->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp->numseg);
 
8799
  dsp->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
8800
 
 
8801
  dsp->ids = ValNodeNew (NULL);
 
8802
  dsp->ids->next = SeqIdFromAccessionDotVersion(interval->prim_accession);
 
8803
 
 
8804
  dsp->starts[0] = interval->tpa_from - 1;
 
8805
  dsp->starts[1] = interval->prim_from - 1;
 
8806
  dsp->lens[0] = interval->tpa_to - interval->tpa_from + 1;
 
8807
  dsp->strands[0] = Seq_strand_plus;
 
8808
  dsp->strands[1] = interval->prim_strand;
 
8809
 
 
8810
  salp = SeqAlignNew ();
 
8811
  salp->dim = 2;
 
8812
  salp->segtype = SAS_DENSEG;
 
8813
  salp->segs = dsp;
 
8814
  salp->type = SAT_PARTIAL;
 
8815
  return salp;
 
8816
}
 
8817
 
 
8818
 
 
8819
static void SeqAlignToAssemblyAlignmentDialog (DialoG d, Pointer data) 
 
8820
{
 
8821
  AssemblyAlignmentDlgPtr dlg;
 
8822
 
 
8823
  dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
 
8824
  if (dlg == NULL) {
 
8825
    return;
 
8826
  }
 
8827
 
 
8828
  PointerToDialog (dlg->intervals_dialog, data);
 
8829
}
 
8830
 
 
8831
 
 
8832
static Pointer AssemblyAlignmentDialogToSeqAlign (DialoG d)
 
8833
{
 
8834
  AssemblyAlignmentDlgPtr dlg;
 
8835
  SeqAlignPtr salp = NULL;
 
8836
 
 
8837
  dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
 
8838
  if (dlg == NULL) {
 
8839
    return NULL;
 
8840
  }
 
8841
 
 
8842
  salp = DialogToPointer (dlg->intervals_dialog);
 
8843
  
 
8844
  return salp;
 
8845
}
 
8846
 
 
8847
 
 
8848
static void SeqAlignToTagDlg (DialoG d, Pointer data)
 
8849
{
 
8850
  TagListPtr tlp;
 
8851
  SeqAlignPtr salp;
 
8852
  AssemblyAlignmentIntervalPtr interval;
 
8853
 
 
8854
  tlp =(TagListPtr) GetObjectExtra (d);
 
8855
  if (tlp == NULL) {
 
8856
    return;
 
8857
  }
 
8858
 
 
8859
  tlp->vnp = ValNodeFreeData (tlp->vnp);
 
8860
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
8861
  salp = (SeqAlignPtr) data;
 
8862
 
 
8863
  while (salp != NULL) {
 
8864
    interval = AssemblyAlignmentIntervalFromSeqAlign (salp);
 
8865
    if (interval != NULL) {
 
8866
      ValNodeAddPointer (&(tlp->vnp), 0, TagListStringFromAssemblyAlignmentInterval (interval));
 
8867
      interval = AssemblyAlignmentIntervalFree (interval);
 
8868
    }
 
8869
    salp = salp->next;
 
8870
  }
 
8871
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
8872
}
 
8873
 
 
8874
 
 
8875
static Pointer SeqAlignFromTagDlg (DialoG d)
 
8876
{
 
8877
  TagListPtr tlp;
 
8878
  SeqAlignPtr salp = NULL, salp_last = NULL, salp_tmp;
 
8879
  ValNodePtr vnp;
 
8880
  AssemblyAlignmentIntervalPtr interval;
 
8881
 
 
8882
  tlp =(TagListPtr) GetObjectExtra (d);
 
8883
  if (tlp == NULL) {
 
8884
    return NULL;
 
8885
  }
 
8886
 
 
8887
  for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
 
8888
    interval = AssemblyAlignmentIntervalFromTagListString (vnp->data.ptrvalue);
 
8889
    if (interval != NULL) {
 
8890
      salp_tmp = SeqAlignFromAssemblyAlignmentInterval (interval);
 
8891
      if (salp_tmp != NULL) {
 
8892
        if (salp_last == NULL) {
 
8893
          salp = salp_tmp;
 
8894
        } else {
 
8895
          salp_last->next = salp_tmp;
 
8896
        }
 
8897
        salp_last = salp_tmp;
 
8898
      }
 
8899
      interval = AssemblyAlignmentIntervalFree (interval);
 
8900
    }
 
8901
  }
 
8902
  return salp;
 
8903
}
 
8904
 
 
8905
 
 
8906
static DialoG CreateAssemblyAlignmentDialog (GrouP g)
 
8907
 
 
8908
{
 
8909
  AssemblyAlignmentDlgPtr dlg;
 
8910
  GrouP                   p;
 
8911
  GrouP                   x;
 
8912
  GrouP                   y;
 
8913
 
 
8914
  p = HiddenGroup (g, -1, 0, NULL);
 
8915
  SetGroupSpacing (p, 10, 10);
 
8916
 
 
8917
  dlg = (AssemblyAlignmentDlgPtr) MemNew (sizeof (AssemblyAlignmentDlgData));
 
8918
  if (dlg == NULL) return NULL;
 
8919
 
 
8920
  SetObjectExtra (p, dlg, NULL);
 
8921
  dlg->dialog = (DialoG) p;
 
8922
  dlg->todialog = SeqAlignToAssemblyAlignmentDialog;
 
8923
  dlg->fromdialog = AssemblyAlignmentDialogToSeqAlign;
 
8924
 
 
8925
  x = HiddenGroup (p, 0, 2, NULL);
 
8926
  y = HiddenGroup (x, 6, 0, NULL);
 
8927
  StaticPrompt (y, "", 16 * stdCharWidth, 0, programFont, 'c');
 
8928
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
8929
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
8930
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
8931
  StaticPrompt (y, "Primary To", 8 * stdCharWidth, 0, programFont, 'c');
 
8932
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
8933
  StaticPrompt (y, "Accessions", 16 * stdCharWidth, 0, programFont, 'c');
 
8934
  StaticPrompt (y, "TPA From", 8 * stdCharWidth, 0, programFont, 'c');
 
8935
  StaticPrompt (y, "TPA To", 8 * stdCharWidth, 0, programFont, 'c');
 
8936
  StaticPrompt (y, "Primary From", 8 * stdCharWidth, 0, programFont, 'c');
 
8937
  StaticPrompt (y, "(Percent Identity)", 8 * stdCharWidth, 0, programFont, 'c');
 
8938
  StaticPrompt (y, "Primary Strand", 8 * stdCharWidth, 0, programFont, 'c');
 
8939
  dlg->intervals_dialog = CreateTagListDialogExEx (x, 6, 6, -1, assmbly_aln_types, assmbly_aln_widths, assmbly_aln_alists,
 
8940
                                                   TRUE, FALSE, SeqAlignToTagDlg, SeqAlignFromTagDlg,
 
8941
                                                   NULL, NULL, FALSE);
 
8942
 
 
8943
 
 
8944
  return (DialoG) p;
 
8945
}
 
8946
 
 
8947
 
 
8948
static void AddTPAIdToAlignment (SeqAlignPtr salp, BioseqPtr bsp)
 
8949
{
 
8950
  DenseSegPtr dsp;
 
8951
  SeqIdPtr    sip;
 
8952
 
 
8953
  if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG || bsp == NULL) {
 
8954
    return;
 
8955
  }
 
8956
 
 
8957
  dsp = salp->segs;
 
8958
  if (dsp == NULL) {
 
8959
    return;
 
8960
  }
 
8961
 
 
8962
  sip = SeqIdFindWorst (bsp->id);
 
8963
  sip = SeqIdDup (sip);
 
8964
 
 
8965
  sip->next = dsp->ids->next;
 
8966
  dsp->ids->next = NULL;
 
8967
  dsp->ids = SeqIdFree (dsp->ids);
 
8968
  dsp->ids = sip;
 
8969
}
 
8970
 
 
8971
 
 
8972
static void AddTPAIdToAlignmentList (SeqAlignPtr salp, BioseqPtr bsp)
 
8973
{
 
8974
  while (salp != NULL) {
 
8975
    AddTPAIdToAlignment (salp, bsp);
 
8976
    salp = salp->next;
 
8977
  }
 
8978
}
 
8979
 
 
8980
typedef struct assemblyalignmentform {
 
8981
  FORM_MESSAGE_BLOCK
 
8982
  DialoG dlg;
 
8983
  BioseqPtr bsp;
 
8984
} AssemblyAlignmentFormData, PNTR AssemblyAlignmentFormPtr;
 
8985
 
 
8986
 
 
8987
static void CheckCoverageWithAddedIntervals (LogInfoPtr lip, BioseqPtr bsp, SeqAlignPtr salp)
 
8988
{
 
8989
  ValNodePtr err_list = NULL;
 
8990
  SeqAlignPtr salp_orig, salp_prev = NULL;
 
8991
 
 
8992
  if (bsp == NULL) {
 
8993
    return;
 
8994
  }
 
8995
 
 
8996
  if (bsp->hist == NULL) {
 
8997
    bsp->hist = SeqHistNew ();
 
8998
  }
 
8999
 
 
9000
  salp_orig = bsp->hist->assembly;
 
9001
  while (salp_orig != NULL) {
 
9002
    salp_prev = salp_orig;
 
9003
    salp_orig = salp_orig->next;
 
9004
  }
 
9005
 
 
9006
  if (salp_prev == NULL) {
 
9007
    bsp->hist->assembly = salp;
 
9008
  } else {
 
9009
    salp_prev->next = salp;
 
9010
  }
 
9011
 
 
9012
  ValidateTPAHistAlign (bsp, &err_list);
 
9013
  if (err_list != NULL) {
 
9014
    fprintf (lip->fp, "Projected Coverage Problems\n");
 
9015
    PrintTPAHistErrors (lip, err_list);
 
9016
    lip->data_in_log = TRUE;
 
9017
    err_list = ValNodeFreeData (err_list);
 
9018
  }
 
9019
 
 
9020
  if (salp_prev == NULL) {
 
9021
    bsp->hist->assembly = NULL;
 
9022
  } else {
 
9023
    salp_prev->next = NULL;
 
9024
  }
 
9025
}
 
9026
 
 
9027
 
 
9028
static Boolean ReportAssemblyIntervalProblems (BioseqPtr bsp, SeqAlignPtr salp)
 
9029
{
 
9030
  LogInfoPtr lip;
 
9031
  AssemblyAlignmentIntervalPtr interval;
 
9032
  Boolean    has_errors = FALSE;
 
9033
  SeqAlignPtr salp_tmp;
 
9034
 
 
9035
  lip = OpenLog ("Assembly Alignment Interval Problems");
 
9036
  fprintf (lip->fp, "Primary Accession\tTPA From\tTPA To\tPrimary From\tPrimary To\tStrand\tPercent Identity\n");
 
9037
  for (salp_tmp = salp; salp_tmp != NULL; salp_tmp = salp_tmp->next) {
 
9038
    interval = AssemblyAlignmentIntervalFromSeqAlign (salp_tmp);
 
9039
    fprintf (lip->fp, "%s\t%d\t%d\t%d\t%d\t%s\t%d%s\n",
 
9040
             interval->prim_accession,
 
9041
             interval->tpa_from,
 
9042
             interval->tpa_to,
 
9043
             interval->prim_from,
 
9044
             interval->prim_from + interval->tpa_to - interval->tpa_from,
 
9045
             interval->prim_strand == Seq_strand_minus ? "c" : "",
 
9046
             interval->percent_identity,
 
9047
             interval->percent_identity < 75 ? "(Suspiciously low percent identity!)" : "");
 
9048
    if (interval->percent_identity < 75) {
 
9049
      lip->data_in_log = TRUE;
 
9050
    }
 
9051
    interval = AssemblyAlignmentIntervalFree (interval);
 
9052
  }
 
9053
  fprintf (lip->fp, "\n");
 
9054
  CheckCoverageWithAddedIntervals (lip, bsp, salp);
 
9055
  CloseLog (lip);
 
9056
  has_errors = lip->data_in_log;
 
9057
  return has_errors;
 
9058
}
 
9059
 
 
9060
 
 
9061
static void AcceptAssemblyAlignment (ButtoN b)
 
9062
{
 
9063
  AssemblyAlignmentFormPtr frm;
 
9064
  SeqAlignPtr              salp, salp_next;
 
9065
  ValNodePtr               list;
 
9066
  MsgAnswer                ans = ANS_OK;
 
9067
 
 
9068
  frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
 
9069
  if (frm == NULL) {
 
9070
    return;
 
9071
  }
 
9072
  salp = DialogToPointer (frm->dlg);
 
9073
  if (salp == NULL) {
 
9074
    Message (MSG_ERROR, "No intervals specified");
 
9075
    return;
 
9076
  }
 
9077
  AddTPAIdToAlignmentList (salp, frm->bsp);
 
9078
  if (ReportAssemblyIntervalProblems (frm->bsp, salp)) {
 
9079
    ans = Message (MSG_OKC, "Continue with errors?");
 
9080
  }
 
9081
 
 
9082
  if (ans == ANS_OK) {
 
9083
    if (frm->bsp->hist == NULL) {
 
9084
      frm->bsp->hist = SeqHistNew ();
 
9085
    }
 
9086
 
 
9087
    /* something is wrong here, alignment is not being sorted */
 
9088
    salp_next = salp;
 
9089
    while (salp_next->next != NULL) {
 
9090
      salp_next = salp_next->next;
 
9091
    }
 
9092
    salp_next->next = frm->bsp->hist->assembly;
 
9093
 
 
9094
    list = SeqAlignSortListNew (salp);
 
9095
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
9096
    salp = SeqAlignFromSeqAlignSortList (list);
 
9097
    list = SeqAlignSortListFree (list);
 
9098
    frm->bsp->hist->assembly = salp;
 
9099
    ObjMgrSetDirtyFlag (frm->bsp->idx.entityID, TRUE);
 
9100
    ObjMgrSendMsg (OM_MSG_UPDATE, frm->bsp->idx.entityID, 0, 0);
 
9101
    Remove (frm->form);
 
9102
  } else {
 
9103
    while (salp != NULL) {
 
9104
      salp_next = salp->next;
 
9105
      salp->next = NULL;
 
9106
      salp = SeqAlignFree (salp);
 
9107
      salp = salp_next;
 
9108
    }
 
9109
  }
 
9110
}
 
9111
 
 
9112
 
 
9113
static void CheckAssemblyAlignment (ButtoN b)
 
9114
{
 
9115
  AssemblyAlignmentFormPtr frm;
 
9116
  SeqAlignPtr              salp, salp_next;
 
9117
 
 
9118
  frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
 
9119
  if (frm == NULL) {
 
9120
    return;
 
9121
  }
 
9122
 
 
9123
  salp = DialogToPointer (frm->dlg);
 
9124
  if (salp == NULL) {
 
9125
    Message (MSG_ERROR, "No intervals specified");
 
9126
    return;
 
9127
  }
 
9128
  AddTPAIdToAlignmentList (salp, frm->bsp);
 
9129
  PointerToDialog (frm->dlg, salp);
 
9130
  ReportAssemblyIntervalProblems (frm->bsp, salp);
 
9131
  
 
9132
  while (salp != NULL) {
 
9133
    salp_next = salp->next;
 
9134
    salp->next = NULL;
 
9135
    salp = SeqAlignFree (salp);
 
9136
    salp = salp_next;
 
9137
  }
 
9138
}
 
9139
 
 
9140
 
 
9141
extern void AdvancedAssemblyAlignmentEditor (IteM i)
 
9142
{
 
9143
  BaseFormPtr        bfp;
 
9144
  BioseqPtr   bsp;
 
9145
  WindoW      w;
 
9146
  GrouP       h, c;
 
9147
  AssemblyAlignmentFormPtr frm;
 
9148
  ButtoN                   b;
 
9149
 
 
9150
#ifdef WIN_MAC
 
9151
  bfp = currentFormDataPtr;
 
9152
#else
 
9153
  bfp = GetObjectExtra (i);
 
9154
#endif
 
9155
  if (bfp == NULL) return;
 
9156
 
 
9157
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
9158
  if (bsp == NULL) {
 
9159
    Message (MSG_ERROR, "Must select single Bioseq!");
 
9160
    return;
 
9161
  }
 
9162
 
 
9163
  frm = (AssemblyAlignmentFormPtr) MemNew (sizeof (AssemblyAlignmentFormData));
 
9164
  frm->bsp = bsp;
 
9165
 
 
9166
  w = FixedWindow (-50, -33, -10, -10, "Add Intervals to Assembly Alignment", StdCloseWindowProc);
 
9167
  SetObjectExtra (w, frm, StdCleanupExtraProc);
 
9168
  frm->form = (ForM) w;
 
9169
 
 
9170
  h = HiddenGroup (w, -1, 0, NULL);
 
9171
  SetGroupSpacing (h, 10, 10);
 
9172
 
 
9173
  frm->dlg = CreateAssemblyAlignmentDialog(h);
 
9174
 
 
9175
  c = HiddenGroup (h, 3, 0, NULL);
 
9176
  b = PushButton (c, "Accept", AcceptAssemblyAlignment);
 
9177
  SetObjectExtra (b, frm, NULL);
 
9178
  b = PushButton (c, "Check", CheckAssemblyAlignment);
 
9179
  SetObjectExtra (b, frm, NULL);
 
9180
  b = PushButton (c, "Cancel", StdCancelButtonProc);
 
9181
 
 
9182
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
 
9183
 
 
9184
  Show (w);
 
9185
  Update ();
 
9186
}
 
9187
 
 
9188
typedef enum {
 
9189
  eAssemblyIntervalInfo_NoAction = 0,
 
9190
  eAssemblyIntervalInfo_Remove,
 
9191
  eAssemblyIntervalInfo_Truncate_Left,
 
9192
  eAssemblyIntervalInfo_Truncate_Right,
 
9193
  eAssemblyIntervalInfo_Truncate_Both
 
9194
} EAssemblyIntervalInfoAction;
 
9195
 
 
9196
 
 
9197
typedef struct assemblyintervalinfo {
 
9198
  SeqAlignPtr salp;
 
9199
  Int4        prim_left;
 
9200
  Int4        prim_right;
 
9201
  Uint1       prim_strand;
 
9202
  Int4        tpa_left;
 
9203
  Int4        tpa_right;
 
9204
  CharPtr     prim_id;
 
9205
  ValNodePtr  conflict_list;
 
9206
  EAssemblyIntervalInfoAction action;
 
9207
} AssemblyIntervalInfoData, PNTR AssemblyIntervalInfoPtr;
 
9208
 
 
9209
typedef enum {
 
9210
  eIntervalConflict_none,
 
9211
  eIntervalConflict_a_contains_b,
 
9212
  eIntervalConflict_a_contained_in_b,
 
9213
  eIntervalConflict_a_overlaps_b_on_5,
 
9214
  eIntervalConflict_a_overlaps_b_on_3
 
9215
} EIntervalConflict;
 
9216
 
 
9217
 
 
9218
static Int4 FindIntervalConflict (Int4 left1, Int4 right1, Int4 left2, Int4 right2, Int4 overlap)
 
9219
{
 
9220
  if (right1 < left2 + overlap || left1 > right2 - overlap) {
 
9221
    return eIntervalConflict_none;
 
9222
  } else if (left1 <= left2 && right1 < right2 && right1 - left2  + 1> overlap) {
 
9223
    return eIntervalConflict_a_overlaps_b_on_5;
 
9224
  } else if (left1 > left2 && right1 >= right2 && right2 - left1  + 1> overlap) {
 
9225
    return eIntervalConflict_a_overlaps_b_on_3;
 
9226
  } else if (left1 <= left2 && right1 >= right2) {
 
9227
    return eIntervalConflict_a_contains_b;
 
9228
  } else if (left2 <= left1 && right2 >= right2) {
 
9229
    return eIntervalConflict_a_contained_in_b;
 
9230
  } else {
 
9231
    Message (MSG_ERROR, "Conflict calculation failed");
 
9232
    return eIntervalConflict_none;
 
9233
  }
 
9234
}
 
9235
 
 
9236
 
 
9237
 
 
9238
typedef struct intervalconflictinfo {
 
9239
  AssemblyIntervalInfoPtr conflict_interval;
 
9240
  EIntervalConflict prim_conflict;
 
9241
  EIntervalConflict tpa_conflict;
 
9242
} IntervalConflictInfoData, PNTR IntervalConflictInfoPtr;
 
9243
 
 
9244
 
 
9245
static IntervalConflictInfoPtr IntervalConflictInfoNew (AssemblyIntervalInfoPtr conflict_interval, EIntervalConflict prim_conflict, EIntervalConflict tpa_conflict)
 
9246
{
 
9247
  IntervalConflictInfoPtr ip;
 
9248
 
 
9249
  ip = (IntervalConflictInfoPtr) MemNew (sizeof (IntervalConflictInfoData));
 
9250
  ip->conflict_interval = conflict_interval;
 
9251
  ip->prim_conflict = prim_conflict;
 
9252
  ip->tpa_conflict = tpa_conflict;
 
9253
  return ip;
 
9254
}
 
9255
 
 
9256
 
 
9257
static IntervalConflictInfoPtr IntervalConflictInfoFree (IntervalConflictInfoPtr ip)
 
9258
{
 
9259
  if (ip != NULL) {
 
9260
    ip = MemFree (ip);
 
9261
  }
 
9262
  return ip;
 
9263
}
 
9264
 
 
9265
 
 
9266
static ValNodePtr IntervalConflictInfoListFree (ValNodePtr vnp)
 
9267
{
 
9268
  ValNodePtr vnp_next;
 
9269
 
 
9270
  while (vnp != NULL) {
 
9271
    vnp_next = vnp->next;
 
9272
    vnp->data.ptrvalue = IntervalConflictInfoFree (vnp->data.ptrvalue);
 
9273
    vnp->next = NULL;
 
9274
    vnp = ValNodeFree (vnp);
 
9275
    vnp = vnp_next;
 
9276
  }
 
9277
  return vnp;
 
9278
}
 
9279
 
 
9280
 
 
9281
static AssemblyIntervalInfoPtr AssemblyIntervalInfoFree (AssemblyIntervalInfoPtr ip)
 
9282
{
 
9283
  if (ip != NULL) {
 
9284
    ip->prim_id = MemFree (ip->prim_id);
 
9285
    ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
 
9286
    ip = MemFree (ip);
 
9287
  }
 
9288
  return ip;
 
9289
}
 
9290
 
 
9291
 
 
9292
static ValNodePtr AssemblyIntervalInfoListFree (ValNodePtr vnp)
 
9293
{
 
9294
  ValNodePtr vnp_next;
 
9295
 
 
9296
  while (vnp != NULL) {
 
9297
    vnp_next = vnp->next;
 
9298
    vnp->data.ptrvalue = AssemblyIntervalInfoFree (vnp->data.ptrvalue);
 
9299
    vnp->next = NULL;
 
9300
    vnp = ValNodeFree (vnp);
 
9301
    vnp = vnp_next;
 
9302
  }
 
9303
  return vnp;
 
9304
}
 
9305
 
 
9306
 
 
9307
static void TruncateForConflictsOnLeft (AssemblyIntervalInfoPtr ai)
 
9308
{
 
9309
  IntervalConflictInfoPtr ip;
 
9310
  ValNodePtr vnp;
 
9311
  Int4       prim_change, tpa_change;
 
9312
 
 
9313
  if (ai == NULL || ai->conflict_list == NULL) {
 
9314
    return;
 
9315
  }
 
9316
 
 
9317
  for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9318
    if (vnp->choice == 1) {
 
9319
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9320
      prim_change = 0;
 
9321
      tpa_change = 0;
 
9322
      if (ip->tpa_conflict == eIntervalConflict_a_overlaps_b_on_5) {
 
9323
        tpa_change = ip->conflict_interval->tpa_right - ai->tpa_left;
 
9324
        if (tpa_change > 0) {
 
9325
          ai->tpa_left += tpa_change;
 
9326
          if (ai->prim_strand == Seq_strand_minus) {
 
9327
            ai->prim_right -= tpa_change;
 
9328
          } else {
 
9329
            ai->prim_left += tpa_change;
 
9330
          }
 
9331
        }
 
9332
      }
 
9333
      if (ip->prim_conflict == eIntervalConflict_a_overlaps_b_on_5) {
 
9334
        prim_change = ip->conflict_interval->prim_right - ai->prim_left; 
 
9335
        if (prim_change > 0) {
 
9336
          ai->prim_left += prim_change;
 
9337
          if (ai->prim_strand == Seq_strand_minus) {
 
9338
            ai->tpa_right -= prim_change;
 
9339
          } else {
 
9340
            ai->tpa_left += prim_change;
 
9341
          }
 
9342
        }
 
9343
      }
 
9344
      vnp->choice = 0;
 
9345
    }
 
9346
  }
 
9347
}
 
9348
 
 
9349
 
 
9350
static void TruncateForConflictsOnRight (AssemblyIntervalInfoPtr ai)
 
9351
{
 
9352
  IntervalConflictInfoPtr ip;
 
9353
  ValNodePtr vnp;
 
9354
  Int4       prim_change, tpa_change;
 
9355
 
 
9356
  if (ai == NULL || ai->conflict_list == NULL) {
 
9357
    return;
 
9358
  }
 
9359
 
 
9360
  for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9361
    if (vnp->choice == 1) {
 
9362
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9363
      prim_change = 0;
 
9364
      tpa_change = 0;
 
9365
      if (ip->tpa_conflict == eIntervalConflict_a_overlaps_b_on_3) {
 
9366
        tpa_change = ai->tpa_right - ip->conflict_interval->tpa_left;
 
9367
        if (tpa_change > 0) {
 
9368
          ai->tpa_right -= tpa_change;
 
9369
          if (ai->prim_strand == Seq_strand_minus) {
 
9370
            ai->prim_left += tpa_change;
 
9371
          } else {
 
9372
            ai->prim_right -= tpa_change;
 
9373
          }
 
9374
        }
 
9375
      }
 
9376
      if (ip->prim_conflict == eIntervalConflict_a_overlaps_b_on_3) {
 
9377
        prim_change = ai->prim_right - ip->conflict_interval->prim_left; 
 
9378
        if (prim_change > 0) {
 
9379
          ai->prim_right -= prim_change;
 
9380
          if (ai->prim_strand == Seq_strand_minus) {
 
9381
            ai->tpa_left += prim_change;
 
9382
          } else {
 
9383
            ai->tpa_right -= prim_change;
 
9384
          }
 
9385
        }
 
9386
      }
 
9387
      vnp->choice = 0;
 
9388
    }
 
9389
  }
 
9390
}
 
9391
 
 
9392
 
 
9393
static void ReevaluateConflicts (AssemblyIntervalInfoPtr ip, Int4 overlap)
 
9394
{
 
9395
  ValNodePtr vnp;
 
9396
  IntervalConflictInfoPtr cp;
 
9397
 
 
9398
  if (ip == NULL) {
 
9399
    return;
 
9400
  }
 
9401
 
 
9402
  for (vnp = ip->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9403
    cp = vnp->data.ptrvalue;
 
9404
    if (cp->conflict_interval->action == eAssemblyIntervalInfo_Remove) {
 
9405
      vnp->choice = 0;
 
9406
    } else if (FindIntervalConflict (ip->tpa_left, ip->tpa_right, 
 
9407
                                     cp->conflict_interval->tpa_left, cp->conflict_interval->tpa_right, overlap) == eIntervalConflict_none
 
9408
               && FindIntervalConflict (ip->prim_left, ip->prim_right,
 
9409
                                        cp->conflict_interval->tpa_left, cp->conflict_interval->tpa_right, overlap) == eIntervalConflict_none) {
 
9410
      vnp->choice = 0;
 
9411
    } else {
 
9412
      vnp->choice = 1;
 
9413
    }
 
9414
  }
 
9415
}
 
9416
 
 
9417
 
 
9418
static void RecalculateAssemblyIntervalInfoEndpoints (AssemblyIntervalInfoPtr ip, Int4 overlap)
 
9419
{
 
9420
  IntervalConflictInfoPtr cp;
 
9421
  ValNodePtr vnp;
 
9422
 
 
9423
  if (ip == NULL) {
 
9424
    return;
 
9425
  }
 
9426
 
 
9427
  /* calculate endpoints */
 
9428
  AlnMgr2IndexSingleChildSeqAlign (ip->salp);
 
9429
  ip->prim_strand = SeqAlignStrand (ip->salp, 2);
 
9430
  AlnMgr2GetNthSeqRangeInSA (ip->salp, 1, &(ip->tpa_left), &(ip->tpa_right));
 
9431
  AlnMgr2GetNthSeqRangeInSA (ip->salp, 2, &(ip->prim_left), &(ip->prim_right));
 
9432
  
 
9433
  /* apply changes for conflicts and actions */
 
9434
  if (ip->action == eAssemblyIntervalInfo_Truncate_Left) {
 
9435
    TruncateForConflictsOnLeft (ip);
 
9436
  } else if (ip->action == eAssemblyIntervalInfo_Truncate_Right) {
 
9437
    TruncateForConflictsOnRight (ip);
 
9438
  } else if (ip->action == eAssemblyIntervalInfo_Truncate_Both) {
 
9439
    TruncateForConflictsOnLeft (ip);
 
9440
    TruncateForConflictsOnRight (ip);
 
9441
  } 
 
9442
 
 
9443
  ReevaluateConflicts (ip, overlap);
 
9444
  for (vnp = ip->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9445
    cp = vnp->data.ptrvalue;
 
9446
    ReevaluateConflicts (cp->conflict_interval, overlap);
 
9447
  }
 
9448
}
 
9449
 
 
9450
 
 
9451
static AssemblyIntervalInfoPtr AssemblyIntervalInfoNew (SeqAlignPtr salp, Int4 overlap)
 
9452
{
 
9453
  AssemblyIntervalInfoPtr ip;
 
9454
  Char        id_txt[255];
 
9455
  SeqIdPtr    sip;
 
9456
  BioseqPtr   bsp;
 
9457
 
 
9458
  if (salp == NULL) {
 
9459
    return NULL;
 
9460
  }
 
9461
 
 
9462
  ip = (AssemblyIntervalInfoPtr) MemNew (sizeof (AssemblyIntervalInfoData));
 
9463
  ip->salp = salp;
 
9464
  AlnMgr2IndexSingleChildSeqAlign (ip->salp);
 
9465
 
 
9466
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
9467
  bsp = BioseqLockById (sip);
 
9468
  if (bsp != NULL) {
 
9469
    sip = SeqIdFree (sip);
 
9470
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
9471
    BioseqUnlock (bsp);
 
9472
  }
 
9473
 
 
9474
  SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
9475
  sip = SeqIdFree (sip);
 
9476
 
 
9477
  ip->prim_id = StringSave (id_txt);
 
9478
  RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
9479
  return ip;
 
9480
}
 
9481
 
 
9482
 
 
9483
static CharPtr SummarizeAssemblyInterval (AssemblyIntervalInfoPtr ip)
 
9484
{
 
9485
  CharPtr summary = NULL;
 
9486
  CharPtr fmt = "%d-%d %s %d-%d%s";
 
9487
  Int4    len;
 
9488
 
 
9489
  if (ip == NULL) {
 
9490
    return NULL;
 
9491
  }
 
9492
 
 
9493
  len = StringLen (fmt) + StringLen (ip->prim_id) + 60;
 
9494
  if (ip->prim_strand == Seq_strand_minus) {
 
9495
    len += 3;
 
9496
  }
 
9497
  summary = (CharPtr) MemNew (sizeof (Char) + len);
 
9498
  sprintf (summary, fmt, ip->tpa_left + 1, ip->tpa_right + 1,
 
9499
                         ip->prim_id, 
 
9500
                         ip->prim_left + 1, ip->prim_right + 1,
 
9501
                         ip->prim_strand == Seq_strand_minus ? "(c)" : "");
 
9502
  return summary;
 
9503
}
 
9504
 
 
9505
 
 
9506
static CharPtr SummarizeConflictList (ValNodePtr list)
 
9507
{
 
9508
  CharPtr summary = NULL, str, conflict = "Conflict with ";
 
9509
  ValNodePtr vnp, strings = NULL;
 
9510
  IntervalConflictInfoPtr ip;
 
9511
  Int4 len = 0;
 
9512
 
 
9513
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
9514
    if (vnp->choice == 1 && vnp->data.ptrvalue != NULL) {
 
9515
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9516
      str = SummarizeAssemblyInterval (ip->conflict_interval);
 
9517
      ValNodeAddPointer (&strings, 0, str);
 
9518
      len += StringLen (str) + 3;
 
9519
    }
 
9520
  }
 
9521
  if (strings == NULL) {
 
9522
    summary = StringSave ("No conflicts");
 
9523
  } else {
 
9524
    summary = (CharPtr) MemNew (sizeof (Char) * (StringLen (conflict) + len));
 
9525
    StringCpy (summary, conflict);
 
9526
    for (vnp = strings; vnp != NULL; vnp = vnp->next) {
 
9527
      StringCat (summary, vnp->data.ptrvalue);
 
9528
      if (vnp->next != NULL) {
 
9529
        StringCat (summary, ", ");
 
9530
      }
 
9531
    }
 
9532
    strings = ValNodeFreeData (strings);
 
9533
  }
 
9534
  return summary;
 
9535
}
 
9536
 
 
9537
 
 
9538
static void RemoveConflictLists (ValNodePtr list)
 
9539
{
 
9540
  AssemblyIntervalInfoPtr ip;
 
9541
 
 
9542
  while (list != NULL) {
 
9543
    ip = (AssemblyIntervalInfoPtr) list->data.ptrvalue;
 
9544
    ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
 
9545
    list = list->next;
 
9546
  }
 
9547
}
 
9548
 
 
9549
 
 
9550
static void BuildConflictLists (ValNodePtr list, Int4 overlap)
 
9551
{
 
9552
  ValNodePtr vnp1, vnp2;
 
9553
  AssemblyIntervalInfoPtr ip1, ip2;
 
9554
  EIntervalConflict prim_conflict, tpa_conflict;
 
9555
  IntervalConflictInfoPtr conflict;
 
9556
 
 
9557
  if (list == NULL || list->next == NULL) {
 
9558
    return;
 
9559
  }
 
9560
 
 
9561
  RemoveConflictLists (list);
 
9562
 
 
9563
  for (vnp1 = list; vnp1->next != NULL; vnp1 = vnp1->next) {
 
9564
    ip1 = (AssemblyIntervalInfoPtr) vnp1->data.ptrvalue;
 
9565
    for (vnp2 = vnp1->next; vnp2 != NULL; vnp2 = vnp2->next) {
 
9566
      ip2 = (AssemblyIntervalInfoPtr) vnp2->data.ptrvalue;
 
9567
      if (StringCmp (ip1->prim_id, ip2->prim_id) == 0) {
 
9568
        tpa_conflict = FindIntervalConflict (ip1->tpa_left, ip1->tpa_right, ip2->tpa_left, ip2->tpa_right, overlap);
 
9569
        prim_conflict = FindIntervalConflict (ip1->prim_left, ip1->prim_right, ip2->prim_left, ip2->prim_right, overlap);
 
9570
        if (tpa_conflict != eIntervalConflict_none || prim_conflict != prim_conflict) {
 
9571
          conflict = IntervalConflictInfoNew (ip2, prim_conflict, tpa_conflict);
 
9572
          ValNodeAddPointer (&(ip1->conflict_list), 1, conflict);
 
9573
        }
 
9574
        tpa_conflict = FindIntervalConflict (ip2->tpa_left, ip2->tpa_right, ip1->tpa_left, ip1->tpa_right, overlap);
 
9575
        prim_conflict = FindIntervalConflict (ip2->prim_left, ip2->prim_right, ip1->prim_left, ip1->prim_right, overlap);
 
9576
        if (tpa_conflict != eIntervalConflict_none || prim_conflict != prim_conflict) {
 
9577
          conflict = IntervalConflictInfoNew (ip1, prim_conflict, tpa_conflict);
 
9578
          ValNodeAddPointer (&(ip2->conflict_list), 1, conflict);
 
9579
        }
 
9580
      }
 
9581
    }
 
9582
  }
 
9583
}
 
9584
 
 
9585
 
 
9586
static ValNodePtr AssemblyIntervalInfoListFromSeqAlign (SeqAlignPtr salp, Int4 overlap)
 
9587
{
 
9588
  ValNodePtr list = NULL;
 
9589
 
 
9590
  while (salp != NULL) {
 
9591
    ValNodeAddPointer (&list, 0, AssemblyIntervalInfoNew (salp, overlap));
 
9592
    salp = salp->next;
 
9593
  }
 
9594
 
 
9595
  BuildConflictLists (list, overlap);
 
9596
  return list;
 
9597
}
 
9598
 
 
9599
 
 
9600
typedef struct assemblyalignmentintervalresolutiondlg {
 
9601
  DIALOG_MESSAGE_BLOCK
 
9602
  DialoG intervals_dialog;
 
9603
  TexT   overlap;
 
9604
  ValNodePtr list;
 
9605
} AssemblyAlignmentIntervalResolutionDlgData, PNTR AssemblyAlignmentIntervalResolutionDlgPtr;
 
9606
 
 
9607
CharPtr assmbly_aln_int_res_labels [] = {
 
9608
  "Action",
 
9609
  "Alignment",
 
9610
  "Conflicts With" };
 
9611
 
 
9612
Uint2 assmbly_aln_int_res_types [] = {
 
9613
  TAGLIST_POPUP, TAGLIST_PROMPT, TAGLIST_PROMPT
 
9614
};
 
9615
 
 
9616
Uint2 assmbly_aln_int_res_widths [] = {
 
9617
  10, 15, 30, 0
 
9618
};
 
9619
 
 
9620
ENUM_ALIST(assmbly_aln_int_res_action_alist)
 
9621
  {"No change",  eAssemblyIntervalInfo_NoAction},
 
9622
  {"Remove",     eAssemblyIntervalInfo_Remove},
 
9623
  {"Truncate Left", eAssemblyIntervalInfo_Truncate_Left},
 
9624
  {"Truncate Right", eAssemblyIntervalInfo_Truncate_Right},
 
9625
  {"Truncate Both", eAssemblyIntervalInfo_Truncate_Both},
 
9626
END_ENUM_ALIST
 
9627
 
 
9628
 
 
9629
static EnumFieldAssocPtr assmbly_aln_int_res_alists[] = {
 
9630
  assmbly_aln_int_res_action_alist, NULL, NULL
 
9631
};
 
9632
 
 
9633
 
 
9634
static CharPtr SummarizeOneIntervalResolutionRow (AssemblyIntervalInfoPtr ip) 
 
9635
{
 
9636
  CharPtr str, int_str, conf_str, fmt = "%d\t%s\t%s\n";
 
9637
 
 
9638
  if (ip == NULL) {
 
9639
    return NULL;
 
9640
  }
 
9641
 
 
9642
  int_str = SummarizeAssemblyInterval (ip);
 
9643
  conf_str = SummarizeConflictList (ip->conflict_list);
 
9644
  str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + 15 + StringLen (int_str) + StringLen (conf_str)));
 
9645
  sprintf (str, fmt, ip->action, int_str, conf_str);
 
9646
  int_str = MemFree (int_str);
 
9647
  conf_str = MemFree (conf_str);
 
9648
 
 
9649
  return str;
 
9650
}
 
9651
 
 
9652
static void UpdateConflicts (Pointer userdata)
 
9653
{
 
9654
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9655
  AssemblyIntervalInfoPtr ip;
 
9656
  TagListPtr tlp;
 
9657
  ValNodePtr vnp, vnp_t;
 
9658
  Int4 action;
 
9659
  Boolean any_change = FALSE;
 
9660
  CharPtr str;
 
9661
  Int4    overlap = 0;
 
9662
  
 
9663
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) userdata;
 
9664
  
 
9665
  if (dlg == NULL) {
 
9666
    return;
 
9667
  }
 
9668
 
 
9669
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
9670
  if (tlp == NULL) {
 
9671
    return;
 
9672
  }
 
9673
 
 
9674
  if (!TextHasNoText (dlg->overlap)) {
 
9675
    str = SaveStringFromText (dlg->overlap);
 
9676
    overlap = atoi (str);
 
9677
    str = MemFree (str);
 
9678
    if (overlap < 0) {
 
9679
      overlap = 0;
 
9680
    }
 
9681
  }
 
9682
 
 
9683
  /* now update conflict lists */
 
9684
  for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
9685
    ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
9686
    str = ExtractTagListColumn ((CharPtr) vnp_t->data.ptrvalue, 0);
 
9687
    action = atoi (str);
 
9688
    str = MemFree (str);
 
9689
    if (action != ip->action) {
 
9690
      ip->action = action;
 
9691
      RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
9692
      any_change = TRUE;
 
9693
    }
 
9694
  }
 
9695
 
 
9696
  if (any_change) {
 
9697
    for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
9698
      ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
9699
      vnp_t->data.ptrvalue = MemFree (vnp_t->data.ptrvalue);
 
9700
      vnp_t->data.ptrvalue = SummarizeOneIntervalResolutionRow (ip);
 
9701
    }
 
9702
    
 
9703
    /* update dialog */
 
9704
    SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9705
    SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
9706
  }
 
9707
}  
 
9708
 
 
9709
static TaglistCallback assmbly_int_res_callback_list[3] = 
 
9710
 { UpdateConflicts, UpdateConflicts, UpdateConflicts };
 
9711
 
 
9712
static void SeqAlignToAssemblyAlignmentIntervalResolutionDialog (DialoG d, Pointer data)
 
9713
{
 
9714
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9715
  SeqAlignPtr salp;
 
9716
  ValNodePtr  vnp;
 
9717
  CharPtr     str;
 
9718
  Int4        overlap = 0;
 
9719
  TagListPtr  tlp;
 
9720
 
 
9721
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
 
9722
  salp = (SeqAlignPtr) data;
 
9723
  if (dlg == NULL) {
 
9724
    return;
 
9725
  }
 
9726
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
9727
  if (tlp == NULL) {
 
9728
    return;
 
9729
  }
 
9730
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
9731
  tlp->vnp = ValNodeFreeData (tlp->vnp);
 
9732
 
 
9733
  if (!TextHasNoText (dlg->overlap)) {
 
9734
    str = SaveStringFromText (dlg->overlap);
 
9735
    overlap = atoi (str);
 
9736
    str = MemFree (str);
 
9737
    if (overlap < 0) {
 
9738
      overlap = 0;
 
9739
    }
 
9740
  }
 
9741
 
 
9742
  dlg->list = AssemblyIntervalInfoListFree (dlg->list);
 
9743
  dlg->list = AssemblyIntervalInfoListFromSeqAlign (salp, overlap);
 
9744
 
 
9745
  for (vnp = dlg->list; vnp != NULL; vnp = vnp->next) {
 
9746
    str = SummarizeOneIntervalResolutionRow (vnp->data.ptrvalue);
 
9747
    ValNodeAddPointer (&(tlp->vnp), 0, str);
 
9748
  }
 
9749
 
 
9750
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9751
  tlp->max = MAX ((Int2) 0, (Int2) (ValNodeLen (tlp->vnp) - tlp->rows));
 
9752
  CorrectBarMax (tlp->bar, tlp->max);
 
9753
  CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
 
9754
  if (tlp->max > 0) {
 
9755
    SafeShow (tlp->bar);
 
9756
  } else {
 
9757
    SafeHide (tlp->bar);
 
9758
  }
 
9759
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
9760
 
 
9761
}
 
9762
 
 
9763
 
 
9764
static Pointer AssemblyAlignmentIntervalResolutionDialogToSeqAlign (DialoG d)
 
9765
{
 
9766
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9767
  AssemblyIntervalInfoPtr ai;
 
9768
  SeqAlignPtr salp_list = NULL, salp_prev = NULL, salp;
 
9769
  ValNodePtr vnp;
 
9770
 
 
9771
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
 
9772
  if (dlg == NULL) {
 
9773
    return NULL;
 
9774
  }
 
9775
 
 
9776
  for (vnp = dlg->list; vnp != NULL; vnp = vnp->next) {
 
9777
    ai = vnp->data.ptrvalue;
 
9778
    if (ai->action != eAssemblyIntervalInfo_Remove) {
 
9779
      salp = (SeqAlignPtr) AsnIoMemCopy (ai->salp, (AsnReadFunc) SeqAlignAsnRead, (AsnWriteFunc) SeqAlignAsnWrite);
 
9780
      /* TODO: truncate alignments */
 
9781
 
 
9782
      /* add to list */
 
9783
      if (salp_prev == NULL) {
 
9784
        salp_list = salp;
 
9785
      } else {
 
9786
        salp_prev->next = salp;
 
9787
      }
 
9788
      salp_prev = salp;
 
9789
    }
 
9790
  }
 
9791
 
 
9792
  return (Pointer) salp_list;
 
9793
}
 
9794
 
 
9795
 
 
9796
static void ChangeAssemblyAlignmentIntervalResolutionOverlap (TexT t)
 
9797
{
 
9798
  AssemblyAlignmentIntervalResolutionDlgPtr  dlg;
 
9799
  AssemblyIntervalInfoPtr ip;
 
9800
  TagListPtr tlp;
 
9801
  ValNodePtr vnp, vnp_t;
 
9802
  CharPtr    str;
 
9803
  Int4       overlap = 0;
 
9804
 
 
9805
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (t);
 
9806
  if (dlg == NULL) {
 
9807
    return;
 
9808
  }
 
9809
 
 
9810
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
9811
  if (tlp == NULL) {
 
9812
    return;
 
9813
  }
 
9814
 
 
9815
  if (!TextHasNoText (dlg->overlap)) {
 
9816
    str = SaveStringFromText (dlg->overlap);
 
9817
    overlap = atoi (str);
 
9818
    str = MemFree (str);
 
9819
    if (overlap < 0) {
 
9820
      overlap = 0;
 
9821
    }
 
9822
  }
 
9823
 
 
9824
  BuildConflictLists (dlg->list, overlap);
 
9825
 
 
9826
  /* change text */
 
9827
  for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
9828
    ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
9829
    RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
9830
    vnp_t->data.ptrvalue = MemFree (vnp_t->data.ptrvalue);
 
9831
    vnp_t->data.ptrvalue = SummarizeOneIntervalResolutionRow (ip);
 
9832
  }
 
9833
  
 
9834
  /* update dialog */
 
9835
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9836
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
9837
 
 
9838
}
 
9839
 
 
9840
 
 
9841
static void CleanupAssemblyAlignmentIntervalResolutionDialog (GraphiC g, VoidPtr data)
 
9842
 
 
9843
{
 
9844
  AssemblyAlignmentIntervalResolutionDlgPtr  dlg;
 
9845
 
 
9846
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) data;
 
9847
  if (dlg != NULL) {
 
9848
    dlg->list =  AssemblyIntervalInfoListFree (dlg->list);
 
9849
    dlg = MemFree (dlg);
 
9850
  }
 
9851
}
 
9852
 
 
9853
 
 
9854
static DialoG CreateAssemblyAlignmentIntervalResolutionDialog (GrouP g)
 
9855
 
 
9856
{
 
9857
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9858
  GrouP                   p;
 
9859
  GrouP                   x, y, z;
 
9860
  Int4                    i;
 
9861
  Int4                    num_columns = sizeof (assmbly_aln_int_res_labels) / sizeof (CharPtr);
 
9862
 
 
9863
  p = HiddenGroup (g, -1, 0, NULL);
 
9864
  SetGroupSpacing (p, 10, 10);
 
9865
 
 
9866
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionDlgData));
 
9867
  if (dlg == NULL) return NULL;
 
9868
 
 
9869
  SetObjectExtra (p, dlg, CleanupAssemblyAlignmentIntervalResolutionDialog);
 
9870
  dlg->dialog = (DialoG) p;
 
9871
  
 
9872
  dlg->todialog = SeqAlignToAssemblyAlignmentIntervalResolutionDialog;
 
9873
  dlg->fromdialog = AssemblyAlignmentIntervalResolutionDialogToSeqAlign;
 
9874
 
 
9875
  z = HiddenGroup (p, 2, 0, NULL);
 
9876
  StaticPrompt (z, "Allowable Overlap", 0, 0, programFont, 'r');
 
9877
  dlg->overlap = DialogText (z, "5", 5, ChangeAssemblyAlignmentIntervalResolutionOverlap);
 
9878
  SetObjectExtra (dlg->overlap, dlg, NULL);
 
9879
 
 
9880
  x = HiddenGroup (p, 0, 2, NULL);
 
9881
  y = HiddenGroup (x, num_columns, 0, NULL);
 
9882
  for (i = 0; i < num_columns; i++) {
 
9883
      StaticPrompt (y, assmbly_aln_int_res_labels[i], assmbly_aln_int_res_widths[i] * stdCharWidth, 0, programFont, 'l');
 
9884
  }
 
9885
  dlg->intervals_dialog = CreateTagListDialogExEx (x, 6, num_columns, -1, assmbly_aln_int_res_types, 
 
9886
                                                   assmbly_aln_int_res_widths, assmbly_aln_int_res_alists,
 
9887
                                                   TRUE, TRUE, NULL, NULL,
 
9888
                                                   assmbly_int_res_callback_list, dlg, FALSE);
 
9889
 
 
9890
  AlignObjects (ALIGN_CENTER, (HANDLE) z, (HANDLE) x, NULL);
 
9891
  return (DialoG) p;
 
9892
}
 
9893
 
 
9894
 
 
9895
typedef struct assemblyalignmentintervalresolutionfrm {
 
9896
  FORM_MESSAGE_BLOCK
 
9897
  DialoG dlg;
 
9898
 
 
9899
  BioseqPtr bsp;
 
9900
} AssemblyAlignmentIntervalResolutionFrmData, PNTR AssemblyAlignmentIntervalResolutionFrmPtr;
 
9901
 
 
9902
 
 
9903
static void AcceptAssemblyAlignmentIntervalResolution (ButtoN b)
 
9904
{
 
9905
  AssemblyAlignmentIntervalResolutionFrmPtr frm;
 
9906
  SeqAlignPtr new_assem, salp, salp_next;
 
9907
 
 
9908
  frm = (AssemblyAlignmentIntervalResolutionFrmPtr) GetObjectExtra (b);
 
9909
  if (frm == NULL) {
 
9910
    return;
 
9911
  }
 
9912
 
 
9913
  /* TODO: check for problems before accepting */
 
9914
 
 
9915
  new_assem = DialogToPointer (frm->dlg);
 
9916
  if (new_assem == NULL) {
 
9917
    Message (MSG_ERROR, "No intervals left in assembly!");
 
9918
    return;
 
9919
  }
 
9920
 
 
9921
  /* remove old assembly */
 
9922
  salp = frm->bsp->hist->assembly;
 
9923
  frm->bsp->hist->assembly = NULL;
 
9924
  while (salp != NULL) {
 
9925
    salp_next = salp->next;
 
9926
    salp->next = NULL;
 
9927
    salp = SeqAlignFree (salp);
 
9928
    salp = salp_next;
 
9929
  }
 
9930
 
 
9931
  /* assign new assembly */
 
9932
  frm->bsp->hist->assembly = new_assem;
 
9933
 
 
9934
  ObjMgrSetDirtyFlag (frm->bsp->idx.entityID, TRUE);
 
9935
  ObjMgrSendMsg (OM_MSG_UPDATE, frm->bsp->idx.entityID, 0, 0);
 
9936
  Remove (frm->form);
 
9937
}
 
9938
 
 
9939
 
 
9940
extern void AssemblyAlignmentIntervalResolution (IteM i)
 
9941
{
 
9942
  BaseFormPtr        bfp;
 
9943
  BioseqPtr   bsp;
 
9944
  WindoW      w;
 
9945
  GrouP       h, c;
 
9946
  AssemblyAlignmentIntervalResolutionFrmPtr frm;
 
9947
  ButtoN                   b;
 
9948
 
 
9949
#ifdef WIN_MAC
 
9950
  bfp = currentFormDataPtr;
 
9951
#else
 
9952
  bfp = GetObjectExtra (i);
 
9953
#endif
 
9954
  if (bfp == NULL) return;
 
9955
 
 
9956
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
9957
  if (bsp == NULL) {
 
9958
    Message (MSG_ERROR, "Must select single Bioseq!");
 
9959
    return;
 
9960
  }
 
9961
  if (bsp->hist == NULL || bsp->hist->assembly == NULL) {
 
9962
    Message (MSG_ERROR, "No assembly alignment!");
 
9963
    return;
 
9964
  }
 
9965
  frm = (AssemblyAlignmentIntervalResolutionFrmPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionFrmData));
 
9966
  frm->bsp = bsp;
 
9967
 
 
9968
  w = FixedWindow (-50, -33, -10, -10, "Resolve Assembly Alignment Intervals", StdCloseWindowProc);
 
9969
  SetObjectExtra (w, frm, StdCleanupExtraProc);
 
9970
  frm->form = (ForM) w;
 
9971
 
 
9972
  h = HiddenGroup (w, -1, 0, NULL);
 
9973
  SetGroupSpacing (h, 10, 10);
 
9974
 
 
9975
  frm->dlg = CreateAssemblyAlignmentIntervalResolutionDialog(h);
 
9976
  PointerToDialog (frm->dlg, bsp->hist->assembly);
 
9977
 
 
9978
  c = HiddenGroup (h, 3, 0, NULL);
 
9979
  b = PushButton (c, "Accept", AcceptAssemblyAlignmentIntervalResolution);
 
9980
  SetObjectExtra (b, frm, NULL);
 
9981
/*  b = PushButton (c, "Check", CheckAssemblyAlignmentIntervalResolution);
 
9982
  SetObjectExtra (b, frm, NULL); */
 
9983
  b = PushButton (c, "Cancel", StdCancelButtonProc);
 
9984
 
 
9985
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
 
9986
  Show (w);
 
9987
  Update ();
 
9988
}
 
9989
 
 
9990
 
 
9991
 
7702
9992
typedef struct historyformdata {
7703
9993
  FEATURE_FORM_BLOCK
7704
9994
 
8108
10398
  Update ();
8109
10399
}
8110
10400
 
 
10401
 
 
10402
typedef struct nw {
 
10403
  Int4 score;
 
10404
  Int4 traceback_pos;
 
10405
} NWData, PNTR NWPtr;
 
10406
 
 
10407
 
 
10408
static Int4 SegmentsNeededForAlignment (CharPtr buf1, CharPtr buf2)
 
10409
{
 
10410
  CharPtr cp1, cp2;
 
10411
  Boolean gap1, gap2, change = FALSE;
 
10412
  Int4    num_segs = 1;
 
10413
 
 
10414
  cp1 = buf1;
 
10415
  cp2 = buf2;
 
10416
  if (*cp1 == '-') {
 
10417
    gap1 = TRUE;
 
10418
  } else {
 
10419
    gap1 = FALSE;
 
10420
  }
 
10421
  cp1++;
 
10422
  if (*cp2 == '-') {
 
10423
    gap2 = TRUE;
 
10424
  } else {
 
10425
    gap2 = FALSE;
 
10426
  }
 
10427
  cp2++;
 
10428
  while (*cp1 != 0 && *cp2 != 0) {
 
10429
    change = FALSE;
 
10430
    if (*cp1 == '-') {
 
10431
      if (!gap1) {
 
10432
        gap1 = TRUE;
 
10433
        change = TRUE;
 
10434
      }
 
10435
    } else if (gap1) {
 
10436
      gap1 = FALSE;
 
10437
      change = TRUE;
 
10438
    }
 
10439
    if (*cp2 == '-') {
 
10440
      if (!gap2) {
 
10441
        gap2 = TRUE;
 
10442
        change = TRUE;
 
10443
      }
 
10444
    } else if (gap2) {
 
10445
      gap2 = FALSE;
 
10446
      change = TRUE;
 
10447
    }
 
10448
    if (change) {
 
10449
      num_segs ++;
 
10450
    }
 
10451
    cp1++;
 
10452
    cp2++;
 
10453
  }
 
10454
  return num_segs;
 
10455
}
 
10456
 
 
10457
static void 
 
10458
FillInStartsAndLensForAlignment 
 
10459
(DenseSegPtr dsp,
 
10460
 CharPtr     buf1,
 
10461
 CharPtr     buf2)
 
10462
{
 
10463
  CharPtr cp1, cp2;
 
10464
  Boolean gap1, gap2, change = FALSE;
 
10465
  Int4    num_segs = 0;
 
10466
  Int4    pos1 = 0, pos2 = 0;
 
10467
 
 
10468
  cp1 = buf1;
 
10469
  cp2 = buf2;
 
10470
  if (*cp1 == '-') {
 
10471
    dsp->starts[dsp->dim * num_segs] = -1;
 
10472
    gap1 = TRUE;
 
10473
  } else {
 
10474
    dsp->starts[dsp->dim * num_segs] = pos1;
 
10475
    gap1 = FALSE;
 
10476
    pos1++;
 
10477
  }
 
10478
  cp1++;
 
10479
  if (*cp2 == '-') {
 
10480
    gap2 = TRUE;
 
10481
    dsp->starts[dsp->dim * num_segs + 1] = -1;
 
10482
  } else {
 
10483
    dsp->starts[dsp->dim * num_segs + 1] = pos2;
 
10484
    gap2 = FALSE;
 
10485
    pos2++;
 
10486
  }
 
10487
  cp2++;
 
10488
  dsp->lens[num_segs] = 1;
 
10489
 
 
10490
  while (*cp1 != 0 && *cp2 != 0) {
 
10491
    change = FALSE;
 
10492
    if (*cp1 == '-') {
 
10493
      if (!gap1) {
 
10494
        gap1 = TRUE;
 
10495
        change = TRUE;
 
10496
      }
 
10497
    } else {
 
10498
      if (gap1) {
 
10499
        gap1 = FALSE;
 
10500
        change = TRUE;
 
10501
      }
 
10502
    }
 
10503
    if (*cp2 == '-') {
 
10504
      if (!gap2) {
 
10505
        gap2 = TRUE;
 
10506
        change = TRUE;
 
10507
      }
 
10508
    } else {
 
10509
      if (gap2) {
 
10510
        gap2 = FALSE;
 
10511
        change = TRUE;
 
10512
      }
 
10513
    }
 
10514
    if (change) {
 
10515
      num_segs ++;
 
10516
      if (gap1) {
 
10517
        dsp->starts[dsp->dim * num_segs] = -1;
 
10518
      } else {
 
10519
        dsp->starts[dsp->dim * num_segs] = pos1;
 
10520
      }
 
10521
      if (gap2) {
 
10522
        dsp->starts[dsp->dim * num_segs + 1] = -1;
 
10523
      } else {
 
10524
        dsp->starts[dsp->dim * num_segs + 1] = pos2;
 
10525
      }
 
10526
      dsp->lens[num_segs] = 1;
 
10527
    } else {
 
10528
      dsp->lens[num_segs]++;
 
10529
    }
 
10530
    cp1++;
 
10531
    cp2++;
 
10532
    if (!gap1) {
 
10533
      pos1++;
 
10534
    }
 
10535
    if (!gap2) {
 
10536
      pos2++;
 
10537
    }
 
10538
  }
 
10539
}
 
10540
 
 
10541
 
 
10542
static void AdjustStringAlingmentForOffsetAndStrand (DenseSegPtr dsp, Int4 start1, Int4 start2, Int4 stop2, Uint1 strand2)
 
10543
{
 
10544
  Int4 i;
 
10545
 
 
10546
  if (dsp == NULL) {
 
10547
    return;
 
10548
  }
 
10549
 
 
10550
  for (i = 0; i < dsp->numseg; i++) {
 
10551
    if (dsp->starts[2 * i] != -1) {
 
10552
      dsp->starts[2 * i] += start1;
 
10553
    }
 
10554
    if (dsp->starts[2 * i + 1] != -1) {
 
10555
      if (strand2 == Seq_strand_plus) {
 
10556
        dsp->starts[2 * i + 1] += start2;
 
10557
      } else {
 
10558
        dsp->starts[2 * i + 1] = stop2 - dsp->starts[2 * i + 1] - dsp->lens[i];
 
10559
      }
 
10560
    }
 
10561
  }
 
10562
}
 
10563
 
 
10564
 
 
10565
/* assumption - first interval always on plus strand */
 
10566
static SeqAlignPtr NWAlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
 
10567
{
 
10568
  BioseqPtr bsp1, bsp2;
 
10569
  Int4      len1, len2, tmp, i, row, col, back_row, back_col;
 
10570
  Uint1     strand2 = Seq_strand_plus;
 
10571
  CharPtr   buf1, buf2;
 
10572
  CharPtr   alnbuf1, alnbuf2, cp1, cp2;
 
10573
  NWPtr     matrix;
 
10574
  Int4      gap_penalty = -1;
 
10575
  Int4      mismatch_penalty = -1;
 
10576
  Int4      match_score = 1;
 
10577
  Int4      left, up, diag;
 
10578
  Int4      num_segs;
 
10579
  DenseSegPtr dsp;
 
10580
  SeqAlignPtr salp = NULL;
 
10581
 
 
10582
  if (sip1 == NULL || sip2 == NULL) {
 
10583
    return NULL;
 
10584
  }
 
10585
 
 
10586
  bsp1 = BioseqLockById (sip1);
 
10587
  bsp2 = BioseqLockById (sip2);
 
10588
  
 
10589
  if (bsp1 != NULL && bsp2 != NULL) {
 
10590
    if (stop2 < start2) {
 
10591
      strand2 = Seq_strand_minus;
 
10592
      tmp = start2;
 
10593
      start2 = stop2;
 
10594
      stop2 = tmp;
 
10595
    }
 
10596
    len1 = stop1 - start1 + 1;
 
10597
    len2 = stop2 - start2 + 1;
 
10598
    buf1 = MemNew (sizeof (Char) * (len1 + 1));
 
10599
    buf2 = MemNew (sizeof (Char) * (len2 + 1));
 
10600
    SeqPortStreamInt (bsp1, start1, stop1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
10601
    SeqPortStreamInt (bsp2, start2, stop2, strand2, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
10602
 
 
10603
    matrix = (NWPtr) MemNew (sizeof (NWData) * (len1 + 1) * (len2 + 1));
 
10604
    /* initalize matrix */
 
10605
    MemSet (matrix, 0, sizeof (NWData) * (len1 + 1) * (len2 + 1));
 
10606
    matrix[0].score = 0;
 
10607
    matrix[0].traceback_pos = 0;
 
10608
    row = 0;
 
10609
    for (col = 1; col <= len1; col++) {
 
10610
      matrix[(row * (len1  + 1)) + col].score = matrix[(row * (len1  + 1)) + col - 1].score + gap_penalty;
 
10611
      matrix[(row * (len1  + 1)) + col].traceback_pos = (row * (len1  + 1)) + col - 1;
 
10612
    }
 
10613
    col = 0;
 
10614
    for (row = 1; row <= len2; row++) {
 
10615
      matrix[(row * (len1  + 1)) + col].score = matrix[((row - 1) * (len1  + 1)) + col].score + gap_penalty;
 
10616
      matrix[(row * (len1  + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col;
 
10617
    }
 
10618
 
 
10619
    /* fill in scores */
 
10620
    for (row = 1; row <= len2; row++) {
 
10621
      for (col = 1; col <= len1; col++) {
 
10622
        /* diagonal */
 
10623
        diag = matrix[((row - 1) * (len1  + 1)) + col - 1].score;
 
10624
        if (buf1[col - 1] == buf2[row - 1]) {
 
10625
          diag += match_score;
 
10626
        } else {
 
10627
          diag += mismatch_penalty;
 
10628
        }
 
10629
        left = matrix[((row) * (len1  + 1)) + col - 1].score + gap_penalty;
 
10630
        up = matrix[((row - 1) * (len1  + 1)) + col].score + gap_penalty;
 
10631
 
 
10632
        /* choose best */
 
10633
        if (left > diag && left > up) {
 
10634
          matrix[((row) * (len1 + 1)) + col].score = left + gap_penalty;
 
10635
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row) * (len1  + 1)) + col - 1;
 
10636
        } else if (up > diag && up > left) {
 
10637
          matrix[((row) * (len1 + 1)) + col].score = up + gap_penalty;
 
10638
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col;
 
10639
        } else {
 
10640
          matrix[((row) * (len1 + 1)) + col].score = diag;
 
10641
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col - 1;
 
10642
        }
 
10643
        
 
10644
      }
 
10645
    }
 
10646
 
 
10647
    /* trace back, create alignment strings */
 
10648
    alnbuf1 = (CharPtr) MemNew (sizeof (Char) * (len1 + len2 + 1));
 
10649
    alnbuf2 = (CharPtr) MemNew (sizeof (Char) * (len1 + len2 + 1));
 
10650
    cp1 = alnbuf1 + len1 + len2;
 
10651
    cp2 = alnbuf2 + len1 + len2;
 
10652
    *cp1 = 0;
 
10653
    *cp2 = 0;
 
10654
    cp1--;
 
10655
    cp2--;
 
10656
    row = len2;
 
10657
    col = len1;
 
10658
    while (row > 0 || col > 0) {
 
10659
      back_row = matrix[(row * (len1 + 1)) + col].traceback_pos / (len1 + 1);
 
10660
      back_col = matrix[(row * (len1 + 1)) + col].traceback_pos % (len1 + 1);
 
10661
      if (row == back_row) {
 
10662
        *cp1 = buf1[col - 1];
 
10663
        *cp2 = '-';
 
10664
      } else if (col == back_col) {
 
10665
        *cp1 = '-';
 
10666
        *cp2 = buf2[row - 1];
 
10667
      } else {
 
10668
        *cp1 = buf1[col - 1];
 
10669
        *cp2 = buf2[row - 1];
 
10670
      }
 
10671
      cp1--;
 
10672
      cp2--;
 
10673
      row = back_row;
 
10674
      col = back_col;
 
10675
    }
 
10676
 
 
10677
    /* no longer need matrix or original sequence buffers */
 
10678
    matrix = MemFree (matrix);
 
10679
    buf1 = MemFree (buf1);
 
10680
    buf2 = MemFree (buf2);
 
10681
 
 
10682
    /* count number of segments needed */
 
10683
    num_segs = SegmentsNeededForAlignment (cp1 + 1, cp2 + 1);
 
10684
        
 
10685
    /* create DenseSeg */
 
10686
    dsp = DenseSegNew ();
 
10687
    dsp->dim = 2;
 
10688
    dsp->ids = SeqIdDup (sip1);
 
10689
    dsp->ids->next = SeqIdDup (sip2);
 
10690
    dsp->numseg = num_segs;
 
10691
    dsp->lens = (Int4Ptr)MemNew (sizeof (Int4) * dsp->numseg);
 
10692
    dsp->starts = (Int4Ptr)MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
10693
    dsp->strands = (Uint1Ptr)MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
10694
 
 
10695
    /* fill in strands */
 
10696
    for (i = 0; i < dsp->numseg; i++) {
 
10697
      dsp->strands[2 * i] = Seq_strand_plus;
 
10698
      dsp->strands[2 * i + 1] = strand2;
 
10699
    }
 
10700
    /* fill in starts and lens */
 
10701
    FillInStartsAndLensForAlignment (dsp, cp1 + 1, cp2 + 1);
 
10702
 
 
10703
    /* no longer need FASTA+GAP alignment strings */
 
10704
    alnbuf1 = MemFree (alnbuf1);
 
10705
    alnbuf2 = MemFree (alnbuf2);
 
10706
 
 
10707
    /* adjust for real sequence position and strand */
 
10708
    AdjustStringAlingmentForOffsetAndStrand (dsp, start1, start2, stop2, strand2);
 
10709
 
 
10710
    salp = SeqAlignNew ();
 
10711
    salp->segs = dsp;
 
10712
    salp->segtype = SAS_DENSEG;
 
10713
    salp->dim = 2;
 
10714
  }
 
10715
  BioseqUnlock (bsp1);
 
10716
  BioseqUnlock (bsp2);
 
10717
  AlnMgr2IndexSingleChildSeqAlign (salp);  
 
10718
  return salp;
 
10719
}
 
10720
 
 
10721
 
 
10722
/* Assumptions:
 
10723
 * first interval always on plus strand
 
10724
 */
 
10725
static SeqAlignPtr AlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
 
10726
{
 
10727
  DenseSegPtr dsp;
 
10728
  SeqAlignPtr salp = NULL;
 
10729
  Int4        len1, len2, i;
 
10730
  Uint1       strand = Seq_strand_plus;
 
10731
 
 
10732
  if (sip1 == NULL || sip2 == NULL) {
 
10733
    return NULL;
 
10734
  }
 
10735
 
 
10736
  salp = NWAlignmentForInterval(sip1, sip2, start1, stop1, start2, stop2);
 
10737
  if (salp != NULL) {
 
10738
    return salp;
 
10739
  }
 
10740
 
 
10741
  dsp = DenseSegNew ();
 
10742
  dsp->dim = 2;
 
10743
  dsp->ids = SeqIdDup (sip1);
 
10744
  dsp->ids->next = SeqIdDup (sip2);
 
10745
  len1 = stop1 - start1 + 1;
 
10746
 
 
10747
  if (stop2 > start2) {
 
10748
    len2 = stop2 - start2 + 1;
 
10749
  } else {
 
10750
    len2 = start2 - stop2 + 1;
 
10751
    strand = Seq_strand_minus;
 
10752
  }
 
10753
 
 
10754
  if (len1 == len2) {
 
10755
    dsp->numseg = 1;
 
10756
  } else {
 
10757
    dsp->numseg = 2;
 
10758
  }
 
10759
 
 
10760
  dsp->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
10761
  dsp->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
10762
  dsp->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim);
 
10763
  
 
10764
  if (len1 == len2) {
 
10765
    dsp->lens[0] = len1;
 
10766
  } else if (len1 > len2) {
 
10767
    dsp->lens[0] = len2;
 
10768
    dsp->lens[1] = len1 - len2;
 
10769
  } else {
 
10770
    dsp->lens[0] = len1;
 
10771
    dsp->lens[1] = len2 - len1;
 
10772
  }
 
10773
 
 
10774
  dsp->starts[0] = start1;
 
10775
  if (strand == Seq_strand_minus) {
 
10776
    dsp->starts[1] = stop2;
 
10777
  } else {
 
10778
    dsp->starts[1] = start2;
 
10779
  }  
 
10780
 
 
10781
  for (i = 0; i < dsp->numseg; i++) {
 
10782
    dsp->strands[2 * i] = Seq_strand_plus;
 
10783
    dsp->strands[2 * i + 1] = strand;
 
10784
  }
 
10785
 
 
10786
  if (dsp->numseg > 1) {
 
10787
    if (len1 > len2) {
 
10788
      dsp->starts[2] = dsp->starts[0] + dsp->lens[0];
 
10789
      dsp->starts[3] = -1;
 
10790
    } else {
 
10791
      dsp->starts[2] = -1;
 
10792
      if (strand == Seq_strand_minus) {
 
10793
        dsp->starts[3] = dsp->starts[1] + dsp->lens[0] + dsp->lens[1] - 1;
 
10794
      } else {
 
10795
        dsp->starts[3] = dsp->starts[1] + dsp->lens[0];
 
10796
      }
 
10797
    }
 
10798
  }
 
10799
 
 
10800
  salp = SeqAlignNew ();
 
10801
  salp->segtype = SAS_DENSEG;
 
10802
  salp->segs = dsp;
 
10803
  
 
10804
  AlnMgr2IndexSingleChildSeqAlign (salp);  
 
10805
  return salp;
 
10806
}
 
10807
 
 
10808
 
 
10809
static void ReportCreatedAlignment (LogInfoPtr lip, SeqAlignPtr salp)
 
10810
{
 
10811
  Int4        from_1, to_1, from_2, to_2;
 
10812
  Uint1       strand;
 
10813
  Char        id1[255], id2[255];
 
10814
  SeqIdPtr    sip;
 
10815
  BioseqPtr   bsp;
 
10816
 
 
10817
  if (lip == NULL || lip->fp == NULL || salp == NULL) {
 
10818
    return;
 
10819
  }
 
10820
 
 
10821
  sip = AlnMgr2GetNthSeqIdPtr (salp, 1);
 
10822
  bsp = BioseqLockById (sip);
 
10823
  if (bsp != NULL) {
 
10824
    sip = SeqIdFree (sip);
 
10825
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
10826
    BioseqUnlock (bsp);
 
10827
  }
 
10828
 
 
10829
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
10830
  sip = SeqIdFree (sip);
 
10831
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
10832
  bsp = BioseqLockById (sip);
 
10833
  if (bsp != NULL) {
 
10834
    sip = SeqIdFree (sip);
 
10835
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
10836
    BioseqUnlock (bsp);
 
10837
  }
 
10838
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
10839
  sip = SeqIdFree (sip);
 
10840
  
 
10841
  strand = SeqAlignStrand (salp, 2);
 
10842
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &from_1, &to_1);
 
10843
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &from_2, &to_2);
 
10844
  fprintf (lip->fp, "Created alignment to cover space between local alignments: %s:%d-%d, %s:%d-%d%s\n",
 
10845
                     id1, from_1, to_1, id2, from_2, to_2,
 
10846
                     strand == Seq_strand_minus ? "(c)" : "");
 
10847
 
 
10848
  WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
 
10849
}
 
10850
 
 
10851
 
 
10852
static void FillInAlignmentHoles (SeqAlignPtr salp_list, LogInfoPtr lip)
 
10853
{
 
10854
  SeqAlignPtr salp, salp_new;
 
10855
  Int4        start1_this, start1_next;
 
10856
  Int4        stop1_this, stop1_next;
 
10857
  Int4        start2_this, start2_next;
 
10858
  Int4        stop2_this, stop2_next;
 
10859
  Uint1       strand;
 
10860
  SeqIdPtr    sip1, sip2;
 
10861
 
 
10862
  if (salp_list == NULL || salp_list->next == NULL) {
 
10863
    return;
 
10864
  }
 
10865
 
 
10866
  sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
10867
  sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
10868
 
 
10869
  /* note - unlike the other functions, SeqAlignStrand uses 0-based index */
 
10870
  strand = SeqAlignStrand (salp_list, 1);
 
10871
 
 
10872
  salp = salp_list;
 
10873
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &start1_this, &stop1_this);
 
10874
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &start2_this, &stop2_this);
 
10875
  
 
10876
  while (salp->next != NULL) {
 
10877
    AlnMgr2GetNthSeqRangeInSA (salp->next, 1, &start1_next, &stop1_next);
 
10878
    AlnMgr2GetNthSeqRangeInSA (salp->next, 2, &start2_next, &stop2_next);
 
10879
    if (start1_next > stop1_this + 1
 
10880
        || (strand == Seq_strand_minus && start2_next < stop2_this - 1)
 
10881
        || (strand != Seq_strand_minus && start2_next > stop2_this + 1)) {
 
10882
      if (strand == Seq_strand_minus) {
 
10883
        salp_new = AlignmentForInterval (sip1, sip2, stop1_this + 1, start1_next - 1, stop2_this - 1, start2_next + 1);
 
10884
      } else {
 
10885
        salp_new = AlignmentForInterval (sip1, sip2, stop1_this + 1, start1_next - 1, stop2_this + 1, start2_next - 1);
 
10886
      }
 
10887
      ReportCreatedAlignment (lip, salp_new);
 
10888
      salp_new->next = salp->next;
 
10889
      salp->next = salp_new;
 
10890
      salp = salp_new;
 
10891
    }
 
10892
    start1_this = start1_next;
 
10893
    stop1_this = stop1_next;
 
10894
    start2_this = start2_next;
 
10895
    stop2_this = stop2_next;
 
10896
    salp = salp->next;
 
10897
  }
 
10898
 
 
10899
}
 
10900
 
 
10901
 
 
10902
static SeqAlignPtr MergeAlignments (SeqAlignPtr salp_list)
 
10903
{
 
10904
  SeqAlignPtr salp_new = NULL, salp, salp_next;
 
10905
  DenseSegPtr dsp, dsp_new;
 
10906
  Int4        seg_num, k;
 
10907
 
 
10908
  if (salp_list == NULL || salp_list->next == NULL) {
 
10909
    return salp_list;
 
10910
  }
 
10911
 
 
10912
  dsp_new = DenseSegNew ();
 
10913
  dsp_new->dim = 2;
 
10914
  dsp_new->ids = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
10915
  dsp_new->ids->next = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
10916
 
 
10917
  /* get total number of segments */
 
10918
  for (salp = salp_list; salp != NULL; salp = salp->next) {
 
10919
    dsp = (DenseSegPtr) salp->segs;
 
10920
    dsp_new->numseg += dsp->numseg;
 
10921
  }
 
10922
 
 
10923
  dsp_new->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp_new->dim * dsp_new->numseg);
 
10924
  dsp_new->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp_new->dim * dsp_new->numseg);
 
10925
  dsp_new->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp_new->numseg);
 
10926
  
 
10927
  seg_num = 0;
 
10928
  for (salp = salp_list; salp != NULL; salp = salp_next) {
 
10929
    salp_next = salp->next;
 
10930
    dsp = (DenseSegPtr) salp->segs;
 
10931
    for (k = 0; k < dsp->numseg; k++) {
 
10932
      dsp_new->lens[seg_num] = dsp->lens[k];
 
10933
      dsp_new->starts[2 * seg_num] = dsp->starts[2 * k];
 
10934
      dsp_new->starts[2 * seg_num + 1] = dsp->starts[2 * k + 1];
 
10935
      dsp_new->strands[2 * seg_num] = dsp->strands[2 * k];
 
10936
      dsp_new->strands[2 * seg_num + 1] = dsp->strands[2 * k + 1];
 
10937
      seg_num++;
 
10938
    }
 
10939
    salp->next = NULL;
 
10940
    salp = SeqAlignFree (salp);
 
10941
  }
 
10942
 
 
10943
  salp_new = SeqAlignNew ();
 
10944
  salp_new->segtype = SAS_DENSEG;
 
10945
  salp_new->segs = dsp_new;
 
10946
  salp_new->dim = 2;
 
10947
 
 
10948
  return salp_new;
 
10949
}
 
10950
 
 
10951
 
 
10952
static Boolean MatchWithAmbiguity (Char ch1, Char ch2)
 
10953
{
 
10954
  Boolean rval = FALSE;
 
10955
 
 
10956
  ch1 = toupper (ch1);
 
10957
  ch2 = toupper (ch2);
 
10958
 
 
10959
  if (ch1 == ch2) {
 
10960
    return TRUE;
 
10961
  }
 
10962
  if (ch1 == 'X' || ch2 == 'X') {
 
10963
    return TRUE;
 
10964
  }
 
10965
  switch (ch1) {
 
10966
    case 'A':
 
10967
      if (ch2 == 'M' || ch2 == 'R' || ch2 == 'W' || ch2 == 'V' || ch2 == 'H' || ch2 == 'D') {
 
10968
        rval = TRUE;
 
10969
      }
 
10970
      break;
 
10971
    case 'T':
 
10972
      if (ch2 == 'K' || ch2 == 'Y' || ch2 == 'W' || ch2 == 'B' || ch2 == 'H' || ch2 == 'D') {
 
10973
        rval = TRUE;
 
10974
      }
 
10975
      break;
 
10976
    case 'G':
 
10977
      if (ch2 == 'K' || ch2 == 'R' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'D') {
 
10978
        rval = TRUE;
 
10979
      }
 
10980
      break;
 
10981
    case 'C':
 
10982
      if (ch2 == 'M' || ch2 == 'Y' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'H') {
 
10983
        rval = TRUE;
 
10984
      }
 
10985
      break;
 
10986
    case 'K':
 
10987
      if (ch2 == 'G' || ch2 == 'T' || ch2 == 'B' || ch2 == 'D') {
 
10988
        rval = TRUE;
 
10989
      }
 
10990
      break;
 
10991
    case 'M':
 
10992
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'V' || ch2 == 'H') {
 
10993
        rval = TRUE;
 
10994
      }
 
10995
      break;
 
10996
    case 'R':
 
10997
      if (ch2 == 'A' || ch2 == 'G' || ch2 == 'V' || ch2 == 'D') {
 
10998
        rval = TRUE;
 
10999
      }
 
11000
      break;
 
11001
    case 'Y':
 
11002
      if (ch2 == 'C' || ch2 == 'T' || ch2 == 'B' || ch2 == 'H') {
 
11003
        rval = TRUE;
 
11004
      }
 
11005
      break;
 
11006
    case 'S':
 
11007
      if (ch2 == 'C' || ch2 == 'G' || ch2 == 'B' || ch2 == 'V') {
 
11008
        rval = TRUE;
 
11009
      }
 
11010
      break;
 
11011
    case 'W':
 
11012
      if (ch2 == 'A' || ch2 == 'T' || ch2 == 'H' || ch2 == 'D') {
 
11013
        rval = TRUE;
 
11014
      }
 
11015
      break;
 
11016
    case 'B':
 
11017
      if (ch2 == 'C' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'Y' || ch2 == 'S') {
 
11018
        rval = TRUE;
 
11019
      }
 
11020
      break;
 
11021
    case 'V':
 
11022
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'G' || ch2 == 'M' || ch2 == 'R' || ch2 == 'S') {
 
11023
        rval = TRUE;
 
11024
      }
 
11025
      break;
 
11026
    case 'H':
 
11027
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'T' || ch2 == 'M' || ch2 == 'Y' || ch2 == 'W') {
 
11028
        rval = TRUE;
 
11029
      }
 
11030
      break;
 
11031
    case 'D':
 
11032
      if (ch2 == 'A' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'R' || ch2 == 'W') {
 
11033
        rval = TRUE;
 
11034
      }
 
11035
      break;
 
11036
  }
 
11037
  return rval;
 
11038
}  
 
11039
  
 
11040
 
 
11041
/* expand for ambiguity characters and poly-A tail */
 
11042
static SeqAlignPtr ExtendAlignmentList (SeqAlignPtr salp_list)
 
11043
{
 
11044
  Int4        from_1, to_1, from_2, to_2, len1, len2, len_check, len_extend;
 
11045
  SeqAlignPtr salp_tmp;
 
11046
  BioseqPtr   bsp1 = NULL;
 
11047
  BioseqPtr   bsp2 = NULL;
 
11048
  Uint1       strand;
 
11049
  CharPtr     buf1, buf2;
 
11050
  Int2        ctr;
 
11051
  SeqIdPtr    sip1, sip2;
 
11052
  DenseSegPtr dsp;
 
11053
 
 
11054
  if (salp_list == NULL) {
 
11055
    return salp_list;
 
11056
  }
 
11057
 
 
11058
  strand = SeqAlignStrand (salp_list, 1);
 
11059
  AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11060
 
 
11061
  sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11062
  bsp1 = BioseqLockById (sip1);
 
11063
  sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11064
  bsp2 = BioseqLockById (sip2);
 
11065
 
 
11066
  AlnMgr2GetNthSeqRangeInSA (salp_list, 1, &from_1, &to_1);  
 
11067
  AlnMgr2GetNthSeqRangeInSA (salp_list, 2, &from_2, &to_2);  
 
11068
 
 
11069
  if (from_1 > 0 
 
11070
      && ((strand == Seq_strand_plus && from_2 > 0)
 
11071
          || (strand == Seq_strand_minus && to_2 < bsp2->length - 1))) {
 
11072
    len1 = from_1;
 
11073
    if (strand == Seq_strand_plus) {
 
11074
      len2 = from_2;
 
11075
    } else {
 
11076
      len2 = bsp2->length - to_2 - 1;
 
11077
    }
 
11078
    if (len1 > len2) {
 
11079
      len_check = len2;
 
11080
    } else {
 
11081
      len_check = len1;
 
11082
    }
 
11083
    buf1 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11084
    buf2 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11085
    ctr = SeqPortStreamInt (bsp1, from_1 - len_check, from_1 - 1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
11086
    buf1[ctr] = 0;
 
11087
    if (strand == Seq_strand_plus) {
 
11088
      ctr = SeqPortStreamInt (bsp2, from_2 - len_check, from_2 - 1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11089
    } else {
 
11090
      ctr = SeqPortStreamInt (bsp2, to_2 + 1, to_2 + len_check, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11091
    }
 
11092
    buf2[ctr] = 0;
 
11093
 
 
11094
    len_extend = 0;
 
11095
    while (len_extend < len_check 
 
11096
           && MatchWithAmbiguity (buf1[len_check - len_extend - 1], buf2[len_check - len_extend - 1])) {
 
11097
      len_extend++;
 
11098
    }
 
11099
    buf1 = MemFree (buf1);
 
11100
    buf2 = MemFree (buf2);
 
11101
    if (len_extend > 0) {
 
11102
      dsp = (DenseSegPtr) salp_list->segs;
 
11103
      dsp->lens[0] += len_extend;
 
11104
      dsp->starts[0] -= len_extend;
 
11105
      if (strand == Seq_strand_plus) {
 
11106
        dsp->starts[1] -= len_extend;
 
11107
      }
 
11108
      SeqAlignIndexFree(salp_list->saip);
 
11109
      salp_list->saip = NULL;
 
11110
      AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11111
    }
 
11112
  }
 
11113
 
 
11114
  /* extend at other end */
 
11115
  salp_tmp = salp_list;
 
11116
  while (salp_tmp->next != NULL) {
 
11117
    salp_tmp = salp_tmp->next;
 
11118
  }
 
11119
 
 
11120
  AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11121
 
 
11122
  AlnMgr2GetNthSeqRangeInSA (salp_tmp, 1, &from_1, &to_1);  
 
11123
  AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11124
  if (to_1 < bsp1->length - 1
 
11125
      && ((strand == Seq_strand_plus && to_2 < bsp2->length - 1)
 
11126
          || (strand == Seq_strand_minus && from_2 > 0))) {
 
11127
    len1 = bsp1->length - to_1 - 1;
 
11128
    if (strand == Seq_strand_plus) {
 
11129
      len2 = bsp2->length - to_2 - 1;
 
11130
    } else {
 
11131
      len2 = from_2;
 
11132
    }
 
11133
    if (len1 > len2) {
 
11134
      len_check = len2;
 
11135
    } else {
 
11136
      len_check = len1;
 
11137
    }
 
11138
    if (len_check > 0) {
 
11139
      buf1 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11140
      buf2 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11141
      ctr = SeqPortStreamInt (bsp1, to_1 + 1, to_1 + len_check, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
11142
      buf1[ctr] = 0;
 
11143
      if (strand == Seq_strand_plus) {
 
11144
        ctr = SeqPortStreamInt (bsp2, to_2 + 1, to_2 + len_check, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11145
      } else {
 
11146
        ctr = SeqPortStreamInt (bsp2, from_2 - len_check, from_2 - 1, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11147
      }
 
11148
      buf2[ctr] = 0;
 
11149
 
 
11150
      len_extend = 0;
 
11151
      while (len_extend < len_check 
 
11152
            && MatchWithAmbiguity (buf1[len_extend], buf2[len_extend])) {
 
11153
        len_extend++;
 
11154
      }
 
11155
      buf1 = MemFree (buf1);
 
11156
      buf2 = MemFree (buf2);
 
11157
      if (len_extend > 0) {
 
11158
        dsp = (DenseSegPtr) salp_tmp->segs;
 
11159
        dsp->lens[dsp->numseg - 1] += len_extend;
 
11160
        if (strand == Seq_strand_minus) {
 
11161
          dsp->starts[(dsp->numseg - 1) * dsp->dim + 1] -= len_extend;
 
11162
        }
 
11163
        SeqAlignIndexFree(salp_tmp->saip);
 
11164
        salp_tmp->saip = NULL;
 
11165
        AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11166
      }
 
11167
    }
 
11168
  }   
 
11169
 
 
11170
  BioseqUnlock (bsp1);
 
11171
  BioseqUnlock (bsp2);
 
11172
  sip1 = SeqIdFree (sip1);  
 
11173
  sip2 = SeqIdFree (sip2);  
 
11174
 
 
11175
  return salp_list;
 
11176
}
 
11177
 
 
11178
 
 
11179
static void ReportInitialBlastResults (LogInfoPtr lip, SeqAlignPtr salp_list)
 
11180
{
 
11181
  Int4        from_1, to_1, from_2, to_2;
 
11182
  Uint1       strand;
 
11183
  Char        id1[255], id2[255];
 
11184
  SeqIdPtr    sip;
 
11185
  BioseqPtr   bsp;
 
11186
 
 
11187
  if (lip == NULL || lip->fp == NULL || salp_list == NULL) {
 
11188
    return;
 
11189
  }
 
11190
 
 
11191
  AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11192
  sip = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11193
  bsp = BioseqLockById (sip);
 
11194
  if (bsp != NULL) {
 
11195
    sip = SeqIdFree (sip);
 
11196
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11197
    BioseqUnlock (bsp);
 
11198
  }
 
11199
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
11200
  sip = SeqIdFree (sip);
 
11201
  sip = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11202
  bsp = BioseqLockById (sip);
 
11203
  if (bsp != NULL) {
 
11204
    sip = SeqIdFree (sip);
 
11205
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11206
    BioseqUnlock (bsp);
 
11207
  }
 
11208
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
11209
  sip = SeqIdFree (sip);
 
11210
  fprintf (lip->fp, "Initial BLAST results\n");
 
11211
  while (salp_list != NULL) {
 
11212
    AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11213
    strand = SeqAlignStrand (salp_list, 2);
 
11214
    AlnMgr2GetNthSeqRangeInSA (salp_list, 1, &from_1, &to_1);
 
11215
    AlnMgr2GetNthSeqRangeInSA (salp_list, 2, &from_2, &to_2);
 
11216
    fprintf (lip->fp, "%s:%d-%d, %s:%d-%d%s\n", id1, from_1, to_1, id2, from_2, to_2,
 
11217
             strand == Seq_strand_minus ? "(c)" : "");
 
11218
    salp_list = salp_list->next;
 
11219
  }
 
11220
  lip->data_in_log = TRUE;
 
11221
}
 
11222
 
 
11223
 
 
11224
static void ReportForRemoval (LogInfoPtr lip, SeqAlignPtr salp, CharPtr reason)
 
11225
{
 
11226
  Int4        from_1, to_1, from_2, to_2;
 
11227
  Uint1       strand;
 
11228
  Char        id1[255], id2[255];
 
11229
  SeqIdPtr    sip;
 
11230
 
 
11231
  if (lip == NULL || lip->fp == NULL || salp == NULL) {
 
11232
    return;
 
11233
  }
 
11234
 
 
11235
  sip = AlnMgr2GetNthSeqIdPtr (salp, 1);
 
11236
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
11237
  sip = SeqIdFree (sip);
 
11238
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
11239
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
11240
  sip = SeqIdFree (sip);
 
11241
  AlnMgr2IndexSingleChildSeqAlign (salp);
 
11242
  strand = SeqAlignStrand (salp, 2);
 
11243
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &from_1, &to_1);
 
11244
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &from_2, &to_2);
 
11245
  fprintf (lip->fp, "Removed alignment %s:%d-%d, %s:%d-%d%s %s\n",
 
11246
                     id1, from_1, to_1, id2, from_2, to_2,
 
11247
                     strand == Seq_strand_minus ? "(c)" : "", reason);
 
11248
}
 
11249
 
 
11250
 
 
11251
/* Assume earlier alignments are better.  
 
11252
 * Remove all alignments that are not the same strand as the first.
 
11253
 * Remove all alignments that overlap on the first sequence.
 
11254
 * Remove all alignments that overlap on the second sequence.
 
11255
 * use Needleman-Wunsch to fill in holes between alignments.
 
11256
 */
 
11257
static SeqAlignPtr CombineTSAAlignments (SeqAlignPtr salp)
 
11258
{
 
11259
  SeqAlignPtr salp_tmp, salp_match, salp_prev, salp_next;
 
11260
  Uint1       strand;
 
11261
  Int4        from_1, to_1, from_2, to_2;
 
11262
  LogInfoPtr  lip = NULL;
 
11263
 
 
11264
  if (salp == NULL) {
 
11265
    return salp;
 
11266
  }
 
11267
 
 
11268
  for (salp_tmp = salp; salp_tmp != NULL; salp_tmp = salp_tmp->next) {
 
11269
    /* if alignment is to minus strand for first sequence, flip alignment */
 
11270
    if (SeqAlignStrand (salp_tmp, 0) != Seq_strand_plus) {
 
11271
      FlipAlignment (salp_tmp);
 
11272
    }
 
11273
  }
 
11274
 
 
11275
  if (salp->next != NULL) {
 
11276
    lip = OpenLog ("TSA Alignment Adjustments");
 
11277
  }
 
11278
 
 
11279
  ReportInitialBlastResults (lip, salp);
 
11280
 
 
11281
  if (salp->next != NULL) {
 
11282
    /* remove alignments that are not the same strand as the initial alignment */
 
11283
    strand = SeqAlignStrand (salp, 1);
 
11284
    salp_prev = salp;
 
11285
    AlnMgr2IndexSingleChildSeqAlign (salp);
 
11286
    salp_tmp = salp->next;
 
11287
    while (salp_tmp != NULL) {
 
11288
      AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11289
      salp_next = salp_tmp->next;
 
11290
      if (SeqAlignStrand (salp_tmp, 1) != strand) {
 
11291
        ReportForRemoval (lip, salp_tmp, "because strands do not match.");
 
11292
        salp_prev->next = salp_tmp->next;
 
11293
        salp_tmp->next = NULL;
 
11294
        salp_tmp = SeqAlignFree (salp_tmp);
 
11295
      }
 
11296
      salp_tmp = salp_next;
 
11297
    }
 
11298
  }
 
11299
  
 
11300
  /* remove alignments that overlap on the first sequence */
 
11301
  salp_match = salp;
 
11302
  while (salp_match != NULL) {
 
11303
    salp_prev = salp_match;
 
11304
    salp_tmp = salp_match->next;
 
11305
    AlnMgr2GetNthSeqRangeInSA (salp_match, 1, &from_1, &to_1);
 
11306
    while (salp_tmp != NULL) {
 
11307
      salp_next = salp_tmp->next;
 
11308
      AlnMgr2GetNthSeqRangeInSA (salp_tmp, 1, &from_2, &to_2);
 
11309
      if ((from_2 >= from_1 && from_2 <= to_1) || (to_2 >= from_1 && to_2 <= to_1)) { 
 
11310
        ReportForRemoval (lip, salp_tmp, "because alignments overlap for first sequence.");
 
11311
        salp_prev->next = salp_tmp->next;
 
11312
        salp_tmp->next = NULL;
 
11313
        salp_tmp = SeqAlignFree (salp_tmp);
 
11314
      }
 
11315
      salp_tmp = salp_next;
 
11316
    }
 
11317
    salp_match = salp_match->next;
 
11318
  }
 
11319
 
 
11320
  if (salp->next != NULL) {
 
11321
    /* remove alignments that overlap on the second sequence */
 
11322
    salp_match = salp;
 
11323
    while (salp_match != NULL) {
 
11324
      salp_prev = salp_match;
 
11325
      salp_tmp = salp_match->next;
 
11326
      AlnMgr2GetNthSeqRangeInSA (salp_match, 2, &from_1, &to_1);
 
11327
      while (salp_tmp != NULL) {
 
11328
        salp_next = salp_tmp->next;
 
11329
        AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11330
        if ((from_2 >= from_1 && from_2 <= to_1) || (to_2 >= from_1 && to_2 <= to_1)) { 
 
11331
          ReportForRemoval (lip, salp_tmp, "because alignments overlap for second sequence.");
 
11332
          salp_prev->next = salp_tmp->next;
 
11333
          salp_tmp->next = NULL;
 
11334
          salp_tmp = SeqAlignFree (salp_tmp);
 
11335
        }
 
11336
        salp_tmp = salp_next;
 
11337
      }
 
11338
      salp_match = salp_match->next;
 
11339
    }
 
11340
  }
 
11341
 
 
11342
  /* sort remaining alignments by start position on the first sequence */
 
11343
  salp = SortPairwiseAlignmentsByFirstSeqRange (salp);
 
11344
 
 
11345
  /* temporary hack.  only interested in "unusual" errors. */
 
11346
  if (lip != NULL) {
 
11347
    lip->data_in_log = FALSE;
 
11348
  }
 
11349
 
 
11350
  if (salp->next != NULL) {
 
11351
    /* remove alignments that are out of order on the second sequence */
 
11352
    salp_prev = salp;
 
11353
    AlnMgr2GetNthSeqRangeInSA (salp_prev, 2, &from_1, &to_1);
 
11354
    salp_tmp = salp->next;
 
11355
    while (salp_tmp != NULL) {
 
11356
      AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11357
      if (from_2 < from_1) {
 
11358
        ReportForRemoval (lip, salp_tmp, "because alignments are out of order for second sequence.");
 
11359
        salp_prev->next = salp_tmp->next;
 
11360
        salp_tmp->next = NULL;
 
11361
        salp_tmp = SeqAlignFree (salp_tmp);
 
11362
      } else {
 
11363
        salp_prev = salp_tmp;
 
11364
        from_1 = from_2;
 
11365
        to_1 = to_2;
 
11366
      }
 
11367
      salp_tmp = salp_prev->next;
 
11368
    }
 
11369
  }
 
11370
 
 
11371
  /* fill in holes */
 
11372
  FillInAlignmentHoles (salp, lip);
 
11373
 
 
11374
  /* extend for good matches */
 
11375
  salp = ExtendAlignmentList (salp);
 
11376
 
 
11377
  /* make new alignment by stringing together local alignments */
 
11378
  salp = MergeAlignments (salp);
 
11379
  CloseLog (lip);
 
11380
  lip = FreeLog (lip);
 
11381
  return salp;
 
11382
}
 
11383
 
 
11384
 
 
11385
NLM_EXTERN SeqAlignPtr GetSeqAlignTSA (BioseqPtr bsp1, BioseqPtr bsp2)
 
11386
{
 
11387
   BLAST_SummaryOptions *options = NULL;
 
11388
   SeqAlignPtr           salp = NULL;
 
11389
   
 
11390
   if (bsp1 == NULL || bsp2 == NULL) return NULL;
 
11391
 
 
11392
   BLAST_SummaryOptionsInit(&options);
 
11393
   options->filter_string = StringSave ("m L");
 
11394
   options->word_size = 20;
 
11395
   options->cutoff_evalue = act_get_eval (1);
 
11396
   options->hint = eNone;
 
11397
   if (ISA_na (bsp1->mol))
 
11398
   {
 
11399
     options->program = eBlastn;
 
11400
   }
 
11401
   else
 
11402
   {
 
11403
     options->program = eBlastp;
 
11404
   }
 
11405
 
 
11406
   BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
 
11407
 
 
11408
   /* if there were no alignments from the first search, try again
 
11409
    * with low-complexity masking turned off.
 
11410
    */
 
11411
   if (salp == NULL) {
 
11412
     options->filter_string = MemFree (options->filter_string);
 
11413
     options->filter_string = StringSave ("m F");
 
11414
     BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
 
11415
   }
 
11416
 
 
11417
   BLAST_SummaryOptionsFree(options);
 
11418
 
 
11419
   if (salp != NULL) {
 
11420
     salp = CombineTSAAlignments (salp);
 
11421
     AlnMgr2IndexSeqAlign(salp);
 
11422
   }
 
11423
   return salp;
 
11424
}
 
11425
 
 
11426
 
 
11427
/* code for editing TSA assembly */
 
11428
typedef struct tsaassemblydialog {
 
11429
  DIALOG_MESSAGE_BLOCK
 
11430
  DialoG        intervals;
 
11431
  BioseqPtr     consensus_bsp;
 
11432
} TSAAssemblyDialog, PNTR TSAAssemblyDialogPtr;
 
11433
 
 
11434
 
 
11435
Uint2 tsa_assembly_types [] = {
 
11436
  TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_PROMPT
 
11437
};
 
11438
 
 
11439
 
 
11440
Uint2 tsa_assembly_widths [] = {
 
11441
  16, 16, 16, 0
 
11442
};
 
11443
 
 
11444
 
 
11445
static void SetTSAAssemblyDialogConsensusBioseq (DialoG d, BioseqPtr bsp)
 
11446
{
 
11447
  TSAAssemblyDialogPtr dlg;
 
11448
 
 
11449
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11450
  if (dlg != NULL) {
 
11451
    dlg->consensus_bsp = bsp;
 
11452
  }
 
11453
}
 
11454
 
 
11455
 
 
11456
static void SeqAlignsToTSAAssemblyDialog (DialoG d, Pointer data)
 
11457
{
 
11458
  TSAAssemblyDialogPtr  dlg;
 
11459
  TagListPtr            tlp;
 
11460
  SeqAlignPtr           salp_list, salp, salp_tmp;
 
11461
  ValNodePtr            data_list = NULL;
 
11462
  Int4                  tsa_from, tsa_to, primary_from, primary_to;
 
11463
  SeqIdPtr              sip;
 
11464
  Char                  id_buf[255];
 
11465
  CharPtr               str;
 
11466
  CharPtr               fmt = "%s\t%d-%d%s\t%d-%d\n";
 
11467
  Uint1                 strand;
 
11468
  BioseqPtr             bsp;
 
11469
 
 
11470
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11471
  if (dlg == NULL) {
 
11472
    return;
 
11473
  }
 
11474
 
 
11475
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
 
11476
  if (tlp == NULL) {
 
11477
    return;
 
11478
  }
 
11479
 
 
11480
  salp_list = (SeqAlignPtr) data;
 
11481
 
 
11482
  salp = salp_list;
 
11483
  while (salp != NULL) {
 
11484
    salp_tmp = salp->next;
 
11485
    salp->next = NULL;
 
11486
    AlnMgr2IndexSeqAlign (salp);
 
11487
    AlnMgr2GetNthSeqRangeInSA(salp, 1, &tsa_from, &tsa_to);
 
11488
    AlnMgr2GetNthSeqRangeInSA(salp, 2, &primary_from, &primary_to);
 
11489
    sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
11490
    bsp = BioseqLockById (sip);
 
11491
    if (bsp != NULL) {
 
11492
      sip = SeqIdFree (sip);
 
11493
      sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11494
      BioseqUnlock (bsp);
 
11495
    }
 
11496
    SeqIdWrite (sip, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
 
11497
    sip = SeqIdFree (sip);
 
11498
    strand = AlnMgr2GetNthStrand (salp, 2);
 
11499
    str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (id_buf) + 70));
 
11500
    sprintf (str, fmt, id_buf, primary_from + 1, primary_to + 1, strand == Seq_strand_minus ? "(c)" : "", tsa_from + 1, tsa_to + 1);
 
11501
    ValNodeAddPointer (&data_list, 0, str);
 
11502
    salp->next = salp_tmp;
 
11503
    salp = salp->next;
 
11504
  }
 
11505
 
 
11506
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
11507
  tlp->vnp = data_list;
 
11508
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
11509
  tlp->max = MAX ((Int2) 0, (Int2) (ValNodeLen (data_list) - tlp->rows));
 
11510
  CorrectBarMax (tlp->bar, tlp->max);
 
11511
  CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
 
11512
  if (tlp->max > 0) {
 
11513
    SafeShow (tlp->bar);
 
11514
  } else {
 
11515
    SafeHide (tlp->bar);
 
11516
  }
 
11517
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
11518
}
 
11519
 
 
11520
 
 
11521
static void TSATableCallback (Pointer data)
 
11522
{
 
11523
  ProcessExternalEvent ();
 
11524
}
 
11525
 
 
11526
 
 
11527
static Pointer TSAAssemblyDialogToTranscriptomeIdsList (DialoG d)
 
11528
{
 
11529
  TSAAssemblyDialogPtr  dlg;
 
11530
  TagListPtr            tlp;
 
11531
  ValNodePtr            vnp;
 
11532
  CharPtr               txt;
 
11533
  Int4                  num_cols = 6;
 
11534
  TranscriptomeIdsPtr   t;
 
11535
  ValNodePtr            token_list = NULL;
 
11536
 
 
11537
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11538
  if (dlg == NULL) {
 
11539
    return NULL;
 
11540
  }
 
11541
 
 
11542
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
 
11543
  if (tlp == NULL) {
 
11544
    return NULL;
 
11545
  }
 
11546
 
 
11547
  if (dlg->consensus_bsp == NULL) {
 
11548
    return NULL;
 
11549
  }
 
11550
 
 
11551
  for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
 
11552
    txt = ExtractTagListColumn (vnp->data.ptrvalue, 0);
 
11553
    if (StringHasNoText (txt)) {
 
11554
      txt = MemFree (txt);
 
11555
    } else {
 
11556
      ValNodeAddPointer (&token_list, 0, txt);
 
11557
    }
 
11558
  }
 
11559
  t = TranscriptomeIdsNew (dlg->consensus_bsp, token_list);
 
11560
  vnp = ValNodeNew (NULL);
 
11561
  vnp->choice = 0;
 
11562
  vnp->data.ptrvalue = t;
 
11563
  return vnp;
 
11564
}
 
11565
 
 
11566
 
 
11567
static DialoG CreateTSAAssemblyDialog (GrouP g)
 
11568
 
 
11569
{
 
11570
  TSAAssemblyDialogPtr  dlg;
 
11571
  GrouP                  p;
 
11572
  GrouP                  x;
 
11573
  GrouP                  y;
 
11574
 
 
11575
  p = HiddenGroup (g, -1, 0, NULL);
 
11576
  SetGroupSpacing (p, 10, 10);
 
11577
 
 
11578
  dlg = (TSAAssemblyDialogPtr) MemNew (sizeof (TSAAssemblyDialog));
 
11579
  if (dlg == NULL) return NULL;
 
11580
 
 
11581
  SetObjectExtra (p, dlg, NULL);
 
11582
  dlg->dialog = (DialoG) p;
 
11583
  dlg->todialog = SeqAlignsToTSAAssemblyDialog;
 
11584
  dlg->fromdialog = TSAAssemblyDialogToTranscriptomeIdsList;
 
11585
 
 
11586
  x = HiddenGroup (p, 0, 2, NULL);
 
11587
  y = HiddenGroup (x, 3, 0, NULL);
 
11588
  /* first line */
 
11589
  StaticPrompt (y, "PrimaryID", 16 * stdCharWidth, 0, programFont, 'c');
 
11590
  StaticPrompt (y, "Primary Interval", 16 * stdCharWidth, 0, programFont, 'c');
 
11591
  StaticPrompt (y, "TSA Interval", 16 * stdCharWidth, 0, programFont, 'c');
 
11592
  dlg->intervals = CreateTagListDialogEx3 (x, 10, 3, 1, tsa_assembly_types, tsa_assembly_widths, NULL, TRUE, FALSE, NULL, NULL, 
 
11593
                                           NULL, NULL, FALSE, TRUE);
 
11594
 
 
11595
  return (DialoG) p;
 
11596
}
 
11597
 
 
11598
 
 
11599
static void ShowAssemblyAlignment (SeqAlignPtr salp)
 
11600
{
 
11601
  LogInfoPtr lip;
 
11602
 
 
11603
  if (salp == NULL) {
 
11604
    return;
 
11605
  }
 
11606
 
 
11607
  lip = OpenLog ("Assembly Alignments");
 
11608
  while (salp != NULL) {
 
11609
    WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
 
11610
    lip->data_in_log = TRUE;
 
11611
    salp = salp->next;
 
11612
  }
 
11613
  CloseLog (lip);
 
11614
  lip = FreeLog (lip);
 
11615
}
 
11616
 
 
11617
 
 
11618
typedef struct tsaassemblyform {
 
11619
  FORM_MESSAGE_BLOCK
 
11620
  DialoG intervals;
 
11621
 
 
11622
} TSAAssemblyFormData, PNTR TSAAssemblyFormPtr;
 
11623
 
 
11624
 
 
11625
static void AcceptTSAAssembly (ButtoN b)
 
11626
{
 
11627
  TSAAssemblyFormPtr frm;
 
11628
  BioseqPtr          bsp;
 
11629
  ValNodePtr         err_list, coverage_report, vnp, ids_list, match_errs;
 
11630
  SeqAlignPtr        salp, salp_next;
 
11631
  LogInfoPtr         lip;
 
11632
 
 
11633
  frm = (TSAAssemblyFormPtr) GetObjectExtra (b);
 
11634
  if (frm == NULL) {
 
11635
    return;
 
11636
  }
 
11637
  bsp = GetBioseqGivenIDs (frm->input_entityID, frm->input_itemID, frm->input_itemtype);
 
11638
  if (bsp == NULL) {
 
11639
    return;
 
11640
  }
 
11641
 
 
11642
  WatchCursor();
 
11643
  Update();
 
11644
  SetTSAAssemblyDialogConsensusBioseq (frm->intervals, bsp);
 
11645
  
 
11646
  ids_list = DialogToPointer (frm->intervals);
 
11647
 
 
11648
  /* remove existing assembly */
 
11649
  if (bsp->hist != NULL) {
 
11650
    salp = bsp->hist->assembly;
 
11651
    bsp->hist->assembly = NULL;
 
11652
    while (salp != NULL) {
 
11653
      salp_next = salp->next;
 
11654
      salp->next = NULL;
 
11655
      salp = SeqAlignFree (salp);
 
11656
      salp = salp_next;
 
11657
    }
 
11658
  }
 
11659
 
 
11660
  if (ids_list == NULL) {
 
11661
    Message (MSG_ERROR, "TSA assembly removed");
 
11662
  } else {
 
11663
    err_list = MakeTranscriptomeAssemblySeqHist (ids_list->data.ptrvalue, GetSeqAlignTSA, TSATableCallback, NULL);
 
11664
    coverage_report = ReportCoverageForTranscriptomeIdsListSeqHist (ids_list);
 
11665
    match_errs = ReportConsensusMatchForBioseqSeqHist (bsp);
 
11666
    ValNodeLink (&coverage_report, match_errs);
 
11667
    ids_list = TranscriptomeIdsListFree (ids_list);
 
11668
 
 
11669
    ValNodeLink (&coverage_report, err_list);
 
11670
    err_list = coverage_report;
 
11671
 
 
11672
    if (err_list != NULL) {
 
11673
      lip = OpenLog ("TSA Table Problems");
 
11674
      for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
 
11675
        fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
 
11676
      }
 
11677
      lip->data_in_log = TRUE;
 
11678
      CloseLog (lip);
 
11679
      lip = FreeLog (lip);
 
11680
      err_list = ValNodeFreeData (err_list);
 
11681
    }
 
11682
  }
 
11683
 
 
11684
  ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
 
11685
  ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
 
11686
  Remove (frm->form);
 
11687
  ArrowCursor();
 
11688
  Update();
 
11689
}
 
11690
 
 
11691
 
 
11692
NLM_EXTERN void EditTSAAssembly (IteM i)
 
11693
{
 
11694
  BaseFormPtr        bfp;
 
11695
  WindoW             w;
 
11696
  TSAAssemblyFormPtr frm;
 
11697
  BioseqPtr          bsp;
 
11698
  GrouP              h, c;
 
11699
  ButtoN             b;
 
11700
  
 
11701
#ifdef WIN_MAC
 
11702
  bfp = currentFormDataPtr;
 
11703
#else
 
11704
  bfp = GetObjectExtra (i);
 
11705
#endif
 
11706
  if (bfp == NULL) return;
 
11707
  
 
11708
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
11709
  if (bsp == NULL) {
 
11710
    Message (MSG_ERROR, "Must select sequence for editing TSA Assembly");
 
11711
    return;
 
11712
  }
 
11713
  frm = (TSAAssemblyFormPtr) MemNew (sizeof (TSAAssemblyFormData));
 
11714
  if (frm == NULL) return;
 
11715
  frm->input_entityID = bfp->input_entityID;
 
11716
  frm->input_itemID = bfp->input_itemID;
 
11717
  frm->input_itemtype = bfp->input_itemtype;
 
11718
 
 
11719
  w = FixedWindow (-50, -33, -10, -10, "TSA Assembly", StdCloseWindowProc);
 
11720
  SetObjectExtra (w, frm, StdCleanupFormProc);
 
11721
  frm->form = (ForM) w;
 
11722
  h = HiddenGroup (w, -1, 0, NULL);
 
11723
  frm->intervals = CreateTSAAssemblyDialog (h);
 
11724
 
 
11725
  if (bsp->hist == NULL) {
 
11726
    PointerToDialog (frm->intervals, NULL);
 
11727
  } else {
 
11728
    PointerToDialog (frm->intervals, bsp->hist->assembly);
 
11729
  }
 
11730
 
 
11731
 
 
11732
  c = HiddenGroup (h, 2, 0, NULL);
 
11733
  b = PushButton (c, "Accept", AcceptTSAAssembly);
 
11734
  SetObjectExtra (b, frm, NULL);
 
11735
  PushButton (c, "Cancel", StdCancelButtonProc);
 
11736
  
 
11737
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->intervals, (HANDLE) c, NULL);
 
11738
  RealizeWindow (w);
 
11739
  Show (w);
 
11740
  Update ();    
 
11741
 
 
11742
}
 
11743
 
 
11744
 
8111
11745
/* automatic defline generator */
8112
11746
 
8113
11747
typedef struct deffeats {
9585
13219
 
9586
13220
static void ExpandGapsToIncludeFlankingNs (BioseqPtr bsp, Pointer userdata)
9587
13221
{
9588
 
  DeltaSeqPtr  dsp, prev_dsp = NULL;
 
13222
  DeltaSeqPtr  dsp, prev_dsp = NULL, next_dsp = NULL, prev_prev_dsp = NULL;
9589
13223
  Int4         change_len;
9590
 
  SeqLitPtr    slip, prev_slip, next_slip;
 
13224
  SeqLitPtr    slip, prev_slip = NULL, next_slip;
9591
13225
  
9592
13226
  if (bsp == NULL || bsp->repr != Seq_repr_delta 
9593
13227
      || bsp->seq_ext_type != 4 || bsp->seq_ext == NULL)
9598
13232
  dsp = bsp->seq_ext;
9599
13233
  while (dsp != NULL) 
9600
13234
  {
 
13235
    next_dsp = dsp->next;
9601
13236
    /* look for gap of known length */
9602
13237
    if (IsDeltaSeqKnownGap(dsp) && !DoesDeltaSeqHaveGapTypeOrLinkage(dsp)) 
9603
13238
    {
9614
13249
        {
9615
13250
          RemoveSeqLitEnd (prev_slip, change_len, SEQLOC_RIGHT_END);
9616
13251
          slip->length += change_len;
 
13252
          if (prev_slip->length == 0) {
 
13253
            if (prev_prev_dsp == NULL) {
 
13254
              bsp->seq_ext = dsp;
 
13255
            } else {
 
13256
              prev_prev_dsp->next = dsp;
 
13257
            }
 
13258
            prev_dsp->next = NULL;
 
13259
            prev_dsp = DeltaSeqFree (prev_dsp);
 
13260
            prev_dsp = dsp;
 
13261
          }
9617
13262
        }
 
13263
      } else {
 
13264
        prev_prev_dsp = prev_dsp;
 
13265
        prev_dsp = dsp;
9618
13266
      }
9619
13267
      /* check for Ns after gap of known length */
9620
13268
      if (dsp->next != NULL && dsp->next->choice == 2
9625
13273
        next_slip = (SeqLitPtr) dsp->next->data.ptrvalue;
9626
13274
        change_len = CountNsAtEndOfSeqLit (next_slip, SEQLOC_LEFT_END);
9627
13275
            
9628
 
        if (change_len > 0)
 
13276
        if (change_len < next_slip->length)
9629
13277
        {
9630
13278
          RemoveSeqLitEnd (next_slip, change_len, SEQLOC_LEFT_END);
9631
13279
          slip->length += change_len;
9632
13280
        }
 
13281
        else 
 
13282
        {
 
13283
          dsp->next = next_dsp->next;
 
13284
          next_dsp->next = NULL;
 
13285
          next_dsp = DeltaSeqFree (next_dsp);
 
13286
          next_dsp = dsp->next;
 
13287
        }
9633
13288
      }
9634
13289
    }
9635
 
    dsp = dsp->next;
 
13290
    dsp = next_dsp;
9636
13291
  }    
9637
13292
  BioseqPack (bsp);
9638
13293
}
9675
13330
}
9676
13331
 
9677
13332
 
 
13333
static void RemoveZeroLengthSeqLits (BioseqPtr bsp)
 
13334
{
 
13335
  DeltaSeqPtr dsp, prev = NULL, dsp_next;
 
13336
  SeqLitPtr slip;
 
13337
 
 
13338
  if (bsp == NULL || bsp->repr != Seq_repr_delta) {
 
13339
    return;
 
13340
  }
 
13341
 
 
13342
  for (dsp = (DeltaSeqPtr) bsp->seq_ext; dsp != NULL; dsp = dsp_next) {
 
13343
    dsp_next = dsp->next;
 
13344
    if (dsp->choice == 2 && (slip = (SeqLitPtr) (dsp->data.ptrvalue)) != NULL 
 
13345
        && slip->length == 0 && slip->seq_data_type == 1) {
 
13346
      if (prev == NULL) {
 
13347
        bsp->seq_ext = dsp->next;
 
13348
      } else {
 
13349
        prev->next = dsp->next;
 
13350
      }
 
13351
      dsp->next = NULL;
 
13352
      dsp = DeltaSeqFree (dsp);
 
13353
    } else {
 
13354
      prev = dsp;
 
13355
    }
 
13356
  }
 
13357
}
 
13358
 
 
13359
 
 
13360
 
9678
13361
extern void CombineAdjacentGapsOnBioseq (BioseqPtr bsp, Pointer userdata)
9679
13362
{
9680
13363
  SeqLitPtr  litp, pitp;
9689
13372
  {
9690
13373
    return;
9691
13374
  }
 
13375
 
 
13376
  RemoveZeroLengthSeqLits (bsp);
9692
13377
  
9693
13378
  /* combine adjacent gaps */
9694
13379
  prev = (DeltaSeqPtr) bsp->seq_ext;
10076
13761
  currentport = ParentWindow (clfp->form);
10077
13762
  temport = SavePort (currentport);
10078
13763
  UseWindow (currentport);
10079
 
  Select (clfp->form);
10080
13764
  switch (ommsp->message) 
10081
13765
  {
10082
13766
      case OM_MSG_UPDATE:
10087
13771
      case OM_MSG_SELECT: 
10088
13772
          break;
10089
13773
      case OM_MSG_DEL:
10090
 
          Remove (clfp->form);
 
13774
          clfp->clickable_list_data = FreeClickableList (clfp->clickable_list_data);
 
13775
          PointerToDialog (clfp->clickable_list_dlg, NULL);
10091
13776
          break;
10092
13777
      case OM_MSG_HIDE:
10093
13778
          break;
10094
13779
      case OM_MSG_SHOW:
10095
13780
          break;
10096
13781
      case OM_MSG_FLUSH:
10097
 
          Remove (clfp->form);  
 
13782
          clfp->clickable_list_data = FreeClickableList (clfp->clickable_list_data);
 
13783
          PointerToDialog (clfp->clickable_list_dlg, NULL);
10098
13784
          break;
10099
13785
      default:
10100
13786
          break;
10146
13832
 
10147
13833
/* There will only be one Discrepancy Report window at a time */
10148
13834
static WindoW discrepancyReportWindow = NULL;
 
13835
static WindoW oncallerReportWindow = NULL;
 
13836
 
 
13837
static WindoW GetWindowForReportType (EDiscrepancyReportType report_type)
 
13838
{
 
13839
  WindoW w = NULL;
 
13840
 
 
13841
  switch (report_type) {
 
13842
    case eReportTypeDiscrepancy:
 
13843
      w = discrepancyReportWindow;
 
13844
      break;
 
13845
    case eReportTypeOnCaller:
 
13846
      w = oncallerReportWindow;
 
13847
      break;
 
13848
  }
 
13849
  return w;
 
13850
}
 
13851
 
 
13852
 
 
13853
static void ClearWindowForReportType (WindoW w)
 
13854
{
 
13855
  if (discrepancyReportWindow == w) {
 
13856
    discrepancyReportWindow = NULL;
 
13857
  }
 
13858
  if (oncallerReportWindow == w) {
 
13859
    oncallerReportWindow = NULL;
 
13860
  }
 
13861
}
 
13862
 
 
13863
 
 
13864
static void SetWindowForReportType (WindoW w, EDiscrepancyReportType report_type)
 
13865
{
 
13866
  switch (report_type) {
 
13867
    case eReportTypeDiscrepancy:
 
13868
      discrepancyReportWindow = w;
 
13869
      break;
 
13870
    case eReportTypeOnCaller:
 
13871
      oncallerReportWindow = w;
 
13872
      break;
 
13873
  }
 
13874
}
 
13875
 
10149
13876
 
10150
13877
typedef void (*DiscrepancyCallback) (ValNodePtr item_list, Pointer userdata);
10151
13878
typedef void (*DiscrepancyCallbackDataFree) (Pointer userdata);
10170
13897
    drfp->clickable_list_data = FreeClickableList (drfp->clickable_list_data);
10171
13898
    drfp->dcp = DiscrepancyConfigFree (drfp->dcp);
10172
13899
    ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
10173
 
    discrepancyReportWindow = NULL;
 
13900
    ClearWindowForReportType ((WindoW) drfp->form);
10174
13901
  }
10175
13902
  StdCleanupFormProc (g, data);
10176
13903
}
10206
13933
  }
10207
13934
}
10208
13935
 
 
13936
 
10209
13937
/* This function returns TRUE if there was a change to the discrepancy config,
10210
13938
 * FALSE otherwise.
10211
13939
 */
10212
 
static Boolean EditDiscrepancyConfig (DiscrepancyConfigPtr dcp)
 
13940
static Boolean EditDiscrepancyConfig (DiscrepancyConfigPtr dcp, EDiscrepancyReportType report_type)
10213
13941
{
10214
13942
  WindoW                w;
10215
13943
  GrouP                 h, g, k, c;
10231
13959
  h = HiddenGroup (w, -1, 0, NULL);
10232
13960
  SetGroupSpacing (h, 10, 10);
10233
13961
  
10234
 
  g = NormalGroup (h, 0, 10, "Discrepancy Tests to Run", programFont, NULL);
 
13962
  g = NormalGroup (h, 0, 14, "Discrepancy Tests to Run", programFont, NULL);
10235
13963
  SetGroupSpacing (g, 10, 10);
10236
13964
  for (i = 0; i < MAX_DISC_TYPE; i++)
10237
13965
  {
10238
 
    test_options[i] = CheckBox (g, GetDiscrepancyTestConfName ((DiscrepancyType) i), NULL);
10239
 
    SetStatus (test_options[i], dcp->conf_list[i]);
 
13966
    if (IsTestTypeAppropriateForReportType (i, report_type)) {
 
13967
      test_options[i] = CheckBox (g, GetDiscrepancyTestConfName ((DiscrepancyType) i), NULL);
 
13968
      SetStatus (test_options[i], dcp->conf_list[i]);
 
13969
    } else {
 
13970
      test_options[i] = NULL;
 
13971
    }
10240
13972
  }
10241
13973
  
10242
13974
  use_feature_table_format_btn = CheckBox (h, "Use feature table format for features in report", NULL);
10804
14536
}
10805
14537
 
10806
14538
 
10807
 
static void ReactivateDiscrepancyReport ()
 
14539
static void ReactivateDiscrepancyReport (EDiscrepancyReportType report_type)
10808
14540
{
10809
14541
  DiscrepancyReportFormPtr drfp;
 
14542
  WindoW                   w;
10810
14543
 
10811
 
  if (discrepancyReportWindow == NULL) 
 
14544
  w = GetWindowForReportType (report_type);
 
14545
  if (w == NULL) 
10812
14546
  {
10813
 
    CreateDiscrepancyReportWindow ();
 
14547
    CreateReportWindow (report_type);
10814
14548
  }
10815
14549
  
10816
 
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (discrepancyReportWindow);
 
14550
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (w);
10817
14551
  if (drfp == NULL)
10818
14552
  {
10819
 
    Remove (discrepancyReportWindow);
10820
 
    discrepancyReportWindow = NULL;
10821
 
    CreateDiscrepancyReportWindow ();
 
14553
    Remove (w);
 
14554
    ClearWindowForReportType (w);
 
14555
    CreateReportWindow (report_type);
 
14556
    w = GetWindowForReportType (report_type);
10822
14557
  }
10823
14558
    
10824
14559
  /* populate discrepancy lists */
10825
14560
  RecheckDiscrepancyProc (drfp->recheck_btn);
10826
 
  Show (discrepancyReportWindow);  
10827
 
  Select (discrepancyReportWindow);
 
14561
  Show (w);  
 
14562
  Select (w);
 
14563
}
 
14564
 
 
14565
 
 
14566
 
 
14567
static void EditReportConfigBtn (EDiscrepancyReportType report_type)
 
14568
{
 
14569
  DiscrepancyReportFormPtr drfp;
 
14570
  WindoW                   w;
 
14571
 
 
14572
  w = GetWindowForReportType (report_type);
 
14573
  
 
14574
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (w);
 
14575
  if (drfp == NULL) return;
 
14576
  
 
14577
  if (EditDiscrepancyConfig (drfp->dcp, report_type))
 
14578
  {
 
14579
    RecheckDiscrepancyProc (drfp->recheck_btn);
 
14580
  }
10828
14581
}
10829
14582
 
10830
14583
 
10831
14584
static void EditDiscrepancyConfigBtn (ButtoN b)
10832
14585
{
10833
 
  DiscrepancyReportFormPtr drfp;
10834
 
  
10835
 
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (discrepancyReportWindow);
10836
 
  if (drfp == NULL) return;
10837
 
  
10838
 
  if (EditDiscrepancyConfig (drfp->dcp))
10839
 
  {
10840
 
    RecheckDiscrepancyProc (b);
 
14586
  EditReportConfigBtn (eReportTypeDiscrepancy);
 
14587
}
 
14588
 
 
14589
 
 
14590
static void EditOnCallerConfigBtn (ButtoN b)
 
14591
{
 
14592
  EditReportConfigBtn (eReportTypeOnCaller);
 
14593
}
 
14594
 
 
14595
 
 
14596
static Nlm_BtnActnProc GetReportEditButtonProc (EDiscrepancyReportType report_type)
 
14597
{
 
14598
  Nlm_BtnActnProc proc = NULL;
 
14599
 
 
14600
  switch (report_type) {
 
14601
    case eReportTypeDiscrepancy:
 
14602
      proc = EditDiscrepancyConfigBtn;
 
14603
      break;
 
14604
    case eReportTypeOnCaller:
 
14605
      proc = EditOnCallerConfigBtn;
 
14606
      break;
10841
14607
  }
 
14608
  return proc;
10842
14609
}
10843
14610
 
10844
14611
 
10847
14614
#endif
10848
14615
 
10849
14616
 
10850
 
extern void CreateDiscrepancyReportWindow (void)
 
14617
static CharPtr GetReportName (EDiscrepancyReportType report_type)
 
14618
{
 
14619
  CharPtr report_name = "";
 
14620
 
 
14621
  switch (report_type) {
 
14622
    case eReportTypeDiscrepancy:
 
14623
      report_name = "Discrepancy Report";
 
14624
      break;
 
14625
    case eReportTypeOnCaller:
 
14626
      report_name = "On Caller Tool";
 
14627
      break;
 
14628
  }
 
14629
  return report_name;
 
14630
}
 
14631
 
 
14632
 
 
14633
static CharPtr GetReportConfigName (EDiscrepancyReportType report_type)
 
14634
{
 
14635
  CharPtr report_name = "";
 
14636
 
 
14637
  switch (report_type) {
 
14638
    case eReportTypeDiscrepancy:
 
14639
      report_name = "DISCREPANCY_REPORT";
 
14640
      break;
 
14641
    case eReportTypeOnCaller:
 
14642
      report_name = "ON_CALLER_TOOL";
 
14643
      break;
 
14644
  }
 
14645
  return report_name;
 
14646
}
 
14647
 
 
14648
 
 
14649
static void AdjustConfigForReportType (EDiscrepancyReportType report_type, DiscrepancyConfigPtr dcp)
 
14650
{
 
14651
  Int4 i;
 
14652
 
 
14653
  if (dcp == NULL) {
 
14654
    return;
 
14655
  }
 
14656
 
 
14657
  for (i = 0; i < MAX_DISC_TYPE; i++) {
 
14658
    if (!IsTestTypeAppropriateForReportType (i, report_type)) {
 
14659
      dcp->conf_list[i] = FALSE;
 
14660
    }
 
14661
  }
 
14662
 
 
14663
}
 
14664
 
 
14665
 
 
14666
static void ExpandAllDiscReportItems (ButtoN b)
 
14667
{
 
14668
  DiscrepancyReportFormPtr d;
 
14669
 
 
14670
  d = (DiscrepancyReportFormPtr) GetObjectExtra (b);
 
14671
  if (d == NULL) {
 
14672
    return;
 
14673
  }
 
14674
 
 
14675
  ExpandClickableItemList (d->clickable_list_data);
 
14676
 
 
14677
  PointerToDialog (d->clickable_list_dlg, d->clickable_list_data);
 
14678
}
 
14679
 
 
14680
 
 
14681
static void ContractAllDiscReportItems (ButtoN b)
 
14682
{
 
14683
  DiscrepancyReportFormPtr d;
 
14684
 
 
14685
  d = (DiscrepancyReportFormPtr) GetObjectExtra (b);
 
14686
  if (d == NULL) {
 
14687
    return;
 
14688
  }
 
14689
  ContractClickableItemList (d->clickable_list_data);
 
14690
 
 
14691
  PointerToDialog (d->clickable_list_dlg, d->clickable_list_data);
 
14692
}
 
14693
 
 
14694
 
 
14695
extern void CreateReportWindow (EDiscrepancyReportType report_type)
10851
14696
{
10852
14697
  DiscrepancyReportFormPtr drfp;
10853
14698
  GrouP                    h;
10854
14699
  ButtoN                   b;
10855
14700
  GrouP                    c;
 
14701
  GrouP                    c1;
10856
14702
  WindoW                   w;
10857
14703
  OMUserDataPtr            omudp;
10858
14704
 
10859
 
  if (discrepancyReportWindow != NULL)
 
14705
  if (GetWindowForReportType(report_type) != NULL)
10860
14706
  {
10861
 
    ReactivateDiscrepancyReport ();
 
14707
    ReactivateDiscrepancyReport (report_type);
10862
14708
    return; 
10863
14709
  }
10864
14710
  
10868
14714
    return;
10869
14715
  }
10870
14716
  
10871
 
  w = FixedWindow (-50, -33, -10, -10, "Discrepancy Report", StdCloseWindowProc);
 
14717
  w = FixedWindow (-50, -33, -10, -10, GetReportName (report_type), StdCloseWindowProc);
10872
14718
  SetObjectExtra (w, drfp, CleanupDiscrepancyReportForm);
10873
14719
  drfp->form = (ForM) w;
10874
14720
  drfp->formmessage = ClickableListFormMessage;
10875
14721
  drfp->exportform = DiscrepancyReportExportProc;
10876
14722
  
10877
14723
  /* read in config file */
10878
 
  drfp->dcp = ReadDiscrepancyConfig();
 
14724
  drfp->dcp = ReadDiscrepancyConfigEx(GetReportConfigName (report_type));
 
14725
 
 
14726
  /* adjust for report type */
 
14727
  AdjustConfigForReportType (report_type, drfp->dcp);
10879
14728
  
10880
14729
  /* register to receive update messages */
10881
14730
  drfp->userkey = OMGetNextUserKey ();
10898
14747
  drfp->clickable_list_dlg = CreateClickableListDialog (h, "Discrepancies", "Affected Items",
10899
14748
                                                    ScrollToDiscrepancyItem, EditDiscrepancyItem, NULL,
10900
14749
                                                    GetDiscrepancyItemText);
10901
 
                                                    
 
14750
                              
 
14751
  c1 = HiddenGroup (h, 2, 0, NULL);
 
14752
  SetGroupSpacing (c1, 10, 10);
 
14753
  b = PushButton (c1, "Expand All", ExpandAllDiscReportItems);
 
14754
  SetObjectExtra (b, drfp, NULL);
 
14755
  b = PushButton (c1, "Contract All", ContractAllDiscReportItems);
 
14756
  SetObjectExtra (b, drfp, NULL);
 
14757
 
10902
14758
  c = HiddenGroup (h, 4, 0, NULL);
10903
14759
  SetGroupSpacing (c, 10, 10);
10904
14760
  b = PushButton (c, "Generate Report", GenerateDiscrepancyReport);
10906
14762
  drfp->recheck_btn = PushButton (c, "Recheck", RecheckDiscrepancyProc);
10907
14763
  SetObjectExtra (drfp->recheck_btn, drfp, NULL);
10908
14764
  
10909
 
  b = PushButton (c, "Configure", EditDiscrepancyConfigBtn);
 
14765
  b = PushButton (c, "Configure", GetReportEditButtonProc (report_type));
10910
14766
  SetObjectExtra (b, drfp, NULL);
10911
14767
  
10912
14768
  PushButton (c, "Dismiss", StdCancelButtonProc);
10913
14769
 
10914
 
  AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list_dlg, (HANDLE) c, NULL);
 
14770
  AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list_dlg, (HANDLE) c1, (HANDLE) c, NULL);
10915
14771
 
10916
14772
  RealizeWindow (w);
10917
14773
  
10918
14774
  /* populate discrepancy lists */
10919
14775
  RecheckDiscrepancyProc (drfp->recheck_btn);
10920
14776
  Show (w);
10921
 
  discrepancyReportWindow = w;
 
14777
  SetWindowForReportType (w, report_type);
10922
14778
}
10923
14779
 
 
14780
 
10924
14781
typedef struct sucform 
10925
14782
{
10926
14783
  CLICKABLE_LIST_FORM_BLOCK
13631
17488
      gene->location = TruncateLocation (gene->location, SeqLocLen (gene->location) - p->overlap_len);
13632
17489
    }
13633
17490
 
13634
 
    AddTranslExcept (p->cds, "TAA stop codon is completed by the addition of 3' A residues to the mRNA", FALSE, FALSE);
 
17491
    AddTranslExcept (p->cds, "TAA stop codon is completed by the addition of 3' A residues to the mRNA", FALSE, FALSE, FALSE);
13635
17492
  }
13636
17493
}  
13637
17494