4414
typedef struct dblinkdialog {
4415
DIALOG_MESSAGE_BLOCK
4418
} DblinkDialog, PNTR DblinkDialogPtr;
4420
typedef struct dblinkform {
4423
} DblinkForm, PNTR DblinkFormPtr;
4425
static void UserObjectPtrToDblinkDialog (
4434
DblinkDialogPtr ddp;
4443
ddp = (DblinkDialogPtr) GetObjectExtra (d);
4444
if (ddp == NULL) return;
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);
4453
for (curr = uop->data; curr != NULL; curr = curr->next) {
4455
if (oip == NULL) continue;
4456
if (StringICmp (oip->str, "Trace Assembly Archive") == 0) {
4457
if (curr->choice == 8) {
4459
ip = (Int4Ptr) curr->data.ptrvalue;
4460
if (num > 0 && ip != NULL) {
4462
for (i = 0; i < num; i++) {
4465
sprintf (buf, "%ld", (long) val);
4466
ValNodeCopyStr (&head, 0, buf);
4470
PointerToDialog (ddp->traceassm, (Pointer) head);
4472
ValNodeFreeData (head);
4475
} else if (StringICmp (oip->str, "Bio Sample") == 0) {
4476
if (curr->choice == 7) {
4478
cpp = (CharPtr PNTR) curr->data.ptrvalue;
4479
if (num > 0 && cpp != NULL) {
4481
for (i = 0; i < num; i++) {
4483
if (StringDoesHaveText (str)) {
4484
ValNodeCopyStr (&head, 0, str);
4488
PointerToDialog (ddp->biosample, (Pointer) head);
4490
ValNodeFreeData (head);
4497
static Pointer DblinkDialogToUserObjectPtr (
4503
DblinkDialogPtr ddp;
4504
ValNodePtr head, vnp;
4507
Boolean okay = FALSE;
4512
ddp = (DblinkDialogPtr) GetObjectExtra (d);
4513
if (ddp == NULL) return NULL;
4515
uop = CreateDBLinkUserObject ();
4516
if (uop == NULL) return NULL;
4518
head = (ValNodePtr) DialogToPointer (ddp->traceassm);
4521
for (vnp = head; vnp != NULL; vnp = vnp->next) {
4522
str = (CharPtr) vnp->data.ptrvalue;
4523
if (StringHasNoText (str)) continue;
4527
ipp = (Int4Ptr) MemNew (sizeof (Int4) * num);
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;
4539
AddTraceAssemblyIDsToDBLinkUserObject (uop, i, ipp);
4545
ValNodeFreeData (head);
4547
head = (ValNodePtr) DialogToPointer (ddp->biosample);
4550
for (vnp = head; vnp != NULL; vnp = vnp->next) {
4551
str = (CharPtr) vnp->data.ptrvalue;
4552
if (StringHasNoText (str)) continue;
4556
cpp = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num);
4559
for (vnp = head; vnp != NULL; vnp = vnp->next) {
4560
str = (CharPtr) vnp->data.ptrvalue;
4561
if (StringHasNoText (str)) continue;
4566
AddBioSampleIDsToDBLinkUserObject (uop, i, cpp);
4572
ValNodeFreeData (head);
4575
uop = UserObjectFree (uop);
4581
static DialoG CreateDblinkDialog (
4586
DblinkDialogPtr ddp;
4589
p = HiddenGroup (g, -1, 0, NULL);
4590
SetGroupSpacing (p, 10, 10);
4592
ddp = (DblinkDialogPtr) MemNew (sizeof (DblinkDialog));
4593
if (ddp == NULL) return NULL;
4595
SetObjectExtra (p, ddp, NULL);
4596
ddp->dialog = (DialoG) p;
4597
ddp->todialog = UserObjectPtrToDblinkDialog;
4598
ddp->fromdialog = DblinkDialogToUserObjectPtr;
4600
x = HiddenGroup (p, 0, 8, NULL);
4602
StaticPrompt (x, "Trace Assembly", 10 * stdCharWidth, 0, programFont, 'c');
4603
ddp->traceassm = CreateVisibleStringDialog (x, 3, -1, 15);
4605
StaticPrompt (x, "Bio Sample", 10 * stdCharWidth, 0, programFont, 'c');
4606
ddp->biosample = CreateVisibleStringDialog (x, 3, -1, 15);
4611
static void DblinkFormMessage (
4619
dfp = (DblinkFormPtr) GetObjectExtra (f);
4622
case VIB_MSG_CLOSE :
4626
StdCutTextProc (NULL);
4629
StdCopyTextProc (NULL);
4631
case VIB_MSG_PASTE :
4632
StdPasteTextProc (NULL);
4634
case VIB_MSG_DELETE :
4635
StdDeleteTextProc (NULL);
4638
if (dfp->appmessage != NULL) {
4639
dfp->appmessage (f, mssg);
4646
static ForM CreateDblinkDescForm (
4654
FormActnFunc actproc
4661
StdEditorProcsPtr sepp;
4665
dfp = (DblinkFormPtr) MemNew (sizeof (DblinkForm));
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;
4677
CreateStdEditorFormMenus (w);
4679
sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4681
SetActivate (w, sepp->activateForm);
4682
dfp->appmessage = sepp->handleMessages;
4685
g = HiddenGroup (w, -1, 0, NULL);
4686
dfp->data = CreateDblinkDialog (g);
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);
4699
extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data);
4700
extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data)
4704
OMProcControlPtr ompcp;
4705
OMUserDataPtr omudp;
4713
ompcp = (OMProcControlPtr) data;
4718
if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4720
switch (ompcp->input_itemtype) {
4722
sdp = (ValNodePtr) ompcp->input_data;
4723
if (sdp != NULL && sdp->choice != Seq_descr_user) {
4724
return OM_MSG_RET_ERROR;
4726
uop = (UserObjectPtr) sdp->data.ptrvalue;
4730
case OBJ_BIOSEQSET :
4735
return OM_MSG_RET_ERROR;
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;
4745
return OM_MSG_RET_DONE;
4747
return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
4752
if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
4753
if (StringCmp (oip->str, "DBLink") != 0) return OM_MSG_RET_OK;
4755
sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
4756
w = (WindoW) CreateDblinkDescForm (-50, -33, -10, -10,
4758
StdDescFormActnProc);
4759
dfp = (DblinkFormPtr) GetObjectExtra (w);
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;
4775
SendMessageToForm (dfp->form, VIB_MSG_INIT);
4777
PointerToDialog (dfp->data, (Pointer) sdp->data.ptrvalue);
4778
SetClosestParentIfDuplicating ((BaseFormPtr) dfp);
4783
return OM_MSG_RET_DONE;
4548
4787
extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data);
6280
6571
lip = FreeLog (lip);
6283
static void CKA_FindNuc(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
6286
BioseqPtr PNTR bspptr;
6288
bspptr = (BioseqPtr PNTR)data;
6291
bsp = (BioseqPtr)sep->data.ptrvalue;
6292
if (ISA_na(bsp->mol))
6299
static int LIBCALLBACK CKA_CompareAlns(VoidPtr ptr1, VoidPtr ptr2)
6306
sap1 = *((SeqAlignPtr PNTR) ptr1);
6307
sap2 = *((SeqAlignPtr PNTR) ptr2);
6308
if (sap1 == NULL || sap2 == NULL)
6310
len1 = AlnMgr2GetAlnLength(sap1, FALSE);
6311
len2 = AlnMgr2GetAlnLength(sap2, FALSE);
6575
typedef struct seqalignrow {
6579
} SeqAlignRowData, PNTR SeqAlignRowPtr;
6581
static SeqAlignRowPtr SeqAlignRowNew (Int4 start, Int4 stop, Uint1 strand)
6586
r = (SeqAlignRowPtr) MemNew (sizeof (SeqAlignRowData));
6590
if (r->start > r->stop) {
6600
static SeqAlignRowPtr SeqAlignRowCopy (SeqAlignRowPtr orig)
6602
SeqAlignRowPtr r = NULL;
6605
r = SeqAlignRowNew (orig->start, orig->stop, orig->strand);
6611
static SeqAlignRowPtr SeqAlignRowFree (SeqAlignRowPtr r)
6618
static Int4 RowDiff (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
6622
if (r1 == NULL || r2 == NULL) {
6626
diff = ABS(r1->start - r2->start) + ABS (r1->stop - r2->stop);
6631
static Int4 SeqAlignRowLen (SeqAlignRowPtr r)
6636
len = r->stop - r->start + 1;
6642
typedef struct seqalignsort {
6643
SeqAlignRowPtr row1;
6644
SeqAlignRowPtr row2;
6646
} SeqAlignSortData, PNTR SeqAlignSortPtr;
6649
static SeqAlignSortPtr SeqAlignSortNew (SeqAlignPtr salp)
6657
s = (SeqAlignSortPtr) MemNew (sizeof (SeqAlignSortData));
6660
AlnMgr2IndexSingleChildSeqAlign(salp);
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));
6669
static SeqAlignSortPtr SeqAlignSortFree (SeqAlignSortPtr s)
6672
s->row1 = SeqAlignRowFree (s->row1);
6673
s->row2 = SeqAlignRowFree (s->row2);
6680
static ValNodePtr SeqAlignSortListNew (SeqAlignPtr salp)
6682
ValNodePtr list = NULL;
6683
SeqAlignPtr salp_next;
6685
while (salp != NULL) {
6686
salp_next = salp->next;
6688
ValNodeAddPointer (&list, 0, SeqAlignSortNew (salp));
6695
static ValNodePtr SeqAlignSortListFree (ValNodePtr vnp)
6697
ValNodePtr vnp_next;
6699
while (vnp != NULL) {
6700
vnp_next = vnp->next;
6702
vnp->data.ptrvalue = SeqAlignSortFree (vnp->data.ptrvalue);
6703
vnp = ValNodeFree (vnp);
6710
static SeqAlignRowPtr SeqAlignRowFromSeqAlignSort (SeqAlignSortPtr s, Int4 row)
6714
} else if (row == 1) {
6722
static Uint1 SeqAlignSortRowStrand (SeqAlignSortPtr s, Int4 row)
6724
Uint1 strand = Seq_strand_plus;
6727
r = SeqAlignRowFromSeqAlignSort (s, row);
6735
static Uint1 SeqAlignSortListFindBestStrand (ValNodePtr vnp, Int4 row)
6737
Int4 num_plus = 0, num_minus = 0;
6740
while (vnp != NULL) {
6741
s = (SeqAlignSortPtr) vnp->data.ptrvalue;
6743
if (SeqAlignSortRowStrand(s, row) == Seq_strand_minus) {
6752
if (num_minus > num_plus) {
6753
return Seq_strand_minus;
6755
return Seq_strand_plus;
6760
static void SeqAlignSortListMarkStrand (ValNodePtr vnp, Int4 row, Uint1 strand)
6762
while (vnp != NULL) {
6763
if (SeqAlignSortRowStrand (vnp->data.ptrvalue, row) == strand) {
6771
static ValNodePtr SeqAlignSortListRemoveAll (ValNodePtr list)
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);
6784
list = SeqAlignSortListFree (list);
6789
static void SeqAlignSortListRemoveMarked (ValNodePtr PNTR list)
6791
ValNodePtr remove_list;
6797
remove_list = ValNodeExtractList (list, 1);
6798
remove_list = SeqAlignSortListRemoveAll (remove_list);
6802
static Uint1 SeqAlignSortListRemoveConflictingStrands (ValNodePtr PNTR list, Int4 row)
6807
return Seq_strand_plus;
6810
strand = SeqAlignSortListFindBestStrand (*list, row);
6811
if (strand == Seq_strand_plus) {
6812
SeqAlignSortListMarkStrand (*list, row, Seq_strand_minus);
6814
SeqAlignSortListMarkStrand (*list, row, Seq_strand_plus);
6817
SeqAlignSortListRemoveMarked (list);
6822
static SeqAlignPtr SeqAlignFromSeqAlignSortList (ValNodePtr vnp)
6824
SeqAlignPtr salp_list = NULL, salp_prev = NULL;
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;
6834
salp_prev->next = s->salp;
6836
salp_prev = s->salp;
6837
s->salp->next = NULL;
6845
static int CompareSeqAlignRow (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
6849
if (r1 == NULL && r2 == NULL) {
6851
} else if (r1 == NULL) {
6853
} else if (r2 == NULL) {
6855
} else if (r1->start < r2->start) {
6857
} else if (r1->start > r2->start) {
6859
} else if (r1->stop < r2->stop) {
6861
} else if (r1->stop > r2->stop) {
6863
} else if (r1->strand < r2->strand) {
6865
} else if (r1->strand > r2->strand) {
6872
static int CompareSeqAlignSortPreferRow1 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
6875
if (s1 == NULL && s2 == NULL) {
6877
} else if (s1 == NULL) {
6879
} else if (s2 == NULL) {
6881
} else if ((rval = CompareSeqAlignRow (s1->row1,s2->row1)) == 0) {
6882
rval = CompareSeqAlignRow (s1->row2, s2->row2);
6888
static int CompareSeqAlignSortPreferRow2 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
6891
if (s1 == NULL && s2 == NULL) {
6893
} else if (s1 == NULL) {
6895
} else if (s2 == NULL) {
6897
} else if ((rval = CompareSeqAlignRow (s1->row2,s2->row2)) == 0) {
6898
rval = CompareSeqAlignRow (s1->row1, s2->row1);
6905
static int LIBCALLBACK SortVnpBySeqAlignSortRow1 (VoidPtr ptr1, VoidPtr ptr2)
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);
6922
static int LIBCALLBACK SortVnpBySeqAlignSortRow2 (VoidPtr ptr1, VoidPtr ptr2)
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);
6939
static ValNodePtr SeqAlignSortListExtractRepeats (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
6941
ValNodePtr repeat_start, repeat_prev = NULL, vnp_prev = NULL, vnp;
6942
ValNodePtr repeat_list = NULL;
6943
SeqAlignSortPtr s1, s2;
6944
SeqAlignRowPtr interval, r2;
6948
if (list == NULL || *list == NULL || (*list)->next == NULL) {
6953
*list = ValNodeSort (*list, SortVnpBySeqAlignSortRow1);
6955
*list = ValNodeSort (*list, SortVnpBySeqAlignSortRow2);
6958
repeat_start = *list;
6959
s1 = repeat_start->data.ptrvalue;
6960
interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
6962
for (vnp = (*list)->next; vnp != NULL; vnp = vnp->next) {
6963
s2 = vnp->data.ptrvalue;
6965
r2 = SeqAlignRowFromSeqAlignSort (s2, row);
6967
if (interval->start <= r2->start && interval->stop >= r2->stop) {
6970
} else if (r2->start <= interval->start && r2->stop >= interval->stop) {
6973
} else if ((diff = RowDiff (interval, r2)) > -1 && diff < fuzz) {
6978
if (interval->start > r2->start) {
6979
interval->start = r2->start;
6981
if (interval->stop < r2->stop) {
6982
interval->stop = r2->stop;
6985
if (repeat_start->next == vnp) {
6986
repeat_prev = vnp_prev;
6989
if (repeat_prev == NULL) {
6992
repeat_prev->next = vnp;
6994
if (vnp_prev != NULL) {
6995
vnp_prev->next = NULL;
6997
ValNodeAddPointer (&repeat_list, 0, repeat_start);
7001
s1 = vnp->data.ptrvalue;
7002
interval = SeqAlignRowFree (interval);
7003
interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
7007
if (repeat_start->next != NULL) {
7008
if (repeat_prev == NULL) {
7011
repeat_prev->next = NULL;
7013
ValNodeAddPointer (&repeat_list, 0, repeat_start);
7016
interval = SeqAlignRowFree (interval);
7021
static int SeqAlignRowFuzzyCompare (SeqAlignRowPtr r1, SeqAlignRowPtr r2, Int4 fuzz)
7023
if (r1 == NULL && r2 == NULL) {
7025
} else if (r1 == NULL) {
7027
} else if (r2 == NULL) {
7031
if (r1->stop < r2->start || r1->stop - r2->start < fuzz) {
7033
} else if (r2->stop < r1->start || r2->stop - r1->start < fuzz) {
7041
static int SeqAlignSortFuzzyCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
7043
if (s1 == NULL && s2 == NULL) {
7045
} else if (s1 == NULL) {
7047
} else if (s2 == NULL) {
7049
} else if (row == 1) {
7050
return SeqAlignRowFuzzyCompare (s1->row1, s2->row1, fuzz);
7052
return SeqAlignRowFuzzyCompare (s1->row2, s2->row2, fuzz);
7057
static void SeqAlignSortListRemoveIntervalsOutOfOrder (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
7059
ValNodePtr vnp, vnp_prev = NULL;
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) {
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 */
7077
if (vnp->choice == 0) {
7082
SeqAlignSortListRemoveMarked (list);
7086
static Int4 GetRepeatIntervalFuzz (SeqAlignSortPtr s_repeat, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row)
7088
Int4 start_fuzz = 0, end_fuzz = 0;
7090
if (s_repeat == NULL) {
7094
if (s_before != NULL) {
7096
start_fuzz = ABS (s_repeat->row1->start - s_before->row1->stop);
7098
start_fuzz = ABS (s_repeat->row2->start - s_before->row2->stop);
7101
if (s_after != NULL) {
7103
end_fuzz = ABS (s_after->row1->start - s_repeat->row1->stop);
7105
end_fuzz = ABS (s_after->row2->start - s_repeat->row2->stop);
7109
return start_fuzz + end_fuzz;
7113
static int StrandedSeqAlignSortRowCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
7115
SeqAlignRowPtr r1 = NULL, r2 = NULL;
7117
Uint1 strand = Seq_strand_plus;
7119
if (s1 == NULL || s2 == NULL) {
7123
r1 = SeqAlignRowFromSeqAlignSort (s1, row);
7124
r2 = SeqAlignRowFromSeqAlignSort (s2, row);
7125
strand = r1->strand;
7127
if (strand == Seq_strand_minus) {
7128
if (r1->start < r2->start - fuzz) {
7130
} else if (r1->start >r2->start + fuzz) {
7134
if (r1->start > r2->start + fuzz) {
7136
} else if (r1->stop < r2->stop - fuzz) {
7145
static Boolean FindSeqAlignSortWithPoint (ValNodePtr list, Int4 point, Int4 row)
7150
Boolean found = FALSE;
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) {
7163
static ValNodePtr FindBestRepeat (ValNodePtr PNTR repeat_list, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row, Int4 fuzz)
7165
Int4 best_diff = -1, diff;
7166
ValNodePtr vnp, vnp_best = NULL, vnp_best_prev = NULL, vnp_prev = NULL;
7167
SeqAlignSortPtr s_this;
7169
if (repeat_list == NULL || *repeat_list == NULL) {
7173
for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
7174
s_this = vnp->data.ptrvalue;
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 */
7180
diff = GetRepeatIntervalFuzz (vnp->data.ptrvalue, s_before, s_after, row);
7181
if (diff > -1 && (best_diff < 0 || best_diff > diff)) {
7183
vnp_best_prev = vnp_prev;
7190
if (vnp_best != NULL) {
7191
if (vnp_best_prev == NULL) {
7192
*repeat_list = vnp_best->next;
7194
vnp_best_prev->next = vnp_best->next;
7196
vnp_best->next = NULL;
7203
static void RemoveRepeatsCoincidingWithBest (ValNodePtr PNTR repeat_list, ValNodePtr best, Int4 row, Int4 fuzz)
7206
SeqAlignSortPtr s_best, s;
7207
SeqAlignRowPtr r_best, r2;
7211
if (repeat_list == NULL || *repeat_list == NULL || best == NULL) {
7215
s_best = best->data.ptrvalue;
7216
r_best = SeqAlignRowFromSeqAlignSort (s_best, row);
7218
for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
7219
s = vnp->data.ptrvalue;
7220
r2 = SeqAlignRowFromSeqAlignSort (s, row);
7223
if (r_best->start <= r2->start && r_best->stop >= r2->stop) {
7226
} else if (r2->start <= r_best->start && r2->stop >= r_best->stop) {
7229
} else if (r2->stop < r_best->stop || r2->stop - r_best->stop < fuzz) {
7231
} else if ((diff = RowDiff (r_best, r2)) > -1 && diff < fuzz) {
7239
SeqAlignSortListRemoveMarked (repeat_list);
7243
static ValNodePtr ExtractLongestSeqAlignRow (ValNodePtr PNTR list, Int4 row)
7245
ValNodePtr vnp, vnp_prev = NULL, rval = NULL;
7246
Int4 longest = 0, len;
7247
Boolean found = FALSE;
7249
if (list == NULL || *list == NULL) {
7253
for (vnp = *list; vnp != NULL; vnp = vnp->next) {
7254
len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
7255
if (longest < len) {
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) {
7266
vnp_prev->next = vnp->next;
7278
static void InsertBestRepeat (ValNodePtr repeat_list, ValNodePtr PNTR sorted_list, Int4 row, Int4 fuzz)
7280
ValNodePtr vnp, vnp_prev = NULL, vnp_new;
7281
SeqAlignSortPtr s_repeat, s, s_before = NULL;
7282
Boolean found = TRUE;
7283
SeqAlignRowPtr r1, r2;
7286
if (repeat_list == NULL || sorted_list == NULL) {
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);
7301
s_repeat = repeat_list->data.ptrvalue;
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);
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);
7318
RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
7319
vnp_new->next = vnp;
7320
if (vnp_prev == NULL) {
7321
*sorted_list = vnp_new;
7323
vnp_prev->next = vnp_new;
7326
s_before = vnp_new->data.ptrvalue;
7332
s_before = vnp->data.ptrvalue;
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);
7344
RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
7345
vnp_new->next = NULL;
7346
if (vnp_prev == NULL) {
7347
*sorted_list = vnp_new;
7349
vnp_prev->next = vnp_new;
7352
s_before = vnp_new->data.ptrvalue;
7358
SeqAlignSortListRemoveMarked (&repeat_list);
7359
repeat_list = ValNodeFree (repeat_list);
7363
static void SelectBestRepeatsFromList (SeqAlignPtr PNTR salp)
7365
ValNodePtr list, vnp;
7366
ValNodePtr row1_repeats, row2_repeats;
7367
Uint1 strand1, strand2;
7368
SeqAlignPtr tmp_salp;
7373
if (salp == NULL || *salp == NULL || (*salp)->next == NULL) {
7377
list = SeqAlignSortListNew (*salp);
7379
FindSeqAlignSortWithPoint (list, missing, 1);
7381
/* remove conflicting strands for row 1 */
7382
strand1 = SeqAlignSortListRemoveConflictingStrands (&list, 1);
7384
/* remove conflicting strands for row 1 */
7385
strand2 = SeqAlignSortListRemoveConflictingStrands (&list, 2);
7387
FindSeqAlignSortWithPoint (list, missing, 1);
7389
if (list != NULL && list->next != NULL) {
7390
row1_repeats = SeqAlignSortListExtractRepeats (&list, 1, fuzz);
7391
row2_repeats = SeqAlignSortListExtractRepeats (&list, 2, fuzz);
7393
FindSeqAlignSortWithPoint (list, missing, 1);
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);
7401
FindSeqAlignSortWithPoint (list, missing, 1);
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);
7410
FindSeqAlignSortWithPoint (list, missing, 1);
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);
7417
row1_repeats = ValNodeFree (row1_repeats);
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);
7424
row2_repeats = ValNodeFree (row2_repeats);
7427
list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7428
*salp = SeqAlignFromSeqAlignSortList (list);
7430
list = SeqAlignSortListFree (list);
6319
7434
static void amconssetfree(AMConsSetPtr acp)
8867
/* advanced editor for Seq-hist assembly alignment */
8868
typedef struct assemblyalignmentdlg {
8869
DIALOG_MESSAGE_BLOCK
8870
DialoG intervals_dialog;
8873
} AssemblyAlignmentDlgData, PNTR AssemblyAlignmentDlgPtr;
8875
Uint2 assmbly_aln_types [] = {
8876
TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_POPUP
8879
Uint2 assmbly_aln_widths [] = {
8880
16, 8, 8, 8, 8, 8, 0
8883
ENUM_ALIST(assmbly_aln_strand_alist)
8890
static EnumFieldAssocPtr assmbly_aln_alists[] = {
8891
NULL, NULL, NULL, NULL, NULL, assmbly_aln_strand_alist
8895
typedef struct assemblyalignmentinterval {
8896
CharPtr prim_accession;
8901
Uint2 percent_identity;
8902
} AssemblyAlignmentIntervalData, PNTR AssemblyAlignmentIntervalPtr;
8905
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFree (AssemblyAlignmentIntervalPtr interval)
8907
if (interval != NULL) {
8908
interval->prim_accession = MemFree (interval->prim_accession);
8909
interval = MemFree (interval);
8915
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromTagListString (CharPtr str)
8917
AssemblyAlignmentIntervalPtr interval;
8921
if (StringHasNoText (str)) {
8925
interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
8926
MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
8928
cp = StringChr (str, '\t');
8930
interval->prim_accession = StringSave (str);
8933
interval->prim_accession = (CharPtr) MemNew (sizeof (Char) * len);
8934
StringNCpy (interval->prim_accession, str, len - 1);
8935
interval->prim_accession[len - 1] = 0;
8937
cp = StringChr (str, '\t');
8938
interval->tpa_from = atoi (str);
8941
cp = StringChr (str, '\t');
8942
interval->tpa_to = atoi (str);
8945
cp = StringChr (str, '\t');
8946
interval->prim_from = atoi (str);
8948
cp = StringChr (cp + 1, '\t');
8950
val = atoi (cp + 1);
8952
interval->prim_strand = Seq_strand_minus;
8954
interval->prim_strand = Seq_strand_plus;
8965
static CharPtr TagListStringFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
8967
CharPtr str, str_fmt = "%s\t%d\t%d\t%d\t%d (%d)\t%d\n";
8969
if (interval == NULL) {
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,
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);
8985
static AssemblyAlignmentIntervalPtr AssemblyAlignmentIntervalFromSeqAlign (SeqAlignPtr salp)
8987
AssemblyAlignmentIntervalPtr interval;
8991
if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG) {
8995
dsp = (DenseSegPtr) salp->segs;
8996
if (dsp == NULL || dsp->numseg != 1) {
9000
interval = (AssemblyAlignmentIntervalPtr) MemNew (sizeof (AssemblyAlignmentIntervalData));
9001
MemSet (interval, 0, sizeof (AssemblyAlignmentIntervalData));
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);
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;
9013
interval->prim_strand = dsp->strands[1];
9016
interval->percent_identity = AlignmentPercentIdentity (salp, FALSE);
9022
static SeqAlignPtr SeqAlignFromAssemblyAlignmentInterval (AssemblyAlignmentIntervalPtr interval)
9027
if (interval == NULL) {
9030
dsp = DenseSegNew ();
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);
9037
dsp->ids = ValNodeNew (NULL);
9038
dsp->ids->next = SeqIdFromAccessionDotVersion(interval->prim_accession);
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;
9046
salp = SeqAlignNew ();
9048
salp->segtype = SAS_DENSEG;
9050
salp->type = SAT_PARTIAL;
9055
static void SeqAlignToAssemblyAlignmentDialog (DialoG d, Pointer data)
9057
AssemblyAlignmentDlgPtr dlg;
9059
dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
9064
PointerToDialog (dlg->intervals_dialog, data);
9068
static Pointer AssemblyAlignmentDialogToSeqAlign (DialoG d)
9070
AssemblyAlignmentDlgPtr dlg;
9071
SeqAlignPtr salp = NULL;
9073
dlg = (AssemblyAlignmentDlgPtr) GetObjectExtra (d);
9078
salp = DialogToPointer (dlg->intervals_dialog);
9084
static void SeqAlignToTagDlg (DialoG d, Pointer data)
9088
AssemblyAlignmentIntervalPtr interval;
9090
tlp =(TagListPtr) GetObjectExtra (d);
9095
tlp->vnp = ValNodeFreeData (tlp->vnp);
9096
SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
9097
salp = (SeqAlignPtr) data;
9099
while (salp != NULL) {
9100
interval = AssemblyAlignmentIntervalFromSeqAlign (salp);
9101
if (interval != NULL) {
9102
ValNodeAddPointer (&(tlp->vnp), 0, TagListStringFromAssemblyAlignmentInterval (interval));
9103
interval = AssemblyAlignmentIntervalFree (interval);
9107
SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
9111
static Pointer SeqAlignFromTagDlg (DialoG d)
9114
SeqAlignPtr salp = NULL, salp_last = NULL, salp_tmp;
9116
AssemblyAlignmentIntervalPtr interval;
9118
tlp =(TagListPtr) GetObjectExtra (d);
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) {
9131
salp_last->next = salp_tmp;
9133
salp_last = salp_tmp;
9135
interval = AssemblyAlignmentIntervalFree (interval);
9142
static DialoG CreateAssemblyAlignmentDialog (GrouP g)
9145
AssemblyAlignmentDlgPtr dlg;
9150
p = HiddenGroup (g, -1, 0, NULL);
9151
SetGroupSpacing (p, 10, 10);
9153
dlg = (AssemblyAlignmentDlgPtr) MemNew (sizeof (AssemblyAlignmentDlgData));
9154
if (dlg == NULL) return NULL;
9156
SetObjectExtra (p, dlg, NULL);
9157
dlg->dialog = (DialoG) p;
9158
dlg->todialog = SeqAlignToAssemblyAlignmentDialog;
9159
dlg->fromdialog = AssemblyAlignmentDialogToSeqAlign;
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,
9184
static void AddTPAIdToAlignment (SeqAlignPtr salp, BioseqPtr bsp)
9189
if (salp == NULL || salp->dim != 2 || salp->segtype != SAS_DENSEG || bsp == NULL) {
9198
sip = SeqIdFindWorst (bsp->id);
9199
sip = SeqIdDup (sip);
9201
sip->next = dsp->ids->next;
9202
dsp->ids->next = NULL;
9203
dsp->ids = SeqIdFree (dsp->ids);
9208
static void AddTPAIdToAlignmentList (SeqAlignPtr salp, BioseqPtr bsp)
9210
while (salp != NULL) {
9211
AddTPAIdToAlignment (salp, bsp);
9216
typedef struct assemblyalignmentform {
9220
} AssemblyAlignmentFormData, PNTR AssemblyAlignmentFormPtr;
9223
static void CheckCoverageWithAddedIntervals (LogInfoPtr lip, BioseqPtr bsp, SeqAlignPtr salp)
9225
ValNodePtr err_list = NULL;
9226
SeqAlignPtr salp_orig, salp_prev = NULL;
9232
if (bsp->hist == NULL) {
9233
bsp->hist = SeqHistNew ();
9236
salp_orig = bsp->hist->assembly;
9237
while (salp_orig != NULL) {
9238
salp_prev = salp_orig;
9239
salp_orig = salp_orig->next;
9242
if (salp_prev == NULL) {
9243
bsp->hist->assembly = salp;
9245
salp_prev->next = salp;
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);
9256
if (salp_prev == NULL) {
9257
bsp->hist->assembly = NULL;
9259
salp_prev->next = NULL;
9264
static Boolean ReportAssemblyIntervalProblems (BioseqPtr bsp, SeqAlignPtr salp)
9267
AssemblyAlignmentIntervalPtr interval;
9268
Boolean has_errors = FALSE;
9269
SeqAlignPtr salp_tmp;
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,
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;
9287
interval = AssemblyAlignmentIntervalFree (interval);
9289
fprintf (lip->fp, "\n");
9290
CheckCoverageWithAddedIntervals (lip, bsp, salp);
9292
has_errors = lip->data_in_log;
9297
static void AcceptAssemblyAlignment (ButtoN b)
9299
AssemblyAlignmentFormPtr frm;
9300
SeqAlignPtr salp, salp_next;
9302
MsgAnswer ans = ANS_OK;
9304
frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
9308
salp = DialogToPointer (frm->dlg);
9310
Message (MSG_ERROR, "No intervals specified");
9313
AddTPAIdToAlignmentList (salp, frm->bsp);
9314
if (ReportAssemblyIntervalProblems (frm->bsp, salp)) {
9315
ans = Message (MSG_OKC, "Continue with errors?");
9318
if (ans == ANS_OK) {
9319
if (frm->bsp->hist == NULL) {
9320
frm->bsp->hist = SeqHistNew ();
9323
/* something is wrong here, alignment is not being sorted */
9325
while (salp_next->next != NULL) {
9326
salp_next = salp_next->next;
9328
salp_next->next = frm->bsp->hist->assembly;
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);
9339
while (salp != NULL) {
9340
salp_next = salp->next;
9342
salp = SeqAlignFree (salp);
9349
static void CheckAssemblyAlignment (ButtoN b)
9351
AssemblyAlignmentFormPtr frm;
9352
SeqAlignPtr salp, salp_next;
9354
frm = (AssemblyAlignmentFormPtr) GetObjectExtra (b);
9359
salp = DialogToPointer (frm->dlg);
9361
Message (MSG_ERROR, "No intervals specified");
9364
AddTPAIdToAlignmentList (salp, frm->bsp);
9365
PointerToDialog (frm->dlg, salp);
9366
ReportAssemblyIntervalProblems (frm->bsp, salp);
9368
while (salp != NULL) {
9369
salp_next = salp->next;
9371
salp = SeqAlignFree (salp);
9377
extern void AdvancedAssemblyAlignmentEditor (IteM i)
9383
AssemblyAlignmentFormPtr frm;
9387
bfp = currentFormDataPtr;
9389
bfp = GetObjectExtra (i);
9391
if (bfp == NULL) return;
9393
bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
9395
Message (MSG_ERROR, "Must select single Bioseq!");
9399
frm = (AssemblyAlignmentFormPtr) MemNew (sizeof (AssemblyAlignmentFormData));
9402
w = FixedWindow (-50, -33, -10, -10, "Add Intervals to Assembly Alignment", StdCloseWindowProc);
9403
SetObjectExtra (w, frm, StdCleanupExtraProc);
9404
frm->form = (ForM) w;
9406
h = HiddenGroup (w, -1, 0, NULL);
9407
SetGroupSpacing (h, 10, 10);
9409
frm->dlg = CreateAssemblyAlignmentDialog(h);
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);
9418
AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
9425
eAssemblyIntervalInfo_NoAction = 0,
9426
eAssemblyIntervalInfo_Remove,
9427
eAssemblyIntervalInfo_Truncate_Left,
9428
eAssemblyIntervalInfo_Truncate_Right,
9429
eAssemblyIntervalInfo_Truncate_Both
9430
} EAssemblyIntervalInfoAction;
9433
typedef struct assemblyintervalinfo {
9441
ValNodePtr conflict_list;
9442
EAssemblyIntervalInfoAction action;
9443
} AssemblyIntervalInfoData, PNTR AssemblyIntervalInfoPtr;
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;
9454
static Int4 FindIntervalConflict (Int4 left1, Int4 right1, Int4 left2, Int4 right2, Int4 overlap)
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;
9467
Message (MSG_ERROR, "Conflict calculation failed");
9468
return eIntervalConflict_none;
9474
typedef struct intervalconflictinfo {
9475
AssemblyIntervalInfoPtr conflict_interval;
9476
EIntervalConflict prim_conflict;
9477
EIntervalConflict tpa_conflict;
9478
} IntervalConflictInfoData, PNTR IntervalConflictInfoPtr;
9481
static IntervalConflictInfoPtr IntervalConflictInfoNew (AssemblyIntervalInfoPtr conflict_interval, EIntervalConflict prim_conflict, EIntervalConflict tpa_conflict)
9483
IntervalConflictInfoPtr ip;
9485
ip = (IntervalConflictInfoPtr) MemNew (sizeof (IntervalConflictInfoData));
9486
ip->conflict_interval = conflict_interval;
9487
ip->prim_conflict = prim_conflict;
9488
ip->tpa_conflict = tpa_conflict;
9493
static IntervalConflictInfoPtr IntervalConflictInfoFree (IntervalConflictInfoPtr ip)
9502
static ValNodePtr IntervalConflictInfoListFree (ValNodePtr vnp)
9504
ValNodePtr vnp_next;
9506
while (vnp != NULL) {
9507
vnp_next = vnp->next;
9508
vnp->data.ptrvalue = IntervalConflictInfoFree (vnp->data.ptrvalue);
9510
vnp = ValNodeFree (vnp);
9517
static AssemblyIntervalInfoPtr AssemblyIntervalInfoFree (AssemblyIntervalInfoPtr ip)
9520
ip->prim_id = MemFree (ip->prim_id);
9521
ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
9528
static ValNodePtr AssemblyIntervalInfoListFree (ValNodePtr vnp)
9530
ValNodePtr vnp_next;
9532
while (vnp != NULL) {
9533
vnp_next = vnp->next;
9534
vnp->data.ptrvalue = AssemblyIntervalInfoFree (vnp->data.ptrvalue);
9536
vnp = ValNodeFree (vnp);
9543
static void TruncateForConflictsOnLeft (AssemblyIntervalInfoPtr ai)
9545
IntervalConflictInfoPtr ip;
9547
Int4 prim_change, tpa_change;
9549
if (ai == NULL || ai->conflict_list == NULL) {
9553
for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
9554
if (vnp->choice == 1) {
9555
ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
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;
9565
ai->prim_left += tpa_change;
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;
9576
ai->tpa_left += prim_change;
9586
static void TruncateForConflictsOnRight (AssemblyIntervalInfoPtr ai)
9588
IntervalConflictInfoPtr ip;
9590
Int4 prim_change, tpa_change;
9592
if (ai == NULL || ai->conflict_list == NULL) {
9596
for (vnp = ai->conflict_list; vnp != NULL; vnp = vnp->next) {
9597
if (vnp->choice == 1) {
9598
ip = (IntervalConflictInfoPtr) vnp->data.ptrvalue;
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;
9608
ai->prim_right -= tpa_change;
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;
9619
ai->tpa_right -= prim_change;
9629
static void ReevaluateConflicts (AssemblyIntervalInfoPtr ip, Int4 overlap)
9632
IntervalConflictInfoPtr cp;
9638
for (vnp = ip->conflict_list; vnp != NULL; vnp = vnp->next) {
9639
cp = vnp->data.ptrvalue;
9640
if (cp->conflict_interval->action == eAssemblyIntervalInfo_Remove) {
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) {
9654
static void RecalculateAssemblyIntervalInfoEndpoints (AssemblyIntervalInfoPtr ip, Int4 overlap)
9656
IntervalConflictInfoPtr cp;
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));
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);
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);
9687
static AssemblyIntervalInfoPtr AssemblyIntervalInfoNew (SeqAlignPtr salp, Int4 overlap)
9689
AssemblyIntervalInfoPtr ip;
9698
ip = (AssemblyIntervalInfoPtr) MemNew (sizeof (AssemblyIntervalInfoData));
9700
AlnMgr2IndexSingleChildSeqAlign (ip->salp);
9702
sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
9703
bsp = BioseqLockById (sip);
9705
sip = SeqIdFree (sip);
9706
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
9710
SeqIdWrite (sip, id_txt, PRINTID_REPORT, sizeof (id_txt) - 1);
9711
sip = SeqIdFree (sip);
9713
ip->prim_id = StringSave (id_txt);
9714
RecalculateAssemblyIntervalInfoEndpoints (ip, overlap);
9719
static CharPtr SummarizeAssemblyInterval (AssemblyIntervalInfoPtr ip)
9721
CharPtr summary = NULL;
9722
CharPtr fmt = "%d-%d %s %d-%d%s";
9729
len = StringLen (fmt) + StringLen (ip->prim_id) + 60;
9730
if (ip->prim_strand == Seq_strand_minus) {
9733
summary = (CharPtr) MemNew (sizeof (Char) + len);
9734
sprintf (summary, fmt, ip->tpa_left + 1, ip->tpa_right + 1,
9736
ip->prim_left + 1, ip->prim_right + 1,
9737
ip->prim_strand == Seq_strand_minus ? "(c)" : "");
9742
static CharPtr SummarizeConflictList (ValNodePtr list)
9744
CharPtr summary = NULL, str, conflict = "Conflict with ";
9745
ValNodePtr vnp, strings = NULL;
9746
IntervalConflictInfoPtr ip;
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;
9757
if (strings == NULL) {
9758
summary = StringSave ("No conflicts");
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, ", ");
9768
strings = ValNodeFreeData (strings);
9774
static void RemoveConflictLists (ValNodePtr list)
9776
AssemblyIntervalInfoPtr ip;
9778
while (list != NULL) {
9779
ip = (AssemblyIntervalInfoPtr) list->data.ptrvalue;
9780
ip->conflict_list = IntervalConflictInfoListFree (ip->conflict_list);
9786
static void BuildConflictLists (ValNodePtr list, Int4 overlap)
9788
ValNodePtr vnp1, vnp2;
9789
AssemblyIntervalInfoPtr ip1, ip2;
9790
EIntervalConflict prim_conflict, tpa_conflict;
9791
IntervalConflictInfoPtr conflict;
9793
if (list == NULL || list->next == NULL) {
9797
RemoveConflictLists (list);
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);
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);
9822
static ValNodePtr AssemblyIntervalInfoListFromSeqAlign (SeqAlignPtr salp, Int4 overlap)
9824
ValNodePtr list = NULL;
9826
while (salp != NULL) {
9827
ValNodeAddPointer (&list, 0, AssemblyIntervalInfoNew (salp, overlap));
9831
BuildConflictLists (list, overlap);
9836
typedef struct assemblyalignmentintervalresolutiondlg {
9837
DIALOG_MESSAGE_BLOCK
9838
DialoG intervals_dialog;
9841
} AssemblyAlignmentIntervalResolutionDlgData, PNTR AssemblyAlignmentIntervalResolutionDlgPtr;
9843
CharPtr assmbly_aln_int_res_labels [] = {
9848
Uint2 assmbly_aln_int_res_types [] = {
9849
TAGLIST_POPUP, TAGLIST_PROMPT, TAGLIST_PROMPT
9852
Uint2 assmbly_aln_int_res_widths [] = {
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},
9865
static EnumFieldAssocPtr assmbly_aln_int_res_alists[] = {
9866
assmbly_aln_int_res_action_alist, NULL, NULL
9870
static CharPtr SummarizeOneIntervalResolutionRow (AssemblyIntervalInfoPtr ip)
9872
CharPtr str, int_str, conf_str, fmt = "%d\t%s\t%s\n";
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);
9888
static void UpdateConflicts (Pointer userdata)
9890
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
9891
AssemblyIntervalInfoPtr ip;
9893
ValNodePtr vnp, vnp_t;
9895
Boolean any_change = FALSE;
9899
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) userdata;
9905
tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
9910
if (!TextHasNoText (dlg->overlap)) {
9911
str = SaveStringFromText (dlg->overlap);
9912
overlap = atoi (str);
9913
str = MemFree (str);
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);
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);
9940
SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
9941
SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
9945
static TaglistCallback assmbly_int_res_callback_list[3] =
9946
{ UpdateConflicts, UpdateConflicts, UpdateConflicts };
9948
static void SeqAlignToAssemblyAlignmentIntervalResolutionDialog (DialoG d, Pointer data)
9950
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
9957
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
9958
salp = (SeqAlignPtr) data;
9962
tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
9966
SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
9967
tlp->vnp = ValNodeFreeData (tlp->vnp);
9969
if (!TextHasNoText (dlg->overlap)) {
9970
str = SaveStringFromText (dlg->overlap);
9971
overlap = atoi (str);
9972
str = MemFree (str);
9978
dlg->list = AssemblyIntervalInfoListFree (dlg->list);
9979
dlg->list = AssemblyIntervalInfoListFromSeqAlign (salp, overlap);
9981
for (vnp = dlg->list; vnp != NULL; vnp = vnp->next) {
9982
str = SummarizeOneIntervalResolutionRow (vnp->data.ptrvalue);
9983
ValNodeAddPointer (&(tlp->vnp), 0, str);
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);
9991
SafeShow (tlp->bar);
9993
SafeHide (tlp->bar);
9995
SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
10000
static Pointer AssemblyAlignmentIntervalResolutionDialogToSeqAlign (DialoG d)
10002
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
10003
AssemblyIntervalInfoPtr ai;
10004
SeqAlignPtr salp_list = NULL, salp_prev = NULL, salp;
10007
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (d);
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 */
10019
if (salp_prev == NULL) {
10022
salp_prev->next = salp;
10028
return (Pointer) salp_list;
10032
static void ChangeAssemblyAlignmentIntervalResolutionOverlap (TexT t)
10034
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
10035
AssemblyIntervalInfoPtr ip;
10037
ValNodePtr vnp, vnp_t;
10041
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) GetObjectExtra (t);
10046
tlp = (TagListPtr) GetObjectExtra (dlg->intervals_dialog);
10051
if (!TextHasNoText (dlg->overlap)) {
10052
str = SaveStringFromText (dlg->overlap);
10053
overlap = atoi (str);
10054
str = MemFree (str);
10060
BuildConflictLists (dlg->list, overlap);
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);
10070
/* update dialog */
10071
SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
10072
SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
10077
static void CleanupAssemblyAlignmentIntervalResolutionDialog (GraphiC g, VoidPtr data)
10080
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
10082
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) data;
10084
dlg->list = AssemblyIntervalInfoListFree (dlg->list);
10085
dlg = MemFree (dlg);
10090
static DialoG CreateAssemblyAlignmentIntervalResolutionDialog (GrouP g)
10093
AssemblyAlignmentIntervalResolutionDlgPtr dlg;
10097
Int4 num_columns = sizeof (assmbly_aln_int_res_labels) / sizeof (CharPtr);
10099
p = HiddenGroup (g, -1, 0, NULL);
10100
SetGroupSpacing (p, 10, 10);
10102
dlg = (AssemblyAlignmentIntervalResolutionDlgPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionDlgData));
10103
if (dlg == NULL) return NULL;
10105
SetObjectExtra (p, dlg, CleanupAssemblyAlignmentIntervalResolutionDialog);
10106
dlg->dialog = (DialoG) p;
10108
dlg->todialog = SeqAlignToAssemblyAlignmentIntervalResolutionDialog;
10109
dlg->fromdialog = AssemblyAlignmentIntervalResolutionDialogToSeqAlign;
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);
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');
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);
10126
AlignObjects (ALIGN_CENTER, (HANDLE) z, (HANDLE) x, NULL);
10131
typedef struct assemblyalignmentintervalresolutionfrm {
10136
} AssemblyAlignmentIntervalResolutionFrmData, PNTR AssemblyAlignmentIntervalResolutionFrmPtr;
10139
static void AcceptAssemblyAlignmentIntervalResolution (ButtoN b)
10141
AssemblyAlignmentIntervalResolutionFrmPtr frm;
10142
SeqAlignPtr new_assem, salp, salp_next;
10144
frm = (AssemblyAlignmentIntervalResolutionFrmPtr) GetObjectExtra (b);
10149
/* TODO: check for problems before accepting */
10151
new_assem = DialogToPointer (frm->dlg);
10152
if (new_assem == NULL) {
10153
Message (MSG_ERROR, "No intervals left in assembly!");
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;
10163
salp = SeqAlignFree (salp);
10167
/* assign new assembly */
10168
frm->bsp->hist->assembly = new_assem;
10170
ObjMgrSetDirtyFlag (frm->bsp->idx.entityID, TRUE);
10171
ObjMgrSendMsg (OM_MSG_UPDATE, frm->bsp->idx.entityID, 0, 0);
10172
Remove (frm->form);
10176
extern void AssemblyAlignmentIntervalResolution (IteM i)
10182
AssemblyAlignmentIntervalResolutionFrmPtr frm;
10186
bfp = currentFormDataPtr;
10188
bfp = GetObjectExtra (i);
10190
if (bfp == NULL) return;
10192
bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
10194
Message (MSG_ERROR, "Must select single Bioseq!");
10197
if (bsp->hist == NULL || bsp->hist->assembly == NULL) {
10198
Message (MSG_ERROR, "No assembly alignment!");
10201
frm = (AssemblyAlignmentIntervalResolutionFrmPtr) MemNew (sizeof (AssemblyAlignmentIntervalResolutionFrmData));
10204
w = FixedWindow (-50, -33, -10, -10, "Resolve Assembly Alignment Intervals", StdCloseWindowProc);
10205
SetObjectExtra (w, frm, StdCleanupExtraProc);
10206
frm->form = (ForM) w;
10208
h = HiddenGroup (w, -1, 0, NULL);
10209
SetGroupSpacing (h, 10, 10);
10211
frm->dlg = CreateAssemblyAlignmentIntervalResolutionDialog(h);
10212
PointerToDialog (frm->dlg, bsp->hist->assembly);
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);
10221
AlignObjects (ALIGN_CENTER, (HANDLE) frm->dlg, (HANDLE) c, NULL);
7702
10228
typedef struct historyformdata {
7703
10229
FEATURE_FORM_BLOCK
10638
typedef struct nw {
10640
Int4 traceback_pos;
10641
} NWData, PNTR NWPtr;
10644
static Int4 SegmentsNeededForAlignment (CharPtr buf1, CharPtr buf2)
10647
Boolean gap1, gap2, change = FALSE;
10664
while (*cp1 != 0 && *cp2 != 0) {
10694
FillInStartsAndLensForAlignment
10700
Boolean gap1, gap2, change = FALSE;
10702
Int4 pos1 = 0, pos2 = 0;
10707
dsp->starts[dsp->dim * num_segs] = -1;
10710
dsp->starts[dsp->dim * num_segs] = pos1;
10717
dsp->starts[dsp->dim * num_segs + 1] = -1;
10719
dsp->starts[dsp->dim * num_segs + 1] = pos2;
10724
dsp->lens[num_segs] = 1;
10726
while (*cp1 != 0 && *cp2 != 0) {
10753
dsp->starts[dsp->dim * num_segs] = -1;
10755
dsp->starts[dsp->dim * num_segs] = pos1;
10758
dsp->starts[dsp->dim * num_segs + 1] = -1;
10760
dsp->starts[dsp->dim * num_segs + 1] = pos2;
10762
dsp->lens[num_segs] = 1;
10764
dsp->lens[num_segs]++;
10778
static void AdjustStringAlingmentForOffsetAndStrand (DenseSegPtr dsp, Int4 start1, Int4 start2, Int4 stop2, Uint1 strand2)
10786
for (i = 0; i < dsp->numseg; i++) {
10787
if (dsp->starts[2 * i] != -1) {
10788
dsp->starts[2 * i] += start1;
10790
if (dsp->starts[2 * i + 1] != -1) {
10791
if (strand2 == Seq_strand_plus) {
10792
dsp->starts[2 * i + 1] += start2;
10794
dsp->starts[2 * i + 1] = stop2 - dsp->starts[2 * i + 1] - dsp->lens[i];
10801
/* assumption - first interval always on plus strand */
10802
static SeqAlignPtr NWAlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
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;
10810
Int4 gap_penalty = -1;
10811
Int4 mismatch_penalty = -1;
10812
Int4 match_score = 1;
10813
Int4 left, up, diag;
10816
SeqAlignPtr salp = NULL;
10818
if (sip1 == NULL || sip2 == NULL) {
10822
bsp1 = BioseqLockById (sip1);
10823
bsp2 = BioseqLockById (sip2);
10825
if (bsp1 != NULL && bsp2 != NULL) {
10826
if (stop2 < start2) {
10827
strand2 = Seq_strand_minus;
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);
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;
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;
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;
10855
/* fill in scores */
10856
for (row = 1; row <= len2; row++) {
10857
for (col = 1; col <= len1; col++) {
10859
diag = matrix[((row - 1) * (len1 + 1)) + col - 1].score;
10860
if (buf1[col - 1] == buf2[row - 1]) {
10861
diag += match_score;
10863
diag += mismatch_penalty;
10865
left = matrix[((row) * (len1 + 1)) + col - 1].score + gap_penalty;
10866
up = matrix[((row - 1) * (len1 + 1)) + col].score + gap_penalty;
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;
10876
matrix[((row) * (len1 + 1)) + col].score = diag;
10877
matrix[((row) * (len1 + 1)) + col].traceback_pos = ((row - 1) * (len1 + 1)) + col - 1;
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;
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];
10900
} else if (col == back_col) {
10902
*cp2 = buf2[row - 1];
10904
*cp1 = buf1[col - 1];
10905
*cp2 = buf2[row - 1];
10913
/* no longer need matrix or original sequence buffers */
10914
matrix = MemFree (matrix);
10915
buf1 = MemFree (buf1);
10916
buf2 = MemFree (buf2);
10918
/* count number of segments needed */
10919
num_segs = SegmentsNeededForAlignment (cp1 + 1, cp2 + 1);
10921
/* create DenseSeg */
10922
dsp = DenseSegNew ();
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);
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;
10936
/* fill in starts and lens */
10937
FillInStartsAndLensForAlignment (dsp, cp1 + 1, cp2 + 1);
10939
/* no longer need FASTA+GAP alignment strings */
10940
alnbuf1 = MemFree (alnbuf1);
10941
alnbuf2 = MemFree (alnbuf2);
10943
/* adjust for real sequence position and strand */
10944
AdjustStringAlingmentForOffsetAndStrand (dsp, start1, start2, stop2, strand2);
10946
salp = SeqAlignNew ();
10948
salp->segtype = SAS_DENSEG;
10951
BioseqUnlock (bsp1);
10952
BioseqUnlock (bsp2);
10953
AlnMgr2IndexSingleChildSeqAlign (salp);
10959
* first interval always on plus strand
10961
static SeqAlignPtr AlignmentForInterval (SeqIdPtr sip1, SeqIdPtr sip2, Int4 start1, Int4 stop1, Int4 start2, Int4 stop2)
10964
SeqAlignPtr salp = NULL;
10965
Int4 len1, len2, i;
10966
Uint1 strand = Seq_strand_plus;
10968
if (sip1 == NULL || sip2 == NULL) {
10972
salp = NWAlignmentForInterval(sip1, sip2, start1, stop1, start2, stop2);
10973
if (salp != NULL) {
10977
dsp = DenseSegNew ();
10979
dsp->ids = SeqIdDup (sip1);
10980
dsp->ids->next = SeqIdDup (sip2);
10981
len1 = stop1 - start1 + 1;
10983
if (stop2 > start2) {
10984
len2 = stop2 - start2 + 1;
10986
len2 = start2 - stop2 + 1;
10987
strand = Seq_strand_minus;
10990
if (len1 == len2) {
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);
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;
11006
dsp->lens[0] = len1;
11007
dsp->lens[1] = len2 - len1;
11010
dsp->starts[0] = start1;
11011
if (strand == Seq_strand_minus) {
11012
dsp->starts[1] = stop2;
11014
dsp->starts[1] = start2;
11017
for (i = 0; i < dsp->numseg; i++) {
11018
dsp->strands[2 * i] = Seq_strand_plus;
11019
dsp->strands[2 * i + 1] = strand;
11022
if (dsp->numseg > 1) {
11024
dsp->starts[2] = dsp->starts[0] + dsp->lens[0];
11025
dsp->starts[3] = -1;
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;
11031
dsp->starts[3] = dsp->starts[1] + dsp->lens[0];
11036
salp = SeqAlignNew ();
11037
salp->segtype = SAS_DENSEG;
11040
AlnMgr2IndexSingleChildSeqAlign (salp);
11045
static void ReportCreatedAlignment (LogInfoPtr lip, SeqAlignPtr salp)
11047
Int4 from_1, to_1, from_2, to_2;
11049
Char id1[255], id2[255];
11053
if (lip == NULL || lip->fp == NULL || salp == NULL) {
11057
sip = AlnMgr2GetNthSeqIdPtr (salp, 1);
11058
bsp = BioseqLockById (sip);
11060
sip = SeqIdFree (sip);
11061
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
11062
BioseqUnlock (bsp);
11065
SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
11066
sip = SeqIdFree (sip);
11067
sip = AlnMgr2GetNthSeqIdPtr (salp, 2);
11068
bsp = BioseqLockById (sip);
11070
sip = SeqIdFree (sip);
11071
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
11072
BioseqUnlock (bsp);
11074
SeqIdWrite (sip, id2, PRINTID_REPORT, sizeof (id2) - 1);
11075
sip = SeqIdFree (sip);
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)" : "");
11084
WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
11088
static void FillInAlignmentHoles (SeqAlignPtr salp_list, LogInfoPtr lip)
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;
11096
SeqIdPtr sip1, sip2;
11098
if (salp_list == NULL || salp_list->next == NULL) {
11102
sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
11103
sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
11105
/* note - unlike the other functions, SeqAlignStrand uses 0-based index */
11106
strand = SeqAlignStrand (salp_list, 1);
11109
AlnMgr2GetNthSeqRangeInSA (salp, 1, &start1_this, &stop1_this);
11110
AlnMgr2GetNthSeqRangeInSA (salp, 2, &start2_this, &stop2_this);
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);
11121
salp_new = AlignmentForInterval (sip1, sip2, stop1_this + 1, start1_next - 1, stop2_this + 1, start2_next - 1);
11123
ReportCreatedAlignment (lip, salp_new);
11124
salp_new->next = salp->next;
11125
salp->next = salp_new;
11128
start1_this = start1_next;
11129
stop1_this = stop1_next;
11130
start2_this = start2_next;
11131
stop2_this = stop2_next;
11138
static SeqAlignPtr MergeAlignments (SeqAlignPtr salp_list)
11140
SeqAlignPtr salp_new = NULL, salp, salp_next;
11141
DenseSegPtr dsp, dsp_new;
11144
if (salp_list == NULL || salp_list->next == NULL) {
11148
dsp_new = DenseSegNew ();
11150
dsp_new->ids = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
11151
dsp_new->ids->next = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
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;
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);
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];
11176
salp = SeqAlignFree (salp);
11179
salp_new = SeqAlignNew ();
11180
salp_new->segtype = SAS_DENSEG;
11181
salp_new->segs = dsp_new;
11188
static Boolean MatchWithAmbiguity (Char ch1, Char ch2)
11190
Boolean rval = FALSE;
11192
ch1 = toupper (ch1);
11193
ch2 = toupper (ch2);
11198
if (ch1 == 'X' || ch2 == 'X') {
11203
if (ch2 == 'M' || ch2 == 'R' || ch2 == 'W' || ch2 == 'V' || ch2 == 'H' || ch2 == 'D') {
11208
if (ch2 == 'K' || ch2 == 'Y' || ch2 == 'W' || ch2 == 'B' || ch2 == 'H' || ch2 == 'D') {
11213
if (ch2 == 'K' || ch2 == 'R' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'D') {
11218
if (ch2 == 'M' || ch2 == 'Y' || ch2 == 'S' || ch2 == 'B' || ch2 == 'V' || ch2 == 'H') {
11223
if (ch2 == 'G' || ch2 == 'T' || ch2 == 'B' || ch2 == 'D') {
11228
if (ch2 == 'A' || ch2 == 'C' || ch2 == 'V' || ch2 == 'H') {
11233
if (ch2 == 'A' || ch2 == 'G' || ch2 == 'V' || ch2 == 'D') {
11238
if (ch2 == 'C' || ch2 == 'T' || ch2 == 'B' || ch2 == 'H') {
11243
if (ch2 == 'C' || ch2 == 'G' || ch2 == 'B' || ch2 == 'V') {
11248
if (ch2 == 'A' || ch2 == 'T' || ch2 == 'H' || ch2 == 'D') {
11253
if (ch2 == 'C' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'Y' || ch2 == 'S') {
11258
if (ch2 == 'A' || ch2 == 'C' || ch2 == 'G' || ch2 == 'M' || ch2 == 'R' || ch2 == 'S') {
11263
if (ch2 == 'A' || ch2 == 'C' || ch2 == 'T' || ch2 == 'M' || ch2 == 'Y' || ch2 == 'W') {
11268
if (ch2 == 'A' || ch2 == 'G' || ch2 == 'T' || ch2 == 'K' || ch2 == 'R' || ch2 == 'W') {
11277
/* expand for ambiguity characters and poly-A tail */
11278
static SeqAlignPtr ExtendAlignmentList (SeqAlignPtr salp_list)
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;
11285
CharPtr buf1, buf2;
11287
SeqIdPtr sip1, sip2;
11290
if (salp_list == NULL) {
11294
strand = SeqAlignStrand (salp_list, 1);
11295
AlnMgr2IndexSingleChildSeqAlign (salp_list);
11297
sip1 = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
11298
bsp1 = BioseqLockById (sip1);
11299
sip2 = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
11300
bsp2 = BioseqLockById (sip2);
11302
AlnMgr2GetNthSeqRangeInSA (salp_list, 1, &from_1, &to_1);
11303
AlnMgr2GetNthSeqRangeInSA (salp_list, 2, &from_2, &to_2);
11306
&& ((strand == Seq_strand_plus && from_2 > 0)
11307
|| (strand == Seq_strand_minus && to_2 < bsp2->length - 1))) {
11309
if (strand == Seq_strand_plus) {
11312
len2 = bsp2->length - to_2 - 1;
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);
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);
11326
ctr = SeqPortStreamInt (bsp2, to_2 + 1, to_2 + len_check, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
11331
while (len_extend < len_check
11332
&& MatchWithAmbiguity (buf1[len_check - len_extend - 1], buf2[len_check - len_extend - 1])) {
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;
11344
SeqAlignIndexFree(salp_list->saip);
11345
salp_list->saip = NULL;
11346
AlnMgr2IndexSingleChildSeqAlign (salp_list);
11350
/* extend at other end */
11351
salp_tmp = salp_list;
11352
while (salp_tmp->next != NULL) {
11353
salp_tmp = salp_tmp->next;
11356
AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
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;
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);
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);
11382
ctr = SeqPortStreamInt (bsp2, from_2 - len_check, from_2 - 1, Seq_strand_minus, STREAM_EXPAND_GAPS | STREAM_CORRECT_INVAL, (Pointer) buf2, NULL);
11387
while (len_extend < len_check
11388
&& MatchWithAmbiguity (buf1[len_extend], buf2[len_extend])) {
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;
11399
SeqAlignIndexFree(salp_tmp->saip);
11400
salp_tmp->saip = NULL;
11401
AlnMgr2IndexSingleChildSeqAlign (salp_tmp);
11406
BioseqUnlock (bsp1);
11407
BioseqUnlock (bsp2);
11408
sip1 = SeqIdFree (sip1);
11409
sip2 = SeqIdFree (sip2);
11415
static void ReportInitialBlastResults (LogInfoPtr lip, SeqAlignPtr salp_list)
11417
Int4 from_1, to_1, from_2, to_2;
11419
Char id1[255], id2[255];
11423
if (lip == NULL || lip->fp == NULL || salp_list == NULL) {
11427
AlnMgr2IndexSingleChildSeqAlign (salp_list);
11428
sip = AlnMgr2GetNthSeqIdPtr (salp_list, 1);
11429
bsp = BioseqLockById (sip);
11431
sip = SeqIdFree (sip);
11432
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
11433
BioseqUnlock (bsp);
11435
SeqIdWrite (sip, id1, PRINTID_REPORT, sizeof (id1) - 1);
11436
sip = SeqIdFree (sip);
11437
sip = AlnMgr2GetNthSeqIdPtr (salp_list, 2);
11438
bsp = BioseqLockById (sip);
11440
sip = SeqIdFree (sip);
11441
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
11442
BioseqUnlock (bsp);
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;
11456
lip->data_in_log = TRUE;
11460
static void ReportForRemoval (LogInfoPtr lip, SeqAlignPtr salp, CharPtr reason)
11462
Int4 from_1, to_1, from_2, to_2;
11464
Char id1[255], id2[255];
11467
if (lip == NULL || lip->fp == NULL || salp == NULL) {
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);
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.
11493
static SeqAlignPtr CombineTSAAlignments (SeqAlignPtr salp)
11495
SeqAlignPtr salp_tmp, salp_match, salp_prev, salp_next;
11497
Int4 from_1, to_1, from_2, to_2;
11498
LogInfoPtr lip = NULL;
11500
if (salp == NULL) {
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);
11511
if (salp->next != NULL) {
11512
lip = OpenLog ("TSA Alignment Adjustments");
11515
ReportInitialBlastResults (lip, salp);
11517
if (salp->next != NULL) {
11518
/* remove alignments that are not the same strand as the initial alignment */
11519
strand = SeqAlignStrand (salp, 1);
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);
11532
salp_tmp = salp_next;
11536
/* remove alignments that overlap on the first sequence */
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);
11551
salp_tmp = salp_next;
11553
salp_match = salp_match->next;
11556
if (salp->next != NULL) {
11557
/* remove alignments that overlap on the second sequence */
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);
11572
salp_tmp = salp_next;
11574
salp_match = salp_match->next;
11578
/* sort remaining alignments by start position on the first sequence */
11579
salp = SortPairwiseAlignmentsByFirstSeqRange (salp);
11581
/* temporary hack. only interested in "unusual" errors. */
11583
lip->data_in_log = FALSE;
11586
if (salp->next != NULL) {
11587
/* remove alignments that are out of order on the second sequence */
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);
11599
salp_prev = salp_tmp;
11603
salp_tmp = salp_prev->next;
11607
/* fill in holes */
11608
FillInAlignmentHoles (salp, lip);
11610
/* extend for good matches */
11611
salp = ExtendAlignmentList (salp);
11613
/* make new alignment by stringing together local alignments */
11614
salp = MergeAlignments (salp);
11616
lip = FreeLog (lip);
11621
NLM_EXTERN SeqAlignPtr GetSeqAlignTSA (BioseqPtr bsp1, BioseqPtr bsp2)
11623
BLAST_SummaryOptions *options = NULL;
11624
SeqAlignPtr salp = NULL;
11626
if (bsp1 == NULL || bsp2 == NULL) return NULL;
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))
11635
options->program = eBlastn;
11639
options->program = eBlastp;
11642
BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
11644
/* if there were no alignments from the first search, try again
11645
* with low-complexity masking turned off.
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);
11653
BLAST_SummaryOptionsFree(options);
11655
if (salp != NULL) {
11656
salp = CombineTSAAlignments (salp);
11657
AlnMgr2IndexSeqAlign(salp);
11663
/* code for editing TSA assembly */
11664
typedef struct tsaassemblydialog {
11665
DIALOG_MESSAGE_BLOCK
11667
BioseqPtr consensus_bsp;
11668
} TSAAssemblyDialog, PNTR TSAAssemblyDialogPtr;
11671
Uint2 tsa_assembly_types [] = {
11672
TAGLIST_TEXT, TAGLIST_PROMPT, TAGLIST_PROMPT
11676
Uint2 tsa_assembly_widths [] = {
11681
static void SetTSAAssemblyDialogConsensusBioseq (DialoG d, BioseqPtr bsp)
11683
TSAAssemblyDialogPtr dlg;
11685
dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
11687
dlg->consensus_bsp = bsp;
11692
static void SeqAlignsToTSAAssemblyDialog (DialoG d, Pointer data)
11694
TSAAssemblyDialogPtr dlg;
11696
SeqAlignPtr salp_list, salp, salp_tmp;
11697
ValNodePtr data_list = NULL;
11698
Int4 tsa_from, tsa_to, primary_from, primary_to;
11702
CharPtr fmt = "%s\t%d-%d%s\t%d-%d\n";
11706
dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
11711
tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
11716
salp_list = (SeqAlignPtr) data;
11719
while (salp != NULL) {
11720
salp_tmp = salp->next;
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);
11728
sip = SeqIdFree (sip);
11729
sip = SeqIdDup (SeqIdFindBest (bsp->id, SEQID_GENBANK));
11730
BioseqUnlock (bsp);
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;
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);
11751
SafeHide (tlp->bar);
11753
SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
11757
static void TSATableCallback (Pointer data)
11759
ProcessExternalEvent ();
11763
static Pointer TSAAssemblyDialogToTranscriptomeIdsList (DialoG d)
11765
TSAAssemblyDialogPtr dlg;
11769
TranscriptomeIdsPtr t;
11770
ValNodePtr token_list = NULL;
11772
dlg = (TSAAssemblyDialogPtr) GetObjectExtra (d);
11777
tlp = (TagListPtr) GetObjectExtra (dlg->intervals);
11782
if (dlg->consensus_bsp == NULL) {
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);
11791
ValNodeAddPointer (&token_list, 0, txt);
11794
t = TranscriptomeIdsNew (dlg->consensus_bsp, token_list);
11795
vnp = ValNodeNew (NULL);
11797
vnp->data.ptrvalue = t;
11802
static DialoG CreateTSAAssemblyDialog (GrouP g)
11805
TSAAssemblyDialogPtr dlg;
11810
p = HiddenGroup (g, -1, 0, NULL);
11811
SetGroupSpacing (p, 10, 10);
11813
dlg = (TSAAssemblyDialogPtr) MemNew (sizeof (TSAAssemblyDialog));
11814
if (dlg == NULL) return NULL;
11816
SetObjectExtra (p, dlg, NULL);
11817
dlg->dialog = (DialoG) p;
11818
dlg->todialog = SeqAlignsToTSAAssemblyDialog;
11819
dlg->fromdialog = TSAAssemblyDialogToTranscriptomeIdsList;
11821
x = HiddenGroup (p, 0, 2, NULL);
11822
y = HiddenGroup (x, 3, 0, NULL);
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);
11834
static void ShowAssemblyAlignment (SeqAlignPtr salp)
11838
if (salp == NULL) {
11842
lip = OpenLog ("Assembly Alignments");
11843
while (salp != NULL) {
11844
WriteAlignmentInterleaveToFileEx (salp, lip->fp, 40, FALSE, TRUE);
11845
lip->data_in_log = TRUE;
11849
lip = FreeLog (lip);
11853
typedef struct tsaassemblyform {
11857
} TSAAssemblyFormData, PNTR TSAAssemblyFormPtr;
11860
static void AcceptTSAAssembly (ButtoN b)
11862
TSAAssemblyFormPtr frm;
11864
ValNodePtr err_list, coverage_report, vnp, ids_list, match_errs;
11865
SeqAlignPtr salp, salp_next;
11868
frm = (TSAAssemblyFormPtr) GetObjectExtra (b);
11872
bsp = GetBioseqGivenIDs (frm->input_entityID, frm->input_itemID, frm->input_itemtype);
11879
SetTSAAssemblyDialogConsensusBioseq (frm->intervals, bsp);
11881
ids_list = DialogToPointer (frm->intervals);
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;
11890
salp = SeqAlignFree (salp);
11895
if (ids_list == NULL) {
11896
Message (MSG_ERROR, "TSA assembly removed");
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);
11904
ValNodeLink (&coverage_report, err_list);
11905
err_list = coverage_report;
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);
11912
lip->data_in_log = TRUE;
11914
lip = FreeLog (lip);
11915
err_list = ValNodeFreeData (err_list);
11919
ObjMgrSetDirtyFlag (frm->input_entityID, TRUE);
11920
ObjMgrSendMsg (OM_MSG_UPDATE, frm->input_entityID, 0, 0);
11921
Remove (frm->form);
11927
NLM_EXTERN void EditTSAAssembly (IteM i)
11931
TSAAssemblyFormPtr frm;
11937
bfp = currentFormDataPtr;
11939
bfp = GetObjectExtra (i);
11941
if (bfp == NULL) return;
11943
bsp = GetBioseqGivenIDs (bfp->input_entityID, bfp->input_itemID, bfp->input_itemtype);
11945
Message (MSG_ERROR, "Must select sequence for editing TSA Assembly");
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;
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);
11960
if (bsp->hist == NULL) {
11961
PointerToDialog (frm->intervals, NULL);
11963
PointerToDialog (frm->intervals, bsp->hist->assembly);
11967
c = HiddenGroup (h, 2, 0, NULL);
11968
b = PushButton (c, "Accept", AcceptTSAAssembly);
11969
SetObjectExtra (b, frm, NULL);
11970
PushButton (c, "Cancel", StdCancelButtonProc);
11972
AlignObjects (ALIGN_CENTER, (HANDLE) frm->intervals, (HANDLE) c, NULL);
8111
11980
/* automatic defline generator */
8113
11982
typedef struct deffeats {