~ubuntu-branches/ubuntu/vivid/ncbi-tools6/vivid-proposed

« back to all changes in this revision

Viewing changes to sequin/sequin8.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2009-03-19 10:17:26 UTC
  • mfrom: (1.3.1 upstream) (5.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090319101726-wjuj7ajnq0w5a0mg
Tags: 6.1.20090301-1
* New upstream release; uploading to unstable now that lenny is out.
* debian/lib{ncbi6,vibrant6a}.symbols: update accordingly.
* doc/man/*.1: update accordingly as well.
* debian/control: place lib*-dbg in the new debug section, per the
  current override file.
* debian/control: declare compliance with Policy 3.8.1 (no changes needed).
* api/aliread.c: merge in fix (from 6.1.20080302-4) to undefined use of
  sprintf caught by Kees Cook's scan.
* debian/watch: belatedly update regex to recognize releases like the
  previous one ([6.1.]20081116a).

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.524 $
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
896
898
}
897
899
 
898
900
 
899
 
extern Boolean RetranslateOneCDS 
900
 
( SeqFeatPtr sfp,
901
 
  Uint2 entityID,
902
 
  Boolean include_stop,
903
 
  Boolean no_stop_at_end_of_complete_cds)
904
 
 
905
 
{
906
 
  SeqFeatPtr    bestprot;
907
 
  ByteStorePtr  bs;
908
 
  BioseqPtr     bsp;
909
 
  Char          ch;
910
 
  SeqFeatPtr    gene;
911
 
  GeneRefPtr    grp;
912
 
  SeqEntryPtr   master;
913
 
  MolInfoPtr    mip;
914
 
  SeqEntryPtr   old;
915
 
  Boolean       partial5;
916
 
  Boolean       partial3;
917
 
  CharPtr       prot;
918
 
  CharPtr       ptr;
919
 
  SeqEntryPtr   sep;
920
 
  SeqIdPtr      sip;
921
 
  ValNodePtr    vnp;
922
 
  ProtRefPtr    prp;
923
 
 
924
 
  if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return TRUE;
925
 
 
926
 
  /* bail on pseudo CDS */
927
 
 
928
 
  if (sfp->pseudo) return TRUE;
929
 
  grp = SeqMgrGetGeneXref (sfp);
930
 
  if (grp != NULL) {
931
 
    if (grp->pseudo) return TRUE;
932
 
  } else {
933
 
    gene = SeqMgrGetOverlappingGene (sfp->location, NULL);
934
 
    if (gene != NULL) {
935
 
      if (gene->pseudo) return TRUE;
936
 
      grp = (GeneRefPtr) gene->data.value.ptrvalue;
937
 
      if (grp != NULL && grp->pseudo) return TRUE;
938
 
    }
939
 
  }
940
 
 
941
 
  if (sfp->location == NULL) return TRUE;
942
 
  CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
943
 
 
944
 
  if (sfp->product == NULL) {
945
 
    master = NULL;
946
 
    old = NULL;
947
 
    bsp = GetBioseqGivenSeqLoc (sfp->location, entityID);
948
 
    if (bsp != NULL) {
949
 
      master = GetBestTopParentForData (entityID, bsp);
950
 
    }
951
 
    bsp = BioseqNew ();
952
 
    if (bsp != NULL) {
953
 
      bsp->mol = Seq_mol_aa;
954
 
      bsp->repr = Seq_repr_raw;
955
 
      bsp->seq_data_type = Seq_code_ncbieaa;
956
 
      bsp->length = 0;
957
 
      bsp->seq_data = (SeqDataPtr) BSNew (0);
958
 
      if (master != NULL) {
959
 
        old = SeqEntrySetScope (master);
960
 
      }
961
 
      bsp->id = MakeNewProteinSeqId (sfp->location, NULL);
962
 
      SeqMgrAddToBioseqIndex (bsp);
963
 
      if (master != NULL) {
964
 
        SeqEntrySetScope (old);
965
 
      }
966
 
      sep = SeqEntryNew ();
967
 
      if (sep != NULL) {
968
 
        sep->choice = 1;
969
 
        sep->data.ptrvalue = (Pointer) bsp;
970
 
        SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
971
 
      }
972
 
      SetSeqFeatProduct (sfp, bsp);
973
 
      if (master != NULL && sep != NULL) {
974
 
        AddSeqEntryToSeqEntry (master, sep, TRUE);
975
 
      }
976
 
    }
977
 
  }
978
 
 
979
 
  sip = SeqLocId (sfp->product);
980
 
  if (sip != NULL) {
981
 
    bsp = BioseqFind (sip);
982
 
    if (bsp != NULL && ISA_aa (bsp->mol) && bsp->repr == Seq_repr_raw) {
983
 
      bestprot = FindBestProtein (entityID, sfp->product);
984
 
      bs = ProteinFromCdRegionExWithTrailingCodonHandling (sfp,
985
 
                                              include_stop,
986
 
                                              FALSE,
987
 
                                              no_stop_at_end_of_complete_cds );
988
 
      if (bs == NULL) return TRUE;
989
 
      prot = BSMerge (bs, NULL);
990
 
      bs = BSFree (bs);
991
 
      if (prot == NULL) return TRUE;
992
 
      ptr = prot;
993
 
      ch = *ptr;
994
 
      while (ch != '\0') {
995
 
        *ptr = TO_UPPER (ch);
996
 
        ptr++;
997
 
        ch = *ptr;
998
 
      }
999
 
      bs = BSNew (1000);
1000
 
      if (bs != NULL) {
1001
 
        ptr = prot;
1002
 
        /*
1003
 
        if (prot [0] == '-') {
1004
 
          ptr++;
1005
 
        }
1006
 
        */
1007
 
        BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
1008
 
      }
1009
 
      bsp->repr = Seq_repr_raw;
1010
 
      bsp->mol = Seq_mol_aa;
1011
 
      bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
1012
 
      bsp->seq_data = (SeqDataPtr) bs;
1013
 
      bsp->seq_data_type = Seq_code_ncbieaa;
1014
 
      bsp->length = BSLen (bs);
1015
 
      sep = SeqMgrGetSeqEntryForData (bsp);
1016
 
      if (sep == NULL) return TRUE;
1017
 
      if (bestprot == NULL)
1018
 
      {
1019
 
        bestprot = CreateNewFeature (sep, NULL, SEQFEAT_PROT, NULL);
1020
 
        prp = ProtRefNew ();
1021
 
        bestprot->data.value.ptrvalue = prp;
1022
 
      }
1023
 
      if (bestprot != NULL) {
1024
 
        bestprot->location = SeqLocFree (bestprot->location);
1025
 
        bestprot->location = CreateWholeInterval (sep);
1026
 
        SetSeqLocPartial (bestprot->location, partial5, partial3);
1027
 
        bestprot->partial = (partial5 || partial3);
1028
 
      }
1029
 
      vnp = SeqEntryGetSeqDescr (sep, Seq_descr_molinfo, NULL);
1030
 
      if (vnp == NULL) {
1031
 
        vnp = CreateNewDescriptor (sep, Seq_descr_molinfo);
1032
 
        if (vnp != NULL) {
1033
 
          mip = MolInfoNew ();
1034
 
          vnp->data.ptrvalue = (Pointer) mip;
1035
 
          if (mip != NULL) {
1036
 
            mip->biomol = 8;
1037
 
            mip->tech = 13;
1038
 
          }
1039
 
        }
1040
 
      }
1041
 
      if (vnp != NULL) {
1042
 
        mip = (MolInfoPtr) vnp->data.ptrvalue;
1043
 
        if (mip != NULL) {
1044
 
          if (partial5 && partial3) {
1045
 
            mip->completeness = 5;
1046
 
          } else if (partial5) {
1047
 
            mip->completeness = 3;
1048
 
          } else if (partial3) {
1049
 
            mip->completeness = 4;
1050
 
          /*
1051
 
          } else if (partial) {
1052
 
            mip->completeness = 2;
1053
 
          */
1054
 
          } else {
1055
 
            mip->completeness = 0;
1056
 
          }
1057
 
        }
1058
 
      }
1059
 
    }
1060
 
  }
1061
 
  return TRUE;
1062
 
}
1063
 
 
1064
901
static Boolean RetranslateCDSCallback (GatherContextPtr gcp)
1065
902
 
1066
903
{
2648
2485
  TexT           toTxt;
2649
2486
  Uint2          itemtype;
2650
2487
  Uint2          subtype;
 
2488
  CharPtr        extra_string;
2651
2489
  ValNodePtr     head;
2652
2490
  Boolean        stringfound;
2653
2491
  Char           findStr [128];
2768
2606
  DeleteMarkedObjects (rfp->input_entityID, OBJ_SEQENTRY, (Pointer) sep);
2769
2607
}
2770
2608
 
 
2609
 
 
2610
static Boolean IsUserObjectType (SeqDescrPtr sdp, CharPtr string)
 
2611
{
 
2612
  UserObjectPtr uop;
 
2613
  ObjectIdPtr   oip;
 
2614
 
 
2615
  if (sdp == NULL || sdp->choice != Seq_descr_user) return FALSE;
 
2616
  if (StringHasNoText (string)) return TRUE;
 
2617
 
 
2618
  uop = (UserObjectPtr) sdp->data.ptrvalue;
 
2619
  if (uop == NULL) return FALSE;
 
2620
  oip = uop->type;
 
2621
  if (oip == NULL || StringICmp (oip->str, string) != 0) return FALSE;
 
2622
  return TRUE;
 
2623
}
 
2624
 
 
2625
 
2771
2626
static void RemoveDescriptorCallback (SeqDescrPtr sdp, Pointer userdata)
2772
2627
{
2773
2628
  ObjValNodePtr ovp;
2781
2636
    
2782
2637
  if (sdp->choice == rfp->subtype) 
2783
2638
  {
2784
 
    ovp->idx.deleteme = TRUE;   
 
2639
    if (sdp->choice != Seq_descr_user || IsUserObjectType (sdp, rfp->extra_string)) {
 
2640
      ovp->idx.deleteme = TRUE; 
 
2641
    }
2785
2642
  }
2786
2643
}
2787
2644
 
2868
2725
    if (GetItemStatus (rfp->objlist, val))
2869
2726
    {
2870
2727
      rfp->subtype = vnp->choice;
 
2728
      rfp->extra_string = NULL;
2871
2729
      if (rfp->subtype != 0) {
2872
2730
        if (rfp->is_feature) {
2873
2731
          RemoveFeatures (sep, rfp);
2874
2732
          removed_some_features = TRUE;
2875
2733
        } else {
 
2734
          if (rfp->subtype == Seq_descr_user && StringCmp (vnp->data.ptrvalue, "User") != 0) {
 
2735
            rfp->extra_string = vnp->data.ptrvalue;
 
2736
          }
2876
2737
          RemoveDescriptors (sep, rfp);
2877
2738
        }
2878
2739
      }
3142
3003
  return head;
3143
3004
}
3144
3005
 
 
3006
 
3145
3007
static void RemoveAsnObject (IteM i, Boolean feature)
3146
3008
 
3147
3009
{
3212
3074
    head = BuildFeatureValNodeList (TRUE, "All", ALL_FEATURES, TRUE, FALSE);
3213
3075
  } else {
3214
3076
    head = BuildDescriptorValNodeList();
 
3077
    vnp = ValNodeNew (NULL);
 
3078
    vnp->choice = Seq_descr_user;
 
3079
    vnp->data.ptrvalue = StringSave ("StructuredComment");
 
3080
    ValNodeInsert (&(head->next), vnp, SortVnpByString);
3215
3081
  }
3216
3082
  if (head != NULL) {
3217
3083
 
4104
3970
          subtype != FEATDEF_mat_peptide &&
4105
3971
          subtype != FEATDEF_sig_peptide &&
4106
3972
          subtype != FEATDEF_transit_peptide &&
4107
 
          subtype != FEATDEF_Imp_CDS) {
 
3973
          subtype != FEATDEF_Imp_CDS &&
 
3974
          !IsUnwantedFeatureType(subtype)) {
4108
3975
        vnp = ValNodeNew (head);
4109
3976
        if (head == NULL) {
4110
3977
          head = vnp;
4544
4411
}
4545
4412
 
4546
4413
 
 
4414
typedef struct dblinkdialog {
 
4415
  DIALOG_MESSAGE_BLOCK
 
4416
  DialoG  traceassm;
 
4417
  DialoG  biosample;
 
4418
} DblinkDialog, PNTR DblinkDialogPtr;
 
4419
 
 
4420
typedef struct dblinkform {
 
4421
  FEATURE_FORM_BLOCK
 
4422
  SeqEntryPtr   sep;
 
4423
} DblinkForm, PNTR DblinkFormPtr;
 
4424
 
 
4425
static void UserObjectPtrToDblinkDialog (
 
4426
  DialoG d,
 
4427
  Pointer data
 
4428
)
 
4429
 
 
4430
{
 
4431
  Char             buf [32];
 
4432
  CharPtr PNTR     cpp;
 
4433
  UserFieldPtr     curr;
 
4434
  DblinkDialogPtr  ddp;
 
4435
  ValNodePtr       head;
 
4436
  Int4             i, val;
 
4437
  Int4Ptr          ip;
 
4438
  Int4             num;
 
4439
  ObjectIdPtr      oip;
 
4440
  CharPtr          str;
 
4441
  UserObjectPtr    uop;
 
4442
 
 
4443
  ddp = (DblinkDialogPtr) GetObjectExtra (d);
 
4444
  if (ddp == NULL) return;
 
4445
 
 
4446
  uop = (UserObjectPtr) data;
 
4447
  if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "DBLink") != 0) {
 
4448
    PointerToDialog (ddp->traceassm, NULL);
 
4449
    PointerToDialog (ddp->biosample, NULL);
 
4450
    return;
 
4451
  }
 
4452
 
 
4453
  for (curr = uop->data; curr != NULL; curr = curr->next) {
 
4454
    oip = curr->label;
 
4455
    if (oip == NULL) continue;
 
4456
    if (StringICmp (oip->str, "Trace Assembly Archive") == 0) {
 
4457
      if (curr->choice == 8) {
 
4458
        num = curr->num;
 
4459
        ip = (Int4Ptr) curr->data.ptrvalue;
 
4460
        if (num > 0 && ip != NULL) {
 
4461
          head = NULL;
 
4462
          for (i = 0; i < num; i++) {
 
4463
            val = ip [i];
 
4464
            if (val > 0) {
 
4465
              sprintf (buf, "%ld", (long) val);
 
4466
              ValNodeCopyStr (&head, 0, buf);
 
4467
            }
 
4468
          }
 
4469
          if (head != NULL) {
 
4470
            PointerToDialog (ddp->traceassm, (Pointer) head);
 
4471
          }
 
4472
          ValNodeFreeData (head);
 
4473
        }
 
4474
      }
 
4475
    } else if (StringICmp (oip->str, "Bio Sample") == 0) {
 
4476
      if (curr->choice == 7) {
 
4477
        num = curr->num;
 
4478
        cpp = (CharPtr PNTR) curr->data.ptrvalue;
 
4479
        if (num > 0 && cpp != NULL) {
 
4480
          head = NULL;
 
4481
          for (i = 0; i < num; i++) {
 
4482
            str = cpp [i];
 
4483
            if (StringDoesHaveText (str)) {
 
4484
              ValNodeCopyStr (&head, 0, str);
 
4485
            }
 
4486
          }
 
4487
          if (head != NULL) {
 
4488
            PointerToDialog (ddp->biosample, (Pointer) head);
 
4489
          }
 
4490
          ValNodeFreeData (head);
 
4491
        }
 
4492
      }
 
4493
    }
 
4494
  }
 
4495
}
 
4496
 
 
4497
static Pointer DblinkDialogToUserObjectPtr (
 
4498
  DialoG d
 
4499
)
 
4500
 
 
4501
{
 
4502
  CharPtr PNTR     cpp;
 
4503
  DblinkDialogPtr  ddp;
 
4504
  ValNodePtr       head, vnp;
 
4505
  Int4             i, num;
 
4506
  Int4Ptr          ipp;
 
4507
  Boolean          okay = FALSE;
 
4508
  CharPtr          str;
 
4509
  UserObjectPtr    uop;
 
4510
  long int         val;
 
4511
 
 
4512
  ddp = (DblinkDialogPtr) GetObjectExtra (d);
 
4513
  if (ddp == NULL) return NULL;
 
4514
 
 
4515
  uop = CreateDBLinkUserObject ();
 
4516
  if (uop == NULL) return NULL;
 
4517
 
 
4518
  head = (ValNodePtr) DialogToPointer (ddp->traceassm);
 
4519
  if (head != NULL) {
 
4520
    num = 0;
 
4521
    for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
4522
      str = (CharPtr) vnp->data.ptrvalue;
 
4523
      if (StringHasNoText (str)) continue;
 
4524
      num++;
 
4525
    }
 
4526
    if (num > 0) {
 
4527
      ipp = (Int4Ptr) MemNew (sizeof (Int4) * num);
 
4528
      if (ipp != NULL) {
 
4529
        i = 0;
 
4530
        for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
4531
          str = (CharPtr) vnp->data.ptrvalue;
 
4532
          if (StringHasNoText (str)) continue;
 
4533
          if (sscanf (str, "%ld", &val) == 1) {
 
4534
            ipp [i] = (Int4) val;
 
4535
            i++;
 
4536
          }
 
4537
        }
 
4538
        if (i > 0) {
 
4539
          AddTraceAssemblyIDsToDBLinkUserObject (uop, i, ipp);
 
4540
          okay = TRUE;
 
4541
        }
 
4542
      }
 
4543
    }
 
4544
  }
 
4545
  ValNodeFreeData (head);
 
4546
 
 
4547
  head = (ValNodePtr) DialogToPointer (ddp->biosample);
 
4548
  if (head != NULL) {
 
4549
    num = 0;
 
4550
    for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
4551
      str = (CharPtr) vnp->data.ptrvalue;
 
4552
      if (StringHasNoText (str)) continue;
 
4553
      num++;
 
4554
    }
 
4555
    if (num > 0) {
 
4556
      cpp = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num);
 
4557
      if (cpp != NULL) {
 
4558
        i = 0;
 
4559
        for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
4560
          str = (CharPtr) vnp->data.ptrvalue;
 
4561
          if (StringHasNoText (str)) continue;
 
4562
          cpp [i] = str;
 
4563
          i++;
 
4564
        }
 
4565
        if (i > 0) {
 
4566
          AddBioSampleIDsToDBLinkUserObject (uop, i, cpp);
 
4567
          okay = TRUE;
 
4568
        }
 
4569
      }
 
4570
    }
 
4571
  }
 
4572
  ValNodeFreeData (head);
 
4573
 
 
4574
  if (! okay) {
 
4575
    uop = UserObjectFree (uop);
 
4576
  }
 
4577
 
 
4578
  return uop;
 
4579
}
 
4580
 
 
4581
static DialoG CreateDblinkDialog (
 
4582
  GrouP g
 
4583
)
 
4584
 
 
4585
{
 
4586
  DblinkDialogPtr  ddp;
 
4587
  GrouP            p, x;
 
4588
 
 
4589
  p = HiddenGroup (g, -1, 0, NULL);
 
4590
  SetGroupSpacing (p, 10, 10);
 
4591
 
 
4592
  ddp = (DblinkDialogPtr) MemNew (sizeof (DblinkDialog));
 
4593
  if (ddp == NULL) return NULL;
 
4594
 
 
4595
  SetObjectExtra (p, ddp, NULL);
 
4596
  ddp->dialog = (DialoG) p;
 
4597
  ddp->todialog = UserObjectPtrToDblinkDialog;
 
4598
  ddp->fromdialog = DblinkDialogToUserObjectPtr;
 
4599
 
 
4600
  x = HiddenGroup (p, 0, 8, NULL);
 
4601
 
 
4602
  StaticPrompt (x, "Trace Assembly", 10 * stdCharWidth, 0, programFont, 'c');
 
4603
  ddp->traceassm = CreateVisibleStringDialog (x, 3, -1, 15);
 
4604
 
 
4605
  StaticPrompt (x, "Bio Sample", 10 * stdCharWidth, 0, programFont, 'c');
 
4606
  ddp->biosample = CreateVisibleStringDialog (x, 3, -1, 15);
 
4607
 
 
4608
  return (DialoG) p;
 
4609
}
 
4610
 
 
4611
static void DblinkFormMessage (
 
4612
  ForM f,
 
4613
  Int2 mssg
 
4614
)
 
4615
 
 
4616
{
 
4617
  DblinkFormPtr  dfp;
 
4618
 
 
4619
  dfp = (DblinkFormPtr) GetObjectExtra (f);
 
4620
  if (dfp != NULL) {
 
4621
    switch (mssg) {
 
4622
      case VIB_MSG_CLOSE :
 
4623
        Remove (f);
 
4624
        break;
 
4625
      case VIB_MSG_CUT :
 
4626
        StdCutTextProc (NULL);
 
4627
        break;
 
4628
      case VIB_MSG_COPY :
 
4629
        StdCopyTextProc (NULL);
 
4630
        break;
 
4631
      case VIB_MSG_PASTE :
 
4632
        StdPasteTextProc (NULL);
 
4633
        break;
 
4634
      case VIB_MSG_DELETE :
 
4635
        StdDeleteTextProc (NULL);
 
4636
        break;
 
4637
      default :
 
4638
        if (dfp->appmessage != NULL) {
 
4639
          dfp->appmessage (f, mssg);
 
4640
        }
 
4641
        break;
 
4642
    }
 
4643
  }
 
4644
}
 
4645
 
 
4646
static ForM CreateDblinkDescForm (
 
4647
  Int2 left,
 
4648
  Int2 top,
 
4649
  Int2 width,
 
4650
  Int2 height,
 
4651
  CharPtr title,
 
4652
  ValNodePtr sdp,
 
4653
  SeqEntryPtr sep,
 
4654
  FormActnFunc actproc
 
4655
)
 
4656
 
 
4657
{
 
4658
  ButtoN             b;
 
4659
  DblinkFormPtr      dfp;
 
4660
  GrouP              c, g;
 
4661
  StdEditorProcsPtr  sepp;
 
4662
  WindoW             w;
 
4663
 
 
4664
  w = NULL;
 
4665
  dfp = (DblinkFormPtr) MemNew (sizeof (DblinkForm));
 
4666
 
 
4667
  if (dfp != NULL) {
 
4668
    w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
 
4669
    SetObjectExtra (w, dfp, StdDescFormCleanupProc);
 
4670
    dfp->form = (ForM) w;
 
4671
    dfp->actproc = actproc;
 
4672
    dfp->formmessage = DblinkFormMessage;
 
4673
 
 
4674
    dfp->sep = sep;
 
4675
 
 
4676
#ifndef WIN_MAC
 
4677
    CreateStdEditorFormMenus (w);
 
4678
#endif
 
4679
    sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
 
4680
    if (sepp != NULL) {
 
4681
      SetActivate (w, sepp->activateForm);
 
4682
      dfp->appmessage = sepp->handleMessages;
 
4683
    }
 
4684
 
 
4685
    g = HiddenGroup (w, -1, 0, NULL);
 
4686
    dfp->data = CreateDblinkDialog (g);
 
4687
 
 
4688
    c = HiddenGroup (w, 2, 0, NULL);
 
4689
    b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
 
4690
    SetObjectExtra (b, dfp, NULL);
 
4691
    PushButton (c, "Cancel", StdCancelButtonProc);
 
4692
    AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
4693
    RealizeWindow (w);
 
4694
  }
 
4695
 
 
4696
  return (ForM) w;
 
4697
}
 
4698
 
 
4699
extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data);
 
4700
extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data)
 
4701
 
 
4702
{
 
4703
  ObjectIdPtr              oip;
 
4704
  OMProcControlPtr         ompcp;
 
4705
  OMUserDataPtr            omudp;
 
4706
  ObjMgrProcPtr            proc;
 
4707
  DblinkFormPtr            dfp;
 
4708
  ValNodePtr               sdp;
 
4709
  SeqEntryPtr              sep;
 
4710
  UserObjectPtr            uop;
 
4711
  WindoW                   w;
 
4712
 
 
4713
  ompcp = (OMProcControlPtr) data;
 
4714
  w = NULL;
 
4715
  sdp = NULL;
 
4716
  sep = NULL;
 
4717
  uop = NULL;
 
4718
  if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
 
4719
  proc = ompcp->proc;
 
4720
  switch (ompcp->input_itemtype) {
 
4721
    case OBJ_SEQDESC :
 
4722
      sdp = (ValNodePtr) ompcp->input_data;
 
4723
      if (sdp != NULL && sdp->choice != Seq_descr_user) {
 
4724
        return OM_MSG_RET_ERROR;
 
4725
      }
 
4726
      uop = (UserObjectPtr) sdp->data.ptrvalue;
 
4727
      break;
 
4728
    case OBJ_BIOSEQ :
 
4729
      break;
 
4730
    case OBJ_BIOSEQSET :
 
4731
      break;
 
4732
    case 0 :
 
4733
      break;
 
4734
    default :
 
4735
      return OM_MSG_RET_ERROR;
 
4736
  }
 
4737
  omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
 
4738
                                ompcp->input_itemtype, ompcp->proc->procid);
 
4739
  if (omudp != NULL) {
 
4740
    if (StringCmp (proc->procname, "Edit DBLink User Desc") == 0) {
 
4741
      dfp = (DblinkFormPtr) omudp->userdata.ptrvalue;
 
4742
      if (dfp != NULL) {
 
4743
        Select (dfp->form);
 
4744
      }
 
4745
      return OM_MSG_RET_DONE;
 
4746
    } else {
 
4747
      return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
 
4748
    }
 
4749
  }
 
4750
  if (uop != NULL) {
 
4751
    oip = uop->type;
 
4752
    if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
 
4753
    if (StringCmp (oip->str, "DBLink") != 0) return OM_MSG_RET_OK;
 
4754
  }
 
4755
  sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
 
4756
  w = (WindoW) CreateDblinkDescForm (-50, -33, -10, -10,
 
4757
                                     "DBLink", sdp, sep,
 
4758
                                     StdDescFormActnProc);
 
4759
  dfp = (DblinkFormPtr) GetObjectExtra (w);
 
4760
  if (dfp != NULL) {
 
4761
    dfp->input_entityID = ompcp->input_entityID;
 
4762
    dfp->input_itemID = ompcp->input_itemID;
 
4763
    dfp->input_itemtype = ompcp->input_itemtype;
 
4764
    dfp->this_itemtype = OBJ_SEQDESC;
 
4765
    dfp->this_subtype = Seq_descr_user;
 
4766
    dfp->procid = ompcp->proc->procid;
 
4767
    dfp->proctype = ompcp->proc->proctype;
 
4768
    dfp->userkey = OMGetNextUserKey ();
 
4769
    omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
 
4770
                                   OMPROC_EDIT, dfp->userkey);
 
4771
    if (omudp != NULL) {
 
4772
      omudp->userdata.ptrvalue = (Pointer) dfp;
 
4773
      omudp->messagefunc = StdVibrantEditorMsgFunc;
 
4774
    }
 
4775
    SendMessageToForm (dfp->form, VIB_MSG_INIT);
 
4776
    if (sdp != NULL) {
 
4777
      PointerToDialog (dfp->data, (Pointer) sdp->data.ptrvalue);
 
4778
      SetClosestParentIfDuplicating ((BaseFormPtr) dfp);
 
4779
    }
 
4780
  }
 
4781
  Show (w);
 
4782
  Select (w);
 
4783
  return OM_MSG_RET_DONE;
 
4784
}
 
4785
 
4547
4786
 
4548
4787
extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data);
4549
4788
 
4559
4798
  GrouP         status;
4560
4799
  ButtoN        generated;
4561
4800
  TexT          curator;
 
4801
  TexT          url;
4562
4802
  TexT          source;
4563
4803
  Int2          indexer;
4564
4804
  DialoG        fields;
4785
5025
    str = (CharPtr) curr->data.ptrvalue;
4786
5026
    SetTitle (rdp->curator, str);
4787
5027
  }
 
5028
 
 
5029
  for (curr = uop->data; curr != NULL; curr = curr->next) {
 
5030
    oip = curr->label;
 
5031
    if (oip != NULL && StringICmp (oip->str, "CollaboratorURL") == 0) {
 
5032
      break;
 
5033
    }
 
5034
  }
 
5035
  if (curr != NULL && curr->choice == 1) {
 
5036
    str = (CharPtr) curr->data.ptrvalue;
 
5037
    SetTitle (rdp->url, str);
 
5038
  }
 
5039
 
4788
5040
  for (curr = uop->data; curr != NULL; curr = curr->next) {
4789
5041
    oip = curr->label;
4790
5042
    if (oip != NULL && StringICmp (oip->str, "GenomicSource") == 0) {
4861
5113
  TagListPtr            tlp;
4862
5114
  CharPtr               txt [6];
4863
5115
  UserObjectPtr         uop;
 
5116
  Char                  url [512];
4864
5117
  long int              val;
4865
5118
  ValNodePtr            vnp;
4866
5119
 
4903
5156
    AddCuratorToRefGeneTrackUserObject (uop, curator);
4904
5157
  }
4905
5158
 
 
5159
  GetTitle (rdp->url, url, sizeof (url));
 
5160
  if (! StringHasNoText (url)) {
 
5161
    AddCuratorURLToRefGeneTrackUserObject (uop, url);
 
5162
  }
 
5163
 
4906
5164
  if (rdp->indexer > 0) {
4907
5165
    AddIndexerToRefGeneTrackUserObject (uop, rdp->indexer);
4908
5166
  }
4968
5226
  TagListPtr            tlp;
4969
5227
  GrouP                 x;
4970
5228
  GrouP                 y;
 
5229
  GrouP                 z;
4971
5230
 
4972
5231
  p = HiddenGroup (g, -1, 0, NULL);
4973
5232
  SetGroupSpacing (p, 10, 10);
4996
5255
 
4997
5256
  y = HiddenGroup (p, 6, 0, NULL);
4998
5257
  rdp->generated = CheckBox (y, "Generated", NULL);
4999
 
  StaticPrompt (y, "Curator", 0, dialogTextHeight, programFont, 'l');
5000
 
  rdp->curator = DialogText (y, "", 14, NULL);
 
5258
  z = HiddenGroup (y, 2, 0, NULL);
 
5259
  StaticPrompt (z, "Curator", 0, dialogTextHeight, programFont, 'l');
 
5260
  rdp->curator = DialogText (z, "", 14, NULL);
 
5261
  StaticPrompt (z, "URL", 0, dialogTextHeight, programFont, 'r');
 
5262
  rdp->url = DialogText (z, "", 14, NULL);
5001
5263
  StaticPrompt (y, "Genomic Source", 0, dialogTextHeight, programFont, 'l');
5002
5264
  rdp->source = DialogText (y, "", 7, NULL);
5003
5265
 
5822
6084
        return SeqIdSelect (sip, order, NUM_SEQID);
5823
6085
}
5824
6086
 
 
6087
 
 
6088
static Boolean ValidateTPAHistAlign (BioseqPtr bsp, ValNodePtr PNTR errors)
 
6089
{
 
6090
  ValNodePtr new_errors;
 
6091
  Boolean    retval = TRUE;
 
6092
  SeqAlignPtr salp;
 
6093
 
 
6094
  if (bsp == NULL || bsp->hist == NULL || bsp->hist->assembly == NULL) {
 
6095
    return FALSE;
 
6096
  }
 
6097
 
 
6098
  for (salp = bsp->hist->assembly; salp != NULL; salp = salp->next) {
 
6099
    AlnMgr2IndexSingleChildSeqAlign(salp);
 
6100
  }
 
6101
 
 
6102
  new_errors = ReportCoverageForBioseqSeqHist (bsp);
 
6103
  if (new_errors != NULL) {
 
6104
    ValNodeLink (errors, new_errors);
 
6105
    retval = FALSE;
 
6106
  }
 
6107
  return retval;
 
6108
}
 
6109
 
 
6110
 
5825
6111
static Boolean CKA_ValidateSeqAlign(SeqAlignPtr sap, CKA_AccPtr acc_head, Int4 bioseqlen, ValNodePtr PNTR errors)
5826
6112
{
5827
6113
   CKA_AccPtr        acc;
5838
6124
   Int4              max;
5839
6125
   Int4              n;
5840
6126
   Int4              prev;
5841
 
   Boolean           retval;
 
6127
   Boolean           retval = TRUE;
5842
6128
   CharPtr           textid;
5843
6129
   Char              textid2[42];
5844
6130
   CharPtr           err_msg;
6118
6404
 
6119
6405
  for (vnp = errors; vnp != NULL; vnp = vnp->next)
6120
6406
  {
6121
 
    fprintf (lip->fp, vnp->data.ptrvalue);
 
6407
    fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
6122
6408
    lip->data_in_log = TRUE;
6123
6409
  }
6124
6410
  fprintf (lip->fp, "\n\n");
6212
6498
           acc = acc->next;
6213
6499
         }
6214
6500
 
6215
 
               if (CKA_ValidateSeqAlign(sap, acc_head, bsp->length, &err_list))
 
6501
         if (sap != NULL) {
 
6502
            AlnMgr2IndexLite(sap);
 
6503
            AlnMgr2SortAlnSetByNthRowPos(sap, 1);
 
6504
                  /* make seq-hist and add it to record */
 
6505
                  if (bsp->hist != NULL)
 
6506
                  {
 
6507
                      shp = bsp->hist;
 
6508
                      if (shp->assembly != NULL)
 
6509
                        SeqAlignSetFree(shp->assembly);
 
6510
                      shp->assembly = (SeqAlignPtr)(sap->segs);
 
6511
                  }
 
6512
            else
 
6513
                  {
 
6514
                      shp = SeqHistNew();
 
6515
                      shp->assembly = (SeqAlignPtr)(sap->segs);
 
6516
                      bsp->hist = shp;
 
6517
                  }
 
6518
         }
 
6519
      
 
6520
         if (ValidateTPAHistAlign(bsp, &err_list)) 
6216
6521
         {
6217
6522
            fprintf (lip->fp, "Alignments were successfully created and are being added to %s.\n", textid);
6218
6523
            lip->data_in_log = TRUE;
6240
6545
            err_list = ValNodeFreeData (err_list);
6241
6546
         }
6242
6547
 
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);
 
6548
         if (sap != NULL) {
 
6549
            sap->segs = NULL;
 
6550
            SeqAlignFree(sap);
 
6551
         }
6261
6552
             } 
6262
6553
     else
6263
6554
     {
6280
6571
  lip = FreeLog (lip);
6281
6572
}
6282
6573
 
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
 
}
 
6574
 
 
6575
typedef struct seqalignrow {
 
6576
  Int4 start;
 
6577
  Int4 stop;
 
6578
  Uint1 strand;
 
6579
} SeqAlignRowData, PNTR SeqAlignRowPtr;
 
6580
 
 
6581
static SeqAlignRowPtr SeqAlignRowNew (Int4 start, Int4 stop, Uint1 strand)
 
6582
{
 
6583
  SeqAlignRowPtr r;
 
6584
  Int4 tmp;
 
6585
 
 
6586
  r = (SeqAlignRowPtr) MemNew (sizeof (SeqAlignRowData));
 
6587
  r->start = start;
 
6588
  r->stop = stop;
 
6589
 
 
6590
  if (r->start > r->stop) {
 
6591
    tmp = r->start;
 
6592
    r->start = r->stop;
 
6593
    r->stop = tmp;
 
6594
  }
 
6595
  r->strand = strand;
 
6596
  return r;
 
6597
}
 
6598
 
 
6599
 
 
6600
static SeqAlignRowPtr SeqAlignRowCopy (SeqAlignRowPtr orig)
 
6601
{
 
6602
  SeqAlignRowPtr r = NULL;
 
6603
 
 
6604
  if (orig != NULL) {
 
6605
    r = SeqAlignRowNew (orig->start, orig->stop, orig->strand);
 
6606
  }
 
6607
  return r;
 
6608
}
 
6609
 
 
6610
 
 
6611
static SeqAlignRowPtr SeqAlignRowFree (SeqAlignRowPtr r)
 
6612
{
 
6613
  r = MemFree (r);
 
6614
  return r;
 
6615
}
 
6616
 
 
6617
 
 
6618
static Int4 RowDiff (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
 
6619
{
 
6620
  Int4 diff = 0;
 
6621
 
 
6622
  if (r1 == NULL || r2 == NULL) {
 
6623
    return -1;
 
6624
  }
 
6625
 
 
6626
  diff = ABS(r1->start - r2->start) + ABS (r1->stop - r2->stop);
 
6627
  return diff;
 
6628
}
 
6629
 
 
6630
 
 
6631
static Int4 SeqAlignRowLen (SeqAlignRowPtr r) 
 
6632
{
 
6633
  Int4 len = 0;
 
6634
 
 
6635
  if (r != NULL) {
 
6636
    len = r->stop - r->start + 1;
 
6637
  }
 
6638
  return len;
 
6639
}
 
6640
 
 
6641
 
 
6642
typedef struct seqalignsort {
 
6643
  SeqAlignRowPtr row1;
 
6644
  SeqAlignRowPtr row2;
 
6645
  SeqAlignPtr salp;
 
6646
} SeqAlignSortData, PNTR SeqAlignSortPtr;
 
6647
 
 
6648
 
 
6649
static SeqAlignSortPtr SeqAlignSortNew (SeqAlignPtr salp)
 
6650
{
 
6651
  SeqAlignSortPtr s;
 
6652
 
 
6653
  if (salp == NULL) {
 
6654
    return NULL;
 
6655
  }
 
6656
 
 
6657
  s = (SeqAlignSortPtr) MemNew (sizeof (SeqAlignSortData));
 
6658
  s->salp = salp;
 
6659
 
 
6660
  AlnMgr2IndexSingleChildSeqAlign(salp);
 
6661
 
 
6662
  s->row1 = SeqAlignRowNew (SeqAlignStart (salp, 0), SeqAlignStop (salp, 0), SeqAlignStrand (salp, 0));
 
6663
  s->row2 = SeqAlignRowNew (SeqAlignStart (salp, 1), SeqAlignStop (salp, 1), SeqAlignStrand (salp, 1));
 
6664
 
 
6665
  return s;
 
6666
}
 
6667
 
 
6668
 
 
6669
static SeqAlignSortPtr SeqAlignSortFree (SeqAlignSortPtr s)
 
6670
{
 
6671
  if (s != NULL) {
 
6672
    s->row1 = SeqAlignRowFree (s->row1);
 
6673
    s->row2 = SeqAlignRowFree (s->row2);
 
6674
    s = MemFree (s);
 
6675
  }
 
6676
  return s;
 
6677
}
 
6678
 
 
6679
 
 
6680
static ValNodePtr SeqAlignSortListNew (SeqAlignPtr salp)
 
6681
{
 
6682
  ValNodePtr list = NULL;
 
6683
  SeqAlignPtr salp_next;
 
6684
 
 
6685
  while (salp != NULL) {
 
6686
    salp_next = salp->next;
 
6687
    salp->next = NULL;
 
6688
    ValNodeAddPointer (&list, 0, SeqAlignSortNew (salp));
 
6689
    salp = salp_next;
 
6690
  }
 
6691
  return list;
 
6692
}
 
6693
 
 
6694
 
 
6695
static ValNodePtr SeqAlignSortListFree (ValNodePtr vnp)
 
6696
{
 
6697
  ValNodePtr vnp_next;
 
6698
 
 
6699
  while (vnp != NULL) {
 
6700
    vnp_next = vnp->next;
 
6701
    vnp->next = NULL;
 
6702
    vnp->data.ptrvalue = SeqAlignSortFree (vnp->data.ptrvalue);
 
6703
    vnp = ValNodeFree (vnp);
 
6704
    vnp = vnp_next;
 
6705
  }
 
6706
  return vnp;
 
6707
}
 
6708
 
 
6709
 
 
6710
static SeqAlignRowPtr SeqAlignRowFromSeqAlignSort (SeqAlignSortPtr s, Int4 row)
 
6711
{
 
6712
  if (s == NULL) {
 
6713
    return NULL;
 
6714
  } else if (row == 1) {
 
6715
    return s->row1;
 
6716
  } else {
 
6717
    return s->row2;
 
6718
  }
 
6719
}
 
6720
 
 
6721
 
 
6722
static Uint1 SeqAlignSortRowStrand (SeqAlignSortPtr s, Int4 row)
 
6723
{
 
6724
  Uint1 strand = Seq_strand_plus;
 
6725
  SeqAlignRowPtr r;
 
6726
 
 
6727
  r = SeqAlignRowFromSeqAlignSort (s, row);
 
6728
  if (r != NULL) {
 
6729
    strand = r->strand;
 
6730
  }
 
6731
  return strand;
 
6732
}
 
6733
 
 
6734
 
 
6735
static Uint1 SeqAlignSortListFindBestStrand (ValNodePtr vnp, Int4 row)
 
6736
{
 
6737
  Int4 num_plus = 0, num_minus = 0;
 
6738
  SeqAlignSortPtr s;
 
6739
 
 
6740
  while (vnp != NULL) {
 
6741
    s = (SeqAlignSortPtr) vnp->data.ptrvalue;
 
6742
    if (s != NULL) {
 
6743
      if (SeqAlignSortRowStrand(s, row) == Seq_strand_minus) {
 
6744
        num_minus++;
 
6745
      } else {
 
6746
        num_plus++;
 
6747
      }
 
6748
    }
 
6749
    vnp = vnp->next;
 
6750
  }
 
6751
 
 
6752
  if (num_minus > num_plus) {
 
6753
    return Seq_strand_minus;
 
6754
  } else {
 
6755
    return Seq_strand_plus;
 
6756
  }
 
6757
}
 
6758
 
 
6759
 
 
6760
static void SeqAlignSortListMarkStrand (ValNodePtr vnp, Int4 row, Uint1 strand)
 
6761
{
 
6762
  while (vnp != NULL) {
 
6763
    if (SeqAlignSortRowStrand (vnp->data.ptrvalue, row) == strand) {
 
6764
      vnp->choice = 1;
 
6765
    }
 
6766
    vnp = vnp->next;
 
6767
  }
 
6768
}
 
6769
 
 
6770
 
 
6771
static ValNodePtr SeqAlignSortListRemoveAll (ValNodePtr list)
 
6772
{
 
6773
  ValNodePtr vnp;
 
6774
  SeqAlignSortPtr s;
 
6775
 
 
6776
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
6777
    s = vnp->data.ptrvalue;
 
6778
    if (s != NULL && s->salp != NULL) {
 
6779
      s->salp->next = NULL;
 
6780
      s->salp = SeqAlignFree (s->salp);
 
6781
    }
 
6782
  }
 
6783
 
 
6784
  list = SeqAlignSortListFree (list);
 
6785
  return list;
 
6786
}
 
6787
 
 
6788
 
 
6789
static void SeqAlignSortListRemoveMarked (ValNodePtr PNTR list)
 
6790
{
 
6791
  ValNodePtr remove_list;
 
6792
 
 
6793
  if (list == NULL) {
 
6794
    return;
 
6795
  }
 
6796
 
 
6797
  remove_list = ValNodeExtractList (list, 1);
 
6798
  remove_list = SeqAlignSortListRemoveAll (remove_list);
 
6799
}
 
6800
 
 
6801
 
 
6802
static Uint1 SeqAlignSortListRemoveConflictingStrands (ValNodePtr PNTR list, Int4 row)
 
6803
{
 
6804
  Uint1 strand;
 
6805
 
 
6806
  if (list == NULL) {
 
6807
    return Seq_strand_plus;
 
6808
  }
 
6809
 
 
6810
  strand = SeqAlignSortListFindBestStrand (*list, row);
 
6811
  if (strand == Seq_strand_plus) {
 
6812
    SeqAlignSortListMarkStrand (*list, row, Seq_strand_minus);
 
6813
  } else {
 
6814
    SeqAlignSortListMarkStrand (*list, row, Seq_strand_plus);
 
6815
  }
 
6816
 
 
6817
  SeqAlignSortListRemoveMarked (list);
 
6818
  return strand;
 
6819
}
 
6820
 
 
6821
 
 
6822
static SeqAlignPtr SeqAlignFromSeqAlignSortList (ValNodePtr vnp)
 
6823
{
 
6824
  SeqAlignPtr salp_list = NULL, salp_prev = NULL;
 
6825
  SeqAlignSortPtr s;
 
6826
 
 
6827
  while (vnp != NULL) {
 
6828
    s = (SeqAlignSortPtr) vnp->data.ptrvalue;
 
6829
    if (s != NULL && s->salp != NULL) {
 
6830
      s->salp->next = NULL;
 
6831
      if (salp_prev == NULL) {
 
6832
        salp_list = s->salp;
 
6833
      } else {
 
6834
        salp_prev->next = s->salp;
 
6835
      }
 
6836
      salp_prev = s->salp;
 
6837
      s->salp->next = NULL;
 
6838
    }
 
6839
    vnp = vnp->next;
 
6840
  }
 
6841
  return salp_list;
 
6842
}
 
6843
 
 
6844
 
 
6845
static int CompareSeqAlignRow (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
 
6846
{
 
6847
  int rval = 0;
 
6848
 
 
6849
  if (r1 == NULL && r2 == NULL) {
 
6850
    rval = 0;
 
6851
  } else if (r1 == NULL) {
 
6852
    rval = -1;
 
6853
  } else if (r2 == NULL) {
 
6854
    rval = 1;
 
6855
  } else if (r1->start < r2->start) {
 
6856
    rval = -1;
 
6857
  } else if (r1->start > r2->start) {
 
6858
    rval = 1;
 
6859
  } else if (r1->stop < r2->stop) {
 
6860
    rval = -1;
 
6861
  } else if (r1->stop > r2->stop) {
 
6862
    rval = 1;
 
6863
  } else if (r1->strand < r2->strand) {
 
6864
    rval = -1;
 
6865
  } else if (r1->strand > r2->strand) {
 
6866
    rval = 1;
 
6867
  }
 
6868
  return rval;
 
6869
}
 
6870
 
 
6871
 
 
6872
static int CompareSeqAlignSortPreferRow1 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
 
6873
{
 
6874
  int rval = 0;
 
6875
  if (s1 == NULL && s2 == NULL) {
 
6876
    rval = 0;
 
6877
  } else if (s1 == NULL) {
 
6878
    rval = -1;
 
6879
  } else if (s2 == NULL) {
 
6880
    rval = 1;
 
6881
  } else if ((rval = CompareSeqAlignRow (s1->row1,s2->row1)) == 0) {
 
6882
    rval = CompareSeqAlignRow (s1->row2, s2->row2);
 
6883
  }
 
6884
  return rval;
 
6885
}
 
6886
 
 
6887
 
 
6888
static int CompareSeqAlignSortPreferRow2 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
 
6889
{
 
6890
  int rval = 0;
 
6891
  if (s1 == NULL && s2 == NULL) {
 
6892
    rval = 0;
 
6893
  } else if (s1 == NULL) {
 
6894
    rval = -1;
 
6895
  } else if (s2 == NULL) {
 
6896
    rval = 1;
 
6897
  } else if ((rval = CompareSeqAlignRow (s1->row2,s2->row2)) == 0) {
 
6898
    rval = CompareSeqAlignRow (s1->row1, s2->row1);
 
6899
  }
 
6900
  return rval;
 
6901
}
 
6902
 
 
6903
 
 
6904
 
 
6905
static int LIBCALLBACK SortVnpBySeqAlignSortRow1 (VoidPtr ptr1, VoidPtr ptr2)
 
6906
 
 
6907
{
 
6908
  ValNodePtr  vnp1;
 
6909
  ValNodePtr  vnp2;
 
6910
 
 
6911
  if (ptr1 != NULL && ptr2 != NULL) {
 
6912
    vnp1 = *((ValNodePtr PNTR) ptr1);
 
6913
    vnp2 = *((ValNodePtr PNTR) ptr2);
 
6914
    if (vnp1 != NULL && vnp2 != NULL) {
 
6915
      return CompareSeqAlignSortPreferRow1 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
 
6916
    }
 
6917
  }
 
6918
  return 0;
 
6919
}
 
6920
 
 
6921
 
 
6922
static int LIBCALLBACK SortVnpBySeqAlignSortRow2 (VoidPtr ptr1, VoidPtr ptr2)
 
6923
 
 
6924
{
 
6925
  ValNodePtr  vnp1;
 
6926
  ValNodePtr  vnp2;
 
6927
 
 
6928
  if (ptr1 != NULL && ptr2 != NULL) {
 
6929
    vnp1 = *((ValNodePtr PNTR) ptr1);
 
6930
    vnp2 = *((ValNodePtr PNTR) ptr2);
 
6931
    if (vnp1 != NULL && vnp2 != NULL) {
 
6932
      return CompareSeqAlignSortPreferRow2 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
 
6933
    }
 
6934
  }
 
6935
  return 0;
 
6936
}
 
6937
 
 
6938
 
 
6939
static ValNodePtr SeqAlignSortListExtractRepeats (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
 
6940
{
 
6941
  ValNodePtr repeat_start, repeat_prev = NULL, vnp_prev = NULL, vnp;
 
6942
  ValNodePtr repeat_list = NULL;
 
6943
  SeqAlignSortPtr s1, s2;
 
6944
  SeqAlignRowPtr  interval, r2;
 
6945
  Int4            diff;
 
6946
  Boolean         is_repeat;
 
6947
 
 
6948
  if (list == NULL || *list == NULL || (*list)->next == NULL) {
 
6949
    return NULL;
 
6950
  }
 
6951
 
 
6952
  if (row == 1) {
 
6953
    *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow1);
 
6954
  } else {
 
6955
    *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow2);
 
6956
  }
 
6957
 
 
6958
  repeat_start = *list;
 
6959
  s1 = repeat_start->data.ptrvalue;
 
6960
  interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
 
6961
  vnp_prev = *list;
 
6962
  for (vnp = (*list)->next; vnp != NULL; vnp = vnp->next) {
 
6963
    s2 = vnp->data.ptrvalue;
 
6964
    is_repeat = FALSE;
 
6965
    r2 = SeqAlignRowFromSeqAlignSort (s2, row);
 
6966
 
 
6967
    if (interval->start <= r2->start && interval->stop >= r2->stop) {
 
6968
      /* contained */
 
6969
      is_repeat = TRUE;
 
6970
    } else if (r2->start <= interval->start && r2->stop >= interval->stop) {
 
6971
      /* contained */
 
6972
      is_repeat = TRUE;
 
6973
    } else if ((diff = RowDiff (interval, r2)) > -1 && diff < fuzz) {
 
6974
      is_repeat = TRUE;
 
6975
    }
 
6976
    if (is_repeat) {
 
6977
      vnp_prev = vnp;
 
6978
      if (interval->start > r2->start) {
 
6979
        interval->start = r2->start;
 
6980
      }
 
6981
      if (interval->stop < r2->stop) {
 
6982
        interval->stop = r2->stop;
 
6983
      }
 
6984
    } else {
 
6985
      if (repeat_start->next == vnp) {
 
6986
        repeat_prev = vnp_prev;
 
6987
        vnp_prev = vnp;
 
6988
      } else {
 
6989
        if (repeat_prev == NULL) {
 
6990
          *list = vnp;
 
6991
        } else {
 
6992
          repeat_prev->next = vnp;
 
6993
        }
 
6994
        if (vnp_prev != NULL) {
 
6995
          vnp_prev->next = NULL;
 
6996
        }
 
6997
        ValNodeAddPointer (&repeat_list, 0, repeat_start);
 
6998
        vnp_prev = vnp;
 
6999
      }
 
7000
      repeat_start = vnp;
 
7001
      s1 = vnp->data.ptrvalue;
 
7002
      interval = SeqAlignRowFree (interval);
 
7003
      interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
 
7004
    }
 
7005
  }
 
7006
 
 
7007
  if (repeat_start->next != NULL) {
 
7008
    if (repeat_prev == NULL) {
 
7009
      *list = NULL;
 
7010
    } else {
 
7011
      repeat_prev->next = NULL;
 
7012
    }
 
7013
    ValNodeAddPointer (&repeat_list, 0, repeat_start);
 
7014
  }
 
7015
 
 
7016
  interval = SeqAlignRowFree (interval);
 
7017
  return repeat_list;
 
7018
}
 
7019
 
 
7020
 
 
7021
static int SeqAlignRowFuzzyCompare (SeqAlignRowPtr r1, SeqAlignRowPtr r2, Int4 fuzz)
 
7022
{
 
7023
  if (r1 == NULL && r2 == NULL) {
 
7024
    return 0;
 
7025
  } else if (r1 == NULL) {
 
7026
    return -1;
 
7027
  } else if (r2 == NULL) {
 
7028
    return 1;
 
7029
  }
 
7030
 
 
7031
  if (r1->stop < r2->start || r1->stop - r2->start < fuzz) {
 
7032
    return -1;
 
7033
  } else if (r2->stop < r1->start || r2->stop - r1->start < fuzz) {
 
7034
    return 1;
 
7035
  } else {
 
7036
    return 0;
 
7037
  }
 
7038
}
 
7039
 
 
7040
 
 
7041
static int SeqAlignSortFuzzyCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
 
7042
{
 
7043
  if (s1 == NULL && s2 == NULL) {
 
7044
    return 0;
 
7045
  } else if (s1 == NULL) {
 
7046
    return -1;
 
7047
  } else if (s2 == NULL) {
 
7048
    return 1;
 
7049
  } else if (row == 1) {
 
7050
    return SeqAlignRowFuzzyCompare (s1->row1, s2->row1, fuzz);
 
7051
  } else {
 
7052
    return SeqAlignRowFuzzyCompare (s1->row2, s2->row2, fuzz);
 
7053
  }
 
7054
}
 
7055
 
 
7056
 
 
7057
static void SeqAlignSortListRemoveIntervalsOutOfOrder (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
 
7058
{
 
7059
  ValNodePtr vnp, vnp_prev = NULL;
 
7060
 
 
7061
  if (list == NULL) {
 
7062
    return;
 
7063
  }
 
7064
 
 
7065
  for (vnp = *list; vnp != NULL; vnp = vnp->next) {
 
7066
    if (vnp_prev != NULL && SeqAlignSortFuzzyCompare (vnp_prev->data.ptrvalue, vnp->data.ptrvalue, row, fuzz) != -1) {
 
7067
      vnp->choice = 1;
 
7068
    } else if (vnp->next != NULL && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->data.ptrvalue, row, fuzz) != -1) {
 
7069
      if (vnp->next->next != NULL 
 
7070
          && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) == -1
 
7071
          && SeqAlignSortFuzzyCompare (vnp->next->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) != -1) {
 
7072
        /* ok to keep this one, we'll toss the next one */
 
7073
      } else {
 
7074
        vnp->choice = 1;
 
7075
      }
 
7076
    }
 
7077
    if (vnp->choice == 0) {
 
7078
      vnp_prev = vnp;
 
7079
    }
 
7080
  }
 
7081
 
 
7082
  SeqAlignSortListRemoveMarked (list);
 
7083
}
 
7084
 
 
7085
 
 
7086
static Int4 GetRepeatIntervalFuzz (SeqAlignSortPtr s_repeat, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row)
 
7087
{
 
7088
  Int4 start_fuzz = 0, end_fuzz = 0;
 
7089
 
 
7090
  if (s_repeat == NULL) {
 
7091
    return -1;
 
7092
  }
 
7093
 
 
7094
  if (s_before != NULL) {
 
7095
    if (row == 1) {
 
7096
      start_fuzz = ABS (s_repeat->row1->start - s_before->row1->stop);
 
7097
    } else {
 
7098
      start_fuzz = ABS (s_repeat->row2->start - s_before->row2->stop);
 
7099
    }
 
7100
  }
 
7101
  if (s_after != NULL) {
 
7102
    if (row == 1) {
 
7103
      end_fuzz = ABS (s_after->row1->start - s_repeat->row1->stop);
 
7104
    } else {
 
7105
      end_fuzz = ABS (s_after->row2->start - s_repeat->row2->stop);
 
7106
    }
 
7107
  }
 
7108
 
 
7109
  return start_fuzz + end_fuzz;
 
7110
}
 
7111
 
 
7112
 
 
7113
static int StrandedSeqAlignSortRowCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
 
7114
{
 
7115
  SeqAlignRowPtr r1 = NULL, r2 = NULL;
 
7116
  int rval = 0;
 
7117
  Uint1 strand = Seq_strand_plus;
 
7118
 
 
7119
  if (s1 == NULL || s2 == NULL) {
 
7120
    return 0;
 
7121
  } 
 
7122
 
 
7123
  r1 = SeqAlignRowFromSeqAlignSort (s1, row);
 
7124
  r2 = SeqAlignRowFromSeqAlignSort (s2, row);
 
7125
  strand = r1->strand;
 
7126
 
 
7127
  if (strand == Seq_strand_minus) {
 
7128
    if (r1->start < r2->start - fuzz) {
 
7129
      rval = 1;
 
7130
    } else if (r1->start >r2->start + fuzz) {
 
7131
      rval = -1;
 
7132
    }
 
7133
  } else {
 
7134
    if (r1->start > r2->start + fuzz) {
 
7135
      rval = 1;
 
7136
    } else if (r1->stop < r2->stop - fuzz) {
 
7137
      rval = -1;
 
7138
    } 
 
7139
  }
 
7140
 
 
7141
  return rval;
 
7142
}
 
7143
 
 
7144
 
 
7145
static Boolean FindSeqAlignSortWithPoint (ValNodePtr list, Int4 point, Int4 row)
 
7146
{
 
7147
  ValNodePtr vnp;
 
7148
  SeqAlignRowPtr r;
 
7149
  SeqAlignSortPtr s;
 
7150
  Boolean found = FALSE;
 
7151
 
 
7152
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
7153
    s = vnp->data.ptrvalue;
 
7154
    r = SeqAlignRowFromSeqAlignSort (s, row);
 
7155
    if (point >= r->start && point <= r->stop) {
 
7156
      found = TRUE;
 
7157
    }
 
7158
  }
 
7159
  return found;
 
7160
}
 
7161
 
 
7162
 
 
7163
static ValNodePtr FindBestRepeat (ValNodePtr PNTR repeat_list, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row, Int4 fuzz)
 
7164
{
 
7165
  Int4       best_diff = -1, diff;
 
7166
  ValNodePtr vnp, vnp_best = NULL, vnp_best_prev = NULL, vnp_prev = NULL;
 
7167
  SeqAlignSortPtr s_this;
 
7168
 
 
7169
  if (repeat_list == NULL || *repeat_list == NULL) {
 
7170
    return NULL;
 
7171
  }
 
7172
 
 
7173
  for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
 
7174
    s_this = vnp->data.ptrvalue;
 
7175
 
 
7176
    if (StrandedSeqAlignSortRowCompare (s_this, s_before, row, fuzz) < 0
 
7177
      || StrandedSeqAlignSortRowCompare (s_this, s_after, row, fuzz) > 0) {
 
7178
      /* skip - already out of order */
 
7179
    } else {
 
7180
      diff = GetRepeatIntervalFuzz (vnp->data.ptrvalue, s_before, s_after, row);
 
7181
      if (diff > -1 && (best_diff < 0 || best_diff > diff)) {
 
7182
        vnp_best = vnp;
 
7183
        vnp_best_prev = vnp_prev;
 
7184
        best_diff = diff;
 
7185
      }
 
7186
    }
 
7187
    vnp_prev = vnp;
 
7188
  }
 
7189
 
 
7190
  if (vnp_best != NULL) {
 
7191
    if (vnp_best_prev == NULL) {
 
7192
      *repeat_list = vnp_best->next;
 
7193
    } else {
 
7194
      vnp_best_prev->next = vnp_best->next;
 
7195
    }
 
7196
    vnp_best->next = NULL;
 
7197
  }
 
7198
 
 
7199
  return vnp_best;
 
7200
}
 
7201
 
 
7202
 
 
7203
static void RemoveRepeatsCoincidingWithBest (ValNodePtr PNTR repeat_list, ValNodePtr best, Int4 row, Int4 fuzz)
 
7204
{
 
7205
  ValNodePtr vnp;
 
7206
  SeqAlignSortPtr s_best, s;
 
7207
  SeqAlignRowPtr r_best, r2;
 
7208
  Boolean        is_repeat;
 
7209
  Int4           diff;
 
7210
 
 
7211
  if (repeat_list == NULL || *repeat_list == NULL || best == NULL) {
 
7212
    return;
 
7213
  }
 
7214
 
 
7215
  s_best = best->data.ptrvalue;
 
7216
  r_best = SeqAlignRowFromSeqAlignSort (s_best, row);
 
7217
 
 
7218
  for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
 
7219
    s = vnp->data.ptrvalue;
 
7220
    r2 = SeqAlignRowFromSeqAlignSort (s, row);
 
7221
 
 
7222
    is_repeat = FALSE;
 
7223
    if (r_best->start <= r2->start && r_best->stop >= r2->stop) {
 
7224
      /* contained */
 
7225
      is_repeat = TRUE;
 
7226
    } else if (r2->start <= r_best->start && r2->stop >= r_best->stop) {
 
7227
      /* contained */
 
7228
      is_repeat = TRUE;
 
7229
    } else if (r2->stop < r_best->stop || r2->stop - r_best->stop < fuzz) {
 
7230
      is_repeat = TRUE;
 
7231
    } else if ((diff = RowDiff (r_best, r2)) > -1 && diff < fuzz) {
 
7232
      is_repeat = TRUE;
 
7233
    }
 
7234
 
 
7235
    if (is_repeat) {
 
7236
      vnp->choice = 1;
 
7237
    }
 
7238
  }
 
7239
  SeqAlignSortListRemoveMarked (repeat_list);
 
7240
}
 
7241
 
 
7242
 
 
7243
static ValNodePtr ExtractLongestSeqAlignRow (ValNodePtr PNTR list, Int4 row)
 
7244
{
 
7245
  ValNodePtr vnp, vnp_prev = NULL, rval = NULL;
 
7246
  Int4       longest = 0, len;
 
7247
  Boolean    found = FALSE;
 
7248
 
 
7249
  if (list == NULL || *list == NULL) {
 
7250
    return NULL;
 
7251
  }
 
7252
 
 
7253
  for (vnp = *list; vnp != NULL; vnp = vnp->next) {
 
7254
    len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
 
7255
    if (longest < len) {
 
7256
      longest = len;
 
7257
    }
 
7258
  }
 
7259
 
 
7260
  for (vnp = *list; vnp != NULL && !found; vnp = vnp->next) {
 
7261
    len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
 
7262
    if (len == longest) {
 
7263
      if (vnp_prev == NULL) {
 
7264
        *list = vnp->next;
 
7265
      } else {
 
7266
        vnp_prev->next = vnp->next;
 
7267
      }
 
7268
      vnp->next = NULL;
 
7269
      rval = vnp;
 
7270
      found = TRUE;
 
7271
    }
 
7272
    vnp_prev = vnp;
 
7273
  }
 
7274
  return rval;
 
7275
}
 
7276
 
 
7277
 
 
7278
static void InsertBestRepeat (ValNodePtr repeat_list, ValNodePtr PNTR sorted_list, Int4 row, Int4 fuzz)
 
7279
{
 
7280
  ValNodePtr vnp, vnp_prev = NULL, vnp_new;
 
7281
  SeqAlignSortPtr s_repeat, s, s_before = NULL;
 
7282
  Boolean         found = TRUE;
 
7283
  SeqAlignRowPtr  r1, r2;
 
7284
  Int4 other_row;
 
7285
 
 
7286
  if (repeat_list == NULL || sorted_list == NULL) {
 
7287
    return;
 
7288
  }
 
7289
 
 
7290
  if (row == 1) {
 
7291
    other_row = 2;
 
7292
  } else {
 
7293
    other_row = 1;
 
7294
  }
 
7295
  if (sorted_list == NULL || *sorted_list == NULL) {
 
7296
    /* keep longest, mark others for removal */
 
7297
    vnp = ExtractLongestSeqAlignRow (&repeat_list, row);
 
7298
    ValNodeLink (sorted_list,vnp);
 
7299
    repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7300
  } else {
 
7301
    s_repeat = repeat_list->data.ptrvalue;
 
7302
    found = FALSE;
 
7303
    vnp = *sorted_list;
 
7304
 
 
7305
    /* find first entry that is after this repeat, and insert before that */
 
7306
    while (vnp != NULL && !found) {
 
7307
      s = vnp->data.ptrvalue;
 
7308
      r1 = SeqAlignRowFromSeqAlignSort (s, row);
 
7309
      r2 = SeqAlignRowFromSeqAlignSort (s_repeat, row);
 
7310
 
 
7311
      if (r1->start > r2->start || r2->start - r1->start < fuzz) {
 
7312
        while (repeat_list != NULL) {
 
7313
          /* extract best repeat */
 
7314
          vnp_new = FindBestRepeat (&repeat_list, s_before, vnp->data.ptrvalue, other_row, fuzz);
 
7315
          if (vnp_new == NULL) {
 
7316
            repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7317
          } else {
 
7318
            RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
 
7319
            vnp_new->next = vnp;
 
7320
            if (vnp_prev == NULL) {
 
7321
              *sorted_list = vnp_new;
 
7322
            } else {
 
7323
              vnp_prev->next = vnp_new;
 
7324
            }
 
7325
            vnp_prev = vnp_new;
 
7326
            s_before = vnp_new->data.ptrvalue;
 
7327
          }
 
7328
        }
 
7329
        found = TRUE;
 
7330
      }
 
7331
      if (!found) {
 
7332
        s_before = vnp->data.ptrvalue;
 
7333
        vnp_prev = vnp;
 
7334
        vnp = vnp->next;
 
7335
      }
 
7336
    }
 
7337
    if (!found) {
 
7338
      while (repeat_list != NULL) {
 
7339
        /* extract best repeat */
 
7340
        vnp_new = FindBestRepeat (&repeat_list, s_before, NULL, other_row, fuzz);
 
7341
        if (vnp_new == NULL) {
 
7342
          repeat_list = SeqAlignSortListRemoveAll (repeat_list);
 
7343
        } else {
 
7344
          RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
 
7345
          vnp_new->next = NULL;
 
7346
          if (vnp_prev == NULL) {
 
7347
            *sorted_list = vnp_new;
 
7348
          } else {
 
7349
            vnp_prev->next = vnp_new;
 
7350
          }
 
7351
          vnp_prev = vnp_new;
 
7352
          s_before = vnp_new->data.ptrvalue;
 
7353
        }
 
7354
      }
 
7355
    }
 
7356
  }
 
7357
 
 
7358
  SeqAlignSortListRemoveMarked (&repeat_list);
 
7359
  repeat_list = ValNodeFree (repeat_list);
 
7360
}
 
7361
 
 
7362
 
 
7363
static void SelectBestRepeatsFromList (SeqAlignPtr PNTR salp)
 
7364
{
 
7365
  ValNodePtr list, vnp;
 
7366
  ValNodePtr row1_repeats, row2_repeats;
 
7367
  Uint1 strand1, strand2;
 
7368
  SeqAlignPtr    tmp_salp;
 
7369
  Int4           fuzz = 15;
 
7370
 
 
7371
  Int4           missing = 600;
 
7372
 
 
7373
  if (salp == NULL || *salp == NULL || (*salp)->next == NULL) {
 
7374
    return;
 
7375
  }
 
7376
 
 
7377
  list = SeqAlignSortListNew (*salp);
 
7378
 
 
7379
  FindSeqAlignSortWithPoint (list, missing, 1);
 
7380
 
 
7381
  /* remove conflicting strands for row 1 */
 
7382
  strand1 = SeqAlignSortListRemoveConflictingStrands (&list, 1);
 
7383
 
 
7384
  /* remove conflicting strands for row 1 */
 
7385
  strand2 = SeqAlignSortListRemoveConflictingStrands (&list, 2);
 
7386
 
 
7387
  FindSeqAlignSortWithPoint (list, missing, 1);
 
7388
 
 
7389
  if (list != NULL && list->next != NULL) {
 
7390
    row1_repeats = SeqAlignSortListExtractRepeats (&list, 1, fuzz);
 
7391
    row2_repeats = SeqAlignSortListExtractRepeats (&list, 2, fuzz);
 
7392
 
 
7393
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7394
 
 
7395
    /* remove scaffold intervals that are out of order */
 
7396
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7397
    SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 1, fuzz);
 
7398
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
 
7399
    SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 2, fuzz);
 
7400
 
 
7401
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7402
 
 
7403
    /* Remove overlaps.*/
 
7404
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7405
    tmp_salp = SeqAlignFromSeqAlignSortList (list);
 
7406
    list = SeqAlignSortListFree (list);
 
7407
    ACT_RemoveInconsistentAlnsFromSet (tmp_salp, 1, 1);
 
7408
    list = SeqAlignSortListNew (tmp_salp);
 
7409
 
 
7410
    FindSeqAlignSortWithPoint (list, missing, 1);
 
7411
 
 
7412
    /* for each repeat on row 1, we want to pick the most consistent interval for row 2 */
 
7413
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7414
    for (vnp = row1_repeats; vnp != NULL; vnp = vnp->next) {   
 
7415
      InsertBestRepeat (vnp->data.ptrvalue, &list, 1, fuzz);
 
7416
    }
 
7417
    row1_repeats = ValNodeFree (row1_repeats);
 
7418
 
 
7419
    /* for each repeat on row 2, we want to pick the most consistent interval for row 1 */
 
7420
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
 
7421
    for (vnp = row2_repeats; vnp != NULL; vnp = vnp->next) {   
 
7422
      InsertBestRepeat (vnp->data.ptrvalue, &list, 2, fuzz);
 
7423
    }
 
7424
    row2_repeats = ValNodeFree (row2_repeats);
 
7425
  }
 
7426
 
 
7427
  list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
7428
  *salp = SeqAlignFromSeqAlignSortList (list);
 
7429
 
 
7430
  list = SeqAlignSortListFree (list);
 
7431
}
 
7432
 
6318
7433
 
6319
7434
static void amconssetfree(AMConsSetPtr acp)
6320
7435
{
6357
7472
      return 0;
6358
7473
}
6359
7474
 
 
7475
 
6360
7476
static void CKA_RemoveInconsistentAlnsFromSet(SeqAlignPtr sap_head, Int4 fuzz)
6361
7477
{
6362
7478
   AMConsSetPtr  acp;
6557
7673
   AlnMgr2IndexLite(sap_head);
6558
7674
}
6559
7675
 
 
7676
 
6560
7677
static BioseqPtr ReadFromTraceDb (CharPtr number)
6561
7678
 
6562
7679
{
6820
7937
      acc_new_head = NULL;
6821
7938
      if (acc->sap != NULL && acc->sap->next != NULL)
6822
7939
      {
 
7940
         if (!CKA_blast_allow_repeats) {
 
7941
           SelectBestRepeatsFromList (&(acc->sap));
 
7942
         }
6823
7943
         AlnMgr2IndexLite(acc->sap);
6824
7944
         if (!CKA_blast_allow_repeats) {
6825
7945
           CKA_RemoveInconsistentAlnsFromSet(acc->sap, -1);
7154
8274
typedef struct assemblyuserform {
7155
8275
  FEATURE_FORM_BLOCK
7156
8276
  SeqEntryPtr   sep;
 
8277
  SeqDescrPtr   orig_sdp;
7157
8278
} AssemblyUserForm, PNTR AssemblyUserFormPtr;
7158
8279
 
7159
8280
static void UserObjectPtrToAssemblyDialog (DialoG d, Pointer data)
7566
8687
}
7567
8688
 
7568
8689
 
 
8690
static void PopulateAssemblyIntervals (ButtoN b)
 
8691
{
 
8692
  AssemblyUserFormPtr  afp;
 
8693
  BioseqPtr            bsp;
 
8694
  UserObjectPtr        uop;
 
8695
  SeqAlignPtr          salp;
 
8696
  Char                 id_txt[355];
 
8697
  SeqIdPtr             sip;
 
8698
  Int4                 primary_start, primary_stop;
 
8699
 
 
8700
  afp = (AssemblyUserFormPtr) GetObjectExtra (b);
 
8701
  if (afp == NULL) {
 
8702
    return;
 
8703
  }
 
8704
 
 
8705
  bsp = GetSequenceForObject (OBJ_SEQDESC, afp->orig_sdp);
 
8706
  if (bsp != NULL && bsp->hist != NULL && bsp->hist->assembly != NULL) {
 
8707
    uop = CreateTpaAssemblyUserObject  ();
 
8708
    /* populate user object with intervals */
 
8709
    for (salp = bsp->hist->assembly; salp != NULL; salp = salp->next) {
 
8710
      AlnMgr2IndexSingleChildSeqAlign (salp); 
 
8711
      sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
8712
      SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
8713
      AlnMgr2GetNthSeqRangeInSA (salp, 2, &primary_start, &primary_stop);
 
8714
      AddAccessionToTpaAssemblyUserObject (uop, id_txt, primary_start, primary_stop);
 
8715
      sip = SeqIdFree (sip);
 
8716
    }
 
8717
 
 
8718
    PointerToDialog (afp->data, uop);
 
8719
    uop = UserObjectFree (uop);
 
8720
  }
 
8721
}
 
8722
 
 
8723
 
7569
8724
static ForM CreateAssemblyDescForm (Int2 left, Int2 top, Int2 width,
7570
8725
                                   Int2 height, CharPtr title, ValNodePtr sdp,
7571
8726
                                   SeqEntryPtr sep, FormActnFunc actproc)
7572
8727
 
7573
8728
{
7574
8729
  AssemblyUserFormPtr  afp;
7575
 
  ButtoN               b;
 
8730
  ButtoN               b, pop_btn = NULL;
7576
8731
  GrouP                c;
7577
8732
  GrouP                g;
7578
8733
  StdEditorProcsPtr    sepp;
7579
8734
  WindoW               w;
 
8735
  BioseqPtr            bsp;
7580
8736
 
7581
8737
  w = NULL;
7582
8738
  afp = (AssemblyUserFormPtr) MemNew (sizeof (AssemblyUserForm));
7601
8757
    g = HiddenGroup (w, -1, 0, NULL);
7602
8758
    afp->data = CreateAssemblyDialog (g);
7603
8759
 
 
8760
    if (sdp != NULL) {
 
8761
      bsp = GetSequenceForObject (OBJ_SEQDESC, sdp);
 
8762
      if (bsp != NULL && bsp->hist != NULL && bsp->hist->assembly != NULL) {
 
8763
        pop_btn = PushButton (g, "Populate Intervals from Assembly Alignment", PopulateAssemblyIntervals);
 
8764
        SetObjectExtra (pop_btn, afp, NULL);
 
8765
      }
 
8766
    }
 
8767
 
7604
8768
    c = HiddenGroup (w, 2, 0, NULL);
7605
8769
    b = DefaultButton (c, "Accept", TPAAssemblyFormAccept);
7606
8770
    SetObjectExtra (b, afp, NULL);
7607
8771
    PushButton (c, "Cancel", StdCancelButtonProc);
7608
 
    AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
 
8772
    AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, (HANDLE) pop_btn, NULL);
7609
8773
    RealizeWindow (w);
7610
8774
  }
7611
8775
  return (ForM) w;
7691
8855
    if (sdp != NULL) {
7692
8856
      PointerToDialog (afp->data, (Pointer) sdp->data.ptrvalue);
7693
8857
      SetClosestParentIfDuplicating ((BaseFormPtr) afp);
 
8858
      afp->orig_sdp = sdp;
7694
8859
    }
7695
8860
  }
7696
8861
  Show (w);
7699
8864
}
7700
8865
 
7701
8866
 
 
8867
/* advanced editor for Seq-hist assembly alignment */
 
8868
typedef struct assemblyalignmentdlg {
 
8869
  DIALOG_MESSAGE_BLOCK
 
8870
  DialoG intervals_dialog;
 
8871
 
 
8872
  
 
8873
} AssemblyAlignmentDlgData, PNTR AssemblyAlignmentDlgPtr;
 
8874
 
 
8875
Uint2 assmbly_aln_types [] = {
 
8876
  TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_POPUP
 
8877
};
 
8878
 
 
8879
Uint2 assmbly_aln_widths [] = {
 
8880
  16, 8, 8, 8, 8, 8, 0
 
8881
};
 
8882
 
 
8883
ENUM_ALIST(assmbly_aln_strand_alist)
 
8884
  {"Plus",  0},
 
8885
  {"Minus",    1},
 
8886
END_ENUM_ALIST
 
8887
 
 
8888
 
 
8889
 
 
8890
static EnumFieldAssocPtr assmbly_aln_alists[] = {
 
8891
  NULL, NULL, NULL, NULL, NULL, assmbly_aln_strand_alist
 
8892
};
 
8893
 
 
8894
 
 
8895
typedef struct assemblyalignmentinterval {
 
8896
  CharPtr prim_accession;
 
8897
  Int4    tpa_from;
 
8898
  Int4    tpa_to;
 
8899
  Int4    prim_from;
 
8900
  Uint1   prim_strand;
 
8901
  Uint2   percent_identity;
 
8902
} AssemblyAlignmentIntervalData, PNTR AssemblyAlignmentIntervalPtr;
 
8903
 
 
8904
 
 
8905
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFree (AssemblyAlignmentIntervalPtr interval)
 
8906
{
 
8907
  if (interval != NULL) {
 
8908
    interval->prim_accession = MemFree (interval->prim_accession);
 
8909
    interval = MemFree (interval);
 
8910
  }
 
8911
  return interval;
 
8912
}
 
8913
 
 
8914
 
 
8915
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromTagListString (CharPtr str)
 
8916
{
 
8917
  AssemblyAlignmentIntervalPtr interval;
 
8918
  CharPtr cp;
 
8919
  Int4    len, val;
 
8920
 
 
8921
  if (StringHasNoText (str)) {
 
8922
    return NULL;
 
8923
  }
 
8924
 
 
8925
  interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
 
8926
  MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
 
8927
 
 
8928
  cp = StringChr (str, '\t');
 
8929
  if (cp == NULL) {
 
8930
    interval->prim_accession = StringSave (str);
 
8931
  } else {
 
8932
    len = cp - str + 1;
 
8933
    interval->prim_accession = (CharPtr) MemNew (sizeof (Char) * len);
 
8934
    StringNCpy (interval->prim_accession, str, len - 1);
 
8935
    interval->prim_accession[len - 1] = 0;
 
8936
    str = cp + 1;
 
8937
    cp = StringChr (str, '\t');
 
8938
    interval->tpa_from = atoi (str);
 
8939
    if (cp != NULL) {
 
8940
      str = cp + 1;
 
8941
      cp = StringChr (str, '\t');
 
8942
      interval->tpa_to = atoi (str);
 
8943
      if (cp != NULL) {
 
8944
        str = cp + 1;
 
8945
        cp = StringChr (str, '\t');
 
8946
        interval->prim_from = atoi (str);
 
8947
        if (cp != NULL) {
 
8948
          cp = StringChr (cp + 1, '\t');
 
8949
          if (cp != NULL) {
 
8950
            val = atoi (cp + 1);
 
8951
            if (val == 1) {
 
8952
              interval->prim_strand = Seq_strand_minus;
 
8953
            } else {
 
8954
              interval->prim_strand = Seq_strand_plus;
 
8955
            }
 
8956
          }
 
8957
        }
 
8958
      }
 
8959
    }
 
8960
  }
 
8961
  return interval;
 
8962
}
 
8963
 
 
8964
 
 
8965
static CharPtr TagListStringFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
 
8966
{
 
8967
  CharPtr str, str_fmt = "%s\t%d\t%d\t%d\t%d (%d)\t%d\n";
 
8968
 
 
8969
  if (interval == NULL) {
 
8970
    return NULL;
 
8971
  }
 
8972
 
 
8973
  str = (CharPtr) MemNew (sizeof (Char) * (StringLen (str_fmt) + StringLen (interval->prim_accession) + 61));
 
8974
  sprintf (str, str_fmt, interval->prim_accession == NULL ? "" : interval->prim_accession,
 
8975
                         interval->tpa_from,
 
8976
                         interval->tpa_to,
 
8977
                         interval->prim_from,
 
8978
                         interval->prim_from + interval->tpa_to - interval->tpa_from,
 
8979
                         interval->percent_identity,
 
8980
                         interval->prim_strand == Seq_strand_minus ? 1 : 0);
 
8981
  return str;
 
8982
}
 
8983
 
 
8984
 
 
8985
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromSeqAlign (SeqAlignPtr salp)
 
8986
{
 
8987
  AssemblyAlignmentIntervalPtr interval;
 
8988
  DenseSegPtr dsp;
 
8989
  Char     id_txt[200];
 
8990
 
 
8991
  if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG) {
 
8992
    return NULL;
 
8993
  }
 
8994
 
 
8995
  dsp = (DenseSegPtr) salp->segs;
 
8996
  if (dsp == NULL || dsp->numseg != 1) {
 
8997
    return NULL;
 
8998
  }
 
8999
 
 
9000
  interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
 
9001
  MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
 
9002
 
 
9003
  /* first row is TPA, second row is primary */  
 
9004
  SeqIdWrite (dsp->ids->next, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
9005
  interval->prim_accession = StringSave (id_txt);
 
9006
 
 
9007
  interval->tpa_from = dsp->starts[0] + 1;
 
9008
  interval->tpa_to = dsp->starts[0] + dsp->lens[0];
 
9009
  interval->prim_from = dsp->starts[1] + 1;
 
9010
  if (dsp->strands == NULL) {
 
9011
    interval->prim_strand = Seq_strand_plus;
 
9012
  } else {
 
9013
    interval->prim_strand = dsp->strands[1];
 
9014
  }
 
9015
 
 
9016
  interval->percent_identity = AlignmentPercentIdentity (salp, FALSE);
 
9017
 
 
9018
  return interval;
 
9019
}
 
9020
 
 
9021
 
 
9022
static SeqAlignPtr SeqAlignFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
 
9023
{
 
9024
  SeqAlignPtr salp;
 
9025
  DenseSegPtr dsp;
 
9026
 
 
9027
  if (interval == NULL) {
 
9028
    return NULL;
 
9029
  }
 
9030
  dsp = DenseSegNew ();
 
9031
  dsp->dim = 2;
 
9032
  dsp->numseg = 1;
 
9033
  dsp->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
9034
  dsp->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp->numseg);
 
9035
  dsp->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
9036
 
 
9037
  dsp->ids = ValNodeNew (NULL);
 
9038
  dsp->ids->next = SeqIdFromAccessionDotVersion(interval->prim_accession);
 
9039
 
 
9040
  dsp->starts[0] = interval->tpa_from - 1;
 
9041
  dsp->starts[1] = interval->prim_from - 1;
 
9042
  dsp->lens[0] = interval->tpa_to - interval->tpa_from + 1;
 
9043
  dsp->strands[0] = Seq_strand_plus;
 
9044
  dsp->strands[1] = interval->prim_strand;
 
9045
 
 
9046
  salp = SeqAlignNew ();
 
9047
  salp->dim = 2;
 
9048
  salp->segtype = SAS_DENSEG;
 
9049
  salp->segs = dsp;
 
9050
  salp->type = SAT_PARTIAL;
 
9051
  return salp;
 
9052
}
 
9053
 
 
9054
 
 
9055
static void SeqAlignToAssemblyAlignmentDialog (DialoG d, Pointer data) 
 
9056
{
 
9057
  AssemblyAlignmentDlgPtr dlg;
 
9058
 
 
9059
  dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
 
9060
  if (dlg == NULL) {
 
9061
    return;
 
9062
  }
 
9063
 
 
9064
  PointerToDialog (dlg->intervals_dialog, data);
 
9065
}
 
9066
 
 
9067
 
 
9068
static Pointer AssemblyAlignmentDialogToSeqAlign (DialoG d)
 
9069
{
 
9070
  AssemblyAlignmentDlgPtr dlg;
 
9071
  SeqAlignPtr salp = NULL;
 
9072
 
 
9073
  dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
 
9074
  if (dlg == NULL) {
 
9075
    return NULL;
 
9076
  }
 
9077
 
 
9078
  salp = DialogToPointer (dlg->intervals_dialog);
 
9079
  
 
9080
  return salp;
 
9081
}
 
9082
 
 
9083
 
 
9084
static void SeqAlignToTagDlg (DialoG d, Pointer data)
 
9085
{
 
9086
  TagListPtr tlp;
 
9087
  SeqAlignPtr salp;
 
9088
  AssemblyAlignmentIntervalPtr interval;
 
9089
 
 
9090
  tlp =(TagListPtr) GetObjectExtra (d);
 
9091
  if (tlp == NULL) {
 
9092
    return;
 
9093
  }
 
9094
 
 
9095
  tlp->vnp = ValNodeFreeData (tlp->vnp);
 
9096
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
9097
  salp = (SeqAlignPtr) data;
 
9098
 
 
9099
  while (salp != NULL) {
 
9100
    interval = AssemblyAlignmentIntervalFromSeqAlign (salp);
 
9101
    if (interval != NULL) {
 
9102
      ValNodeAddPointer (&(tlp->vnp), 0, TagListStringFromAssemblyAlignmentInterval (interval));
 
9103
      interval = AssemblyAlignmentIntervalFree (interval);
 
9104
    }
 
9105
    salp = salp->next;
 
9106
  }
 
9107
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9108
}
 
9109
 
 
9110
 
 
9111
static Pointer SeqAlignFromTagDlg (DialoG d)
 
9112
{
 
9113
  TagListPtr tlp;
 
9114
  SeqAlignPtr salp = NULL, salp_last = NULL, salp_tmp;
 
9115
  ValNodePtr vnp;
 
9116
  AssemblyAlignmentIntervalPtr interval;
 
9117
 
 
9118
  tlp =(TagListPtr) GetObjectExtra (d);
 
9119
  if (tlp == NULL) {
 
9120
    return NULL;
 
9121
  }
 
9122
 
 
9123
  for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
 
9124
    interval = AssemblyAlignmentIntervalFromTagListString (vnp->data.ptrvalue);
 
9125
    if (interval != NULL) {
 
9126
      salp_tmp = SeqAlignFromAssemblyAlignmentInterval (interval);
 
9127
      if (salp_tmp != NULL) {
 
9128
        if (salp_last == NULL) {
 
9129
          salp = salp_tmp;
 
9130
        } else {
 
9131
          salp_last->next = salp_tmp;
 
9132
        }
 
9133
        salp_last = salp_tmp;
 
9134
      }
 
9135
      interval = AssemblyAlignmentIntervalFree (interval);
 
9136
    }
 
9137
  }
 
9138
  return salp;
 
9139
}
 
9140
 
 
9141
 
 
9142
static DialoG CreateAssemblyAlignmentDialog (GrouP g)
 
9143
 
 
9144
{
 
9145
  AssemblyAlignmentDlgPtr dlg;
 
9146
  GrouP                   p;
 
9147
  GrouP                   x;
 
9148
  GrouP                   y;
 
9149
 
 
9150
  p = HiddenGroup (g, -1, 0, NULL);
 
9151
  SetGroupSpacing (p, 10, 10);
 
9152
 
 
9153
  dlg = (AssemblyAlignmentDlgPtr) MemNew (sizeof (AssemblyAlignmentDlgData));
 
9154
  if (dlg == NULL) return NULL;
 
9155
 
 
9156
  SetObjectExtra (p, dlg, NULL);
 
9157
  dlg->dialog = (DialoG) p;
 
9158
  dlg->todialog = SeqAlignToAssemblyAlignmentDialog;
 
9159
  dlg->fromdialog = AssemblyAlignmentDialogToSeqAlign;
 
9160
 
 
9161
  x = HiddenGroup (p, 0, 2, NULL);
 
9162
  y = HiddenGroup (x, 6, 0, NULL);
 
9163
  StaticPrompt (y, "", 16 * stdCharWidth, 0, programFont, 'c');
 
9164
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
9165
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
9166
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
9167
  StaticPrompt (y, "Primary To", 8 * stdCharWidth, 0, programFont, 'c');
 
9168
  StaticPrompt (y, "", 8 * stdCharWidth, 0, programFont, 'c');
 
9169
  StaticPrompt (y, "Accessions", 16 * stdCharWidth, 0, programFont, 'c');
 
9170
  StaticPrompt (y, "TPA From", 8 * stdCharWidth, 0, programFont, 'c');
 
9171
  StaticPrompt (y, "TPA To", 8 * stdCharWidth, 0, programFont, 'c');
 
9172
  StaticPrompt (y, "Primary From", 8 * stdCharWidth, 0, programFont, 'c');
 
9173
  StaticPrompt (y, "(Percent Identity)", 8 * stdCharWidth, 0, programFont, 'c');
 
9174
  StaticPrompt (y, "Primary Strand", 8 * stdCharWidth, 0, programFont, 'c');
 
9175
  dlg->intervals_dialog = CreateTagListDialogExEx (x, 6, 6, -1, assmbly_aln_types, assmbly_aln_widths, assmbly_aln_alists,
 
9176
                                                   TRUE, FALSE, SeqAlignToTagDlg, SeqAlignFromTagDlg,
 
9177
                                                   NULL, NULL, FALSE);
 
9178
 
 
9179
 
 
9180
  return (DialoG) p;
 
9181
}
 
9182
 
 
9183
 
 
9184
static void AddTPAIdToAlignment (SeqAlignPtr salp, BioseqPtr bsp)
 
9185
{
 
9186
  DenseSegPtr dsp;
 
9187
  SeqIdPtr    sip;
 
9188
 
 
9189
  if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG || bsp == NULL) {
 
9190
    return;
 
9191
  }
 
9192
 
 
9193
  dsp = salp->segs;
 
9194
  if (dsp == NULL) {
 
9195
    return;
 
9196
  }
 
9197
 
 
9198
  sip = SeqIdFindWorst (bsp->id);
 
9199
  sip = SeqIdDup (sip);
 
9200
 
 
9201
  sip->next = dsp->ids->next;
 
9202
  dsp->ids->next = NULL;
 
9203
  dsp->ids = SeqIdFree (dsp->ids);
 
9204
  dsp->ids = sip;
 
9205
}
 
9206
 
 
9207
 
 
9208
static void AddTPAIdToAlignmentList (SeqAlignPtr salp, BioseqPtr bsp)
 
9209
{
 
9210
  while (salp != NULL) {
 
9211
    AddTPAIdToAlignment (salp, bsp);
 
9212
    salp = salp->next;
 
9213
  }
 
9214
}
 
9215
 
 
9216
typedef struct assemblyalignmentform {
 
9217
  FORM_MESSAGE_BLOCK
 
9218
  DialoG dlg;
 
9219
  BioseqPtr bsp;
 
9220
} AssemblyAlignmentFormData, PNTR AssemblyAlignmentFormPtr;
 
9221
 
 
9222
 
 
9223
static void CheckCoverageWithAddedIntervals (LogInfoPtr lip, BioseqPtr bsp, SeqAlignPtr salp)
 
9224
{
 
9225
  ValNodePtr err_list = NULL;
 
9226
  SeqAlignPtr salp_orig, salp_prev = NULL;
 
9227
 
 
9228
  if (bsp == NULL) {
 
9229
    return;
 
9230
  }
 
9231
 
 
9232
  if (bsp->hist == NULL) {
 
9233
    bsp->hist = SeqHistNew ();
 
9234
  }
 
9235
 
 
9236
  salp_orig = bsp->hist->assembly;
 
9237
  while (salp_orig != NULL) {
 
9238
    salp_prev = salp_orig;
 
9239
    salp_orig = salp_orig->next;
 
9240
  }
 
9241
 
 
9242
  if (salp_prev == NULL) {
 
9243
    bsp->hist->assembly = salp;
 
9244
  } else {
 
9245
    salp_prev->next = salp;
 
9246
  }
 
9247
 
 
9248
  ValidateTPAHistAlign (bsp, &err_list);
 
9249
  if (err_list != NULL) {
 
9250
    fprintf (lip->fp, "Projected Coverage Problems\n");
 
9251
    PrintTPAHistErrors (lip, err_list);
 
9252
    lip->data_in_log = TRUE;
 
9253
    err_list = ValNodeFreeData (err_list);
 
9254
  }
 
9255
 
 
9256
  if (salp_prev == NULL) {
 
9257
    bsp->hist->assembly = NULL;
 
9258
  } else {
 
9259
    salp_prev->next = NULL;
 
9260
  }
 
9261
}
 
9262
 
 
9263
 
 
9264
static Boolean ReportAssemblyIntervalProblems (BioseqPtr bsp, SeqAlignPtr salp)
 
9265
{
 
9266
  LogInfoPtr lip;
 
9267
  AssemblyAlignmentIntervalPtr interval;
 
9268
  Boolean    has_errors = FALSE;
 
9269
  SeqAlignPtr salp_tmp;
 
9270
 
 
9271
  lip = OpenLog ("Assembly Alignment Interval Problems");
 
9272
  fprintf (lip->fp, "Primary Accession\tTPA From\tTPA To\tPrimary From\tPrimary To\tStrand\tPercent Identity\n");
 
9273
  for (salp_tmp = salp; salp_tmp != NULL; salp_tmp = salp_tmp->next) {
 
9274
    interval = AssemblyAlignmentIntervalFromSeqAlign (salp_tmp);
 
9275
    fprintf (lip->fp, "%s\t%d\t%d\t%d\t%d\t%s\t%d%s\n",
 
9276
             interval->prim_accession,
 
9277
             interval->tpa_from,
 
9278
             interval->tpa_to,
 
9279
             interval->prim_from,
 
9280
             interval->prim_from + interval->tpa_to - interval->tpa_from,
 
9281
             interval->prim_strand == Seq_strand_minus ? "c" : "",
 
9282
             interval->percent_identity,
 
9283
             interval->percent_identity < 75 ? "(Suspiciously low percent identity!)" : "");
 
9284
    if (interval->percent_identity < 75) {
 
9285
      lip->data_in_log = TRUE;
 
9286
    }
 
9287
    interval = AssemblyAlignmentIntervalFree (interval);
 
9288
  }
 
9289
  fprintf (lip->fp, "\n");
 
9290
  CheckCoverageWithAddedIntervals (lip, bsp, salp);
 
9291
  CloseLog (lip);
 
9292
  has_errors = lip->data_in_log;
 
9293
  return has_errors;
 
9294
}
 
9295
 
 
9296
 
 
9297
static void AcceptAssemblyAlignment (ButtoN b)
 
9298
{
 
9299
  AssemblyAlignmentFormPtr frm;
 
9300
  SeqAlignPtr              salp, salp_next;
 
9301
  ValNodePtr               list;
 
9302
  MsgAnswer                ans = ANS_OK;
 
9303
 
 
9304
  frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
 
9305
  if (frm == NULL) {
 
9306
    return;
 
9307
  }
 
9308
  salp = DialogToPointer (frm->dlg);
 
9309
  if (salp == NULL) {
 
9310
    Message (MSG_ERROR, "No intervals specified");
 
9311
    return;
 
9312
  }
 
9313
  AddTPAIdToAlignmentList (salp, frm->bsp);
 
9314
  if (ReportAssemblyIntervalProblems (frm->bsp, salp)) {
 
9315
    ans = Message (MSG_OKC, "Continue with errors?");
 
9316
  }
 
9317
 
 
9318
  if (ans == ANS_OK) {
 
9319
    if (frm->bsp->hist == NULL) {
 
9320
      frm->bsp->hist = SeqHistNew ();
 
9321
    }
 
9322
 
 
9323
    /* something is wrong here, alignment is not being sorted */
 
9324
    salp_next = salp;
 
9325
    while (salp_next->next != NULL) {
 
9326
      salp_next = salp_next->next;
 
9327
    }
 
9328
    salp_next->next = frm->bsp->hist->assembly;
 
9329
 
 
9330
    list = SeqAlignSortListNew (salp);
 
9331
    list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
 
9332
    salp = SeqAlignFromSeqAlignSortList (list);
 
9333
    list = SeqAlignSortListFree (list);
 
9334
    frm->bsp->hist->assembly = salp;
 
9335
    ObjMgrSetDirtyFlag (frm->bsp->idx.entityID, TRUE);
 
9336
    ObjMgrSendMsg (OM_MSG_UPDATE, frm->bsp->idx.entityID, 0, 0);
 
9337
    Remove (frm->form);
 
9338
  } else {
 
9339
    while (salp != NULL) {
 
9340
      salp_next = salp->next;
 
9341
      salp->next = NULL;
 
9342
      salp = SeqAlignFree (salp);
 
9343
      salp = salp_next;
 
9344
    }
 
9345
  }
 
9346
}
 
9347
 
 
9348
 
 
9349
static void CheckAssemblyAlignment (ButtoN b)
 
9350
{
 
9351
  AssemblyAlignmentFormPtr frm;
 
9352
  SeqAlignPtr              salp, salp_next;
 
9353
 
 
9354
  frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
 
9355
  if (frm == NULL) {
 
9356
    return;
 
9357
  }
 
9358
 
 
9359
  salp = DialogToPointer (frm->dlg);
 
9360
  if (salp == NULL) {
 
9361
    Message (MSG_ERROR, "No intervals specified");
 
9362
    return;
 
9363
  }
 
9364
  AddTPAIdToAlignmentList (salp, frm->bsp);
 
9365
  PointerToDialog (frm->dlg, salp);
 
9366
  ReportAssemblyIntervalProblems (frm->bsp, salp);
 
9367
  
 
9368
  while (salp != NULL) {
 
9369
    salp_next = salp->next;
 
9370
    salp->next = NULL;
 
9371
    salp = SeqAlignFree (salp);
 
9372
    salp = salp_next;
 
9373
  }
 
9374
}
 
9375
 
 
9376
 
 
9377
extern void AdvancedAssemblyAlignmentEditor (IteM i)
 
9378
{
 
9379
  BaseFormPtr        bfp;
 
9380
  BioseqPtr   bsp;
 
9381
  WindoW      w;
 
9382
  GrouP       h, c;
 
9383
  AssemblyAlignmentFormPtr frm;
 
9384
  ButtoN                   b;
 
9385
 
 
9386
#ifdef WIN_MAC
 
9387
  bfp = currentFormDataPtr;
 
9388
#else
 
9389
  bfp = GetObjectExtra (i);
 
9390
#endif
 
9391
  if (bfp == NULL) return;
 
9392
 
 
9393
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
9394
  if (bsp == NULL) {
 
9395
    Message (MSG_ERROR, "Must select single Bioseq!");
 
9396
    return;
 
9397
  }
 
9398
 
 
9399
  frm = (AssemblyAlignmentFormPtr) MemNew (sizeof (AssemblyAlignmentFormData));
 
9400
  frm->bsp = bsp;
 
9401
 
 
9402
  w = FixedWindow (-50, -33, -10, -10, "Add Intervals to Assembly Alignment", StdCloseWindowProc);
 
9403
  SetObjectExtra (w, frm, StdCleanupExtraProc);
 
9404
  frm->form = (ForM) w;
 
9405
 
 
9406
  h = HiddenGroup (w, -1, 0, NULL);
 
9407
  SetGroupSpacing (h, 10, 10);
 
9408
 
 
9409
  frm->dlg = CreateAssemblyAlignmentDialog(h);
 
9410
 
 
9411
  c = HiddenGroup (h, 3, 0, NULL);
 
9412
  b = PushButton (c, "Accept", AcceptAssemblyAlignment);
 
9413
  SetObjectExtra (b, frm, NULL);
 
9414
  b = PushButton (c, "Check", CheckAssemblyAlignment);
 
9415
  SetObjectExtra (b, frm, NULL);
 
9416
  b = PushButton (c, "Cancel", StdCancelButtonProc);
 
9417
 
 
9418
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
 
9419
 
 
9420
  Show (w);
 
9421
  Update ();
 
9422
}
 
9423
 
 
9424
typedef enum {
 
9425
  eAssemblyIntervalInfo_NoAction = 0,
 
9426
  eAssemblyIntervalInfo_Remove,
 
9427
  eAssemblyIntervalInfo_Truncate_Left,
 
9428
  eAssemblyIntervalInfo_Truncate_Right,
 
9429
  eAssemblyIntervalInfo_Truncate_Both
 
9430
} EAssemblyIntervalInfoAction;
 
9431
 
 
9432
 
 
9433
typedef struct assemblyintervalinfo {
 
9434
  SeqAlignPtr salp;
 
9435
  Int4        prim_left;
 
9436
  Int4        prim_right;
 
9437
  Uint1       prim_strand;
 
9438
  Int4        tpa_left;
 
9439
  Int4        tpa_right;
 
9440
  CharPtr     prim_id;
 
9441
  ValNodePtr  conflict_list;
 
9442
  EAssemblyIntervalInfoAction action;
 
9443
} AssemblyIntervalInfoData, PNTR AssemblyIntervalInfoPtr;
 
9444
 
 
9445
typedef enum {
 
9446
  eIntervalConflict_none,
 
9447
  eIntervalConflict_a_contains_b,
 
9448
  eIntervalConflict_a_contained_in_b,
 
9449
  eIntervalConflict_a_overlaps_b_on_5,
 
9450
  eIntervalConflict_a_overlaps_b_on_3
 
9451
} EIntervalConflict;
 
9452
 
 
9453
 
 
9454
static Int4 FindIntervalConflict (Int4 left1, Int4 right1, Int4 left2, Int4 right2, Int4 overlap)
 
9455
{
 
9456
  if (right1 < left2 + overlap || left1 > right2 - overlap) {
 
9457
    return eIntervalConflict_none;
 
9458
  } else if (left1 <= left2 && right1 < right2 && right1 - left2  + 1> overlap) {
 
9459
    return eIntervalConflict_a_overlaps_b_on_5;
 
9460
  } else if (left1 > left2 && right1 >= right2 && right2 - left1  + 1> overlap) {
 
9461
    return eIntervalConflict_a_overlaps_b_on_3;
 
9462
  } else if (left1 <= left2 && right1 >= right2) {
 
9463
    return eIntervalConflict_a_contains_b;
 
9464
  } else if (left2 <= left1 && right2 >= right2) {
 
9465
    return eIntervalConflict_a_contained_in_b;
 
9466
  } else {
 
9467
    Message (MSG_ERROR, "Conflict calculation failed");
 
9468
    return eIntervalConflict_none;
 
9469
  }
 
9470
}
 
9471
 
 
9472
 
 
9473
 
 
9474
typedef struct intervalconflictinfo {
 
9475
  AssemblyIntervalInfoPtr conflict_interval;
 
9476
  EIntervalConflict prim_conflict;
 
9477
  EIntervalConflict tpa_conflict;
 
9478
} IntervalConflictInfoData, PNTR IntervalConflictInfoPtr;
 
9479
 
 
9480
 
 
9481
static IntervalConflictInfoPtr IntervalConflictInfoNew (AssemblyIntervalInfoPtr conflict_interval, EIntervalConflict prim_conflict, EIntervalConflict tpa_conflict)
 
9482
{
 
9483
  IntervalConflictInfoPtr ip;
 
9484
 
 
9485
  ip = (IntervalConflictInfoPtr) MemNew (sizeof (IntervalConflictInfoData));
 
9486
  ip->conflict_interval = conflict_interval;
 
9487
  ip->prim_conflict = prim_conflict;
 
9488
  ip->tpa_conflict = tpa_conflict;
 
9489
  return ip;
 
9490
}
 
9491
 
 
9492
 
 
9493
static IntervalConflictInfoPtr IntervalConflictInfoFree (IntervalConflictInfoPtr ip)
 
9494
{
 
9495
  if (ip != NULL) {
 
9496
    ip = MemFree (ip);
 
9497
  }
 
9498
  return ip;
 
9499
}
 
9500
 
 
9501
 
 
9502
static ValNodePtr IntervalConflictInfoListFree (ValNodePtr vnp)
 
9503
{
 
9504
  ValNodePtr vnp_next;
 
9505
 
 
9506
  while (vnp != NULL) {
 
9507
    vnp_next = vnp->next;
 
9508
    vnp->data.ptrvalue = IntervalConflictInfoFree (vnp->data.ptrvalue);
 
9509
    vnp->next = NULL;
 
9510
    vnp = ValNodeFree (vnp);
 
9511
    vnp = vnp_next;
 
9512
  }
 
9513
  return vnp;
 
9514
}
 
9515
 
 
9516
 
 
9517
static AssemblyIntervalInfoPtr AssemblyIntervalInfoFree (AssemblyIntervalInfoPtr ip)
 
9518
{
 
9519
  if (ip != NULL) {
 
9520
    ip->prim_id = MemFree (ip->prim_id);
 
9521
    ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
 
9522
    ip = MemFree (ip);
 
9523
  }
 
9524
  return ip;
 
9525
}
 
9526
 
 
9527
 
 
9528
static ValNodePtr AssemblyIntervalInfoListFree (ValNodePtr vnp)
 
9529
{
 
9530
  ValNodePtr vnp_next;
 
9531
 
 
9532
  while (vnp != NULL) {
 
9533
    vnp_next = vnp->next;
 
9534
    vnp->data.ptrvalue = AssemblyIntervalInfoFree (vnp->data.ptrvalue);
 
9535
    vnp->next = NULL;
 
9536
    vnp = ValNodeFree (vnp);
 
9537
    vnp = vnp_next;
 
9538
  }
 
9539
  return vnp;
 
9540
}
 
9541
 
 
9542
 
 
9543
static void TruncateForConflictsOnLeft (AssemblyIntervalInfoPtr ai)
 
9544
{
 
9545
  IntervalConflictInfoPtr ip;
 
9546
  ValNodePtr vnp;
 
9547
  Int4       prim_change, tpa_change;
 
9548
 
 
9549
  if (ai == NULL || ai->conflict_list == NULL) {
 
9550
    return;
 
9551
  }
 
9552
 
 
9553
  for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9554
    if (vnp->choice == 1) {
 
9555
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9556
      prim_change = 0;
 
9557
      tpa_change = 0;
 
9558
      if (ip->tpa_conflict == eIntervalConflict_a_overlaps_b_on_5) {
 
9559
        tpa_change = ip->conflict_interval->tpa_right - ai->tpa_left;
 
9560
        if (tpa_change > 0) {
 
9561
          ai->tpa_left += tpa_change;
 
9562
          if (ai->prim_strand == Seq_strand_minus) {
 
9563
            ai->prim_right -= tpa_change;
 
9564
          } else {
 
9565
            ai->prim_left += tpa_change;
 
9566
          }
 
9567
        }
 
9568
      }
 
9569
      if (ip->prim_conflict == eIntervalConflict_a_overlaps_b_on_5) {
 
9570
        prim_change = ip->conflict_interval->prim_right - ai->prim_left; 
 
9571
        if (prim_change > 0) {
 
9572
          ai->prim_left += prim_change;
 
9573
          if (ai->prim_strand == Seq_strand_minus) {
 
9574
            ai->tpa_right -= prim_change;
 
9575
          } else {
 
9576
            ai->tpa_left += prim_change;
 
9577
          }
 
9578
        }
 
9579
      }
 
9580
      vnp->choice = 0;
 
9581
    }
 
9582
  }
 
9583
}
 
9584
 
 
9585
 
 
9586
static void TruncateForConflictsOnRight (AssemblyIntervalInfoPtr ai)
 
9587
{
 
9588
  IntervalConflictInfoPtr ip;
 
9589
  ValNodePtr vnp;
 
9590
  Int4       prim_change, tpa_change;
 
9591
 
 
9592
  if (ai == NULL || ai->conflict_list == NULL) {
 
9593
    return;
 
9594
  }
 
9595
 
 
9596
  for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9597
    if (vnp->choice == 1) {
 
9598
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9599
      prim_change = 0;
 
9600
      tpa_change = 0;
 
9601
      if (ip->tpa_conflict == eIntervalConflict_a_overlaps_b_on_3) {
 
9602
        tpa_change = ai->tpa_right - ip->conflict_interval->tpa_left;
 
9603
        if (tpa_change > 0) {
 
9604
          ai->tpa_right -= tpa_change;
 
9605
          if (ai->prim_strand == Seq_strand_minus) {
 
9606
            ai->prim_left += tpa_change;
 
9607
          } else {
 
9608
            ai->prim_right -= tpa_change;
 
9609
          }
 
9610
        }
 
9611
      }
 
9612
      if (ip->prim_conflict == eIntervalConflict_a_overlaps_b_on_3) {
 
9613
        prim_change = ai->prim_right - ip->conflict_interval->prim_left; 
 
9614
        if (prim_change > 0) {
 
9615
          ai->prim_right -= prim_change;
 
9616
          if (ai->prim_strand == Seq_strand_minus) {
 
9617
            ai->tpa_left += prim_change;
 
9618
          } else {
 
9619
            ai->tpa_right -= prim_change;
 
9620
          }
 
9621
        }
 
9622
      }
 
9623
      vnp->choice = 0;
 
9624
    }
 
9625
  }
 
9626
}
 
9627
 
 
9628
 
 
9629
static void ReevaluateConflicts (AssemblyIntervalInfoPtr ip, Int4 overlap)
 
9630
{
 
9631
  ValNodePtr vnp;
 
9632
  IntervalConflictInfoPtr cp;
 
9633
 
 
9634
  if (ip == NULL) {
 
9635
    return;
 
9636
  }
 
9637
 
 
9638
  for (vnp = ip->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9639
    cp = vnp->data.ptrvalue;
 
9640
    if (cp->conflict_interval->action == eAssemblyIntervalInfo_Remove) {
 
9641
      vnp->choice = 0;
 
9642
    } else if (FindIntervalConflict (ip->tpa_left, ip->tpa_right, 
 
9643
                                     cp->conflict_interval->tpa_left, cp->conflict_interval->tpa_right, overlap) == eIntervalConflict_none
 
9644
               && FindIntervalConflict (ip->prim_left, ip->prim_right,
 
9645
                                        cp->conflict_interval->tpa_left, cp->conflict_interval->tpa_right, overlap) == eIntervalConflict_none) {
 
9646
      vnp->choice = 0;
 
9647
    } else {
 
9648
      vnp->choice = 1;
 
9649
    }
 
9650
  }
 
9651
}
 
9652
 
 
9653
 
 
9654
static void RecalculateAssemblyIntervalInfoEndpoints (AssemblyIntervalInfoPtr ip, Int4 overlap)
 
9655
{
 
9656
  IntervalConflictInfoPtr cp;
 
9657
  ValNodePtr vnp;
 
9658
 
 
9659
  if (ip == NULL) {
 
9660
    return;
 
9661
  }
 
9662
 
 
9663
  /* calculate endpoints */
 
9664
  AlnMgr2IndexSingleChildSeqAlign (ip->salp);
 
9665
  ip->prim_strand = SeqAlignStrand (ip->salp, 2);
 
9666
  AlnMgr2GetNthSeqRangeInSA (ip->salp, 1, &(ip->tpa_left), &(ip->tpa_right));
 
9667
  AlnMgr2GetNthSeqRangeInSA (ip->salp, 2, &(ip->prim_left), &(ip->prim_right));
 
9668
  
 
9669
  /* apply changes for conflicts and actions */
 
9670
  if (ip->action == eAssemblyIntervalInfo_Truncate_Left) {
 
9671
    TruncateForConflictsOnLeft (ip);
 
9672
  } else if (ip->action == eAssemblyIntervalInfo_Truncate_Right) {
 
9673
    TruncateForConflictsOnRight (ip);
 
9674
  } else if (ip->action == eAssemblyIntervalInfo_Truncate_Both) {
 
9675
    TruncateForConflictsOnLeft (ip);
 
9676
    TruncateForConflictsOnRight (ip);
 
9677
  } 
 
9678
 
 
9679
  ReevaluateConflicts (ip, overlap);
 
9680
  for (vnp = ip->conflict_list; vnp != NULL; vnp = vnp->next) {
 
9681
    cp = vnp->data.ptrvalue;
 
9682
    ReevaluateConflicts (cp->conflict_interval, overlap);
 
9683
  }
 
9684
}
 
9685
 
 
9686
 
 
9687
static AssemblyIntervalInfoPtr AssemblyIntervalInfoNew (SeqAlignPtr salp, Int4 overlap)
 
9688
{
 
9689
  AssemblyIntervalInfoPtr ip;
 
9690
  Char        id_txt[255];
 
9691
  SeqIdPtr    sip;
 
9692
  BioseqPtr   bsp;
 
9693
 
 
9694
  if (salp == NULL) {
 
9695
    return NULL;
 
9696
  }
 
9697
 
 
9698
  ip = (AssemblyIntervalInfoPtr) MemNew (sizeof (AssemblyIntervalInfoData));
 
9699
  ip->salp = salp;
 
9700
  AlnMgr2IndexSingleChildSeqAlign (ip->salp);
 
9701
 
 
9702
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
9703
  bsp = BioseqLockById (sip);
 
9704
  if (bsp != NULL) {
 
9705
    sip = SeqIdFree (sip);
 
9706
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
9707
    BioseqUnlock (bsp);
 
9708
  }
 
9709
 
 
9710
  SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
 
9711
  sip = SeqIdFree (sip);
 
9712
 
 
9713
  ip->prim_id = StringSave (id_txt);
 
9714
  RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
9715
  return ip;
 
9716
}
 
9717
 
 
9718
 
 
9719
static CharPtr SummarizeAssemblyInterval (AssemblyIntervalInfoPtr ip)
 
9720
{
 
9721
  CharPtr summary = NULL;
 
9722
  CharPtr fmt = "%d-%d %s %d-%d%s";
 
9723
  Int4    len;
 
9724
 
 
9725
  if (ip == NULL) {
 
9726
    return NULL;
 
9727
  }
 
9728
 
 
9729
  len = StringLen (fmt) + StringLen (ip->prim_id) + 60;
 
9730
  if (ip->prim_strand == Seq_strand_minus) {
 
9731
    len += 3;
 
9732
  }
 
9733
  summary = (CharPtr) MemNew (sizeof (Char) + len);
 
9734
  sprintf (summary, fmt, ip->tpa_left + 1, ip->tpa_right + 1,
 
9735
                         ip->prim_id, 
 
9736
                         ip->prim_left + 1, ip->prim_right + 1,
 
9737
                         ip->prim_strand == Seq_strand_minus ? "(c)" : "");
 
9738
  return summary;
 
9739
}
 
9740
 
 
9741
 
 
9742
static CharPtr SummarizeConflictList (ValNodePtr list)
 
9743
{
 
9744
  CharPtr summary = NULL, str, conflict = "Conflict with ";
 
9745
  ValNodePtr vnp, strings = NULL;
 
9746
  IntervalConflictInfoPtr ip;
 
9747
  Int4 len = 0;
 
9748
 
 
9749
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
9750
    if (vnp->choice == 1 && vnp->data.ptrvalue != NULL) {
 
9751
      ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
 
9752
      str = SummarizeAssemblyInterval (ip->conflict_interval);
 
9753
      ValNodeAddPointer (&strings, 0, str);
 
9754
      len += StringLen (str) + 3;
 
9755
    }
 
9756
  }
 
9757
  if (strings == NULL) {
 
9758
    summary = StringSave ("No conflicts");
 
9759
  } else {
 
9760
    summary = (CharPtr) MemNew (sizeof (Char) * (StringLen (conflict) + len));
 
9761
    StringCpy (summary, conflict);
 
9762
    for (vnp = strings; vnp != NULL; vnp = vnp->next) {
 
9763
      StringCat (summary, vnp->data.ptrvalue);
 
9764
      if (vnp->next != NULL) {
 
9765
        StringCat (summary, ", ");
 
9766
      }
 
9767
    }
 
9768
    strings = ValNodeFreeData (strings);
 
9769
  }
 
9770
  return summary;
 
9771
}
 
9772
 
 
9773
 
 
9774
static void RemoveConflictLists (ValNodePtr list)
 
9775
{
 
9776
  AssemblyIntervalInfoPtr ip;
 
9777
 
 
9778
  while (list != NULL) {
 
9779
    ip = (AssemblyIntervalInfoPtr) list->data.ptrvalue;
 
9780
    ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
 
9781
    list = list->next;
 
9782
  }
 
9783
}
 
9784
 
 
9785
 
 
9786
static void BuildConflictLists (ValNodePtr list, Int4 overlap)
 
9787
{
 
9788
  ValNodePtr vnp1, vnp2;
 
9789
  AssemblyIntervalInfoPtr ip1, ip2;
 
9790
  EIntervalConflict prim_conflict, tpa_conflict;
 
9791
  IntervalConflictInfoPtr conflict;
 
9792
 
 
9793
  if (list == NULL || list->next == NULL) {
 
9794
    return;
 
9795
  }
 
9796
 
 
9797
  RemoveConflictLists (list);
 
9798
 
 
9799
  for (vnp1 = list; vnp1->next != NULL; vnp1 = vnp1->next) {
 
9800
    ip1 = (AssemblyIntervalInfoPtr) vnp1->data.ptrvalue;
 
9801
    for (vnp2 = vnp1->next; vnp2 != NULL; vnp2 = vnp2->next) {
 
9802
      ip2 = (AssemblyIntervalInfoPtr) vnp2->data.ptrvalue;
 
9803
      if (StringCmp (ip1->prim_id, ip2->prim_id) == 0) {
 
9804
        tpa_conflict = FindIntervalConflict (ip1->tpa_left, ip1->tpa_right, ip2->tpa_left, ip2->tpa_right, overlap);
 
9805
        prim_conflict = FindIntervalConflict (ip1->prim_left, ip1->prim_right, ip2->prim_left, ip2->prim_right, overlap);
 
9806
        if (tpa_conflict != eIntervalConflict_none || prim_conflict != prim_conflict) {
 
9807
          conflict = IntervalConflictInfoNew (ip2, prim_conflict, tpa_conflict);
 
9808
          ValNodeAddPointer (&(ip1->conflict_list), 1, conflict);
 
9809
        }
 
9810
        tpa_conflict = FindIntervalConflict (ip2->tpa_left, ip2->tpa_right, ip1->tpa_left, ip1->tpa_right, overlap);
 
9811
        prim_conflict = FindIntervalConflict (ip2->prim_left, ip2->prim_right, ip1->prim_left, ip1->prim_right, overlap);
 
9812
        if (tpa_conflict != eIntervalConflict_none || prim_conflict != prim_conflict) {
 
9813
          conflict = IntervalConflictInfoNew (ip1, prim_conflict, tpa_conflict);
 
9814
          ValNodeAddPointer (&(ip2->conflict_list), 1, conflict);
 
9815
        }
 
9816
      }
 
9817
    }
 
9818
  }
 
9819
}
 
9820
 
 
9821
 
 
9822
static ValNodePtr AssemblyIntervalInfoListFromSeqAlign (SeqAlignPtr salp, Int4 overlap)
 
9823
{
 
9824
  ValNodePtr list = NULL;
 
9825
 
 
9826
  while (salp != NULL) {
 
9827
    ValNodeAddPointer (&list, 0, AssemblyIntervalInfoNew (salp, overlap));
 
9828
    salp = salp->next;
 
9829
  }
 
9830
 
 
9831
  BuildConflictLists (list, overlap);
 
9832
  return list;
 
9833
}
 
9834
 
 
9835
 
 
9836
typedef struct assemblyalignmentintervalresolutiondlg {
 
9837
  DIALOG_MESSAGE_BLOCK
 
9838
  DialoG intervals_dialog;
 
9839
  TexT   overlap;
 
9840
  ValNodePtr list;
 
9841
} AssemblyAlignmentIntervalResolutionDlgData, PNTR AssemblyAlignmentIntervalResolutionDlgPtr;
 
9842
 
 
9843
CharPtr assmbly_aln_int_res_labels [] = {
 
9844
  "Action",
 
9845
  "Alignment",
 
9846
  "Conflicts With" };
 
9847
 
 
9848
Uint2 assmbly_aln_int_res_types [] = {
 
9849
  TAGLIST_POPUP, TAGLIST_PROMPT, TAGLIST_PROMPT
 
9850
};
 
9851
 
 
9852
Uint2 assmbly_aln_int_res_widths [] = {
 
9853
  10, 15, 30, 0
 
9854
};
 
9855
 
 
9856
ENUM_ALIST(assmbly_aln_int_res_action_alist)
 
9857
  {"No change",  eAssemblyIntervalInfo_NoAction},
 
9858
  {"Remove",     eAssemblyIntervalInfo_Remove},
 
9859
  {"Truncate Left", eAssemblyIntervalInfo_Truncate_Left},
 
9860
  {"Truncate Right", eAssemblyIntervalInfo_Truncate_Right},
 
9861
  {"Truncate Both", eAssemblyIntervalInfo_Truncate_Both},
 
9862
END_ENUM_ALIST
 
9863
 
 
9864
 
 
9865
static EnumFieldAssocPtr assmbly_aln_int_res_alists[] = {
 
9866
  assmbly_aln_int_res_action_alist, NULL, NULL
 
9867
};
 
9868
 
 
9869
 
 
9870
static CharPtr SummarizeOneIntervalResolutionRow (AssemblyIntervalInfoPtr ip) 
 
9871
{
 
9872
  CharPtr str, int_str, conf_str, fmt = "%d\t%s\t%s\n";
 
9873
 
 
9874
  if (ip == NULL) {
 
9875
    return NULL;
 
9876
  }
 
9877
 
 
9878
  int_str = SummarizeAssemblyInterval (ip);
 
9879
  conf_str = SummarizeConflictList (ip->conflict_list);
 
9880
  str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + 15 + StringLen (int_str) + StringLen (conf_str)));
 
9881
  sprintf (str, fmt, ip->action, int_str, conf_str);
 
9882
  int_str = MemFree (int_str);
 
9883
  conf_str = MemFree (conf_str);
 
9884
 
 
9885
  return str;
 
9886
}
 
9887
 
 
9888
static void UpdateConflicts (Pointer userdata)
 
9889
{
 
9890
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9891
  AssemblyIntervalInfoPtr ip;
 
9892
  TagListPtr tlp;
 
9893
  ValNodePtr vnp, vnp_t;
 
9894
  Int4 action;
 
9895
  Boolean any_change = FALSE;
 
9896
  CharPtr str;
 
9897
  Int4    overlap = 0;
 
9898
  
 
9899
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) userdata;
 
9900
  
 
9901
  if (dlg == NULL) {
 
9902
    return;
 
9903
  }
 
9904
 
 
9905
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
9906
  if (tlp == NULL) {
 
9907
    return;
 
9908
  }
 
9909
 
 
9910
  if (!TextHasNoText (dlg->overlap)) {
 
9911
    str = SaveStringFromText (dlg->overlap);
 
9912
    overlap = atoi (str);
 
9913
    str = MemFree (str);
 
9914
    if (overlap < 0) {
 
9915
      overlap = 0;
 
9916
    }
 
9917
  }
 
9918
 
 
9919
  /* now update conflict lists */
 
9920
  for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
9921
    ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
9922
    str = ExtractTagListColumn ((CharPtr) vnp_t->data.ptrvalue, 0);
 
9923
    action = atoi (str);
 
9924
    str = MemFree (str);
 
9925
    if (action != ip->action) {
 
9926
      ip->action = action;
 
9927
      RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
9928
      any_change = TRUE;
 
9929
    }
 
9930
  }
 
9931
 
 
9932
  if (any_change) {
 
9933
    for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
9934
      ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
9935
      vnp_t->data.ptrvalue = MemFree (vnp_t->data.ptrvalue);
 
9936
      vnp_t->data.ptrvalue = SummarizeOneIntervalResolutionRow (ip);
 
9937
    }
 
9938
    
 
9939
    /* update dialog */
 
9940
    SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9941
    SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
9942
  }
 
9943
}  
 
9944
 
 
9945
static TaglistCallback assmbly_int_res_callback_list[3] = 
 
9946
 { UpdateConflicts, UpdateConflicts, UpdateConflicts };
 
9947
 
 
9948
static void SeqAlignToAssemblyAlignmentIntervalResolutionDialog (DialoG d, Pointer data)
 
9949
{
 
9950
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
9951
  SeqAlignPtr salp;
 
9952
  ValNodePtr  vnp;
 
9953
  CharPtr     str;
 
9954
  Int4        overlap = 0;
 
9955
  TagListPtr  tlp;
 
9956
 
 
9957
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
 
9958
  salp = (SeqAlignPtr) data;
 
9959
  if (dlg == NULL) {
 
9960
    return;
 
9961
  }
 
9962
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
9963
  if (tlp == NULL) {
 
9964
    return;
 
9965
  }
 
9966
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
9967
  tlp->vnp = ValNodeFreeData (tlp->vnp);
 
9968
 
 
9969
  if (!TextHasNoText (dlg->overlap)) {
 
9970
    str = SaveStringFromText (dlg->overlap);
 
9971
    overlap = atoi (str);
 
9972
    str = MemFree (str);
 
9973
    if (overlap < 0) {
 
9974
      overlap = 0;
 
9975
    }
 
9976
  }
 
9977
 
 
9978
  dlg->list = AssemblyIntervalInfoListFree (dlg->list);
 
9979
  dlg->list = AssemblyIntervalInfoListFromSeqAlign (salp, overlap);
 
9980
 
 
9981
  for (vnp = dlg->list; vnp != NULL; vnp = vnp->next) {
 
9982
    str = SummarizeOneIntervalResolutionRow (vnp->data.ptrvalue);
 
9983
    ValNodeAddPointer (&(tlp->vnp), 0, str);
 
9984
  }
 
9985
 
 
9986
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
9987
  tlp->max = MAX ((Int2) 0, (Int2) (ValNodeLen (tlp->vnp) - tlp->rows));
 
9988
  CorrectBarMax (tlp->bar, tlp->max);
 
9989
  CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
 
9990
  if (tlp->max > 0) {
 
9991
    SafeShow (tlp->bar);
 
9992
  } else {
 
9993
    SafeHide (tlp->bar);
 
9994
  }
 
9995
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
9996
 
 
9997
}
 
9998
 
 
9999
 
 
10000
static Pointer AssemblyAlignmentIntervalResolutionDialogToSeqAlign (DialoG d)
 
10001
{
 
10002
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
10003
  AssemblyIntervalInfoPtr ai;
 
10004
  SeqAlignPtr salp_list = NULL, salp_prev = NULL, salp;
 
10005
  ValNodePtr vnp;
 
10006
 
 
10007
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
 
10008
  if (dlg == NULL) {
 
10009
    return NULL;
 
10010
  }
 
10011
 
 
10012
  for (vnp = dlg->list; vnp != NULL; vnp = vnp->next) {
 
10013
    ai = vnp->data.ptrvalue;
 
10014
    if (ai->action != eAssemblyIntervalInfo_Remove) {
 
10015
      salp = (SeqAlignPtr) AsnIoMemCopy (ai->salp, (AsnReadFunc) SeqAlignAsnRead, (AsnWriteFunc) SeqAlignAsnWrite);
 
10016
      /* TODO: truncate alignments */
 
10017
 
 
10018
      /* add to list */
 
10019
      if (salp_prev == NULL) {
 
10020
        salp_list = salp;
 
10021
      } else {
 
10022
        salp_prev->next = salp;
 
10023
      }
 
10024
      salp_prev = salp;
 
10025
    }
 
10026
  }
 
10027
 
 
10028
  return (Pointer) salp_list;
 
10029
}
 
10030
 
 
10031
 
 
10032
static void ChangeAssemblyAlignmentIntervalResolutionOverlap (TexT t)
 
10033
{
 
10034
  AssemblyAlignmentIntervalResolutionDlgPtr  dlg;
 
10035
  AssemblyIntervalInfoPtr ip;
 
10036
  TagListPtr tlp;
 
10037
  ValNodePtr vnp, vnp_t;
 
10038
  CharPtr    str;
 
10039
  Int4       overlap = 0;
 
10040
 
 
10041
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (t);
 
10042
  if (dlg == NULL) {
 
10043
    return;
 
10044
  }
 
10045
 
 
10046
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
 
10047
  if (tlp == NULL) {
 
10048
    return;
 
10049
  }
 
10050
 
 
10051
  if (!TextHasNoText (dlg->overlap)) {
 
10052
    str = SaveStringFromText (dlg->overlap);
 
10053
    overlap = atoi (str);
 
10054
    str = MemFree (str);
 
10055
    if (overlap < 0) {
 
10056
      overlap = 0;
 
10057
    }
 
10058
  }
 
10059
 
 
10060
  BuildConflictLists (dlg->list, overlap);
 
10061
 
 
10062
  /* change text */
 
10063
  for (vnp = dlg->list, vnp_t = tlp->vnp; vnp != NULL && tlp->vnp != NULL; vnp = vnp->next, vnp_t = vnp_t->next) {
 
10064
    ip = (AssemblyIntervalInfoPtr) vnp->data.ptrvalue;
 
10065
    RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
 
10066
    vnp_t->data.ptrvalue = MemFree (vnp_t->data.ptrvalue);
 
10067
    vnp_t->data.ptrvalue = SummarizeOneIntervalResolutionRow (ip);
 
10068
  }
 
10069
  
 
10070
  /* update dialog */
 
10071
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
10072
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
10073
 
 
10074
}
 
10075
 
 
10076
 
 
10077
static void CleanupAssemblyAlignmentIntervalResolutionDialog (GraphiC g, VoidPtr data)
 
10078
 
 
10079
{
 
10080
  AssemblyAlignmentIntervalResolutionDlgPtr  dlg;
 
10081
 
 
10082
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) data;
 
10083
  if (dlg != NULL) {
 
10084
    dlg->list =  AssemblyIntervalInfoListFree (dlg->list);
 
10085
    dlg = MemFree (dlg);
 
10086
  }
 
10087
}
 
10088
 
 
10089
 
 
10090
static DialoG CreateAssemblyAlignmentIntervalResolutionDialog (GrouP g)
 
10091
 
 
10092
{
 
10093
  AssemblyAlignmentIntervalResolutionDlgPtr dlg;
 
10094
  GrouP                   p;
 
10095
  GrouP                   x, y, z;
 
10096
  Int4                    i;
 
10097
  Int4                    num_columns = sizeof (assmbly_aln_int_res_labels) / sizeof (CharPtr);
 
10098
 
 
10099
  p = HiddenGroup (g, -1, 0, NULL);
 
10100
  SetGroupSpacing (p, 10, 10);
 
10101
 
 
10102
  dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionDlgData));
 
10103
  if (dlg == NULL) return NULL;
 
10104
 
 
10105
  SetObjectExtra (p, dlg, CleanupAssemblyAlignmentIntervalResolutionDialog);
 
10106
  dlg->dialog = (DialoG) p;
 
10107
  
 
10108
  dlg->todialog = SeqAlignToAssemblyAlignmentIntervalResolutionDialog;
 
10109
  dlg->fromdialog = AssemblyAlignmentIntervalResolutionDialogToSeqAlign;
 
10110
 
 
10111
  z = HiddenGroup (p, 2, 0, NULL);
 
10112
  StaticPrompt (z, "Allowable Overlap", 0, 0, programFont, 'r');
 
10113
  dlg->overlap = DialogText (z, "5", 5, ChangeAssemblyAlignmentIntervalResolutionOverlap);
 
10114
  SetObjectExtra (dlg->overlap, dlg, NULL);
 
10115
 
 
10116
  x = HiddenGroup (p, 0, 2, NULL);
 
10117
  y = HiddenGroup (x, num_columns, 0, NULL);
 
10118
  for (i = 0; i < num_columns; i++) {
 
10119
      StaticPrompt (y, assmbly_aln_int_res_labels[i], assmbly_aln_int_res_widths[i] * stdCharWidth, 0, programFont, 'l');
 
10120
  }
 
10121
  dlg->intervals_dialog = CreateTagListDialogExEx (x, 6, num_columns, -1, assmbly_aln_int_res_types, 
 
10122
                                                   assmbly_aln_int_res_widths, assmbly_aln_int_res_alists,
 
10123
                                                   TRUE, TRUE, NULL, NULL,
 
10124
                                                   assmbly_int_res_callback_list, dlg, FALSE);
 
10125
 
 
10126
  AlignObjects (ALIGN_CENTER, (HANDLE) z, (HANDLE) x, NULL);
 
10127
  return (DialoG) p;
 
10128
}
 
10129
 
 
10130
 
 
10131
typedef struct assemblyalignmentintervalresolutionfrm {
 
10132
  FORM_MESSAGE_BLOCK
 
10133
  DialoG dlg;
 
10134
 
 
10135
  BioseqPtr bsp;
 
10136
} AssemblyAlignmentIntervalResolutionFrmData, PNTR AssemblyAlignmentIntervalResolutionFrmPtr;
 
10137
 
 
10138
 
 
10139
static void AcceptAssemblyAlignmentIntervalResolution (ButtoN b)
 
10140
{
 
10141
  AssemblyAlignmentIntervalResolutionFrmPtr frm;
 
10142
  SeqAlignPtr new_assem, salp, salp_next;
 
10143
 
 
10144
  frm = (AssemblyAlignmentIntervalResolutionFrmPtr) GetObjectExtra (b);
 
10145
  if (frm == NULL) {
 
10146
    return;
 
10147
  }
 
10148
 
 
10149
  /* TODO: check for problems before accepting */
 
10150
 
 
10151
  new_assem = DialogToPointer (frm->dlg);
 
10152
  if (new_assem == NULL) {
 
10153
    Message (MSG_ERROR, "No intervals left in assembly!");
 
10154
    return;
 
10155
  }
 
10156
 
 
10157
  /* remove old assembly */
 
10158
  salp = frm->bsp->hist->assembly;
 
10159
  frm->bsp->hist->assembly = NULL;
 
10160
  while (salp != NULL) {
 
10161
    salp_next = salp->next;
 
10162
    salp->next = NULL;
 
10163
    salp = SeqAlignFree (salp);
 
10164
    salp = salp_next;
 
10165
  }
 
10166
 
 
10167
  /* assign new assembly */
 
10168
  frm->bsp->hist->assembly = new_assem;
 
10169
 
 
10170
  ObjMgrSetDirtyFlag (frm->bsp->idx.entityID, TRUE);
 
10171
  ObjMgrSendMsg (OM_MSG_UPDATE, frm->bsp->idx.entityID, 0, 0);
 
10172
  Remove (frm->form);
 
10173
}
 
10174
 
 
10175
 
 
10176
extern void AssemblyAlignmentIntervalResolution (IteM i)
 
10177
{
 
10178
  BaseFormPtr        bfp;
 
10179
  BioseqPtr   bsp;
 
10180
  WindoW      w;
 
10181
  GrouP       h, c;
 
10182
  AssemblyAlignmentIntervalResolutionFrmPtr frm;
 
10183
  ButtoN                   b;
 
10184
 
 
10185
#ifdef WIN_MAC
 
10186
  bfp = currentFormDataPtr;
 
10187
#else
 
10188
  bfp = GetObjectExtra (i);
 
10189
#endif
 
10190
  if (bfp == NULL) return;
 
10191
 
 
10192
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
10193
  if (bsp == NULL) {
 
10194
    Message (MSG_ERROR, "Must select single Bioseq!");
 
10195
    return;
 
10196
  }
 
10197
  if (bsp->hist == NULL || bsp->hist->assembly == NULL) {
 
10198
    Message (MSG_ERROR, "No assembly alignment!");
 
10199
    return;
 
10200
  }
 
10201
  frm = (AssemblyAlignmentIntervalResolutionFrmPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionFrmData));
 
10202
  frm->bsp = bsp;
 
10203
 
 
10204
  w = FixedWindow (-50, -33, -10, -10, "Resolve Assembly Alignment Intervals", StdCloseWindowProc);
 
10205
  SetObjectExtra (w, frm, StdCleanupExtraProc);
 
10206
  frm->form = (ForM) w;
 
10207
 
 
10208
  h = HiddenGroup (w, -1, 0, NULL);
 
10209
  SetGroupSpacing (h, 10, 10);
 
10210
 
 
10211
  frm->dlg = CreateAssemblyAlignmentIntervalResolutionDialog(h);
 
10212
  PointerToDialog (frm->dlg, bsp->hist->assembly);
 
10213
 
 
10214
  c = HiddenGroup (h, 3, 0, NULL);
 
10215
  b = PushButton (c, "Accept", AcceptAssemblyAlignmentIntervalResolution);
 
10216
  SetObjectExtra (b, frm, NULL);
 
10217
/*  b = PushButton (c, "Check", CheckAssemblyAlignmentIntervalResolution);
 
10218
  SetObjectExtra (b, frm, NULL); */
 
10219
  b = PushButton (c, "Cancel", StdCancelButtonProc);
 
10220
 
 
10221
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
 
10222
  Show (w);
 
10223
  Update ();
 
10224
}
 
10225
 
 
10226
 
 
10227
 
7702
10228
typedef struct historyformdata {
7703
10229
  FEATURE_FORM_BLOCK
7704
10230
 
8108
10634
  Update ();
8109
10635
}
8110
10636
 
 
10637
 
 
10638
typedef struct nw {
 
10639
  Int4 score;
 
10640
  Int4 traceback_pos;
 
10641
} NWData, PNTR NWPtr;
 
10642
 
 
10643
 
 
10644
static Int4 SegmentsNeededForAlignment (CharPtr buf1, CharPtr buf2)
 
10645
{
 
10646
  CharPtr cp1, cp2;
 
10647
  Boolean gap1, gap2, change = FALSE;
 
10648
  Int4    num_segs = 1;
 
10649
 
 
10650
  cp1 = buf1;
 
10651
  cp2 = buf2;
 
10652
  if (*cp1 == '-') {
 
10653
    gap1 = TRUE;
 
10654
  } else {
 
10655
    gap1 = FALSE;
 
10656
  }
 
10657
  cp1++;
 
10658
  if (*cp2 == '-') {
 
10659
    gap2 = TRUE;
 
10660
  } else {
 
10661
    gap2 = FALSE;
 
10662
  }
 
10663
  cp2++;
 
10664
  while (*cp1 != 0 && *cp2 != 0) {
 
10665
    change = FALSE;
 
10666
    if (*cp1 == '-') {
 
10667
      if (!gap1) {
 
10668
        gap1 = TRUE;
 
10669
        change = TRUE;
 
10670
      }
 
10671
    } else if (gap1) {
 
10672
      gap1 = FALSE;
 
10673
      change = TRUE;
 
10674
    }
 
10675
    if (*cp2 == '-') {
 
10676
      if (!gap2) {
 
10677
        gap2 = TRUE;
 
10678
        change = TRUE;
 
10679
      }
 
10680
    } else if (gap2) {
 
10681
      gap2 = FALSE;
 
10682
      change = TRUE;
 
10683
    }
 
10684
    if (change) {
 
10685
      num_segs ++;
 
10686
    }
 
10687
    cp1++;
 
10688
    cp2++;
 
10689
  }
 
10690
  return num_segs;
 
10691
}
 
10692
 
 
10693
static void 
 
10694
FillInStartsAndLensForAlignment 
 
10695
(DenseSegPtr dsp,
 
10696
 CharPtr     buf1,
 
10697
 CharPtr     buf2)
 
10698
{
 
10699
  CharPtr cp1, cp2;
 
10700
  Boolean gap1, gap2, change = FALSE;
 
10701
  Int4    num_segs = 0;
 
10702
  Int4    pos1 = 0, pos2 = 0;
 
10703
 
 
10704
  cp1 = buf1;
 
10705
  cp2 = buf2;
 
10706
  if (*cp1 == '-') {
 
10707
    dsp->starts[dsp->dim * num_segs] = -1;
 
10708
    gap1 = TRUE;
 
10709
  } else {
 
10710
    dsp->starts[dsp->dim * num_segs] = pos1;
 
10711
    gap1 = FALSE;
 
10712
    pos1++;
 
10713
  }
 
10714
  cp1++;
 
10715
  if (*cp2 == '-') {
 
10716
    gap2 = TRUE;
 
10717
    dsp->starts[dsp->dim * num_segs + 1] = -1;
 
10718
  } else {
 
10719
    dsp->starts[dsp->dim * num_segs + 1] = pos2;
 
10720
    gap2 = FALSE;
 
10721
    pos2++;
 
10722
  }
 
10723
  cp2++;
 
10724
  dsp->lens[num_segs] = 1;
 
10725
 
 
10726
  while (*cp1 != 0 && *cp2 != 0) {
 
10727
    change = FALSE;
 
10728
    if (*cp1 == '-') {
 
10729
      if (!gap1) {
 
10730
        gap1 = TRUE;
 
10731
        change = TRUE;
 
10732
      }
 
10733
    } else {
 
10734
      if (gap1) {
 
10735
        gap1 = FALSE;
 
10736
        change = TRUE;
 
10737
      }
 
10738
    }
 
10739
    if (*cp2 == '-') {
 
10740
      if (!gap2) {
 
10741
        gap2 = TRUE;
 
10742
        change = TRUE;
 
10743
      }
 
10744
    } else {
 
10745
      if (gap2) {
 
10746
        gap2 = FALSE;
 
10747
        change = TRUE;
 
10748
      }
 
10749
    }
 
10750
    if (change) {
 
10751
      num_segs ++;
 
10752
      if (gap1) {
 
10753
        dsp->starts[dsp->dim * num_segs] = -1;
 
10754
      } else {
 
10755
        dsp->starts[dsp->dim * num_segs] = pos1;
 
10756
      }
 
10757
      if (gap2) {
 
10758
        dsp->starts[dsp->dim * num_segs + 1] = -1;
 
10759
      } else {
 
10760
        dsp->starts[dsp->dim * num_segs + 1] = pos2;
 
10761
      }
 
10762
      dsp->lens[num_segs] = 1;
 
10763
    } else {
 
10764
      dsp->lens[num_segs]++;
 
10765
    }
 
10766
    cp1++;
 
10767
    cp2++;
 
10768
    if (!gap1) {
 
10769
      pos1++;
 
10770
    }
 
10771
    if (!gap2) {
 
10772
      pos2++;
 
10773
    }
 
10774
  }
 
10775
}
 
10776
 
 
10777
 
 
10778
static void AdjustStringAlingmentForOffsetAndStrand (DenseSegPtr dsp, Int4 start1, Int4 start2, Int4 stop2, Uint1 strand2)
 
10779
{
 
10780
  Int4 i;
 
10781
 
 
10782
  if (dsp == NULL) {
 
10783
    return;
 
10784
  }
 
10785
 
 
10786
  for (i = 0; i < dsp->numseg; i++) {
 
10787
    if (dsp->starts[2 * i] != -1) {
 
10788
      dsp->starts[2 * i] += start1;
 
10789
    }
 
10790
    if (dsp->starts[2 * i + 1] != -1) {
 
10791
      if (strand2 == Seq_strand_plus) {
 
10792
        dsp->starts[2 * i + 1] += start2;
 
10793
      } else {
 
10794
        dsp->starts[2 * i + 1] = stop2 - dsp->starts[2 * i + 1] - dsp->lens[i];
 
10795
      }
 
10796
    }
 
10797
  }
 
10798
}
 
10799
 
 
10800
 
 
10801
/* assumption - first interval always on plus strand */
 
10802
static SeqAlignPtr NWAlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
 
10803
{
 
10804
  BioseqPtr bsp1, bsp2;
 
10805
  Int4      len1, len2, tmp, i, row, col, back_row, back_col;
 
10806
  Uint1     strand2 = Seq_strand_plus;
 
10807
  CharPtr   buf1, buf2;
 
10808
  CharPtr   alnbuf1, alnbuf2, cp1, cp2;
 
10809
  NWPtr     matrix;
 
10810
  Int4      gap_penalty = -1;
 
10811
  Int4      mismatch_penalty = -1;
 
10812
  Int4      match_score = 1;
 
10813
  Int4      left, up, diag;
 
10814
  Int4      num_segs;
 
10815
  DenseSegPtr dsp;
 
10816
  SeqAlignPtr salp = NULL;
 
10817
 
 
10818
  if (sip1 == NULL || sip2 == NULL) {
 
10819
    return NULL;
 
10820
  }
 
10821
 
 
10822
  bsp1 = BioseqLockById (sip1);
 
10823
  bsp2 = BioseqLockById (sip2);
 
10824
  
 
10825
  if (bsp1 != NULL && bsp2 != NULL) {
 
10826
    if (stop2 < start2) {
 
10827
      strand2 = Seq_strand_minus;
 
10828
      tmp = start2;
 
10829
      start2 = stop2;
 
10830
      stop2 = tmp;
 
10831
    }
 
10832
    len1 = stop1 - start1 + 1;
 
10833
    len2 = stop2 - start2 + 1;
 
10834
    buf1 = MemNew (sizeof (Char) * (len1 + 1));
 
10835
    buf2 = MemNew (sizeof (Char) * (len2 + 1));
 
10836
    SeqPortStreamInt (bsp1, start1, stop1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
10837
    SeqPortStreamInt (bsp2, start2, stop2, strand2, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
10838
 
 
10839
    matrix = (NWPtr) MemNew (sizeof (NWData) * (len1 + 1) * (len2 + 1));
 
10840
    /* initalize matrix */
 
10841
    MemSet (matrix, 0, sizeof (NWData) * (len1 + 1) * (len2 + 1));
 
10842
    matrix[0].score = 0;
 
10843
    matrix[0].traceback_pos = 0;
 
10844
    row = 0;
 
10845
    for (col = 1; col <= len1; col++) {
 
10846
      matrix[(row * (len1  + 1)) + col].score = matrix[(row * (len1  + 1)) + col - 1].score + gap_penalty;
 
10847
      matrix[(row * (len1  + 1)) + col].traceback_pos = (row * (len1  + 1)) + col - 1;
 
10848
    }
 
10849
    col = 0;
 
10850
    for (row = 1; row <= len2; row++) {
 
10851
      matrix[(row * (len1  + 1)) + col].score = matrix[((row - 1) * (len1  + 1)) + col].score + gap_penalty;
 
10852
      matrix[(row * (len1  + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col;
 
10853
    }
 
10854
 
 
10855
    /* fill in scores */
 
10856
    for (row = 1; row <= len2; row++) {
 
10857
      for (col = 1; col <= len1; col++) {
 
10858
        /* diagonal */
 
10859
        diag = matrix[((row - 1) * (len1  + 1)) + col - 1].score;
 
10860
        if (buf1[col - 1] == buf2[row - 1]) {
 
10861
          diag += match_score;
 
10862
        } else {
 
10863
          diag += mismatch_penalty;
 
10864
        }
 
10865
        left = matrix[((row) * (len1  + 1)) + col - 1].score + gap_penalty;
 
10866
        up = matrix[((row - 1) * (len1  + 1)) + col].score + gap_penalty;
 
10867
 
 
10868
        /* choose best */
 
10869
        if (left > diag && left > up) {
 
10870
          matrix[((row) * (len1 + 1)) + col].score = left + gap_penalty;
 
10871
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row) * (len1  + 1)) + col - 1;
 
10872
        } else if (up > diag && up > left) {
 
10873
          matrix[((row) * (len1 + 1)) + col].score = up + gap_penalty;
 
10874
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col;
 
10875
        } else {
 
10876
          matrix[((row) * (len1 + 1)) + col].score = diag;
 
10877
          matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row - 1) * (len1  + 1)) + col - 1;
 
10878
        }
 
10879
        
 
10880
      }
 
10881
    }
 
10882
 
 
10883
    /* trace back, create alignment strings */
 
10884
    alnbuf1 = (CharPtr) MemNew (sizeof (Char) * (len1 + len2 + 1));
 
10885
    alnbuf2 = (CharPtr) MemNew (sizeof (Char) * (len1 + len2 + 1));
 
10886
    cp1 = alnbuf1 + len1 + len2;
 
10887
    cp2 = alnbuf2 + len1 + len2;
 
10888
    *cp1 = 0;
 
10889
    *cp2 = 0;
 
10890
    cp1--;
 
10891
    cp2--;
 
10892
    row = len2;
 
10893
    col = len1;
 
10894
    while (row > 0 || col > 0) {
 
10895
      back_row = matrix[(row * (len1 + 1)) + col].traceback_pos / (len1 + 1);
 
10896
      back_col = matrix[(row * (len1 + 1)) + col].traceback_pos % (len1 + 1);
 
10897
      if (row == back_row) {
 
10898
        *cp1 = buf1[col - 1];
 
10899
        *cp2 = '-';
 
10900
      } else if (col == back_col) {
 
10901
        *cp1 = '-';
 
10902
        *cp2 = buf2[row - 1];
 
10903
      } else {
 
10904
        *cp1 = buf1[col - 1];
 
10905
        *cp2 = buf2[row - 1];
 
10906
      }
 
10907
      cp1--;
 
10908
      cp2--;
 
10909
      row = back_row;
 
10910
      col = back_col;
 
10911
    }
 
10912
 
 
10913
    /* no longer need matrix or original sequence buffers */
 
10914
    matrix = MemFree (matrix);
 
10915
    buf1 = MemFree (buf1);
 
10916
    buf2 = MemFree (buf2);
 
10917
 
 
10918
    /* count number of segments needed */
 
10919
    num_segs = SegmentsNeededForAlignment (cp1 + 1, cp2 + 1);
 
10920
        
 
10921
    /* create DenseSeg */
 
10922
    dsp = DenseSegNew ();
 
10923
    dsp->dim = 2;
 
10924
    dsp->ids = SeqIdDup (sip1);
 
10925
    dsp->ids->next = SeqIdDup (sip2);
 
10926
    dsp->numseg = num_segs;
 
10927
    dsp->lens = (Int4Ptr)MemNew (sizeof (Int4) * dsp->numseg);
 
10928
    dsp->starts = (Int4Ptr)MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
10929
    dsp->strands = (Uint1Ptr)MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
10930
 
 
10931
    /* fill in strands */
 
10932
    for (i = 0; i < dsp->numseg; i++) {
 
10933
      dsp->strands[2 * i] = Seq_strand_plus;
 
10934
      dsp->strands[2 * i + 1] = strand2;
 
10935
    }
 
10936
    /* fill in starts and lens */
 
10937
    FillInStartsAndLensForAlignment (dsp, cp1 + 1, cp2 + 1);
 
10938
 
 
10939
    /* no longer need FASTA+GAP alignment strings */
 
10940
    alnbuf1 = MemFree (alnbuf1);
 
10941
    alnbuf2 = MemFree (alnbuf2);
 
10942
 
 
10943
    /* adjust for real sequence position and strand */
 
10944
    AdjustStringAlingmentForOffsetAndStrand (dsp, start1, start2, stop2, strand2);
 
10945
 
 
10946
    salp = SeqAlignNew ();
 
10947
    salp->segs = dsp;
 
10948
    salp->segtype = SAS_DENSEG;
 
10949
    salp->dim = 2;
 
10950
  }
 
10951
  BioseqUnlock (bsp1);
 
10952
  BioseqUnlock (bsp2);
 
10953
  AlnMgr2IndexSingleChildSeqAlign (salp);  
 
10954
  return salp;
 
10955
}
 
10956
 
 
10957
 
 
10958
/* Assumptions:
 
10959
 * first interval always on plus strand
 
10960
 */
 
10961
static SeqAlignPtr AlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
 
10962
{
 
10963
  DenseSegPtr dsp;
 
10964
  SeqAlignPtr salp = NULL;
 
10965
  Int4        len1, len2, i;
 
10966
  Uint1       strand = Seq_strand_plus;
 
10967
 
 
10968
  if (sip1 == NULL || sip2 == NULL) {
 
10969
    return NULL;
 
10970
  }
 
10971
 
 
10972
  salp = NWAlignmentForInterval(sip1, sip2, start1, stop1, start2, stop2);
 
10973
  if (salp != NULL) {
 
10974
    return salp;
 
10975
  }
 
10976
 
 
10977
  dsp = DenseSegNew ();
 
10978
  dsp->dim = 2;
 
10979
  dsp->ids = SeqIdDup (sip1);
 
10980
  dsp->ids->next = SeqIdDup (sip2);
 
10981
  len1 = stop1 - start1 + 1;
 
10982
 
 
10983
  if (stop2 > start2) {
 
10984
    len2 = stop2 - start2 + 1;
 
10985
  } else {
 
10986
    len2 = start2 - stop2 + 1;
 
10987
    strand = Seq_strand_minus;
 
10988
  }
 
10989
 
 
10990
  if (len1 == len2) {
 
10991
    dsp->numseg = 1;
 
10992
  } else {
 
10993
    dsp->numseg = 2;
 
10994
  }
 
10995
 
 
10996
  dsp->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim * dsp->numseg);
 
10997
  dsp->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp->dim * dsp->numseg);
 
10998
  dsp->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp->dim);
 
10999
  
 
11000
  if (len1 == len2) {
 
11001
    dsp->lens[0] = len1;
 
11002
  } else if (len1 > len2) {
 
11003
    dsp->lens[0] = len2;
 
11004
    dsp->lens[1] = len1 - len2;
 
11005
  } else {
 
11006
    dsp->lens[0] = len1;
 
11007
    dsp->lens[1] = len2 - len1;
 
11008
  }
 
11009
 
 
11010
  dsp->starts[0] = start1;
 
11011
  if (strand == Seq_strand_minus) {
 
11012
    dsp->starts[1] = stop2;
 
11013
  } else {
 
11014
    dsp->starts[1] = start2;
 
11015
  }  
 
11016
 
 
11017
  for (i = 0; i < dsp->numseg; i++) {
 
11018
    dsp->strands[2 * i] = Seq_strand_plus;
 
11019
    dsp->strands[2 * i + 1] = strand;
 
11020
  }
 
11021
 
 
11022
  if (dsp->numseg > 1) {
 
11023
    if (len1 > len2) {
 
11024
      dsp->starts[2] = dsp->starts[0] + dsp->lens[0];
 
11025
      dsp->starts[3] = -1;
 
11026
    } else {
 
11027
      dsp->starts[2] = -1;
 
11028
      if (strand == Seq_strand_minus) {
 
11029
        dsp->starts[3] = dsp->starts[1] + dsp->lens[0] + dsp->lens[1] - 1;
 
11030
      } else {
 
11031
        dsp->starts[3] = dsp->starts[1] + dsp->lens[0];
 
11032
      }
 
11033
    }
 
11034
  }
 
11035
 
 
11036
  salp = SeqAlignNew ();
 
11037
  salp->segtype = SAS_DENSEG;
 
11038
  salp->segs = dsp;
 
11039
  
 
11040
  AlnMgr2IndexSingleChildSeqAlign (salp);  
 
11041
  return salp;
 
11042
}
 
11043
 
 
11044
 
 
11045
static void ReportCreatedAlignment (LogInfoPtr lip, SeqAlignPtr salp)
 
11046
{
 
11047
  Int4        from_1, to_1, from_2, to_2;
 
11048
  Uint1       strand;
 
11049
  Char        id1[255], id2[255];
 
11050
  SeqIdPtr    sip;
 
11051
  BioseqPtr   bsp;
 
11052
 
 
11053
  if (lip == NULL || lip->fp == NULL || salp == NULL) {
 
11054
    return;
 
11055
  }
 
11056
 
 
11057
  sip = AlnMgr2GetNthSeqIdPtr (salp, 1);
 
11058
  bsp = BioseqLockById (sip);
 
11059
  if (bsp != NULL) {
 
11060
    sip = SeqIdFree (sip);
 
11061
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11062
    BioseqUnlock (bsp);
 
11063
  }
 
11064
 
 
11065
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
11066
  sip = SeqIdFree (sip);
 
11067
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
11068
  bsp = BioseqLockById (sip);
 
11069
  if (bsp != NULL) {
 
11070
    sip = SeqIdFree (sip);
 
11071
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11072
    BioseqUnlock (bsp);
 
11073
  }
 
11074
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
11075
  sip = SeqIdFree (sip);
 
11076
  
 
11077
  strand = SeqAlignStrand (salp, 2);
 
11078
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &from_1, &to_1);
 
11079
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &from_2, &to_2);
 
11080
  fprintf (lip->fp, "Created alignment to cover space between local alignments: %s:%d-%d, %s:%d-%d%s\n",
 
11081
                     id1, from_1, to_1, id2, from_2, to_2,
 
11082
                     strand == Seq_strand_minus ? "(c)" : "");
 
11083
 
 
11084
  WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
 
11085
}
 
11086
 
 
11087
 
 
11088
static void FillInAlignmentHoles (SeqAlignPtr salp_list, LogInfoPtr lip)
 
11089
{
 
11090
  SeqAlignPtr salp, salp_new;
 
11091
  Int4        start1_this, start1_next;
 
11092
  Int4        stop1_this, stop1_next;
 
11093
  Int4        start2_this, start2_next;
 
11094
  Int4        stop2_this, stop2_next;
 
11095
  Uint1       strand;
 
11096
  SeqIdPtr    sip1, sip2;
 
11097
 
 
11098
  if (salp_list == NULL || salp_list->next == NULL) {
 
11099
    return;
 
11100
  }
 
11101
 
 
11102
  sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11103
  sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11104
 
 
11105
  /* note - unlike the other functions, SeqAlignStrand uses 0-based index */
 
11106
  strand = SeqAlignStrand (salp_list, 1);
 
11107
 
 
11108
  salp = salp_list;
 
11109
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &start1_this, &stop1_this);
 
11110
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &start2_this, &stop2_this);
 
11111
  
 
11112
  while (salp->next != NULL) {
 
11113
    AlnMgr2GetNthSeqRangeInSA (salp->next, 1, &start1_next, &stop1_next);
 
11114
    AlnMgr2GetNthSeqRangeInSA (salp->next, 2, &start2_next, &stop2_next);
 
11115
    if (start1_next > stop1_this + 1
 
11116
        || (strand == Seq_strand_minus && start2_next < stop2_this - 1)
 
11117
        || (strand != Seq_strand_minus && start2_next > stop2_this + 1)) {
 
11118
      if (strand == Seq_strand_minus) {
 
11119
        salp_new = AlignmentForInterval (sip1, sip2, stop1_this + 1, start1_next - 1, stop2_this - 1, start2_next + 1);
 
11120
      } else {
 
11121
        salp_new = AlignmentForInterval (sip1, sip2, stop1_this + 1, start1_next - 1, stop2_this + 1, start2_next - 1);
 
11122
      }
 
11123
      ReportCreatedAlignment (lip, salp_new);
 
11124
      salp_new->next = salp->next;
 
11125
      salp->next = salp_new;
 
11126
      salp = salp_new;
 
11127
    }
 
11128
    start1_this = start1_next;
 
11129
    stop1_this = stop1_next;
 
11130
    start2_this = start2_next;
 
11131
    stop2_this = stop2_next;
 
11132
    salp = salp->next;
 
11133
  }
 
11134
 
 
11135
}
 
11136
 
 
11137
 
 
11138
static SeqAlignPtr MergeAlignments (SeqAlignPtr salp_list)
 
11139
{
 
11140
  SeqAlignPtr salp_new = NULL, salp, salp_next;
 
11141
  DenseSegPtr dsp, dsp_new;
 
11142
  Int4        seg_num, k;
 
11143
 
 
11144
  if (salp_list == NULL || salp_list->next == NULL) {
 
11145
    return salp_list;
 
11146
  }
 
11147
 
 
11148
  dsp_new = DenseSegNew ();
 
11149
  dsp_new->dim = 2;
 
11150
  dsp_new->ids = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11151
  dsp_new->ids->next = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11152
 
 
11153
  /* get total number of segments */
 
11154
  for (salp = salp_list; salp != NULL; salp = salp->next) {
 
11155
    dsp = (DenseSegPtr) salp->segs;
 
11156
    dsp_new->numseg += dsp->numseg;
 
11157
  }
 
11158
 
 
11159
  dsp_new->starts = (Int4Ptr) MemNew (sizeof (Int4) * dsp_new->dim * dsp_new->numseg);
 
11160
  dsp_new->strands = (Uint1Ptr) MemNew (sizeof (Uint1) * dsp_new->dim * dsp_new->numseg);
 
11161
  dsp_new->lens = (Int4Ptr) MemNew (sizeof (Int4) * dsp_new->numseg);
 
11162
  
 
11163
  seg_num = 0;
 
11164
  for (salp = salp_list; salp != NULL; salp = salp_next) {
 
11165
    salp_next = salp->next;
 
11166
    dsp = (DenseSegPtr) salp->segs;
 
11167
    for (k = 0; k < dsp->numseg; k++) {
 
11168
      dsp_new->lens[seg_num] = dsp->lens[k];
 
11169
      dsp_new->starts[2 * seg_num] = dsp->starts[2 * k];
 
11170
      dsp_new->starts[2 * seg_num + 1] = dsp->starts[2 * k + 1];
 
11171
      dsp_new->strands[2 * seg_num] = dsp->strands[2 * k];
 
11172
      dsp_new->strands[2 * seg_num + 1] = dsp->strands[2 * k + 1];
 
11173
      seg_num++;
 
11174
    }
 
11175
    salp->next = NULL;
 
11176
    salp = SeqAlignFree (salp);
 
11177
  }
 
11178
 
 
11179
  salp_new = SeqAlignNew ();
 
11180
  salp_new->segtype = SAS_DENSEG;
 
11181
  salp_new->segs = dsp_new;
 
11182
  salp_new->dim = 2;
 
11183
 
 
11184
  return salp_new;
 
11185
}
 
11186
 
 
11187
 
 
11188
static Boolean MatchWithAmbiguity (Char ch1, Char ch2)
 
11189
{
 
11190
  Boolean rval = FALSE;
 
11191
 
 
11192
  ch1 = toupper (ch1);
 
11193
  ch2 = toupper (ch2);
 
11194
 
 
11195
  if (ch1 == ch2) {
 
11196
    return TRUE;
 
11197
  }
 
11198
  if (ch1 == 'X' || ch2 == 'X') {
 
11199
    return TRUE;
 
11200
  }
 
11201
  switch (ch1) {
 
11202
    case 'A':
 
11203
      if (ch2 == 'M' || ch2 == 'R' || ch2 == 'W' || ch2 == 'V' || ch2 == 'H' || ch2 == 'D') {
 
11204
        rval = TRUE;
 
11205
      }
 
11206
      break;
 
11207
    case 'T':
 
11208
      if (ch2 == 'K' || ch2 == 'Y' || ch2 == 'W' || ch2 == 'B' || ch2 == 'H' || ch2 == 'D') {
 
11209
        rval = TRUE;
 
11210
      }
 
11211
      break;
 
11212
    case 'G':
 
11213
      if (ch2 == 'K' || ch2 == 'R' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'D') {
 
11214
        rval = TRUE;
 
11215
      }
 
11216
      break;
 
11217
    case 'C':
 
11218
      if (ch2 == 'M' || ch2 == 'Y' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'H') {
 
11219
        rval = TRUE;
 
11220
      }
 
11221
      break;
 
11222
    case 'K':
 
11223
      if (ch2 == 'G' || ch2 == 'T' || ch2 == 'B' || ch2 == 'D') {
 
11224
        rval = TRUE;
 
11225
      }
 
11226
      break;
 
11227
    case 'M':
 
11228
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'V' || ch2 == 'H') {
 
11229
        rval = TRUE;
 
11230
      }
 
11231
      break;
 
11232
    case 'R':
 
11233
      if (ch2 == 'A' || ch2 == 'G' || ch2 == 'V' || ch2 == 'D') {
 
11234
        rval = TRUE;
 
11235
      }
 
11236
      break;
 
11237
    case 'Y':
 
11238
      if (ch2 == 'C' || ch2 == 'T' || ch2 == 'B' || ch2 == 'H') {
 
11239
        rval = TRUE;
 
11240
      }
 
11241
      break;
 
11242
    case 'S':
 
11243
      if (ch2 == 'C' || ch2 == 'G' || ch2 == 'B' || ch2 == 'V') {
 
11244
        rval = TRUE;
 
11245
      }
 
11246
      break;
 
11247
    case 'W':
 
11248
      if (ch2 == 'A' || ch2 == 'T' || ch2 == 'H' || ch2 == 'D') {
 
11249
        rval = TRUE;
 
11250
      }
 
11251
      break;
 
11252
    case 'B':
 
11253
      if (ch2 == 'C' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'Y' || ch2 == 'S') {
 
11254
        rval = TRUE;
 
11255
      }
 
11256
      break;
 
11257
    case 'V':
 
11258
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'G' || ch2 == 'M' || ch2 == 'R' || ch2 == 'S') {
 
11259
        rval = TRUE;
 
11260
      }
 
11261
      break;
 
11262
    case 'H':
 
11263
      if (ch2 == 'A' || ch2 == 'C' || ch2 == 'T' || ch2 == 'M' || ch2 == 'Y' || ch2 == 'W') {
 
11264
        rval = TRUE;
 
11265
      }
 
11266
      break;
 
11267
    case 'D':
 
11268
      if (ch2 == 'A' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'R' || ch2 == 'W') {
 
11269
        rval = TRUE;
 
11270
      }
 
11271
      break;
 
11272
  }
 
11273
  return rval;
 
11274
}  
 
11275
  
 
11276
 
 
11277
/* expand for ambiguity characters and poly-A tail */
 
11278
static SeqAlignPtr ExtendAlignmentList (SeqAlignPtr salp_list)
 
11279
{
 
11280
  Int4        from_1, to_1, from_2, to_2, len1, len2, len_check, len_extend;
 
11281
  SeqAlignPtr salp_tmp;
 
11282
  BioseqPtr   bsp1 = NULL;
 
11283
  BioseqPtr   bsp2 = NULL;
 
11284
  Uint1       strand;
 
11285
  CharPtr     buf1, buf2;
 
11286
  Int2        ctr;
 
11287
  SeqIdPtr    sip1, sip2;
 
11288
  DenseSegPtr dsp;
 
11289
 
 
11290
  if (salp_list == NULL) {
 
11291
    return salp_list;
 
11292
  }
 
11293
 
 
11294
  strand = SeqAlignStrand (salp_list, 1);
 
11295
  AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11296
 
 
11297
  sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11298
  bsp1 = BioseqLockById (sip1);
 
11299
  sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11300
  bsp2 = BioseqLockById (sip2);
 
11301
 
 
11302
  AlnMgr2GetNthSeqRangeInSA (salp_list, 1, &from_1, &to_1);  
 
11303
  AlnMgr2GetNthSeqRangeInSA (salp_list, 2, &from_2, &to_2);  
 
11304
 
 
11305
  if (from_1 > 0 
 
11306
      && ((strand == Seq_strand_plus && from_2 > 0)
 
11307
          || (strand == Seq_strand_minus && to_2 < bsp2->length - 1))) {
 
11308
    len1 = from_1;
 
11309
    if (strand == Seq_strand_plus) {
 
11310
      len2 = from_2;
 
11311
    } else {
 
11312
      len2 = bsp2->length - to_2 - 1;
 
11313
    }
 
11314
    if (len1 > len2) {
 
11315
      len_check = len2;
 
11316
    } else {
 
11317
      len_check = len1;
 
11318
    }
 
11319
    buf1 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11320
    buf2 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11321
    ctr = SeqPortStreamInt (bsp1, from_1 - len_check, from_1 - 1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
11322
    buf1[ctr] = 0;
 
11323
    if (strand == Seq_strand_plus) {
 
11324
      ctr = SeqPortStreamInt (bsp2, from_2 - len_check, from_2 - 1, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11325
    } else {
 
11326
      ctr = SeqPortStreamInt (bsp2, to_2 + 1, to_2 + len_check, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11327
    }
 
11328
    buf2[ctr] = 0;
 
11329
 
 
11330
    len_extend = 0;
 
11331
    while (len_extend < len_check 
 
11332
           && MatchWithAmbiguity (buf1[len_check - len_extend - 1], buf2[len_check - len_extend - 1])) {
 
11333
      len_extend++;
 
11334
    }
 
11335
    buf1 = MemFree (buf1);
 
11336
    buf2 = MemFree (buf2);
 
11337
    if (len_extend > 0) {
 
11338
      dsp = (DenseSegPtr) salp_list->segs;
 
11339
      dsp->lens[0] += len_extend;
 
11340
      dsp->starts[0] -= len_extend;
 
11341
      if (strand == Seq_strand_plus) {
 
11342
        dsp->starts[1] -= len_extend;
 
11343
      }
 
11344
      SeqAlignIndexFree(salp_list->saip);
 
11345
      salp_list->saip = NULL;
 
11346
      AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11347
    }
 
11348
  }
 
11349
 
 
11350
  /* extend at other end */
 
11351
  salp_tmp = salp_list;
 
11352
  while (salp_tmp->next != NULL) {
 
11353
    salp_tmp = salp_tmp->next;
 
11354
  }
 
11355
 
 
11356
  AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11357
 
 
11358
  AlnMgr2GetNthSeqRangeInSA (salp_tmp, 1, &from_1, &to_1);  
 
11359
  AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11360
  if (to_1 < bsp1->length - 1
 
11361
      && ((strand == Seq_strand_plus && to_2 < bsp2->length - 1)
 
11362
          || (strand == Seq_strand_minus && from_2 > 0))) {
 
11363
    len1 = bsp1->length - to_1 - 1;
 
11364
    if (strand == Seq_strand_plus) {
 
11365
      len2 = bsp2->length - to_2 - 1;
 
11366
    } else {
 
11367
      len2 = from_2;
 
11368
    }
 
11369
    if (len1 > len2) {
 
11370
      len_check = len2;
 
11371
    } else {
 
11372
      len_check = len1;
 
11373
    }
 
11374
    if (len_check > 0) {
 
11375
      buf1 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11376
      buf2 = (CharPtr) MemNew (sizeof (Char) * (len_check  + 1));
 
11377
      ctr = SeqPortStreamInt (bsp1, to_1 + 1, to_1 + len_check, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf1, NULL);
 
11378
      buf1[ctr] = 0;
 
11379
      if (strand == Seq_strand_plus) {
 
11380
        ctr = SeqPortStreamInt (bsp2, to_2 + 1, to_2 + len_check, Seq_strand_plus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11381
      } else {
 
11382
        ctr = SeqPortStreamInt (bsp2, from_2 - len_check, from_2 - 1, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
 
11383
      }
 
11384
      buf2[ctr] = 0;
 
11385
 
 
11386
      len_extend = 0;
 
11387
      while (len_extend < len_check 
 
11388
            && MatchWithAmbiguity (buf1[len_extend], buf2[len_extend])) {
 
11389
        len_extend++;
 
11390
      }
 
11391
      buf1 = MemFree (buf1);
 
11392
      buf2 = MemFree (buf2);
 
11393
      if (len_extend > 0) {
 
11394
        dsp = (DenseSegPtr) salp_tmp->segs;
 
11395
        dsp->lens[dsp->numseg - 1] += len_extend;
 
11396
        if (strand == Seq_strand_minus) {
 
11397
          dsp->starts[(dsp->numseg - 1) * dsp->dim + 1] -= len_extend;
 
11398
        }
 
11399
        SeqAlignIndexFree(salp_tmp->saip);
 
11400
        salp_tmp->saip = NULL;
 
11401
        AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11402
      }
 
11403
    }
 
11404
  }   
 
11405
 
 
11406
  BioseqUnlock (bsp1);
 
11407
  BioseqUnlock (bsp2);
 
11408
  sip1 = SeqIdFree (sip1);  
 
11409
  sip2 = SeqIdFree (sip2);  
 
11410
 
 
11411
  return salp_list;
 
11412
}
 
11413
 
 
11414
 
 
11415
static void ReportInitialBlastResults (LogInfoPtr lip, SeqAlignPtr salp_list)
 
11416
{
 
11417
  Int4        from_1, to_1, from_2, to_2;
 
11418
  Uint1       strand;
 
11419
  Char        id1[255], id2[255];
 
11420
  SeqIdPtr    sip;
 
11421
  BioseqPtr   bsp;
 
11422
 
 
11423
  if (lip == NULL || lip->fp == NULL || salp_list == NULL) {
 
11424
    return;
 
11425
  }
 
11426
 
 
11427
  AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11428
  sip = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
 
11429
  bsp = BioseqLockById (sip);
 
11430
  if (bsp != NULL) {
 
11431
    sip = SeqIdFree (sip);
 
11432
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11433
    BioseqUnlock (bsp);
 
11434
  }
 
11435
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
11436
  sip = SeqIdFree (sip);
 
11437
  sip = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
 
11438
  bsp = BioseqLockById (sip);
 
11439
  if (bsp != NULL) {
 
11440
    sip = SeqIdFree (sip);
 
11441
    sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11442
    BioseqUnlock (bsp);
 
11443
  }
 
11444
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
11445
  sip = SeqIdFree (sip);
 
11446
  fprintf (lip->fp, "Initial BLAST results\n");
 
11447
  while (salp_list != NULL) {
 
11448
    AlnMgr2IndexSingleChildSeqAlign (salp_list);
 
11449
    strand = SeqAlignStrand (salp_list, 2);
 
11450
    AlnMgr2GetNthSeqRangeInSA (salp_list, 1, &from_1, &to_1);
 
11451
    AlnMgr2GetNthSeqRangeInSA (salp_list, 2, &from_2, &to_2);
 
11452
    fprintf (lip->fp, "%s:%d-%d, %s:%d-%d%s\n", id1, from_1, to_1, id2, from_2, to_2,
 
11453
             strand == Seq_strand_minus ? "(c)" : "");
 
11454
    salp_list = salp_list->next;
 
11455
  }
 
11456
  lip->data_in_log = TRUE;
 
11457
}
 
11458
 
 
11459
 
 
11460
static void ReportForRemoval (LogInfoPtr lip, SeqAlignPtr salp, CharPtr reason)
 
11461
{
 
11462
  Int4        from_1, to_1, from_2, to_2;
 
11463
  Uint1       strand;
 
11464
  Char        id1[255], id2[255];
 
11465
  SeqIdPtr    sip;
 
11466
 
 
11467
  if (lip == NULL || lip->fp == NULL || salp == NULL) {
 
11468
    return;
 
11469
  }
 
11470
 
 
11471
  sip = AlnMgr2GetNthSeqIdPtr (salp, 1);
 
11472
  SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
 
11473
  sip = SeqIdFree (sip);
 
11474
  sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
11475
  SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
 
11476
  sip = SeqIdFree (sip);
 
11477
  AlnMgr2IndexSingleChildSeqAlign (salp);
 
11478
  strand = SeqAlignStrand (salp, 2);
 
11479
  AlnMgr2GetNthSeqRangeInSA (salp, 1, &from_1, &to_1);
 
11480
  AlnMgr2GetNthSeqRangeInSA (salp, 2, &from_2, &to_2);
 
11481
  fprintf (lip->fp, "Removed alignment %s:%d-%d, %s:%d-%d%s %s\n",
 
11482
                     id1, from_1, to_1, id2, from_2, to_2,
 
11483
                     strand == Seq_strand_minus ? "(c)" : "", reason);
 
11484
}
 
11485
 
 
11486
 
 
11487
/* Assume earlier alignments are better.  
 
11488
 * Remove all alignments that are not the same strand as the first.
 
11489
 * Remove all alignments that overlap on the first sequence.
 
11490
 * Remove all alignments that overlap on the second sequence.
 
11491
 * use Needleman-Wunsch to fill in holes between alignments.
 
11492
 */
 
11493
static SeqAlignPtr CombineTSAAlignments (SeqAlignPtr salp)
 
11494
{
 
11495
  SeqAlignPtr salp_tmp, salp_match, salp_prev, salp_next;
 
11496
  Uint1       strand;
 
11497
  Int4        from_1, to_1, from_2, to_2;
 
11498
  LogInfoPtr  lip = NULL;
 
11499
 
 
11500
  if (salp == NULL) {
 
11501
    return salp;
 
11502
  }
 
11503
 
 
11504
  for (salp_tmp = salp; salp_tmp != NULL; salp_tmp = salp_tmp->next) {
 
11505
    /* if alignment is to minus strand for first sequence, flip alignment */
 
11506
    if (SeqAlignStrand (salp_tmp, 0) != Seq_strand_plus) {
 
11507
      FlipAlignment (salp_tmp);
 
11508
    }
 
11509
  }
 
11510
 
 
11511
  if (salp->next != NULL) {
 
11512
    lip = OpenLog ("TSA Alignment Adjustments");
 
11513
  }
 
11514
 
 
11515
  ReportInitialBlastResults (lip, salp);
 
11516
 
 
11517
  if (salp->next != NULL) {
 
11518
    /* remove alignments that are not the same strand as the initial alignment */
 
11519
    strand = SeqAlignStrand (salp, 1);
 
11520
    salp_prev = salp;
 
11521
    AlnMgr2IndexSingleChildSeqAlign (salp);
 
11522
    salp_tmp = salp->next;
 
11523
    while (salp_tmp != NULL) {
 
11524
      AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
 
11525
      salp_next = salp_tmp->next;
 
11526
      if (SeqAlignStrand (salp_tmp, 1) != strand) {
 
11527
        ReportForRemoval (lip, salp_tmp, "because strands do not match.");
 
11528
        salp_prev->next = salp_tmp->next;
 
11529
        salp_tmp->next = NULL;
 
11530
        salp_tmp = SeqAlignFree (salp_tmp);
 
11531
      }
 
11532
      salp_tmp = salp_next;
 
11533
    }
 
11534
  }
 
11535
  
 
11536
  /* remove alignments that overlap on the first sequence */
 
11537
  salp_match = salp;
 
11538
  while (salp_match != NULL) {
 
11539
    salp_prev = salp_match;
 
11540
    salp_tmp = salp_match->next;
 
11541
    AlnMgr2GetNthSeqRangeInSA (salp_match, 1, &from_1, &to_1);
 
11542
    while (salp_tmp != NULL) {
 
11543
      salp_next = salp_tmp->next;
 
11544
      AlnMgr2GetNthSeqRangeInSA (salp_tmp, 1, &from_2, &to_2);
 
11545
      if ((from_2 >= from_1 && from_2 <= to_1) || (to_2 >= from_1 && to_2 <= to_1)) { 
 
11546
        ReportForRemoval (lip, salp_tmp, "because alignments overlap for first sequence.");
 
11547
        salp_prev->next = salp_tmp->next;
 
11548
        salp_tmp->next = NULL;
 
11549
        salp_tmp = SeqAlignFree (salp_tmp);
 
11550
      }
 
11551
      salp_tmp = salp_next;
 
11552
    }
 
11553
    salp_match = salp_match->next;
 
11554
  }
 
11555
 
 
11556
  if (salp->next != NULL) {
 
11557
    /* remove alignments that overlap on the second sequence */
 
11558
    salp_match = salp;
 
11559
    while (salp_match != NULL) {
 
11560
      salp_prev = salp_match;
 
11561
      salp_tmp = salp_match->next;
 
11562
      AlnMgr2GetNthSeqRangeInSA (salp_match, 2, &from_1, &to_1);
 
11563
      while (salp_tmp != NULL) {
 
11564
        salp_next = salp_tmp->next;
 
11565
        AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11566
        if ((from_2 >= from_1 && from_2 <= to_1) || (to_2 >= from_1 && to_2 <= to_1)) { 
 
11567
          ReportForRemoval (lip, salp_tmp, "because alignments overlap for second sequence.");
 
11568
          salp_prev->next = salp_tmp->next;
 
11569
          salp_tmp->next = NULL;
 
11570
          salp_tmp = SeqAlignFree (salp_tmp);
 
11571
        }
 
11572
        salp_tmp = salp_next;
 
11573
      }
 
11574
      salp_match = salp_match->next;
 
11575
    }
 
11576
  }
 
11577
 
 
11578
  /* sort remaining alignments by start position on the first sequence */
 
11579
  salp = SortPairwiseAlignmentsByFirstSeqRange (salp);
 
11580
 
 
11581
  /* temporary hack.  only interested in "unusual" errors. */
 
11582
  if (lip != NULL) {
 
11583
    lip->data_in_log = FALSE;
 
11584
  }
 
11585
 
 
11586
  if (salp->next != NULL) {
 
11587
    /* remove alignments that are out of order on the second sequence */
 
11588
    salp_prev = salp;
 
11589
    AlnMgr2GetNthSeqRangeInSA (salp_prev, 2, &from_1, &to_1);
 
11590
    salp_tmp = salp->next;
 
11591
    while (salp_tmp != NULL) {
 
11592
      AlnMgr2GetNthSeqRangeInSA (salp_tmp, 2, &from_2, &to_2);
 
11593
      if (from_2 < from_1) {
 
11594
        ReportForRemoval (lip, salp_tmp, "because alignments are out of order for second sequence.");
 
11595
        salp_prev->next = salp_tmp->next;
 
11596
        salp_tmp->next = NULL;
 
11597
        salp_tmp = SeqAlignFree (salp_tmp);
 
11598
      } else {
 
11599
        salp_prev = salp_tmp;
 
11600
        from_1 = from_2;
 
11601
        to_1 = to_2;
 
11602
      }
 
11603
      salp_tmp = salp_prev->next;
 
11604
    }
 
11605
  }
 
11606
 
 
11607
  /* fill in holes */
 
11608
  FillInAlignmentHoles (salp, lip);
 
11609
 
 
11610
  /* extend for good matches */
 
11611
  salp = ExtendAlignmentList (salp);
 
11612
 
 
11613
  /* make new alignment by stringing together local alignments */
 
11614
  salp = MergeAlignments (salp);
 
11615
  CloseLog (lip);
 
11616
  lip = FreeLog (lip);
 
11617
  return salp;
 
11618
}
 
11619
 
 
11620
 
 
11621
NLM_EXTERN SeqAlignPtr GetSeqAlignTSA (BioseqPtr bsp1, BioseqPtr bsp2)
 
11622
{
 
11623
   BLAST_SummaryOptions *options = NULL;
 
11624
   SeqAlignPtr           salp = NULL;
 
11625
   
 
11626
   if (bsp1 == NULL || bsp2 == NULL) return NULL;
 
11627
 
 
11628
   BLAST_SummaryOptionsInit(&options);
 
11629
   options->filter_string = StringSave ("m L");
 
11630
   options->word_size = 20;
 
11631
   options->cutoff_evalue = act_get_eval (1);
 
11632
   options->hint = eNone;
 
11633
   if (ISA_na (bsp1->mol))
 
11634
   {
 
11635
     options->program = eBlastn;
 
11636
   }
 
11637
   else
 
11638
   {
 
11639
     options->program = eBlastp;
 
11640
   }
 
11641
 
 
11642
   BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
 
11643
 
 
11644
   /* if there were no alignments from the first search, try again
 
11645
    * with low-complexity masking turned off.
 
11646
    */
 
11647
   if (salp == NULL) {
 
11648
     options->filter_string = MemFree (options->filter_string);
 
11649
     options->filter_string = StringSave ("m F");
 
11650
     BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
 
11651
   }
 
11652
 
 
11653
   BLAST_SummaryOptionsFree(options);
 
11654
 
 
11655
   if (salp != NULL) {
 
11656
     salp = CombineTSAAlignments (salp);
 
11657
     AlnMgr2IndexSeqAlign(salp);
 
11658
   }
 
11659
   return salp;
 
11660
}
 
11661
 
 
11662
 
 
11663
/* code for editing TSA assembly */
 
11664
typedef struct tsaassemblydialog {
 
11665
  DIALOG_MESSAGE_BLOCK
 
11666
  DialoG        intervals;
 
11667
  BioseqPtr     consensus_bsp;
 
11668
} TSAAssemblyDialog, PNTR TSAAssemblyDialogPtr;
 
11669
 
 
11670
 
 
11671
Uint2 tsa_assembly_types [] = {
 
11672
  TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_PROMPT
 
11673
};
 
11674
 
 
11675
 
 
11676
Uint2 tsa_assembly_widths [] = {
 
11677
  16, 16, 16, 0
 
11678
};
 
11679
 
 
11680
 
 
11681
static void SetTSAAssemblyDialogConsensusBioseq (DialoG d, BioseqPtr bsp)
 
11682
{
 
11683
  TSAAssemblyDialogPtr dlg;
 
11684
 
 
11685
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11686
  if (dlg != NULL) {
 
11687
    dlg->consensus_bsp = bsp;
 
11688
  }
 
11689
}
 
11690
 
 
11691
 
 
11692
static void SeqAlignsToTSAAssemblyDialog (DialoG d, Pointer data)
 
11693
{
 
11694
  TSAAssemblyDialogPtr  dlg;
 
11695
  TagListPtr            tlp;
 
11696
  SeqAlignPtr           salp_list, salp, salp_tmp;
 
11697
  ValNodePtr            data_list = NULL;
 
11698
  Int4                  tsa_from, tsa_to, primary_from, primary_to;
 
11699
  SeqIdPtr              sip;
 
11700
  Char                  id_buf[255];
 
11701
  CharPtr               str;
 
11702
  CharPtr               fmt = "%s\t%d-%d%s\t%d-%d\n";
 
11703
  Uint1                 strand;
 
11704
  BioseqPtr             bsp;
 
11705
 
 
11706
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11707
  if (dlg == NULL) {
 
11708
    return;
 
11709
  }
 
11710
 
 
11711
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
 
11712
  if (tlp == NULL) {
 
11713
    return;
 
11714
  }
 
11715
 
 
11716
  salp_list = (SeqAlignPtr) data;
 
11717
 
 
11718
  salp = salp_list;
 
11719
  while (salp != NULL) {
 
11720
    salp_tmp = salp->next;
 
11721
    salp->next = NULL;
 
11722
    AlnMgr2IndexSeqAlign (salp);
 
11723
    AlnMgr2GetNthSeqRangeInSA(salp, 1, &tsa_from, &tsa_to);
 
11724
    AlnMgr2GetNthSeqRangeInSA(salp, 2, &primary_from, &primary_to);
 
11725
    sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
 
11726
    bsp = BioseqLockById (sip);
 
11727
    if (bsp != NULL) {
 
11728
      sip = SeqIdFree (sip);
 
11729
      sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
 
11730
      BioseqUnlock (bsp);
 
11731
    }
 
11732
    SeqIdWrite (sip, id_buf, PRINTID_FASTA_SHORT, sizeof (id_buf) - 1);
 
11733
    sip = SeqIdFree (sip);
 
11734
    strand = AlnMgr2GetNthStrand (salp, 2);
 
11735
    str = (CharPtr) MemNew (sizeof (Char) * (StringLen (fmt) + StringLen (id_buf) + 70));
 
11736
    sprintf (str, fmt, id_buf, primary_from + 1, primary_to + 1, strand == Seq_strand_minus ? "(c)" : "", tsa_from + 1, tsa_to + 1);
 
11737
    ValNodeAddPointer (&data_list, 0, str);
 
11738
    salp->next = salp_tmp;
 
11739
    salp = salp->next;
 
11740
  }
 
11741
 
 
11742
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
11743
  tlp->vnp = data_list;
 
11744
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
11745
  tlp->max = MAX ((Int2) 0, (Int2) (ValNodeLen (data_list) - tlp->rows));
 
11746
  CorrectBarMax (tlp->bar, tlp->max);
 
11747
  CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
 
11748
  if (tlp->max > 0) {
 
11749
    SafeShow (tlp->bar);
 
11750
  } else {
 
11751
    SafeHide (tlp->bar);
 
11752
  }
 
11753
  SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
 
11754
}
 
11755
 
 
11756
 
 
11757
static void TSATableCallback (Pointer data)
 
11758
{
 
11759
  ProcessExternalEvent ();
 
11760
}
 
11761
 
 
11762
 
 
11763
static Pointer TSAAssemblyDialogToTranscriptomeIdsList (DialoG d)
 
11764
{
 
11765
  TSAAssemblyDialogPtr  dlg;
 
11766
  TagListPtr            tlp;
 
11767
  ValNodePtr            vnp;
 
11768
  CharPtr               txt;
 
11769
  TranscriptomeIdsPtr   t;
 
11770
  ValNodePtr            token_list = NULL;
 
11771
 
 
11772
  dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
 
11773
  if (dlg == NULL) {
 
11774
    return NULL;
 
11775
  }
 
11776
 
 
11777
  tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
 
11778
  if (tlp == NULL) {
 
11779
    return NULL;
 
11780
  }
 
11781
 
 
11782
  if (dlg->consensus_bsp == NULL) {
 
11783
    return NULL;
 
11784
  }
 
11785
 
 
11786
  for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
 
11787
    txt = ExtractTagListColumn (vnp->data.ptrvalue, 0);
 
11788
    if (StringHasNoText (txt)) {
 
11789
      txt = MemFree (txt);
 
11790
    } else {
 
11791
      ValNodeAddPointer (&token_list, 0, txt);
 
11792
    }
 
11793
  }
 
11794
  t = TranscriptomeIdsNew (dlg->consensus_bsp, token_list);
 
11795
  vnp = ValNodeNew (NULL);
 
11796
  vnp->choice = 0;
 
11797
  vnp->data.ptrvalue = t;
 
11798
  return vnp;
 
11799
}
 
11800
 
 
11801
 
 
11802
static DialoG CreateTSAAssemblyDialog (GrouP g)
 
11803
 
 
11804
{
 
11805
  TSAAssemblyDialogPtr  dlg;
 
11806
  GrouP                  p;
 
11807
  GrouP                  x;
 
11808
  GrouP                  y;
 
11809
 
 
11810
  p = HiddenGroup (g, -1, 0, NULL);
 
11811
  SetGroupSpacing (p, 10, 10);
 
11812
 
 
11813
  dlg = (TSAAssemblyDialogPtr) MemNew (sizeof (TSAAssemblyDialog));
 
11814
  if (dlg == NULL) return NULL;
 
11815
 
 
11816
  SetObjectExtra (p, dlg, NULL);
 
11817
  dlg->dialog = (DialoG) p;
 
11818
  dlg->todialog = SeqAlignsToTSAAssemblyDialog;
 
11819
  dlg->fromdialog = TSAAssemblyDialogToTranscriptomeIdsList;
 
11820
 
 
11821
  x = HiddenGroup (p, 0, 2, NULL);
 
11822
  y = HiddenGroup (x, 3, 0, NULL);
 
11823
  /* first line */
 
11824
  StaticPrompt (y, "PrimaryID", 16 * stdCharWidth, 0, programFont, 'c');
 
11825
  StaticPrompt (y, "Primary Interval", 16 * stdCharWidth, 0, programFont, 'c');
 
11826
  StaticPrompt (y, "TSA Interval", 16 * stdCharWidth, 0, programFont, 'c');
 
11827
  dlg->intervals = CreateTagListDialogEx3 (x, 10, 3, 1, tsa_assembly_types, tsa_assembly_widths, NULL, TRUE, FALSE, NULL, NULL, 
 
11828
                                           NULL, NULL, FALSE, TRUE);
 
11829
 
 
11830
  return (DialoG) p;
 
11831
}
 
11832
 
 
11833
 
 
11834
static void ShowAssemblyAlignment (SeqAlignPtr salp)
 
11835
{
 
11836
  LogInfoPtr lip;
 
11837
 
 
11838
  if (salp == NULL) {
 
11839
    return;
 
11840
  }
 
11841
 
 
11842
  lip = OpenLog ("Assembly Alignments");
 
11843
  while (salp != NULL) {
 
11844
    WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
 
11845
    lip->data_in_log = TRUE;
 
11846
    salp = salp->next;
 
11847
  }
 
11848
  CloseLog (lip);
 
11849
  lip = FreeLog (lip);
 
11850
}
 
11851
 
 
11852
 
 
11853
typedef struct tsaassemblyform {
 
11854
  FORM_MESSAGE_BLOCK
 
11855
  DialoG intervals;
 
11856
 
 
11857
} TSAAssemblyFormData, PNTR TSAAssemblyFormPtr;
 
11858
 
 
11859
 
 
11860
static void AcceptTSAAssembly (ButtoN b)
 
11861
{
 
11862
  TSAAssemblyFormPtr frm;
 
11863
  BioseqPtr          bsp;
 
11864
  ValNodePtr         err_list, coverage_report, vnp, ids_list, match_errs;
 
11865
  SeqAlignPtr        salp, salp_next;
 
11866
  LogInfoPtr         lip;
 
11867
 
 
11868
  frm = (TSAAssemblyFormPtr) GetObjectExtra (b);
 
11869
  if (frm == NULL) {
 
11870
    return;
 
11871
  }
 
11872
  bsp = GetBioseqGivenIDs (frm->input_entityID, frm->input_itemID, frm->input_itemtype);
 
11873
  if (bsp == NULL) {
 
11874
    return;
 
11875
  }
 
11876
 
 
11877
  WatchCursor();
 
11878
  Update();
 
11879
  SetTSAAssemblyDialogConsensusBioseq (frm->intervals, bsp);
 
11880
  
 
11881
  ids_list = DialogToPointer (frm->intervals);
 
11882
 
 
11883
  /* remove existing assembly */
 
11884
  if (bsp->hist != NULL) {
 
11885
    salp = bsp->hist->assembly;
 
11886
    bsp->hist->assembly = NULL;
 
11887
    while (salp != NULL) {
 
11888
      salp_next = salp->next;
 
11889
      salp->next = NULL;
 
11890
      salp = SeqAlignFree (salp);
 
11891
      salp = salp_next;
 
11892
    }
 
11893
  }
 
11894
 
 
11895
  if (ids_list == NULL) {
 
11896
    Message (MSG_ERROR, "TSA assembly removed");
 
11897
  } else {
 
11898
    err_list = MakeTranscriptomeAssemblySeqHist (ids_list->data.ptrvalue, GetSeqAlignTSA, TSATableCallback, NULL);
 
11899
    coverage_report = ReportCoverageForTranscriptomeIdsListSeqHist (ids_list);
 
11900
    match_errs = ReportConsensusMatchForBioseqSeqHist (bsp);
 
11901
    ValNodeLink (&coverage_report, match_errs);
 
11902
    ids_list = TranscriptomeIdsListFree (ids_list);
 
11903
 
 
11904
    ValNodeLink (&coverage_report, err_list);
 
11905
    err_list = coverage_report;
 
11906
 
 
11907
    if (err_list != NULL) {
 
11908
      lip = OpenLog ("TSA Table Problems");
 
11909
      for (vnp = err_list; vnp != NULL; vnp = vnp->next) {
 
11910
        fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
 
11911
      }
 
11912
      lip->data_in_log = TRUE;
 
11913
      CloseLog (lip);
 
11914
      lip = FreeLog (lip);
 
11915
      err_list = ValNodeFreeData (err_list);
 
11916
    }
 
11917
  }
 
11918
 
 
11919
  ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
 
11920
  ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
 
11921
  Remove (frm->form);
 
11922
  ArrowCursor();
 
11923
  Update();
 
11924
}
 
11925
 
 
11926
 
 
11927
NLM_EXTERN void EditTSAAssembly (IteM i)
 
11928
{
 
11929
  BaseFormPtr        bfp;
 
11930
  WindoW             w;
 
11931
  TSAAssemblyFormPtr frm;
 
11932
  BioseqPtr          bsp;
 
11933
  GrouP              h, c;
 
11934
  ButtoN             b;
 
11935
  
 
11936
#ifdef WIN_MAC
 
11937
  bfp = currentFormDataPtr;
 
11938
#else
 
11939
  bfp = GetObjectExtra (i);
 
11940
#endif
 
11941
  if (bfp == NULL) return;
 
11942
  
 
11943
  bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
 
11944
  if (bsp == NULL) {
 
11945
    Message (MSG_ERROR, "Must select sequence for editing TSA Assembly");
 
11946
    return;
 
11947
  }
 
11948
  frm = (TSAAssemblyFormPtr) MemNew (sizeof (TSAAssemblyFormData));
 
11949
  if (frm == NULL) return;
 
11950
  frm->input_entityID = bfp->input_entityID;
 
11951
  frm->input_itemID = bfp->input_itemID;
 
11952
  frm->input_itemtype = bfp->input_itemtype;
 
11953
 
 
11954
  w = FixedWindow (-50, -33, -10, -10, "TSA Assembly", StdCloseWindowProc);
 
11955
  SetObjectExtra (w, frm, StdCleanupFormProc);
 
11956
  frm->form = (ForM) w;
 
11957
  h = HiddenGroup (w, -1, 0, NULL);
 
11958
  frm->intervals = CreateTSAAssemblyDialog (h);
 
11959
 
 
11960
  if (bsp->hist == NULL) {
 
11961
    PointerToDialog (frm->intervals, NULL);
 
11962
  } else {
 
11963
    PointerToDialog (frm->intervals, bsp->hist->assembly);
 
11964
  }
 
11965
 
 
11966
 
 
11967
  c = HiddenGroup (h, 2, 0, NULL);
 
11968
  b = PushButton (c, "Accept", AcceptTSAAssembly);
 
11969
  SetObjectExtra (b, frm, NULL);
 
11970
  PushButton (c, "Cancel", StdCancelButtonProc);
 
11971
  
 
11972
  AlignObjects (ALIGN_CENTER, (HANDLE) frm->intervals, (HANDLE) c, NULL);
 
11973
  RealizeWindow (w);
 
11974
  Show (w);
 
11975
  Update ();    
 
11976
 
 
11977
}
 
11978
 
 
11979
 
8111
11980
/* automatic defline generator */
8112
11981
 
8113
11982
typedef struct deffeats {
9585
13454
 
9586
13455
static void ExpandGapsToIncludeFlankingNs (BioseqPtr bsp, Pointer userdata)
9587
13456
{
9588
 
  DeltaSeqPtr  dsp, prev_dsp = NULL;
 
13457
  DeltaSeqPtr  dsp, prev_dsp = NULL, next_dsp = NULL, prev_prev_dsp = NULL;
9589
13458
  Int4         change_len;
9590
 
  SeqLitPtr    slip, prev_slip, next_slip;
 
13459
  SeqLitPtr    slip, prev_slip = NULL, next_slip;
9591
13460
  
9592
13461
  if (bsp == NULL || bsp->repr != Seq_repr_delta 
9593
13462
      || bsp->seq_ext_type != 4 || bsp->seq_ext == NULL)
9598
13467
  dsp = bsp->seq_ext;
9599
13468
  while (dsp != NULL) 
9600
13469
  {
 
13470
    next_dsp = dsp->next;
9601
13471
    /* look for gap of known length */
9602
13472
    if (IsDeltaSeqKnownGap(dsp) && !DoesDeltaSeqHaveGapTypeOrLinkage(dsp)) 
9603
13473
    {
9614
13484
        {
9615
13485
          RemoveSeqLitEnd (prev_slip, change_len, SEQLOC_RIGHT_END);
9616
13486
          slip->length += change_len;
 
13487
          if (prev_slip->length == 0) {
 
13488
            if (prev_prev_dsp == NULL) {
 
13489
              bsp->seq_ext = dsp;
 
13490
            } else {
 
13491
              prev_prev_dsp->next = dsp;
 
13492
            }
 
13493
            prev_dsp->next = NULL;
 
13494
            prev_dsp = DeltaSeqFree (prev_dsp);
 
13495
            prev_dsp = dsp;
 
13496
          }
9617
13497
        }
 
13498
      } else {
 
13499
        prev_prev_dsp = prev_dsp;
 
13500
        prev_dsp = dsp;
9618
13501
      }
9619
13502
      /* check for Ns after gap of known length */
9620
13503
      if (dsp->next != NULL && dsp->next->choice == 2
9625
13508
        next_slip = (SeqLitPtr) dsp->next->data.ptrvalue;
9626
13509
        change_len = CountNsAtEndOfSeqLit (next_slip, SEQLOC_LEFT_END);
9627
13510
            
9628
 
        if (change_len > 0)
 
13511
        if (change_len < next_slip->length)
9629
13512
        {
9630
13513
          RemoveSeqLitEnd (next_slip, change_len, SEQLOC_LEFT_END);
9631
13514
          slip->length += change_len;
9632
13515
        }
 
13516
        else 
 
13517
        {
 
13518
          dsp->next = next_dsp->next;
 
13519
          next_dsp->next = NULL;
 
13520
          next_dsp = DeltaSeqFree (next_dsp);
 
13521
          next_dsp = dsp->next;
 
13522
        }
9633
13523
      }
9634
13524
    }
9635
 
    dsp = dsp->next;
 
13525
    dsp = next_dsp;
9636
13526
  }    
9637
13527
  BioseqPack (bsp);
9638
13528
}
9689
13579
  {
9690
13580
    return;
9691
13581
  }
9692
 
  
 
13582
 
9693
13583
  /* combine adjacent gaps */
9694
13584
  prev = (DeltaSeqPtr) bsp->seq_ext;
9695
13585
  if (prev == NULL) return;
10076
13966
  currentport = ParentWindow (clfp->form);
10077
13967
  temport = SavePort (currentport);
10078
13968
  UseWindow (currentport);
10079
 
  Select (clfp->form);
10080
13969
  switch (ommsp->message) 
10081
13970
  {
10082
13971
      case OM_MSG_UPDATE:
10087
13976
      case OM_MSG_SELECT: 
10088
13977
          break;
10089
13978
      case OM_MSG_DEL:
10090
 
          Remove (clfp->form);
 
13979
          clfp->clickable_list_data = FreeClickableList (clfp->clickable_list_data);
 
13980
          PointerToDialog (clfp->clickable_list_dlg, NULL);
10091
13981
          break;
10092
13982
      case OM_MSG_HIDE:
10093
13983
          break;
10094
13984
      case OM_MSG_SHOW:
10095
13985
          break;
10096
13986
      case OM_MSG_FLUSH:
10097
 
          Remove (clfp->form);  
 
13987
          clfp->clickable_list_data = FreeClickableList (clfp->clickable_list_data);
 
13988
          PointerToDialog (clfp->clickable_list_dlg, NULL);
10098
13989
          break;
10099
13990
      default:
10100
13991
          break;
10146
14037
 
10147
14038
/* There will only be one Discrepancy Report window at a time */
10148
14039
static WindoW discrepancyReportWindow = NULL;
 
14040
static WindoW oncallerReportWindow = NULL;
 
14041
 
 
14042
static WindoW GetWindowForReportType (EDiscrepancyReportType report_type)
 
14043
{
 
14044
  WindoW w = NULL;
 
14045
 
 
14046
  switch (report_type) {
 
14047
    case eReportTypeDiscrepancy:
 
14048
      w = discrepancyReportWindow;
 
14049
      break;
 
14050
    case eReportTypeOnCaller:
 
14051
      w = oncallerReportWindow;
 
14052
      break;
 
14053
  }
 
14054
  return w;
 
14055
}
 
14056
 
 
14057
 
 
14058
static void ClearWindowForReportType (WindoW w)
 
14059
{
 
14060
  if (discrepancyReportWindow == w) {
 
14061
    discrepancyReportWindow = NULL;
 
14062
  }
 
14063
  if (oncallerReportWindow == w) {
 
14064
    oncallerReportWindow = NULL;
 
14065
  }
 
14066
}
 
14067
 
 
14068
 
 
14069
static void SetWindowForReportType (WindoW w, EDiscrepancyReportType report_type)
 
14070
{
 
14071
  switch (report_type) {
 
14072
    case eReportTypeDiscrepancy:
 
14073
      discrepancyReportWindow = w;
 
14074
      break;
 
14075
    case eReportTypeOnCaller:
 
14076
      oncallerReportWindow = w;
 
14077
      break;
 
14078
  }
 
14079
}
 
14080
 
10149
14081
 
10150
14082
typedef void (*DiscrepancyCallback) (ValNodePtr item_list, Pointer userdata);
10151
14083
typedef void (*DiscrepancyCallbackDataFree) (Pointer userdata);
10164
14096
 
10165
14097
{
10166
14098
  DiscrepancyReportFormPtr drfp;
 
14099
  ValNodePtr               vnp;
 
14100
  ClickableItemPtr         cip;
10167
14101
 
10168
14102
  drfp = (DiscrepancyReportFormPtr) data;
10169
14103
  if (drfp != NULL) {
 
14104
    /* find whether source qual report is open or closed */
 
14105
    for (vnp = drfp->clickable_list_data; vnp != NULL; vnp = vnp->next) {
 
14106
      cip = vnp->data.ptrvalue;
 
14107
      if (cip != NULL && cip->clickable_item_type == DISC_SRC_QUAL_PROBLEM) {
 
14108
        if (cip->expanded) {
 
14109
          SetAppParam ("SEQUINCUSTOM", "ONCALLERTOOL", "EXPAND_SRCQUAL_REPORT", "TRUE");
 
14110
        } else {
 
14111
          SetAppParam ("SEQUINCUSTOM", "ONCALLERTOOL", "EXPAND_SRCQUAL_REPORT", "FALSE");
 
14112
        }
 
14113
        break;
 
14114
      }
 
14115
    }
10170
14116
    drfp->clickable_list_data = FreeClickableList (drfp->clickable_list_data);
10171
14117
    drfp->dcp = DiscrepancyConfigFree (drfp->dcp);
10172
14118
    ObjMgrFreeUserData (drfp->input_entityID, drfp->procid, drfp->proctype, drfp->userkey);
10173
 
    discrepancyReportWindow = NULL;
 
14119
    ClearWindowForReportType ((WindoW) drfp->form);
10174
14120
  }
10175
14121
  StdCleanupFormProc (g, data);
10176
14122
}
10206
14152
  }
10207
14153
}
10208
14154
 
 
14155
 
10209
14156
/* This function returns TRUE if there was a change to the discrepancy config,
10210
14157
 * FALSE otherwise.
10211
14158
 */
10212
 
static Boolean EditDiscrepancyConfig (DiscrepancyConfigPtr dcp)
 
14159
static Boolean EditDiscrepancyConfig (DiscrepancyConfigPtr dcp, EDiscrepancyReportType report_type)
10213
14160
{
10214
14161
  WindoW                w;
10215
14162
  GrouP                 h, g, k, c;
10231
14178
  h = HiddenGroup (w, -1, 0, NULL);
10232
14179
  SetGroupSpacing (h, 10, 10);
10233
14180
  
10234
 
  g = NormalGroup (h, 0, 10, "Discrepancy Tests to Run", programFont, NULL);
 
14181
  g = NormalGroup (h, 0, 14, "Discrepancy Tests to Run", programFont, NULL);
10235
14182
  SetGroupSpacing (g, 10, 10);
10236
14183
  for (i = 0; i < MAX_DISC_TYPE; i++)
10237
14184
  {
10238
 
    test_options[i] = CheckBox (g, GetDiscrepancyTestConfName ((DiscrepancyType) i), NULL);
10239
 
    SetStatus (test_options[i], dcp->conf_list[i]);
 
14185
    if (IsTestTypeAppropriateForReportType (i, report_type)) {
 
14186
      test_options[i] = CheckBox (g, GetDiscrepancyTestConfName ((DiscrepancyType) i), NULL);
 
14187
      SetStatus (test_options[i], dcp->conf_list[i]);
 
14188
    } else {
 
14189
      test_options[i] = NULL;
 
14190
    }
10240
14191
  }
10241
14192
  
10242
14193
  use_feature_table_format_btn = CheckBox (h, "Use feature table format for features in report", NULL);
10312
14263
    {
10313
14264
      if (dip->chosen || count_all)
10314
14265
      {
10315
 
        if (dip->expanded)
 
14266
        if (dip->expanded && dip->subcategories != NULL)
10316
14267
        {
10317
14268
          num_chosen += CountChosenDiscrepancies (dip->subcategories, TRUE);
10318
14269
        }
10463
14414
}
10464
14415
 
10465
14416
 
 
14417
static void ExtendPartialsToEndOrGapCallback (ValNodePtr list, Pointer userdata)
 
14418
{
 
14419
  ValNodePtr vnp, entityID_list = NULL;
 
14420
  SeqFeatPtr sfp;
 
14421
  LogInfoPtr lip;
 
14422
  CharPtr    orig_location, new_location;
 
14423
 
 
14424
  if (Message (MSG_OKC, "Extend partial ends of features to gaps/end of sequence if within two nucleotides?") == ANS_CANCEL) {
 
14425
    return;
 
14426
  }
 
14427
  WatchCursor();
 
14428
  Update();
 
14429
  lip = OpenLog ("Extended Features");
 
14430
  for (vnp = list; vnp != NULL; vnp = vnp->next) {
 
14431
    if (vnp->choice == OBJ_SEQFEAT && (sfp = vnp->data.ptrvalue) != NULL) {
 
14432
      orig_location = SeqLocPrintUseBestID (sfp->location);
 
14433
      if (ExtendPartialsToEndOrGap (sfp)) {
 
14434
        ValNodeAddInt (&entityID_list, 0, sfp->idx.entityID);
 
14435
        new_location = SeqLocPrintUseBestID (sfp->location);
 
14436
        fprintf (lip->fp, "Extended %s to %s\n", orig_location, new_location);
 
14437
        new_location = MemFree (new_location);
 
14438
        lip->data_in_log = TRUE;
 
14439
      }
 
14440
      orig_location = MemFree (orig_location);
 
14441
    }
 
14442
  }
 
14443
  entityID_list = ValNodeSort (entityID_list, SortByIntvalue);
 
14444
  ValNodeUnique (&entityID_list, SortByIntvalue, ValNodeFree);
 
14445
  for (vnp = entityID_list; vnp != NULL; vnp = vnp->next) {
 
14446
    ObjMgrSetDirtyFlag (vnp->data.intvalue, TRUE);
 
14447
    ObjMgrSendMsg (OM_MSG_UPDATE, vnp->data.intvalue, 0, 0);
 
14448
  }
 
14449
  ArrowCursor();
 
14450
  Update();
 
14451
  CloseLog (lip);
 
14452
  lip = FreeLog (lip);
 
14453
}
 
14454
 
 
14455
 
10466
14456
extern void SetBioseqViewTargetByBioseq (BaseFormPtr bfp, BioseqPtr bsp)
10467
14457
{
10468
14458
  Char       id_text [41];
10653
14643
      if (cip->clickable_item_type == DISC_CDS_OVERLAP_TRNA) {
10654
14644
        cip->callback_func = EditCDStRNAOverlapCallback;    
10655
14645
      } else if (cip->clickable_item_type == DISC_INCONSISTENT_BIOSRC_DEFLINE) {
10656
 
        cip->callback_func = ApplyTagToCodingRegionsCallback;  
 
14646
        cip->callback_func = ApplyTagToCodingRegionsCallback; 
 
14647
      } else if (cip->clickable_item_type == DISC_BACTERIAL_PARTIAL_PROBLEMS) {
 
14648
        cip->callback_func = ExtendPartialsToEndOrGapCallback;
10657
14649
      } else {
10658
14650
        subtype = GetSubtypeForBulkEdit (cip->item_list);
10659
14651
        /* Note - using FEATDEF_rRNA to represent all editable RNA features */
10804
14796
}
10805
14797
 
10806
14798
 
10807
 
static void ReactivateDiscrepancyReport ()
 
14799
static void ReactivateDiscrepancyReport (EDiscrepancyReportType report_type)
10808
14800
{
10809
14801
  DiscrepancyReportFormPtr drfp;
 
14802
  WindoW                   w;
10810
14803
 
10811
 
  if (discrepancyReportWindow == NULL) 
 
14804
  w = GetWindowForReportType (report_type);
 
14805
  if (w == NULL) 
10812
14806
  {
10813
 
    CreateDiscrepancyReportWindow ();
 
14807
    CreateReportWindow (report_type);
10814
14808
  }
10815
14809
  
10816
 
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (discrepancyReportWindow);
 
14810
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (w);
10817
14811
  if (drfp == NULL)
10818
14812
  {
10819
 
    Remove (discrepancyReportWindow);
10820
 
    discrepancyReportWindow = NULL;
10821
 
    CreateDiscrepancyReportWindow ();
 
14813
    Remove (w);
 
14814
    ClearWindowForReportType (w);
 
14815
    CreateReportWindow (report_type);
 
14816
    w = GetWindowForReportType (report_type);
10822
14817
  }
10823
14818
    
10824
14819
  /* populate discrepancy lists */
10825
14820
  RecheckDiscrepancyProc (drfp->recheck_btn);
10826
 
  Show (discrepancyReportWindow);  
10827
 
  Select (discrepancyReportWindow);
 
14821
  Show (w);  
 
14822
  Select (w);
 
14823
}
 
14824
 
 
14825
 
 
14826
 
 
14827
static void EditReportConfigBtn (EDiscrepancyReportType report_type)
 
14828
{
 
14829
  DiscrepancyReportFormPtr drfp;
 
14830
  WindoW                   w;
 
14831
 
 
14832
  w = GetWindowForReportType (report_type);
 
14833
  
 
14834
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (w);
 
14835
  if (drfp == NULL) return;
 
14836
  
 
14837
  if (EditDiscrepancyConfig (drfp->dcp, report_type))
 
14838
  {
 
14839
    RecheckDiscrepancyProc (drfp->recheck_btn);
 
14840
  }
10828
14841
}
10829
14842
 
10830
14843
 
10831
14844
static void EditDiscrepancyConfigBtn (ButtoN b)
10832
14845
{
10833
 
  DiscrepancyReportFormPtr drfp;
10834
 
  
10835
 
  drfp = (DiscrepancyReportFormPtr) GetObjectExtra (discrepancyReportWindow);
10836
 
  if (drfp == NULL) return;
10837
 
  
10838
 
  if (EditDiscrepancyConfig (drfp->dcp))
10839
 
  {
10840
 
    RecheckDiscrepancyProc (b);
 
14846
  EditReportConfigBtn (eReportTypeDiscrepancy);
 
14847
}
 
14848
 
 
14849
 
 
14850
static void EditOnCallerConfigBtn (ButtoN b)
 
14851
{
 
14852
  EditReportConfigBtn (eReportTypeOnCaller);
 
14853
}
 
14854
 
 
14855
 
 
14856
static Nlm_BtnActnProc GetReportEditButtonProc (EDiscrepancyReportType report_type)
 
14857
{
 
14858
  Nlm_BtnActnProc proc = NULL;
 
14859
 
 
14860
  switch (report_type) {
 
14861
    case eReportTypeDiscrepancy:
 
14862
      proc = EditDiscrepancyConfigBtn;
 
14863
      break;
 
14864
    case eReportTypeOnCaller:
 
14865
      proc = EditOnCallerConfigBtn;
 
14866
      break;
10841
14867
  }
 
14868
  return proc;
10842
14869
}
10843
14870
 
10844
14871
 
10847
14874
#endif
10848
14875
 
10849
14876
 
10850
 
extern void CreateDiscrepancyReportWindow (void)
 
14877
static CharPtr GetReportName (EDiscrepancyReportType report_type)
 
14878
{
 
14879
  CharPtr report_name = "";
 
14880
 
 
14881
  switch (report_type) {
 
14882
    case eReportTypeDiscrepancy:
 
14883
      report_name = "Discrepancy Report";
 
14884
      break;
 
14885
    case eReportTypeOnCaller:
 
14886
      report_name = "On Caller Tool";
 
14887
      break;
 
14888
  }
 
14889
  return report_name;
 
14890
}
 
14891
 
 
14892
 
 
14893
static CharPtr GetReportConfigName (EDiscrepancyReportType report_type)
 
14894
{
 
14895
  CharPtr report_name = "";
 
14896
 
 
14897
  switch (report_type) {
 
14898
    case eReportTypeDiscrepancy:
 
14899
      report_name = "DISCREPANCY_REPORT";
 
14900
      break;
 
14901
    case eReportTypeOnCaller:
 
14902
      report_name = "ON_CALLER_TOOL";
 
14903
      break;
 
14904
  }
 
14905
  return report_name;
 
14906
}
 
14907
 
 
14908
 
 
14909
static void AdjustConfigForReportType (EDiscrepancyReportType report_type, DiscrepancyConfigPtr dcp)
 
14910
{
 
14911
  Int4 i;
 
14912
 
 
14913
  if (dcp == NULL) {
 
14914
    return;
 
14915
  }
 
14916
 
 
14917
  for (i = 0; i < MAX_DISC_TYPE; i++) {
 
14918
    if (!IsTestTypeAppropriateForReportType (i, report_type)) {
 
14919
      dcp->conf_list[i] = FALSE;
 
14920
    }
 
14921
  }
 
14922
 
 
14923
}
 
14924
 
 
14925
 
 
14926
static void ExpandAllDiscReportItems (ButtoN b)
 
14927
{
 
14928
  DiscrepancyReportFormPtr d;
 
14929
 
 
14930
  d = (DiscrepancyReportFormPtr) GetObjectExtra (b);
 
14931
  if (d == NULL) {
 
14932
    return;
 
14933
  }
 
14934
 
 
14935
  ExpandClickableItemList (d->clickable_list_data);
 
14936
 
 
14937
  PointerToDialog (d->clickable_list_dlg, d->clickable_list_data);
 
14938
}
 
14939
 
 
14940
 
 
14941
static void ContractAllDiscReportItems (ButtoN b)
 
14942
{
 
14943
  DiscrepancyReportFormPtr d;
 
14944
 
 
14945
  d = (DiscrepancyReportFormPtr) GetObjectExtra (b);
 
14946
  if (d == NULL) {
 
14947
    return;
 
14948
  }
 
14949
  ContractClickableItemList (d->clickable_list_data);
 
14950
 
 
14951
  PointerToDialog (d->clickable_list_dlg, d->clickable_list_data);
 
14952
}
 
14953
 
 
14954
 
 
14955
extern void CreateReportWindow (EDiscrepancyReportType report_type)
10851
14956
{
10852
14957
  DiscrepancyReportFormPtr drfp;
10853
14958
  GrouP                    h;
10854
14959
  ButtoN                   b;
10855
14960
  GrouP                    c;
 
14961
  GrouP                    c1;
10856
14962
  WindoW                   w;
10857
14963
  OMUserDataPtr            omudp;
10858
14964
 
10859
 
  if (discrepancyReportWindow != NULL)
 
14965
  if (GetWindowForReportType(report_type) != NULL)
10860
14966
  {
10861
 
    ReactivateDiscrepancyReport ();
 
14967
    ReactivateDiscrepancyReport (report_type);
10862
14968
    return; 
10863
14969
  }
10864
14970
  
10868
14974
    return;
10869
14975
  }
10870
14976
  
10871
 
  w = FixedWindow (-50, -33, -10, -10, "Discrepancy Report", StdCloseWindowProc);
 
14977
  w = FixedWindow (-50, -33, -10, -10, GetReportName (report_type), StdCloseWindowProc);
10872
14978
  SetObjectExtra (w, drfp, CleanupDiscrepancyReportForm);
10873
14979
  drfp->form = (ForM) w;
10874
14980
  drfp->formmessage = ClickableListFormMessage;
10875
14981
  drfp->exportform = DiscrepancyReportExportProc;
10876
14982
  
10877
14983
  /* read in config file */
10878
 
  drfp->dcp = ReadDiscrepancyConfig();
 
14984
  drfp->dcp = ReadDiscrepancyConfigEx(GetReportConfigName (report_type));
 
14985
 
 
14986
  /* adjust for report type */
 
14987
  AdjustConfigForReportType (report_type, drfp->dcp);
10879
14988
  
10880
14989
  /* register to receive update messages */
10881
14990
  drfp->userkey = OMGetNextUserKey ();
10898
15007
  drfp->clickable_list_dlg = CreateClickableListDialog (h, "Discrepancies", "Affected Items",
10899
15008
                                                    ScrollToDiscrepancyItem, EditDiscrepancyItem, NULL,
10900
15009
                                                    GetDiscrepancyItemText);
10901
 
                                                    
 
15010
                              
 
15011
  c1 = HiddenGroup (h, 2, 0, NULL);
 
15012
  SetGroupSpacing (c1, 10, 10);
 
15013
  b = PushButton (c1, "Expand All", ExpandAllDiscReportItems);
 
15014
  SetObjectExtra (b, drfp, NULL);
 
15015
  b = PushButton (c1, "Contract All", ContractAllDiscReportItems);
 
15016
  SetObjectExtra (b, drfp, NULL);
 
15017
 
10902
15018
  c = HiddenGroup (h, 4, 0, NULL);
10903
15019
  SetGroupSpacing (c, 10, 10);
10904
15020
  b = PushButton (c, "Generate Report", GenerateDiscrepancyReport);
10906
15022
  drfp->recheck_btn = PushButton (c, "Recheck", RecheckDiscrepancyProc);
10907
15023
  SetObjectExtra (drfp->recheck_btn, drfp, NULL);
10908
15024
  
10909
 
  b = PushButton (c, "Configure", EditDiscrepancyConfigBtn);
 
15025
  b = PushButton (c, "Configure", GetReportEditButtonProc (report_type));
10910
15026
  SetObjectExtra (b, drfp, NULL);
10911
15027
  
10912
15028
  PushButton (c, "Dismiss", StdCancelButtonProc);
10913
15029
 
10914
 
  AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list_dlg, (HANDLE) c, NULL);
 
15030
  AlignObjects (ALIGN_CENTER, (HANDLE) drfp->clickable_list_dlg, (HANDLE) c1, (HANDLE) c, NULL);
10915
15031
 
10916
15032
  RealizeWindow (w);
10917
15033
  
10918
15034
  /* populate discrepancy lists */
10919
15035
  RecheckDiscrepancyProc (drfp->recheck_btn);
10920
15036
  Show (w);
10921
 
  discrepancyReportWindow = w;
 
15037
  SetWindowForReportType (w, report_type);
10922
15038
}
10923
15039
 
 
15040
 
10924
15041
typedef struct sucform 
10925
15042
{
10926
15043
  CLICKABLE_LIST_FORM_BLOCK
13631
17748
      gene->location = TruncateLocation (gene->location, SeqLocLen (gene->location) - p->overlap_len);
13632
17749
    }
13633
17750
 
13634
 
    AddTranslExcept (p->cds, "TAA stop codon is completed by the addition of 3' A residues to the mRNA", FALSE, FALSE);
 
17751
    AddTranslExcept (p->cds, "TAA stop codon is completed by the addition of 3' A residues to the mRNA", FALSE, FALSE, FALSE);
13635
17752
  }
13636
17753
}  
13637
17754
 
13844
17961
  }
13845
17962
}
13846
17963
 
 
17964
 
 
17965
static void SelectAllCDS (ButtoN b)
 
17966
{
 
17967
  CDStRNAToolPtr    dlg;
 
17968
 
 
17969
  dlg = (CDStRNAToolPtr) GetObjectExtra (b);
 
17970
  if (dlg == NULL) return;
 
17971
 
 
17972
  ChooseCategories (dlg->clickable_list, TRUE);
 
17973
  PointerToDialog (dlg->clickable_list_dlg, dlg->clickable_list);
 
17974
 
 
17975
}
 
17976
 
 
17977
 
13847
17978
static void EditCDStRNAOverlap (ValNodePtr item_list)
13848
17979
{
13849
17980
  ValNodePtr overlap_list;
13896
18027
 
13897
18028
  b = PushButton (c, "Trim Selected", TrimSelectedCDS);
13898
18029
  SetObjectExtra (b, dlg, NULL);
 
18030
  b = PushButton (c, "Select All", SelectAllCDS);
 
18031
  SetObjectExtra (b, dlg, NULL);
13899
18032
  b = PushButton (c, "Dismiss", StdCancelButtonProc);
13900
18033
 
13901
18034
  AlignObjects (ALIGN_CENTER, (HANDLE) dlg->clickable_list_dlg, (HANDLE) c, NULL);