|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/sequin/sequin8.c |
source navigation diff markup identifier search freetext search file search |
1 /* sequin8.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: sequin8.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 2/3/98
31 *
32 * $Revision: 6.557 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include "sequin.h"
46 #include <objsub.h>
47 #include <valid.h>
48 #include <cdrgn.h>
49 #include <suggslp.h>
50 #include <toasn3.h>
51 #include <subutil.h>
52 #include <explore.h>
53 #include <medarch.h>
54 #include <medutil.h>
55 #include <tofasta.h>
56 #include <asn2gnbk.h>
57 #include <alignmgr2.h>
58 #include <spidey.h>
59 #include <blast.h>
60 #include <salpanel.h>
61 #include <seqpanel.h>
62 #include <edutil.h>
63 #include <tax3api.h>
64 #include <asn2gnbp.h> /* included for discrepancy report */
65 #include <algo/blast/api/twoseq_api.h>
66 #include <algo/blast/api/blast_seqalign.h>
67
68 #include <macrodlg.h>
69 #include <macroapi.h>
70 #include <alignval.h>
71 #include <pubdesc.h>
72
73 #define DEFLINE_MAX_LEN 380
74 #define TEXT_MAX_LEN 64
75 #define DEFLINE_MAX_GENENAME_LEN 64
76 #define ALL_FEATURES 255
77
78 typedef struct evidenceformdata {
79 FEATURE_FORM_BLOCK
80
81 LisT objlist;
82 TexT findthis;
83 Uint2 itemtype;
84 Uint2 subtype;
85 PopuP evdence;
86 Uint2 exp_ev;
87 ValNodePtr head;
88 Boolean stringfound;
89 Char findStr [128];
90 ButtoN case_insensitive;
91 ButtoN when_string_not_present;
92 } EvidenceFormData, PNTR
93
94 EvidenceFormPtr;
95
96 typedef struct codebreakformdata {
97 FEATURE_FORM_BLOCK
98 PopuP aminoAcidPopup;
99 Char currentCodonStr [4];
100 TexT codonText;
101 ButtoN acceptButton;
102 } CodeBreakFormData, PNTR CodeBreakFormPtr;
103
104 static Boolean IsRealImpFeat (Uint2 subtype)
105
106 {
107 if (subtype >= FEATDEF_allele && subtype <= FEATDEF_site_ref) return TRUE;
108 if (subtype == FEATDEF_oriT) return TRUE;
109 return FALSE;
110 }
111
112
113
114 static void BreakIntoAGroup (BioseqSetPtr parent, Uint1 _class, SeqEntryPtr list)
115
116 {
117 BioseqSetPtr bssp;
118 Int2 count;
119 SeqEntryPtr sep;
120 SeqEntryPtr tmp;
121
122 while (list != NULL) {
123 bssp = BioseqSetNew ();
124 if (bssp == NULL) return;
125 bssp->_class = _class;
126 sep = SeqEntryNew ();
127 if (sep == NULL) return;
128 sep->choice = 2;
129 sep->data.ptrvalue = (Pointer) bssp;
130 if (parent->seq_set != NULL) {
131 tmp = parent->seq_set;
132 while (tmp->next != NULL) {
133 tmp = tmp->next;
134 }
135 tmp->next = sep;
136 } else {
137 parent->seq_set = sep;
138 }
139 bssp->seq_set = list;
140 for (tmp = list, count = 0; tmp != NULL && count < 99; tmp = tmp->next, count++) continue;
141 if (tmp != NULL) {
142 list = tmp->next;
143 tmp->next = NULL;
144 } else {
145 list = NULL;
146 }
147 }
148 }
149
150
151 extern Int2 LIBCALLBACK MakeGroupsOf200 (Pointer data)
152
153 {
154 BioseqSetPtr bssp;
155 ObjMgrDataPtr omdptop;
156 ObjMgrData omdata;
157 OMProcControlPtr ompcp;
158 Uint2 parenttype;
159 Pointer parentptr;
160 SeqEntryPtr sep;
161 AsnIoPtr aip;
162 Uint1 _class;
163 Int2 count;
164 Char file [FILENAME_MAX];
165 SeqEntryPtr list;
166 SeqEntryPtr next;
167 Char output [PATH_MAX];
168 Char path [PATH_MAX];
169 CharPtr ptr;
170 SeqSubmitPtr ssp;
171 Char str [FILENAME_MAX];
172 SeqEntryPtr tmp;
173 #ifdef WIN_MAC
174 FILE *f;
175 #endif
176
177 ompcp = (OMProcControlPtr) data;
178 if (ompcp == NULL) return OM_MSG_RET_ERROR;
179 if (ompcp->input_itemtype != OBJ_BIOSEQSET) {
180 Message (MSG_ERROR, "Must select Bioseq-set!");
181 return OM_MSG_RET_ERROR;
182 }
183 bssp = (BioseqSetPtr) ompcp->input_data;
184 if (bssp == NULL) return OM_MSG_RET_ERROR;
185 sep = SeqMgrGetSeqEntryForData (bssp);
186
187 _class = bssp->_class;
188 if (_class != 7 && _class != 13 && _class != 14 &&
189 _class != 15 && _class != 16 && _class != 18) {
190 Message (MSG_ERROR, "Can only use this for GenBank, Mut, Pop, Phy, Eco, and WGS sets!");
191 return OM_MSG_RET_ERROR;
192 }
193
194 SaveSeqEntryObjMgrData (sep, &omdptop, &omdata);
195 GetSeqEntryParent (sep, &parentptr, &parenttype);
196
197 list = bssp->seq_set;
198 bssp->seq_set = NULL;
199 bssp->_class = 7;
200 BreakIntoAGroup (bssp, _class, list);
201
202 SeqMgrLinkSeqEntry (sep, parenttype, parentptr);
203 RestoreSeqEntryObjMgrData (sep, omdptop, &omdata);
204 PropagateFromGenBankBioseqSet (sep, TRUE);
205
206 if (parenttype == OBJ_SEQSUB) {
207 if (GetOutputFileName (path, sizeof (path), "")) {
208 ssp = (SeqSubmitPtr) parentptr;
209 if (ssp != NULL && ssp->datatype == 1) {
210 sep = (SeqEntryPtr) ssp->data;
211 ptr = StringRChr (path, DIRDELIMCHR);
212 if (ptr != NULL) {
213 ptr++;
214 StringNCpy_0 (file, ptr, sizeof (file));
215 *ptr = '\0';
216 tmp = bssp->seq_set;
217 count = 0;
218 while (tmp != NULL) {
219 next = tmp->next;
220 tmp->next = NULL;
221 ssp->data = (Pointer) tmp;
222 StringCpy (output, path);
223 count++;
224 if (count < 10) {
225 sprintf (str, "%s0%1d", file, (int) count);
226 } else {
227 sprintf (str, "%s%2d", file, (int) count);
228 }
229 FileBuildPath (output, NULL, str);
230 #ifdef WIN_MAC
231 f = FileOpen (output, "r");
232 if (f != NULL) {
233 FileClose (f);
234 } else {
235 FileCreate (output, "TEXT", "ttxt");
236 }
237 #endif
238 aip = AsnIoOpen (output, "w");
239 if (aip != NULL) {
240 SeqSubmitAsnWrite (ssp, aip, NULL);
241 }
242 AsnIoClose (aip);
243 tmp->next = next;
244 tmp = next;
245 }
246 ssp->data = (Pointer) sep;
247 }
248 }
249 }
250 }
251
252 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
253 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
254 Update ();
255 return OM_MSG_RET_DONE;
256 }
257
258 extern void ParseInNucUpdates (IteM i)
259
260 {
261 BaseFormPtr bfp;
262 SeqEntryPtr sep;
263
264 #ifdef WIN_MAC
265 bfp = currentFormDataPtr;
266 #else
267 bfp = GetObjectExtra (i);
268 #endif
269 if (bfp == NULL) return;
270 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
271 if (sep == NULL) return;
272 Message (MSG_OK, "Not yet implemented");
273 }
274
275 #undef NLM_EXTERN
276 #ifdef NLM_IMPORT
277 #define NLM_EXTERN NLM_IMPORT
278 #else
279 #define NLM_EXTERN extern
280 #endif
281
282 static Int2 GeneticCodeFromCrp (CdRegionPtr crp)
283
284 {
285 Int2 code;
286 GeneticCodePtr gcp;
287 Char name [256];
288 ValNodePtr tmp;
289
290 code = 0;
291 name [0] = '\0';
292 gcp = crp->genetic_code;
293 if (gcp != NULL) {
294 tmp = (ValNodePtr) gcp->data.ptrvalue;
295 for (tmp = (ValNodePtr) gcp->data.ptrvalue; tmp != NULL; tmp = tmp->next) {
296 switch (tmp->choice) {
297 case 1 :
298 if (name [0] == '\0') {
299 StringNCpy_0 (name, (CharPtr) tmp->data.ptrvalue, sizeof (name));
300 }
301 break;
302 case 2 :
303 code = tmp->data.intvalue;
304 break;
305 default :
306 break;
307 }
308 }
309 if (code == 0) {
310 gcp = GeneticCodeFind (code, name);
311 if (gcp != NULL) {
312 for (tmp = (ValNodePtr) gcp->data.ptrvalue; tmp != NULL; tmp = tmp->next) {
313 switch (tmp->choice) {
314 case 2 :
315 code = tmp->data.intvalue;
316 break;
317 default :
318 break;
319 }
320 }
321 }
322 }
323 }
324 return code;
325 }
326
327 extern void ExtendSeqLocToPosition (SeqLocPtr slp, Boolean end5, Int4 pos)
328 {
329 Uint1 strand;
330 SeqLocPtr slp_to_change, slp_index;
331 Int4 extent_to_change;
332 Int4 start, stop;
333 SeqIdPtr sip;
334 BioseqPtr bsp;
335
336 if (slp == NULL || pos < 0) return;
337
338 bsp = BioseqFindFromSeqLoc (slp);
339 if (bsp == NULL) return;
340
341 slp_to_change = NULL;
342 strand = SeqLocStrand (slp);
343 switch (slp->choice)
344 {
345 case SEQLOC_INT:
346 slp_to_change = slp;
347 break;
348 case SEQLOC_MIX:
349 case SEQLOC_PACKED_INT:
350 sip = SeqLocId (slp);
351 if (sip == NULL) return; /* can only process if all on one bioseq */
352 slp_to_change = NULL;
353 if ((strand == Seq_strand_minus && end5)
354 || (strand != Seq_strand_minus && !end5))
355 {
356 extent_to_change = 0;
357 for (slp_index = (SeqLocPtr)slp->data.ptrvalue; slp_index != NULL; slp_index = slp_index->next)
358 {
359 stop = GetOffsetInBioseq (slp_index, bsp, SEQLOC_STOP);
360 if (stop > extent_to_change)
361 {
362 slp_to_change = slp_index;
363 extent_to_change = stop;
364 }
365 }
366 }
367 else
368 {
369 extent_to_change = bsp->length;
370 for (slp_index = (SeqLocPtr)slp->data.ptrvalue; slp_index != NULL; slp_index = slp_index->next)
371 {
372 start = GetOffsetInBioseq (slp_index, bsp, SEQLOC_START);
373 if (start < extent_to_change)
374 {
375 slp_to_change = slp_index;
376 extent_to_change = start;
377 }
378 }
379 }
380 break;
381 }
382
383 if (slp_to_change != NULL)
384 {
385 if ((strand == Seq_strand_minus && end5)
386 || (strand != Seq_strand_minus && !end5))
387 {
388 start = GetOffsetInBioseq (slp_to_change, bsp, SEQLOC_START);
389 stop = pos;
390 }
391 else
392 {
393 start = pos;
394 stop = GetOffsetInBioseq (slp_to_change, bsp, SEQLOC_STOP);
395 }
396 if (start < 0
397 || stop > bsp->length - 1
398 || start > stop)
399 {
400 return;
401 }
402 expand_seq_loc (start, stop, strand, slp_to_change);
403 }
404 }
405
406
407 static void ExtendOnePartialFeatureExEx (SeqFeatPtr sfp, Boolean extend5, Boolean extend3, Boolean stop_at_gap)
408 {
409 BioseqPtr bsp;
410 Boolean partial3, partial5;
411 Int4 start_diff;
412 CdRegionPtr crp;
413
414 if (sfp == NULL) return;
415 bsp = BioseqFindFromSeqLoc (sfp->location);
416 if (bsp == NULL) return;
417 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
418 if (partial5 && extend5)
419 {
420 if (stop_at_gap) {
421 start_diff = ExtendSeqLocToEndOrGap (sfp->location, bsp, TRUE);
422 } else {
423 start_diff = ExtendSeqLocToEnd (sfp->location, bsp, TRUE);
424 }
425 if (start_diff > 0 && sfp->data.choice == SEQFEAT_CDREGION) {
426 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
427 if (crp != NULL) {
428 if (crp->frame == 0) {
429 crp->frame = 1;
430 }
431 crp->frame = (crp->frame + start_diff - 1) % 3 + 1;
432 }
433 }
434 }
435 if (partial3 && extend3)
436 {
437 if (stop_at_gap) {
438 ExtendSeqLocToEndOrGap (sfp->location, bsp, FALSE);
439 } else {
440 ExtendSeqLocToEnd (sfp->location, bsp, FALSE);
441 }
442 }
443 }
444
445
446 static void ExtendOnePartialFeatureEx (SeqFeatPtr sfp, Boolean extend5, Boolean extend3)
447 {
448 ExtendOnePartialFeatureExEx (sfp, extend5, extend3, FALSE);
449 }
450
451
452 static void ExtendOnePartialFeatureToEndOrGap (SeqFeatPtr sfp, Pointer userdata)
453 {
454 ExtendOnePartialFeatureExEx (sfp, TRUE, TRUE, TRUE);
455 }
456
457
458 static void ExtendOnePartialFeature (SeqFeatPtr sfp, Pointer userdata)
459 {
460 ExtendOnePartialFeatureEx (sfp, TRUE, TRUE);
461 }
462
463 extern void ExtendPartialFeatures (IteM i)
464 {
465 BaseFormPtr bfp;
466 SeqEntryPtr sep, old_scope;
467 SelStructPtr sel;
468 SeqFeatPtr sfp;
469 SeqMgrFeatContext fcontext;
470
471 #ifdef WIN_MAC
472 bfp = currentFormDataPtr;
473 #else
474 bfp = GetObjectExtra (i);
475 #endif
476 if (bfp == NULL) return;
477 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
478 if (sep == NULL) return;
479 sel = ObjMgrGetSelected ();
480 WatchCursor ();
481 Update ();
482 old_scope = SeqEntrySetScope(sep);
483 if (sel == NULL)
484 {
485 VisitFeaturesInSep (sep, NULL, ExtendOnePartialFeature);
486 }
487 else
488 {
489 while (sel != NULL)
490 {
491 if (sel->entityID == bfp->input_entityID
492 && sel->itemtype == OBJ_SEQFEAT)
493 {
494 sfp = SeqMgrGetDesiredFeature (bfp->input_entityID, NULL, sel->itemID, 0, NULL, &fcontext);
495 if (sfp != NULL)
496 {
497 ExtendOnePartialFeature (sfp, NULL);
498 }
499 }
500 sel = sel->next;
501 }
502 }
503 SeqEntrySetScope(old_scope);
504 ArrowCursor ();
505 Update ();
506 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
507 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
508 }
509
510
511 typedef struct extendpartialfeaturesform {
512 FORM_MESSAGE_BLOCK
513 DialoG feature_type;
514 ButtoN extend5;
515 ButtoN extend3;
516 ButtoN stop_at_gaps;
517 DialoG string_constraint;
518 ButtoN leave_dlg_up;
519 } ExtendPartialFeaturesFormData, PNTR ExtendPartialFeaturesFormPtr;
520
521 static void DoExtendPartialFeatures (ButtoN b)
522 {
523 ExtendPartialFeaturesFormPtr f;
524 SeqEntryPtr sep;
525 AECRActionPtr action;
526 ApplyActionPtr fake_apply;
527 FeatureFieldPtr feature_field;
528 ValNodePtr vnp;
529 StringConstraintPtr scp;
530 ValNodePtr object_list;
531 Boolean extend5, extend3, stop_at_gaps;
532
533 f = (ExtendPartialFeaturesFormPtr) GetObjectExtra (b);
534 if (f == NULL) return;
535
536 sep = GetTopSeqEntryForEntityID (f->input_entityID);
537 if (sep == NULL) return;
538
539 /* note - this is a small amount of hackery, designed to put off adding "extend partial features" as a macro language action.
540 * if this is ever added, this code should be moved to macroapi.c.
541 */
542 feature_field = FeatureFieldNew ();
543 vnp = DialogToPointer (f->feature_type);
544 if (vnp == NULL) {
545 feature_field->type = Feature_type_any;
546 } else {
547 feature_field->type = vnp->choice;
548 vnp = ValNodeFree (vnp);
549 }
550 fake_apply = ApplyActionNew ();
551 ValNodeAddPointer (&(fake_apply->field), FieldType_feature_field, feature_field);
552 action = AECRActionNew ();
553 ValNodeAddPointer (&(action->action), ActionChoice_apply, fake_apply);
554
555 scp = DialogToPointer (f->string_constraint);
556 if (scp != NULL) {
557 ValNodeAddPointer (&(action->constraint), ConstraintChoice_string, scp);
558 }
559 object_list = GetObjectListForAECRAction (sep, action);
560 action = AECRActionFree (action);
561
562 extend5 = GetStatus (f->extend5);
563 extend3 = GetStatus (f->extend3);
564 stop_at_gaps = GetStatus (f->stop_at_gaps);
565 for (vnp = object_list; vnp != NULL; vnp = vnp->next) {
566 if (vnp->choice == OBJ_SEQFEAT && vnp->data.ptrvalue != NULL) {
567 ExtendOnePartialFeatureExEx (vnp->data.ptrvalue, extend5, extend3, stop_at_gaps);
568 }
569 }
570 object_list = ValNodeFree (object_list);
571 ArrowCursor ();
572 Update ();
573 ObjMgrSetDirtyFlag (f->input_entityID, TRUE);
574 ObjMgrSendMsg (OM_MSG_UPDATE, f->input_entityID, 0, 0);
575 if (!GetStatus (f->leave_dlg_up)) {
576 Remove (f->form);
577 }
578 }
579
580
581 extern void ExtendPartialFeaturesWithConstraint (IteM i)
582 {
583 BaseFormPtr bfp;
584 ExtendPartialFeaturesFormPtr f;
585 ValNodePtr feature_list = NULL;
586 ValNode vn;
587 WindoW w;
588 GrouP h, g, c;
589 PrompT p1, p2;
590 ButtoN b;
591
592 #ifdef WIN_MAC
593 bfp = currentFormDataPtr;
594 #else
595 bfp = GetObjectExtra (i);
596 #endif
597 if (bfp == NULL) return;
598
599 f = (ExtendPartialFeaturesFormPtr) MemNew (sizeof (ExtendPartialFeaturesFormData));
600 if (f == NULL) return;
601
602 w = FixedWindow (-50, -33, -10, -10, "Extend Partial Features", StdCloseWindowProc);
603 SetObjectExtra (w, f, StdCleanupExtraProc);
604 f->form = (ForM) w;
605 f->input_entityID = bfp->input_entityID;
606
607 h = HiddenGroup (w, -1, 0, NULL);
608 SetGroupSpacing (h, 10, 10);
609
610 p1 = StaticPrompt (h, "Feature Type to Extend", 0, dialogTextHeight, programFont, 'c');
611 ValNodeAddPointer (&feature_list, Feature_type_any, StringSave ("Any"));
612 AddAllFeaturesToChoiceList (&feature_list);
613
614 f->feature_type = ValNodeSelectionDialog (h, feature_list, TALL_SELECTION_LIST, ValNodeStringName,
615 ValNodeSimpleDataFree, ValNodeStringCopy,
616 ValNodeChoiceMatch, "feature type",
617 NULL, NULL, FALSE);
618 vn.choice = Feature_type_any;
619 vn.data.ptrvalue = NULL;
620 vn.next = NULL;
621 PointerToDialog (f->feature_type, &vn);
622
623 g = HiddenGroup (h, 2, 0, NULL);
624 f->extend5 = CheckBox (g, "Extend partial 5'", NULL);
625 SetStatus (f->extend5, TRUE);
626 f->extend3 = CheckBox (g, "Extend partial 3'", NULL);
627 SetStatus (f->extend3, TRUE);
628
629 f->stop_at_gaps = CheckBox (h, "Stop at gaps", NULL);
630 SetStatus (f->stop_at_gaps, TRUE);
631
632 p2 = StaticPrompt (h, "Optional Constraint", 0, dialogTextHeight, programFont, 'c');
633 f->string_constraint = StringConstraintDialog (h, "Where feature text", FALSE, NULL, NULL);
634
635 c = HiddenGroup (h, 3, 0, NULL);
636 b = PushButton (c, "Accept", DoExtendPartialFeatures);
637 SetObjectExtra (b, f, NULL);
638 PushButton (c, "Cancel", StdCancelButtonProc);
639 f->leave_dlg_up = CheckBox (c, "Leave Dialog Up", NULL);
640
641 AlignObjects (ALIGN_CENTER, (HANDLE) p1,
642 (HANDLE) f->feature_type,
643 (HANDLE) g,
644 (HANDLE) f->stop_at_gaps,
645 (HANDLE) p2,
646 (HANDLE) f->string_constraint,
647 (HANDLE) c,
648 NULL);
649 Show (w);
650 }
651
652
653 static Boolean HasValidStartCodon (SeqFeatPtr cds)
654 {
655 ByteStorePtr bs;
656 CharPtr prot;
657
658 if (cds == NULL) return FALSE;
659
660 bs = ProteinFromCdRegionEx (cds, TRUE, FALSE);
661
662 if (bs == NULL) return FALSE;
663 prot = BSMerge (bs, NULL);
664 bs = BSFree (bs);
665 if (prot == NULL) return FALSE;
666 if (prot [0] != 'M') return FALSE;
667 return TRUE;
668 }
669
670 static void FixReadingFrame (
671 CdRegionPtr crp,
672 SeqLocPtr slp,
673 BioseqPtr bsp,
674 Int4 start
675 )
676 {
677 Int4 offset;
678
679 if (crp == NULL || slp == NULL) return;
680
681 if (SeqLocStrand (slp) == Seq_strand_minus)
682 {
683 offset = bsp->length - start;
684 }
685 else
686 {
687 offset = start;
688 }
689 start = offset % 3;
690 start = start + 1;
691 crp->frame = start;
692 }
693
694 extern void RecomputeSuggestedIntervalsForCDS
695 (Uint2 entityID,
696 BioseqPtr PNTR batchbsp,
697 Int4Ptr count,
698 MonitorPtr mon,
699 SeqFeatPtr sfp)
700 {
701 Int2 code;
702 CdRegionPtr crp;
703 BioseqPtr nucbsp;
704 BioseqPtr protbsp;
705 SeqIdPtr sip;
706 SeqLocPtr slp;
707 Char str [256];
708 Char tmp [256];
709 Boolean partial3, partial5;
710
711 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return;
712 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
713 if (crp == NULL) return;
714
715 code = GeneticCodeFromCrp (crp);
716
717 nucbsp = GetBioseqGivenSeqLoc (sfp->location, entityID);
718 if (nucbsp != NULL && batchbsp != NULL && *batchbsp != NULL
719 && nucbsp != *batchbsp) {
720 ClearBatchSuggestNucleotide ();
721 *batchbsp = nucbsp;
722 SetBatchSuggestNucleotide (*batchbsp, code);
723 /* Message (MSG_POSTERR, "Recompute Suggest is reverting to slower processing"); */
724 }
725 sip = SeqLocId (sfp->product);
726 if (sip != NULL) {
727 protbsp = BioseqFind (sip);
728 if (nucbsp != NULL && protbsp != NULL &&
729 ISA_na (nucbsp->mol) && ISA_aa (protbsp->mol) &&
730 nucbsp->length > 0 && protbsp->length > 0) {
731 str [0] = '\0';
732 tmp [0] = '\0';
733 sip = SeqIdFindWorst (protbsp->id);
734 SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
735 if (count != NULL)
736 {
737 (*count) ++;
738 if (mon != NULL)
739 {
740 sprintf (str, "Processing sequence %d [%s]", *count, tmp);
741 MonitorStrValue (mon, str);
742 Update ();
743 }
744 }
745 slp = PredictCodingRegion (nucbsp, protbsp, code);
746 if (slp == NULL) return;
747
748 /* correct for partial conditions */
749 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
750
751 sfp->location = SeqLocFree (sfp->location);
752 sfp->location = slp;
753
754 /* if no valid start codon, cds is 5' partial */
755 if (! HasValidStartCodon (sfp))
756 {
757 partial5 = TRUE;
758 }
759
760 if (partial5 || partial3)
761 {
762 #if 0
763 /* removed, per DeAnne's request */
764 if (partial5)
765 {
766 start = GetOffsetInBioseq (sfp->location, nucbsp, SEQLOC_START);
767 FixReadingFrame (crp, sfp->location, nucbsp, start);
768 ExtendSeqLocToEnd (sfp->location, nucbsp, TRUE);
769 }
770 #endif
771 if (partial3)
772 {
773 ExtendSeqLocToEnd (sfp->location, nucbsp, FALSE);
774 }
775 SetSeqLocPartial (sfp->location, partial5, partial3);
776 }
777 sfp->partial = LocationHasNullsBetween (sfp->location);
778 sfp->partial |= partial5 || partial3;
779 }
780 }
781 }
782
783 extern void RecomputeIntervalsForOneCDS (SeqFeatPtr sfp, RecompDataPtr rdp)
784 {
785 SeqFeatPtr gene_to_update = NULL;
786 SeqLocPtr orig_loc = NULL;
787
788 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION || rdp == NULL)
789 {
790 return;
791 }
792
793 if (rdp->fix_genes)
794 {
795 gene_to_update = SeqMgrGetOverlappingGene (sfp->location, NULL);
796 orig_loc = (SeqLocPtr) AsnIoMemCopy (sfp->location,
797 (AsnReadFunc) SeqLocAsnRead,
798 (AsnWriteFunc) SeqLocAsnWrite);
799 }
800 RecomputeSuggestedIntervalsForCDS (rdp->entityID, &(rdp->batchbsp),
801 &(rdp->count), rdp->mon, sfp);
802
803 if (gene_to_update != NULL)
804 {
805 UpdateGeneLocation (gene_to_update, orig_loc,
806 sfp->location, rdp->entityID);
807 }
808 orig_loc = SeqLocFree (orig_loc);
809
810 }
811
812 static Boolean RecomputeSuggCallback (GatherContextPtr gcp)
813 {
814 RecompDataPtr rdp;
815 SeqFeatPtr sfp;
816
817 if (gcp == NULL) return TRUE;
818 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
819 rdp = (RecompDataPtr) gcp->userdata;
820 if (rdp == NULL) return TRUE;
821 sfp = (SeqFeatPtr) gcp->thisitem;
822 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION) return TRUE;
823
824 RecomputeIntervalsForOneCDS (sfp, rdp);
825 return TRUE;
826 }
827
828 extern void RecomputeSuggestEx (Uint2 entityID, Boolean fix_genes, Boolean recompute_all)
829
830 {
831 Int2 code;
832 GatherScope gs;
833 SeqEntryPtr nucsep;
834 RecompData rd;
835 SeqEntryPtr sep;
836 SelStructPtr sel;
837 SeqFeatPtr sfp;
838 SeqMgrFeatContext fcontext;
839
840 sep = GetTopSeqEntryForEntityID (entityID);
841 if (sep == NULL) return;
842 sel = ObjMgrGetSelected ();
843 WatchCursor ();
844 Update ();
845 rd.count = 0;
846 rd.mon = MonitorStrNewEx ("Correcting Coding Regions", 20, FALSE);
847 rd.batchbsp = NULL;
848 rd.no_stop_at_end_of_complete_cds = FALSE;
849 rd.fix_genes = fix_genes;
850 rd.entityID = entityID;
851 nucsep = FindNucSeqEntry (sep);
852 if (nucsep != NULL && IS_Bioseq (nucsep)) {
853 rd.batchbsp = (BioseqPtr) nucsep->data.ptrvalue;
854 }
855 if (rd.batchbsp != NULL) {
856 code = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
857 SetBatchSuggestNucleotide (rd.batchbsp, code);
858 }
859 if (sel == NULL || recompute_all)
860 {
861 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
862 gs.seglevels = 1;
863 gs.get_feats_location = FALSE;
864 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
865 gs.ignore[OBJ_BIOSEQ] = FALSE;
866 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
867 gs.ignore[OBJ_SEQFEAT] = FALSE;
868 gs.ignore[OBJ_SEQANNOT] = FALSE;
869 GatherEntity (entityID, (Pointer) (&rd), RecomputeSuggCallback, &gs);
870 }
871 else
872 {
873 while (sel != NULL)
874 {
875 if (sel->entityID == entityID
876 && sel->itemtype == OBJ_SEQFEAT)
877 {
878 sfp = SeqMgrGetDesiredFeature (entityID, NULL, sel->itemID, 0, NULL, &fcontext);
879 if (sfp != NULL && sfp->idx.subtype == FEATDEF_CDS)
880 {
881 RecomputeIntervalsForOneCDS (sfp, &rd);
882 }
883 }
884 sel = sel->next;
885 }
886 }
887 MonitorFree (rd.mon);
888 if (rd.batchbsp != NULL) {
889 ClearBatchSuggestNucleotide ();
890 }
891 ArrowCursor ();
892 Update ();
893 ObjMgrSetDirtyFlag (entityID, TRUE);
894 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
895 }
896
897 extern void RecomputeSuggest (IteM i)
898 {
899 BaseFormPtr bfp;
900
901 #ifdef WIN_MAC
902 bfp = currentFormDataPtr;
903 #else
904 bfp = GetObjectExtra (i);
905 #endif
906 if (bfp == NULL)
907 {
908 return;
909 }
910 RecomputeSuggestEx (bfp->input_entityID, FALSE, FALSE);
911 }
912
913 extern void RecomputeSuggestFixGenes (IteM i)
914 {
915 BaseFormPtr bfp;
916
917 #ifdef WIN_MAC
918 bfp = currentFormDataPtr;
919 #else
920 bfp = GetObjectExtra (i);
921 #endif
922 if (bfp == NULL)
923 {
924 return;
925 }
926 RecomputeSuggestEx (bfp->input_entityID, TRUE, FALSE);
927 }
928
929
930 static Boolean RetranslateCDSCallback (GatherContextPtr gcp)
931
932 {
933 RecompDataPtr rdp;
934 SeqFeatPtr sfp;
935
936 if (gcp == NULL) return TRUE;
937 if (gcp->thistype != OBJ_SEQFEAT) return TRUE;
938 rdp = (RecompDataPtr) gcp->userdata;
939 if (rdp == NULL) return TRUE;
940 sfp = (SeqFeatPtr) gcp->thisitem;
941 return RetranslateOneCDS (sfp, gcp->entityID, rdp->include_stop,
942 rdp->no_stop_at_end_of_complete_cds);
943 }
944
945 extern void RetranslateCdRegionsEx (
946 Uint2 entityID,
947 Boolean include_stop,
948 Boolean no_stop_at_end_of_complete_cds )
949
950 {
951 GatherScope gs;
952 RecompData rd;
953 SeqEntryPtr sep;
954
955 sep = GetTopSeqEntryForEntityID (entityID);
956 if (sep == NULL) return;
957 WatchCursor ();
958 Update ();
959 rd.count = 0;
960 rd.mon = MonitorStrNewEx ("Correcting Coding Regions", 20, FALSE);
961 rd.include_stop = include_stop;
962 rd.no_stop_at_end_of_complete_cds = no_stop_at_end_of_complete_cds;
963 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
964 gs.seglevels = 1;
965 gs.get_feats_location = FALSE;
966 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
967 gs.ignore[OBJ_BIOSEQ] = FALSE;
968 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
969 gs.ignore[OBJ_SEQFEAT] = FALSE;
970 gs.ignore[OBJ_SEQANNOT] = FALSE;
971 GatherEntity (entityID, (Pointer) (&rd), RetranslateCDSCallback, &gs);
972 MonitorFree (rd.mon);
973 ArrowCursor ();
974 Update ();
975 ObjMgrSetDirtyFlag (entityID, TRUE);
976 ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
977 }
978
979 static void RetranslateCdRegions (
980 IteM i,
981 Boolean include_stop,
982 Boolean no_stop_at_end_of_complete_cds )
983
984 {
985 BaseFormPtr bfp;
986
987 #ifdef WIN_MAC
988 bfp = currentFormDataPtr;
989 #else
990 bfp = GetObjectExtra (i);
991 #endif
992 if (bfp == NULL) return;
993 RetranslateCdRegionsEx (bfp->input_entityID, include_stop, no_stop_at_end_of_complete_cds);
994 }
995
996 extern void RetranslateCdRegionsNoStop (IteM i)
997
998 {
999 RetranslateCdRegions (i, FALSE, FALSE);
1000 }
1001
1002 extern void RetranslateCdRegionsDoStop (IteM i)
1003
1004 {
1005 RetranslateCdRegions (i, TRUE, FALSE);
1006 }
1007
1008 extern void RetranslateCdRegionsNoStopExceptEndCompleteCDS (IteM i)
1009 {
1010 RetranslateCdRegions (i, TRUE, TRUE);
1011 }
1012
1013
1014 static void DoReprocessPeptides (SeqFeatPtr sfp, Pointer userdata)
1015
1016 {
1017 SeqFeatPtr bestprot;
1018 ByteStorePtr bs;
1019 BioseqPtr bsp;
1020 Char ch;
1021 MolInfoPtr mip;
1022 Boolean partial5;
1023 Boolean partial3;
1024 CharPtr prot;
1025 ProtRefPtr prp;
1026 CharPtr ptr;
1027 SeqEntryPtr sep;
1028 SeqIdPtr sip;
1029 ValNodePtr vnp;
1030
1031 if (sfp->data.choice != SEQFEAT_PROT) return;
1032 if (sfp->product == NULL) return;
1033 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
1034 if (prp == NULL) return;
1035 if (prp->processed < 1 || prp->processed > 4) return;
1036 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
1037 sip = SeqLocId (sfp->product);
1038 if (sip == NULL) return;
1039 bsp = BioseqFind (sip);
1040 if (bsp != NULL && ISA_aa (bsp->mol) && bsp->repr == Seq_repr_raw) {
1041 bestprot = FindBestProtein (sfp->idx.entityID, sfp->product);
1042 prot = GetSequenceByFeature (sfp);
1043 if (prot == NULL) return;
1044 ptr = prot;
1045 ch = *ptr;
1046 while (ch != '\0') {
1047 *ptr = TO_UPPER (ch);
1048 ptr++;
1049 ch = *ptr;
1050 }
1051 bs = BSNew (1000);
1052 if (bs != NULL) {
1053 ptr = prot;
1054 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
1055 }
1056 bsp->repr = Seq_repr_raw;
1057 bsp->mol = Seq_mol_aa;
1058 bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
1059 bsp->seq_data = (SeqDataPtr) bs;
1060 bsp->seq_data_type = Seq_code_ncbieaa;
1061 bsp->length = BSLen (bs);
1062 sep = SeqMgrGetSeqEntryForData (bsp);
1063 if (sep == NULL) return;
1064 if (bestprot != NULL) {
1065 bestprot->location = SeqLocFree (bestprot->location);
1066 bestprot->location = CreateWholeInterval (sep);
1067 SetSeqLocPartial (bestprot->location, partial5, partial3);
1068 bestprot->partial = (partial5 || partial3);
1069 }
1070 vnp = SeqEntryGetSeqDescr (sep, Seq_descr_molinfo, NULL);
1071 if (vnp == NULL) {
1072 vnp = CreateNewDescriptor (sep, Seq_descr_molinfo);
1073 if (vnp != NULL) {
1074 mip = MolInfoNew ();
1075 vnp->data.ptrvalue = (Pointer) mip;
1076 if (mip != NULL) {
1077 mip->biomol = 8;
1078 mip->tech = 13;
1079 }
1080 }
1081 }
1082 if (vnp != NULL) {
1083 mip = (MolInfoPtr) vnp->data.ptrvalue;
1084 if (mip != NULL) {
1085 if (partial5 && partial3) {
1086 mip->completeness = 5;
1087 } else if (partial5) {
1088 mip->completeness = 3;
1089 } else if (partial3) {
1090 mip->completeness = 4;
1091 /*
1092 } else if (partial) {
1093 mip->completeness = 2;
1094 */
1095 } else {
1096 mip->completeness = 0;
1097 }
1098 }
1099 }
1100 }
1101 }
1102
1103 extern void ReprocessPeptideProducts (IteM i);
1104 extern void ReprocessPeptideProducts (IteM i)
1105
1106 {
1107 BaseFormPtr bfp;
1108 SeqEntryPtr sep;
1109
1110 #ifdef WIN_MAC
1111 bfp = currentFormDataPtr;
1112 #else
1113 bfp = GetObjectExtra (i);
1114 #endif
1115 if (bfp == NULL) return;
1116 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1117 if (sep == NULL) return;
1118 VisitFeaturesInSep (sep, NULL, DoReprocessPeptides);
1119 Update ();
1120 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1121 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1122 }
1123
1124 static void DoReprocessMrnas (SeqFeatPtr sfp, Pointer userdata)
1125
1126 {
1127 ByteStorePtr bs;
1128 BioseqPtr bsp;
1129 Char ch;
1130 MolInfoPtr mip;
1131 Boolean partial5;
1132 Boolean partial3;
1133 CharPtr prot;
1134 CharPtr ptr;
1135 RnaRefPtr rrp;
1136 SeqEntryPtr sep;
1137 SeqIdPtr sip;
1138 ValNodePtr vnp;
1139
1140 if (sfp->data.choice != SEQFEAT_RNA) return;
1141 if (sfp->product == NULL) return;
1142 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
1143 if (rrp == NULL) return;
1144 if (rrp->type != 2) return;
1145 CheckSeqLocForPartial (sfp->location, &partial5, &partial3);
1146 sip = SeqLocId (sfp->product);
1147 if (sip == NULL) return;
1148 bsp = BioseqFind (sip);
1149 if (bsp != NULL && ISA_na (bsp->mol) && bsp->repr == Seq_repr_raw) {
1150 prot = GetSequenceByFeature (sfp);
1151 if (prot == NULL) return;
1152 ptr = prot;
1153 ch = *ptr;
1154 while (ch != '\0') {
1155 *ptr = TO_UPPER (ch);
1156 ptr++;
1157 ch = *ptr;
1158 }
1159 bs = BSNew (1000);
1160 if (bs != NULL) {
1161 ptr = prot;
1162 BSWrite (bs, (VoidPtr) ptr, (Int4) StringLen (ptr));
1163 }
1164 bsp->repr = Seq_repr_raw;
1165 bsp->mol = Seq_mol_na;
1166 bsp->seq_data = SeqDataFree (bsp->seq_data, bsp->seq_data_type);
1167 bsp->seq_data = (SeqDataPtr) bs;
1168 bsp->seq_data_type = Seq_code_iupacna;
1169 bsp->length = BSLen (bs);
1170 sep = SeqMgrGetSeqEntryForData (bsp);
1171 if (sep == NULL) return;
1172 vnp = SeqEntryGetSeqDescr (sep, Seq_descr_molinfo, NULL);
1173 if (vnp == NULL) {
1174 vnp = CreateNewDescriptor (sep, Seq_descr_molinfo);
1175 if (vnp != NULL) {
1176 mip = MolInfoNew ();
1177 vnp->data.ptrvalue = (Pointer) mip;
1178 if (mip != NULL) {
1179 mip->biomol = 8;
1180 mip->tech = 13;
1181 }
1182 }
1183 }
1184 if (vnp != NULL) {
1185 mip = (MolInfoPtr) vnp->data.ptrvalue;
1186 if (mip != NULL) {
1187 if (partial5 && partial3) {
1188 mip->completeness = 5;
1189 } else if (partial5) {
1190 mip->completeness = 3;
1191 } else if (partial3) {
1192 mip->completeness = 4;
1193 /*
1194 } else if (partial) {
1195 mip->completeness = 2;
1196 */
1197 } else {
1198 mip->completeness = 0;
1199 }
1200 }
1201 }
1202 }
1203 }
1204
1205 extern void ReprocessmRNAProducts (IteM i);
1206 extern void ReprocessmRNAProducts (IteM i)
1207
1208 {
1209 BaseFormPtr bfp;
1210 SeqEntryPtr sep;
1211
1212 #ifdef WIN_MAC
1213 bfp = currentFormDataPtr;
1214 #else
1215 bfp = GetObjectExtra (i);
1216 #endif
1217 if (bfp == NULL) return;
1218 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1219 if (sep == NULL) return;
1220 VisitFeaturesInSep (sep, NULL, DoReprocessMrnas);
1221 Update ();
1222 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1223 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1224 }
1225
1226 /*
1227 * ApplyCodeBreakToCDS
1228 */
1229
1230 static Boolean ApplyCodeBreakToCDS (SeqFeatPtr sfp, CharPtr codonStr, Uint1 aaNum)
1231 {
1232 Uint1 aaChar;
1233 SeqLocPtr aaSlp;
1234 Int4 aaPosition;
1235 SeqPntPtr aaSpp;
1236 CharPtr basePtr;
1237 CharPtr bases;
1238 CodeBreakPtr cbp;
1239 CdRegionPtr crp;
1240 Int4 dnaLen;
1241 SeqLocPtr dnaSlp;
1242 CodeBreakPtr lastCbp;
1243 SeqCodeTablePtr sctp;
1244 Int4 total;
1245 Boolean added_code_breaks = FALSE;
1246
1247 if (sfp == NULL || codonStr == NULL)
1248 {
1249 return FALSE;
1250 }
1251
1252 /* Get the nucleotide sequence */
1253
1254 dnaLen = SeqLocLen (sfp->location);
1255 if (dnaLen < 1)
1256 return FALSE;
1257
1258 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
1259
1260 bases = ReadCodingRegionBases (sfp->location, dnaLen, crp->frame, &total);
1261
1262 /* Search for the selected codon in the */
1263 /* nucleotide sequence. If found, add */
1264 /* it as a codebreak. */
1265
1266 basePtr = bases;
1267 aaPosition = 0;
1268 while (basePtr[0] != '\0') {
1269 if (StringNCmp (basePtr, codonStr, 3) == 0) {
1270
1271 /* Create a new seq point object with the aa location */
1272
1273 aaSpp = SeqPntNew ();
1274 aaSpp->point = aaPosition;
1275 aaSpp->strand = Seq_strand_plus;
1276 aaSpp->id = SeqLocId (sfp->product);
1277 aaSpp->fuzz = NULL;
1278
1279 /* Make a SeqLoc using the seq point */
1280
1281 aaSlp = (SeqLocPtr) ValNodeNew (NULL);
1282 aaSlp->choice = SEQLOC_PNT;
1283 aaSlp->data.ptrvalue = (Pointer) aaSpp;
1284
1285 /* Convert the seqloc to a DNA location */
1286
1287 dnaSlp = aaLoc_to_dnaLoc (sfp, aaSlp);
1288
1289 /* Create the code break using the DNA location */
1290
1291 cbp = CodeBreakNew ();
1292 cbp->loc = dnaSlp;
1293 sctp = SeqCodeTableFind (Seq_code_ncbieaa);
1294 aaChar = (Uint1) GetSymbolForResidue (sctp, aaNum);
1295 cbp->aa.value.intvalue = aaChar;
1296 cbp->aa.choice = 1; /* ncbieaa */
1297
1298 /* Insert the code break into the CDS's */
1299 /* existing list of code breaks. */
1300
1301 lastCbp = crp->code_break;
1302 if (lastCbp == NULL)
1303 {
1304 crp->code_break = cbp;
1305 }
1306 else
1307 {
1308 while (lastCbp->next != NULL)
1309 {
1310 lastCbp = lastCbp->next;
1311 }
1312 lastCbp->next = cbp;
1313 cbp->next = NULL;
1314 }
1315
1316 added_code_breaks = TRUE;
1317 }
1318 basePtr += 3;
1319 aaPosition++;
1320 }
1321
1322 return added_code_breaks;
1323 }
1324
1325 /*---------------------------------------------------------------------*/
1326 /* */
1327 /* ApplyCodeBreak_FeatureCallback () -- Called for each CDS feature in */
1328 /* a Bioseq. Checks for any */
1329 /* nucleotide triplets that match */
1330 /* the one in the given code */
1331 /* break and sets a code break */
1332 /* for each one that is found. */
1333 /* */
1334 /*---------------------------------------------------------------------*/
1335
1336 static Boolean LIBCALLBACK ApplyCodeBreak_FeatureCallback (SeqFeatPtr sfp,
1337 SeqMgrFeatContextPtr fcontext)
1338 {
1339 Uint1 aaNum;
1340 CodeBreakFormPtr cbfp;
1341 Char codonStr [4];
1342 Int2 i;
1343
1344 cbfp = (CodeBreakFormPtr) fcontext->userdata;
1345
1346
1347 /* Get the selected Amino Acid and codon triplet */
1348
1349 GetTitle (cbfp->codonText, codonStr, sizeof (codonStr));
1350 for (i = 0; i < 3; i++)
1351 codonStr [i] = TO_UPPER (codonStr [i]);
1352
1353 aaNum = (Uint1) GetValue (cbfp->aminoAcidPopup);
1354 aaNum += 63;
1355
1356 /*
1357 if (aaNum >= 74)
1358 {
1359 aaNum++;
1360 }
1361 if (aaNum >= 79)
1362 {
1363 aaNum++;
1364 }
1365 */
1366
1367 if (ApplyCodeBreakToCDS (sfp, codonStr, aaNum))
1368 {
1369 /* Retranslate the CDS */
1370
1371 RetranslateOneCDS (sfp, fcontext->entityID, TRUE, FALSE);
1372
1373 }
1374
1375 /* Return TRUE to continue on to the next CDS feature */
1376
1377 return TRUE;
1378 }
1379
1380 /*---------------------------------------------------------------------*/
1381 /* */
1382 /* ApplyCodeBreak_BioseqCallback () -- Called by SeqMgrExploreBioseqs */
1383 /* for each Bioseq. Searches the */
1384 /* Bioseq for CDS features and adds*/
1385 /* the given code break to any */
1386 /* found. */
1387 /* */
1388 /*---------------------------------------------------------------------*/
1389
1390 static Boolean LIBCALLBACK ApplyCodeBreak_BioseqCallback (BioseqPtr bsp,
1391 SeqMgrBioseqContextPtr bcontext)
1392 {
1393 Boolean featureFilterArray [SEQFEAT_MAX];
1394
1395 /* Set up to explore only CDS features */
1396
1397 MemSet ((Pointer) (featureFilterArray),
1398 (int) FALSE,
1399 SEQFEAT_MAX);
1400
1401 featureFilterArray[SEQFEAT_CDREGION] = TRUE;
1402
1403 /* Explore the Bioseq's CDS features, marking the */
1404 /* ones with internal stop codons as pseudo. */
1405
1406 SeqMgrExploreFeatures (bsp, bcontext->userdata,
1407 ApplyCodeBreak_FeatureCallback, NULL,
1408 featureFilterArray, NULL);
1409
1410 /* Return TRUE to continue on to the next Bioseq */
1411
1412 return TRUE;
1413 }
1414
1415 /*---------------------------------------------------------------------*/
1416 /* */
1417 /* DoAddCodeBreak_Callback () -- Called when the 'Apply' button is */
1418 /* pressed in the "Add Code Break" */
1419 /* window. Adds the entered code break */
1420 /* to all CDS features. */
1421 /* */
1422 /*---------------------------------------------------------------------*/
1423
1424 static void DoAddCodeBreak_Callback (ButtoN b)
1425 {
1426 CodeBreakFormPtr cbfp;
1427
1428 cbfp = (CodeBreakFormPtr) GetObjectExtra (b);
1429
1430 /* Change to the "working" cursor */
1431
1432 Hide (cbfp->form);
1433 WatchCursor ();
1434 Update ();
1435
1436 /* Visit all the Bioseqs, where we will */
1437 /* then explore their CDS features. */
1438
1439 SeqMgrExploreBioseqs (cbfp->input_entityID, NULL, (Pointer) cbfp,
1440 ApplyCodeBreak_BioseqCallback, TRUE, FALSE, TRUE);
1441
1442 /* Restore the cursor and force an update */
1443
1444 ArrowCursor ();
1445 Update ();
1446 ObjMgrSetDirtyFlag (cbfp->input_entityID, TRUE);
1447 ObjMgrSendMsg (OM_MSG_UPDATE, cbfp->input_entityID, 0, 0);
1448 Remove (cbfp->form);
1449 }
1450
1451 /*---------------------------------------------------------------------*/
1452 /* */
1453 /* PopulateAAPopup () -- Creates a popup list of amino acids. */
1454 /* */
1455 /* NOTE : This function is identical to (and identically named as) */
1456 /* a function in cdrgn.c */
1457 /* */
1458 /*---------------------------------------------------------------------*/
1459
1460 static void PopulateAAPopup (PopuP AAitem)
1461
1462 {
1463 Char ch;
1464 Uint1 first;
1465 Uint1 i;
1466 Char item [77];
1467 Uint1 last;
1468 SeqCodeTablePtr sctp;
1469 CharPtr str;
1470
1471 sctp = SeqCodeTableFind (Seq_code_ncbieaa);
1472 first = FirstResidueInCode (sctp);
1473 last = LastResidueInCode (sctp);
1474 PopupItem (AAitem, " ");
1475 for (i = 65; i <= last; i++) {
1476 /*
1477 if (i == 74 || i == 79) {
1478 continue;
1479 }
1480 */
1481 ch = GetSymbolForResidue (sctp, i);
1482 str = (CharPtr) GetNameForResidue (sctp, i);
1483 sprintf (item, "%c %s", ch, str);
1484 PopupItem (AAitem, item);
1485 }
1486 SetValue (AAitem, 1);
1487 }
1488
1489 /*---------------------------------------------------------------------*/
1490 /* */
1491 /* IsLegalCodon () - Determines if a three base string is a legal */
1492 /* codon. */
1493 /* */
1494 /*---------------------------------------------------------------------*/
1495
1496 static Boolean IsLegalCodon (CharPtr codonStr)
1497 {
1498 Int2 i;
1499 Char baseChar;
1500
1501 /* Only allow three characters */
1502
1503 if (StringLen (codonStr) > 3)
1504 return FALSE;
1505
1506 /* Allow only the character A,C,G,T,U and */
1507 /* convert the U to a T. */
1508
1509 i = 0;
1510 while (i < 3) {
1511
1512 if (codonStr [i] == '\0')
1513 break;
1514
1515 baseChar = codonStr [i];
1516
1517 if (StringChr ("acgtuACGTU", baseChar) == NULL)
1518 return FALSE;
1519 if ('U' == baseChar)
1520 codonStr [i] = 'T';
1521 else if ('u' == baseChar)
1522 codonStr [i] = 't';
1523
1524 i++;
1525 }
1526
1527 /* If we made it this far, it's a valid codon */
1528
1529 return TRUE;
1530 }
1531
1532 /*---------------------------------------------------------------------*/
1533 /* */
1534 /* CodonText_Callback () -- Called whenever a keystoke is entered in */
1535 /* Codon text field. Validates to see if the */
1536 /* keystroke should be allowed. */
1537 /* */
1538 /*---------------------------------------------------------------------*/
1539
1540 static void CodonText_Callback (TexT codonText)
1541
1542 {
1543 CodeBreakFormPtr cbfp;
1544 Int2 aaNum;
1545 Char newCodonStr [5];
1546
1547 /* Get the currect code break data */
1548
1549 cbfp = (CodeBreakFormPtr) GetObjectExtra (codonText);
1550 if (cbfp == NULL)
1551 return;
1552
1553 /* If the new codon string is not legal */
1554 /* then reset to the previous text. */
1555
1556 GetTitle (codonText, newCodonStr, sizeof (newCodonStr));
1557
1558 if (!IsLegalCodon (newCodonStr))
1559 StringCpy (newCodonStr, cbfp->currentCodonStr);
1560 else
1561 StringCpy (cbfp->currentCodonStr, newCodonStr);
1562
1563 SafeSetTitle (cbfp->codonText, newCodonStr);
1564
1565 /* Only enable the accept button if */
1566 /* we have a full codon. */
1567
1568 if (StringLen (newCodonStr) != 3) {
1569 SafeDisable (cbfp->acceptButton);
1570 return;
1571 }
1572
1573 /* See if an amino acid has been selected yet */
1574
1575 aaNum = GetValue (cbfp->aminoAcidPopup);
1576 if (aaNum <= 1) {
1577 SafeDisable (cbfp->acceptButton);
1578 return;
1579 }
1580
1581 /* If we made it this far then we have both a codon and */
1582 /* an amino acid, so enable the accept button. */
1583
1584 SafeEnable (cbfp->acceptButton);
1585 }
1586
1587 /*---------------------------------------------------------------------*/
1588 /* */
1589 /* SelectAminoAcid_Callback () -- Called whenever a new amino acid is */
1590 /* selected in the Amino Acid Popup. */
1591 /* Toggles 'Accept' button base on */
1592 /* current state. */
1593 /* */
1594 /*---------------------------------------------------------------------*/
1595
1596 static void SelectAminoAcid_Callback (PopuP p)
1597 {
1598 CodeBreakFormPtr cbfp;
1599 Char codonStr [4];
1600 Int2 aaNum;
1601
1602 /* Get the currect code break data */
1603
1604 cbfp = (CodeBreakFormPtr) GetObjectExtra (p);
1605 if (cbfp == NULL)
1606 return;
1607
1608 /* Only enable the accept button if */
1609 /* we have a full codon. */
1610
1611 GetTitle (cbfp->codonText, codonStr, sizeof (codonStr));
1612 if (StringLen (codonStr) != 3) {
1613 SafeDisable (cbfp->acceptButton);
1614 return;
1615 }
1616
1617 /* Get the newly selected amino acid */
1618
1619 aaNum = GetValue (cbfp->aminoAcidPopup);
1620
1621 /* If an amino acid is selected then */
1622 /* enable the accept button. */
1623
1624 if (aaNum > 1)
1625 SafeEnable (cbfp->acceptButton);
1626 else
1627 SafeDisable (cbfp->acceptButton);
1628 }
1629
1630 /*---------------------------------------------------------------------*/
1631 /* */
1632 /* AddGlobalCodeBreak () -- Gets a nucleotide triplet and an amino */
1633 /* acid from the user and adds them as */
1634 /* codebreaks for all CDS features. */
1635 /* */
1636 /*---------------------------------------------------------------------*/
1637
1638 extern void AddGlobalCodeBreak (IteM i);
1639 extern void AddGlobalCodeBreak (IteM i)
1640
1641 {
1642 BaseFormPtr bfp;
1643 WindoW breakWin;
1644 GrouP mainGroup;
1645 GrouP buttGroup;
1646 CodeBreakFormPtr cbfp;
1647
1648 /* Get the current state of things */
1649
1650 #ifdef WIN_MAC
1651 bfp = currentFormDataPtr;
1652 #else
1653 bfp = GetObjectExtra (i);
1654 #endif
1655 if (bfp == NULL)
1656 return;
1657
1658 cbfp = (CodeBreakFormPtr) MemNew (sizeof (EvidenceFormData));
1659
1660 /* Create a window to get the codon and */
1661 /* the Amino acid from the user. */
1662
1663 breakWin = FixedWindow (-50, -33, -10, -10,
1664 "Add Code Break", StdCloseWindowProc);
1665 SetObjectExtra (breakWin, cbfp, StdCleanupFormProc);
1666 cbfp->form = (ForM) breakWin;
1667 cbfp->formmessage = NULL;
1668 cbfp->input_entityID = bfp->input_entityID;
1669
1670 mainGroup = HiddenGroup (breakWin, -2, 0, NULL);
1671
1672 /* Create a text entry box for the nucl. codon */
1673
1674 StaticPrompt (mainGroup, "Triplet Codon", 0, popupMenuHeight,
1675 programFont, 'l');
1676 cbfp->codonText = DialogText (mainGroup, "", 3, CodonText_Callback);
1677 SetObjectExtra (cbfp->codonText, cbfp, NULL);
1678 cbfp->currentCodonStr [0] = '\0';
1679
1680 /* Add a Popup list of Amino Acids */
1681
1682 StaticPrompt (mainGroup, "Amino Acid", 0, popupMenuHeight,
1683 programFont, 'l');
1684 cbfp->aminoAcidPopup = PopupList (mainGroup, TRUE,
1685 SelectAminoAcid_Callback);
1686 PopulateAAPopup (cbfp->aminoAcidPopup);
1687 SetObjectExtra (cbfp->aminoAcidPopup, cbfp, NULL);
1688
1689 /* Add Accept and Cancel buttons */
1690
1691 buttGroup = HiddenGroup (breakWin, 2, 0, NULL);
1692 cbfp->acceptButton = DefaultButton (buttGroup, "Accept",
1693 DoAddCodeBreak_Callback);
1694 SetObjectExtra (cbfp->acceptButton, cbfp, NULL);
1695 SafeDisable (cbfp->acceptButton);
1696 PushButton (buttGroup, "Cancel", StdCancelButtonProc);
1697
1698 /* Line things up and display the window */
1699
1700 AlignObjects (ALIGN_CENTER, (HANDLE) mainGroup, (HANDLE) buttGroup, NULL);
1701 RealizeWindow (breakWin);
1702 Show (breakWin);
1703 Update ();
1704
1705 }
1706
1707 static void ParseCodonQualToCodeBreakCallback (SeqFeatPtr sfp, Pointer userdata)
1708 {
1709 SeqCodeTablePtr sctp;
1710 GBQualPtr gqual, prev_qual = NULL, next_qual;
1711 CharPtr cp;
1712 Char codon_text[4];
1713 Char symbol_text [4];
1714 Uint1 aaNum;
1715 Int4 i;
1716 Boolean converted_qual;
1717
1718 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION || userdata == NULL)
1719 {
1720 return;
1721 }
1722
1723 sctp = (SeqCodeTablePtr) userdata;
1724
1725 for (gqual = sfp->qual; gqual != NULL; gqual = next_qual)
1726 {
1727 next_qual = gqual->next;
1728 converted_qual = FALSE;
1729 if (StringCmp (gqual->qual, "codon") == 0)
1730 {
1731 cp = StringSearch (gqual->val, "seq:\"");
1732 if (cp != NULL)
1733 {
1734 cp += 5;
1735 StringNCpy (codon_text, cp, 3);
1736 codon_text [3] = 0;
1737 for (i = 0; i < 3; i++)
1738 codon_text [i] = TO_UPPER (codon_text [i]);
1739
1740 cp = StrChr (cp, ':');
1741 if (cp != NULL)
1742 {
1743 cp++;
1744 StringNCpy (symbol_text, cp, 3);
1745 symbol_text [3] = 0;
1746 aaNum = FindResidueByName (symbol_text, sctp);
1747 if (ApplyCodeBreakToCDS (sfp, codon_text, aaNum))
1748 {
1749 /* Retranslate the CDS */
1750
1751 RetranslateOneCDS (sfp, sfp->idx.entityID, TRUE, FALSE);
1752
1753 /* remove the codon qual */
1754 if (prev_qual == NULL)
1755 {
1756 sfp->qual = gqual->next;
1757 }
1758 else
1759 {
1760 prev_qual->next = gqual->next;
1761 }
1762 gqual->next = NULL;
1763 GBQualFree (gqual);
1764 converted_qual = TRUE;
1765 }
1766 }
1767 }
1768 }
1769 if (!converted_qual)
1770 {
1771 prev_qual = gqual;
1772 }
1773 }
1774 }
1775
1776 extern void ParseCodonQualToCodeBreak (IteM i)
1777 {
1778 BaseFormPtr bfp;
1779 SeqEntryPtr sep;
1780 SeqCodeTablePtr sctp;
1781
1782 #ifdef WIN_MAC
1783 bfp = currentFormDataPtr;
1784 #else
1785 bfp = GetObjectExtra (i);
1786 #endif
1787 if (bfp == NULL) return;
1788
1789 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1790 if (sep == NULL) return;
1791
1792 WatchCursor ();
1793 Update ();
1794
1795 sctp = SeqCodeTableFind (Seq_code_ncbieaa);
1796
1797 VisitFeaturesInSep (sep, sctp, ParseCodonQualToCodeBreakCallback);
1798 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1799 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1800 ArrowCursor ();
1801 Update ();
1802 }
1803
1804 static void CorrectGenCodeIndexedCallback (SeqFeatPtr sfp, Pointer userdata)
1805 {
1806 CdRegionPtr crp;
1807 GeneticCodePtr gc;
1808 Int2Ptr pGenCode;
1809 ValNodePtr vnp;
1810 Boolean need_replacement = FALSE;
1811
1812 if (sfp == NULL || sfp->data.choice != SEQFEAT_CDREGION
1813 || sfp->data.value.ptrvalue == NULL
1814 || userdata == NULL) return;
1815
1816 pGenCode = (Int2Ptr) userdata;
1817 crp = (CdRegionPtr) sfp->data.value.ptrvalue;
1818 if (crp->genetic_code != NULL
1819 && crp->genetic_code->choice == 254) {
1820 if (crp->genetic_code->data.ptrvalue == NULL) {
1821 vnp = ValNodeNew (NULL);
1822 vnp->choice = 2;
1823 vnp->data.intvalue = (Int4) *pGenCode;
1824 } else {
1825 vnp = crp->genetic_code->data.ptrvalue;
1826 if (vnp->next == NULL && vnp->choice == 2) {
1827 vnp->data.intvalue = (Int4) *pGenCode;
1828 } else {
1829 need_replacement = TRUE;
1830 }
1831 }
1832 } else {
1833 need_replacement = TRUE;
1834 }
1835 if (need_replacement) {
1836 gc = GeneticCodeNew ();
1837 if (gc == NULL) return;
1838 crp->genetic_code = GeneticCodeFree (crp->genetic_code);
1839 vnp = ValNodeNew (NULL);
1840 gc->data.ptrvalue = vnp;
1841 if (vnp != NULL) {
1842 vnp->choice = 2;
1843 vnp->data.intvalue = (Int4) *pGenCode;
1844 }
1845 crp->genetic_code = gc;
1846 }
1847 }
1848
1849 static void CorrectGenCodesBioseqCallback (BioseqPtr bsp, Pointer userdata)
1850 {
1851 SeqMgrFeatContext fcontext;
1852 SeqFeatPtr sfp;
1853
1854 if (bsp == NULL || userdata == NULL) return;
1855 for (sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, FEATDEF_CDS, &fcontext);
1856 sfp != NULL;
1857 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_CDREGION, FEATDEF_CDS, &fcontext)) {
1858 CorrectGenCodeIndexedCallback (sfp, userdata);
1859 }
1860
1861 }
1862
1863 typedef struct gencodescan {
1864 Boolean mito;
1865 Boolean plastid;
1866 Int2 nuclCode;
1867 Int2 mitoCode;
1868 Boolean already_found;
1869 } GenCodeScanData, PNTR GenCodeScanPtr;
1870
1871 static void JustGetGenCodeFromOrgRef (OrgRefPtr orp, GenCodeScanPtr gp)
1872 {
1873 if (orp == NULL || orp->orgname == NULL || gp == NULL || gp->already_found) return;
1874
1875 gp->nuclCode = orp->orgname->gcode;
1876 gp->mitoCode = orp->orgname->mgcode;
1877 }
1878
1879 static void JustGetGenCodeFromBiop (BioSourcePtr biop, GenCodeScanPtr gp)
1880 {
1881 if (biop == NULL || gp == NULL) return;
1882 if (gp->already_found && !biop->is_focus) return;
1883
1884 gp->mito = (Boolean) (biop->genome == GENOME_kinetoplast ||
1885 biop->genome == GENOME_mitochondrion ||
1886 biop->genome == GENOME_hydrogenosome);
1887
1888 gp->plastid = (Boolean) (biop->genome == GENOME_chloroplast ||
1889 biop->genome == GENOME_chromoplast ||
1890 biop->genome == GENOME_plastid ||
1891 biop->genome == GENOME_cyanelle ||
1892 biop->genome == GENOME_apicoplast ||
1893 biop->genome == GENOME_leucoplast ||
1894 biop->genome == GENOME_proplastid);
1895
1896 JustGetGenCodeFromOrgRef (biop->org, gp);
1897 gp->already_found = TRUE;
1898 }
1899
1900
1901 static void JustGetGenCodeFromFeat (SeqFeatPtr sfp, Pointer userdata)
1902 {
1903 GenCodeScanPtr gp;
1904
1905 if (sfp == NULL || userdata == NULL || sfp->data.choice != SEQFEAT_BIOSRC) return;
1906
1907 gp = (GenCodeScanPtr) userdata;
1908
1909 JustGetGenCodeFromBiop (sfp->data.value.ptrvalue, gp);
1910 }
1911
1912 static void JustGetGenCodeFromDesc (SeqDescrPtr sdp, Pointer userdata)
1913 {
1914 GenCodeScanPtr gp;
1915
1916 if (sdp == NULL || userdata == NULL || sdp->choice != Seq_descr_source) return;
1917
1918 gp = (GenCodeScanPtr) userdata;
1919
1920 JustGetGenCodeFromBiop (sdp->data.ptrvalue, gp);
1921 }
1922
1923 static Int2 JustGetGenCodeForSeqEntry (SeqEntryPtr sep)
1924 {
1925 GenCodeScanData gd;
1926
1927 gd.already_found = FALSE;
1928 gd.mito = FALSE;
1929 gd.mitoCode = 0;
1930 gd.nuclCode = 0;
1931 gd.plastid = FALSE;
1932
1933 VisitDescriptorsInSep (sep, &gd, JustGetGenCodeFromDesc);
1934 VisitFeaturesInSep (sep, &gd, JustGetGenCodeFromFeat);
1935
1936 if (gd.plastid) {
1937 return 11;
1938 } else if (gd.mito) {
1939 return gd.mitoCode;
1940 } else {
1941 return gd.nuclCode;
1942 }
1943 }
1944
1945
1946 extern void CorrectGenCodes (SeqEntryPtr sep, Uint2 entityID)
1947
1948 {
1949 BioseqSetPtr bssp;
1950 Int2 genCode;
1951
1952 if (sep == NULL) return;
1953 if (IS_Bioseq_set (sep)) {
1954 bssp = (BioseqSetPtr) sep->data.ptrvalue;
1955 if (bssp != NULL && (bssp->_class == 7 ||
1956 (IsPopPhyEtcSet (bssp->_class)))) {
1957 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
1958 CorrectGenCodes (sep, entityID);
1959 }
1960 return;
1961 }
1962 }
1963
1964 genCode = JustGetGenCodeForSeqEntry(sep);
1965 VisitFeaturesInSep (sep, &genCode, CorrectGenCodeIndexedCallback);
1966 VisitBioseqsInSep (sep, &genCode, CorrectGenCodesBioseqCallback);
1967 }
1968
1969 extern void CorrectCDSGenCodes (IteM i)
1970
1971 {
1972 BaseFormPtr bfp;
1973 SeqEntryPtr sep;
1974
1975 #ifdef WIN_MAC
1976 bfp = currentFormDataPtr;
1977 #else
1978 bfp = GetObjectExtra (i);
1979 #endif
1980 if (bfp == NULL) return;
1981 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
1982 if (sep == NULL) return;
1983 CorrectGenCodes (sep, bfp->input_entityID);
1984 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
1985 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
1986 }
1987
1988 static BioseqPtr SqnGetBioseqGivenSeqLoc (SeqLocPtr slp, Uint2 entityID)
1989
1990 {
1991 BioseqPtr bsp;
1992 SeqEntryPtr sep;
1993 SeqIdPtr sip;
1994 SeqLocPtr tmp;
1995
1996 if (slp == NULL) return NULL;
1997 bsp = NULL;
1998 sip = SeqLocId (slp);
1999 if (sip != NULL) {
2000 bsp = BioseqFind (sip);
2001 } else {
2002 tmp = SeqLocFindNext (slp, NULL);
2003 if (tmp != NULL) {
2004 sip = SeqLocId (tmp);
2005 if (sip != NULL) {
2006 bsp = BioseqFind (sip);
2007 if (bsp != NULL) {
2008 sep = SeqMgrGetSeqEntryForData (bsp);
2009 entityID = ObjMgrGetEntityIDForChoice (sep);
2010 bsp = GetBioseqGivenSeqLoc (slp, entityID);
2011 }
2012 }
2013 }
2014 }
2015 return bsp;
2016 }
2017
2018 static BioseqPtr GetBioseqReferencedByAnnot (SeqAnnotPtr sap, Uint2 entityID)
2019
2020 {
2021 SeqAlignPtr align;
2022 BioseqPtr bsp;
2023 DenseDiagPtr ddp;
2024 DenseSegPtr dsp;
2025 SeqFeatPtr feat;
2026 SeqGraphPtr graph;
2027 SeqIdPtr sip;
2028 SeqLocPtr slp;
2029 StdSegPtr ssp;
2030 SeqLocPtr tloc;
2031
2032 if (sap == NULL) return NULL;
2033 switch (sap->type) {
2034 case 1 :
2035 feat = (SeqFeatPtr) sap->data;
2036 while (feat != NULL) {
2037 slp = feat->location;
2038 if (slp != NULL) {
2039 bsp = SqnGetBioseqGivenSeqLoc (slp, entityID);
2040 if (bsp != NULL) return bsp;
2041 }
2042 feat = feat->next;
2043 }
2044 break;
2045 case 2 :
2046 align = (SeqAlignPtr) sap->data;
2047 while (align != NULL) {
2048 if (align->segtype == 1) {
2049 ddp = (DenseDiagPtr) align->segs;
2050 if (ddp != NULL) {
2051 for (sip = ddp->id; sip != NULL; sip = sip->next) {
2052 bsp = BioseqFind (sip);
2053 if (bsp != NULL) return bsp;
2054 }
2055 }
2056 } else if (align->segtype == 2) {
2057 dsp = (DenseSegPtr) align->segs;
2058 if (dsp != NULL) {
2059 for (sip = dsp->ids; sip != NULL; sip = sip->next) {
2060 bsp = BioseqFind (sip);
2061 if (bsp != NULL) return bsp;
2062 }
2063 }
2064 } else if (align->segtype == 3) {
2065 ssp = (StdSegPtr) align->segs;
2066 if (ssp != NULL && ssp->loc != NULL) {
2067 for (tloc = ssp->loc; tloc != NULL; tloc = tloc->next) {
2068 bsp = BioseqFind (SeqLocId (tloc));
2069 if (bsp != NULL) return bsp;
2070 }
2071 }
2072 }
2073 align = align->next;
2074 }
2075 break;
2076 case 3 :
2077 graph = (SeqGraphPtr) sap->data;
2078 while (graph != NULL) {
2079 slp = graph->loc;
2080 if (slp != NULL) {
2081 bsp = SqnGetBioseqGivenSeqLoc (slp, entityID);
2082 if (bsp != NULL) return bsp;
2083 }
2084 graph = graph->next;
2085 }
2086 break;
2087 default :
2088 break;
2089 }
2090 return NULL;
2091 }
2092
2093 static Int4 GetScore (ScorePtr score)
2094
2095 {
2096 ObjectIdPtr id;
2097
2098 while (score != NULL) {
2099 id = score->id;
2100 if (id != NULL) {
2101 if (StringICmp (id->str, "score") == 0) {
2102 if (score->choice == 1) {
2103 return (score->value.intvalue);
2104 }
2105 }
2106 }
2107 score = score->next;
2108 }
2109 return 0;
2110 }
2111
2112 static Int4 FindScore (SeqAlignPtr align)
2113
2114 {
2115 if (align == NULL) return 0;
2116 if (align->score != NULL) {
2117 return GetScore (align->score);
2118 }
2119 return 0;
2120 }
2121
2122 static int LIBCALLBACK SortByScoreCallback (VoidPtr ptr1, VoidPtr ptr2)
2123
2124 {
2125 SeqAlignPtr sap1;
2126 SeqAlignPtr sap2;
2127 Int4 score1;
2128 Int4 score2;
2129
2130 if (ptr1 != NULL && ptr2 != NULL) {
2131 sap1 = *((SeqAlignPtr PNTR) ptr1);
2132 sap2 = *((SeqAlignPtr PNTR) ptr2);
2133 if (sap1 != NULL && sap2 != NULL) {
2134 score1 = FindScore (sap1);
2135 score2 = FindScore (sap2);
2136 if (score1 < score2) {
2137 return 1;
2138 } else if (score1 > score2) {
2139 return -1;
2140 } else {
2141 return 0;
2142 }
2143 } else {
2144 return 0;
2145 }
2146 } else {
2147 return 0;
2148 }
2149 }
2150
2151 static SeqAlignPtr SortBySeqAlignScore (SeqAlignPtr list)
2152
2153 {
2154 SeqAlignPtr align;
2155 Int4 count, i;
2156 SeqAlignPtr PNTR head;
2157
2158 if (list == NULL) return 0;
2159 count = 0;
2160 for (align = list; align != NULL; align = align->next) {
2161 count++;
2162 }
2163 head = MemNew (sizeof (SeqAlignPtr) * (size_t) (count + 1));
2164 if (head == NULL) return 0;
2165 for (align = list, i = 0; align != NULL && i < count; i++) {
2166 head [i] = align;
2167 align = align->next;
2168 }
2169 HeapSort (head, (size_t) count, sizeof (SeqAlignPtr), SortByScoreCallback);
2170 for (i = 0; i < count; i++) {
2171 align = head [i];
2172 align->next = head [i + 1];
2173 }
2174 list = head [0];
2175 MemFree (head);
2176 return list;
2177 }
2178
2179 static void TakeTop10Alignments (SeqAnnotPtr sap)
2180
2181 {
2182 SeqAlignPtr align;
2183 MsgAnswer ans;
2184 Int2 count;
2185 SeqAlignPtr next;
2186
2187 if (sap == NULL || sap->type != 2 || sap->data == NULL) return;
2188 count = 0;
2189 for (align = (SeqAlignPtr) sap->data; align != NULL; align = align->next) {
2190 count++;
2191 }
2192 if (count <= 10) return;
2193 ans = Message (MSG_YN, "Do you want to take only the top 10 (out of %d) alignments?", (int) count);
2194 if (ans == ANS_NO) return;
2195 sap->data = SortBySeqAlignScore ((SeqAlignPtr) sap->data);
2196 for (align = (SeqAlignPtr) sap->data, count = 0; align != NULL && count < 10; align = align->next) {
2197 count++;
2198 }
2199 next = align->next;
2200 align->next = NULL;
2201 align = next;
2202 while (align != NULL) {
2203 next = align->next;
2204 align->next = NULL;
2205 SeqAlignFree (align);
2206 align = next;
2207 }
2208 }
2209
2210 static void DoOnePub (PubdescPtr pdp)
2211
2212 {
2213 ValNodePtr citartptr = NULL;
2214 Int4 muid = 0;
2215 Int4 pmid = 0;
2216 ValNodePtr tmp = NULL;
2217 ValNodePtr vnp;
2218
2219 if (pdp != NULL) {
2220 for (vnp = pdp->pub; vnp != NULL; vnp = vnp->next) {
2221 if (vnp->choice == PUB_Muid) {
2222 muid = vnp->data.intvalue;
2223 } else if (vnp->choice == PUB_PMid) {
2224 pmid = vnp->data.intvalue;
2225 } else if (vnp->choice == PUB_Article) {
2226 citartptr = vnp;
2227 }
2228 }
2229 if (pmid != 0) {
2230 tmp = MedArchGetPubPmId (pmid);
2231 muid = MedArchPm2Mu (pmid);
2232 } else if (muid != 0) {
2233 tmp = MedArchGetPub (muid);
2234 pmid = MedArchMu2Pm (muid);
2235 } else if (citartptr != NULL) {
2236 muid = MedArchCitMatch (citartptr);
2237 if (muid != 0) {
2238 tmp = MedArchGetPub (muid);
2239 pmid = MedArchMu2Pm (muid);
2240 }
2241 }
2242 if (tmp != NULL) {
2243 MedlineToISO (tmp);
2244 if (pmid != 0) {
2245 ValNodeAddInt (&tmp, PUB_PMid, pmid);
2246 }
2247 if (muid != 0) {
2248 ValNodeAddInt (&tmp, PUB_Muid, muid);
2249 }
2250 pdp->pub = PubEquivFree (pdp->pub);
2251 pdp->pub = tmp;
2252 }
2253 }
2254 }
2255
2256 static void DoLookupPub (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
2257
2258 {
2259 BioseqPtr bsp;
2260 BioseqSetPtr bssp;
2261 PubdescPtr pdp;
2262 SeqAnnotPtr sap;
2263 ValNodePtr sdp;
2264 SeqFeatPtr sfp;
2265
2266 if (IS_Bioseq (sep)) {
2267 bsp = (BioseqPtr) sep->data.ptrvalue;
2268 sap = bsp->annot;
2269 sdp = bsp->descr;
2270 } else if (IS_Bioseq_set (sep)) {
2271 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2272 sap = bssp->annot;
2273 sdp = bssp->descr;
2274 } else return;
2275 while (sap != NULL) {
2276 if (sap->type == 1) {
2277 for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
2278 if (sfp->data.choice == SEQFEAT_PUB) {
2279 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
2280 DoOnePub (pdp);
2281 }
2282 }
2283 }
2284 sap = sap->next;
2285 }
2286 while (sdp != NULL) {
2287 if (sdp->choice == Seq_descr_pub) {
2288 pdp = (PubdescPtr) sdp->data.ptrvalue;
2289 DoOnePub (pdp);
2290 }
2291 sdp = sdp->next;
2292 }
2293 }
2294
2295 extern void LookupAllPubs (IteM i);
2296 extern void LookupAllPubs (IteM i)
2297
2298 {
2299 BaseFormPtr bfp;
2300 MonitorPtr mon = NULL;
2301 SeqEntryPtr sep;
2302 ErrSev sev;
2303
2304
2305 if (! useMedarch) return;
2306 #ifdef WIN_MAC
2307 bfp = currentFormDataPtr;
2308 #else
2309 bfp = GetObjectExtra (i);
2310 #endif
2311 if (bfp == NULL) return;
2312 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
2313 if (sep == NULL) return;
2314 sev = ErrSetMessageLevel (SEV_FATAL);
2315 WatchCursor ();
2316 mon = MonitorStrNewEx ("Processing Publications", 40, FALSE);
2317 MonitorStrValue (mon, "Connecting to MedArch");
2318 Update ();
2319 if (! MedArchInit ()) {
2320 MonitorFree (mon);
2321 ArrowCursor ();
2322 Update ();
2323 Message (MSG_POST, "Unable to connect to MedArch");
2324 return;
2325 }
2326 SeqEntryExplore (sep, NULL, DoLookupPub);
2327 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
2328 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
2329 MonitorStrValue (mon, "Closing MedArch");
2330 Update ();
2331 MedArchFini ();
2332 MonitorFree (mon);
2333 ArrowCursor ();
2334 Update ();
2335 ErrSetMessageLevel (sev);
2336 ErrClear ();
2337 ErrShow ();
2338 }
2339
2340 static void LookupPublications (SeqAnnotPtr sap)
2341
2342 {
2343 MonitorPtr mon = NULL;
2344 PubdescPtr pdp;
2345 SeqFeatPtr sfp;
2346 ValNodePtr tmp;
2347 Int4 uid;
2348 Boolean usingMedarch = FALSE;
2349 ValNodePtr vnp;
2350
2351 if (! useMedarch) return;
2352 if (sap == NULL || sap->type != 1) return;
2353 for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
2354 if (sfp->data.choice == SEQFEAT_PUB) {
2355 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
2356 if (pdp != NULL) {
2357 vnp = pdp->pub;
2358 if (vnp != NULL && vnp->next == NULL) {
2359 if (vnp->choice == PUB_Muid || vnp->choice == PUB_PMid) {
2360 if (! usingMedarch) {
2361 WatchCursor ();
2362 mon = MonitorStrNewEx ("Processing Publications", 40, FALSE);
2363 MonitorStrValue (mon, "Connecting to MedArch");
2364 Update ();
2365 if (MedArchInit ()) {
2366 usingMedarch = TRUE;
2367 } else {
2368 MonitorFree (mon);
2369 ArrowCursor ();
2370 Update ();
2371 Message (MSG_POST, "Unable to connect to MedArch");
2372 return;
2373 }
2374 }
2375 }
2376 tmp = NULL;
2377 if (vnp->choice == PUB_Muid) {
2378 uid = vnp->data.intvalue;
2379 tmp = MedArchGetPub (uid);
2380 } else if (vnp->choice == PUB_PMid) {
2381 uid = vnp->data.intvalue;
2382 tmp = MedArchGetPubPmId (uid);
2383 }
2384 if (tmp != NULL) {
2385 MedlineToISO (tmp);
2386 tmp->next = vnp;
2387 pdp->pub = tmp;
2388 }
2389 }
2390 }
2391 }
2392 }
2393 if (usingMedarch) {
2394 MonitorStrValue (mon, "Closing MedArch");
2395 Update ();
2396 MedArchFini ();
2397 MonitorFree (mon);
2398 ArrowCursor ();
2399 Update ();
2400 }
2401 }
2402
2403 static void PromotePubs (SeqFeatPtr first, BioseqPtr bsp, Uint2 entityID)
2404
2405 {
2406 MsgAnswer ans;
2407 Boolean asked = FALSE;
2408 PubdescPtr pdp;
2409 SeqDescrPtr sdp;
2410 SeqEntryPtr sep;
2411 SeqFeatPtr sfp;
2412 ValNode vn;
2413
2414 MemSet ((Pointer) &vn, 0, sizeof (ValNode));
2415 vn.choice = SEQLOC_WHOLE;
2416 vn.data.ptrvalue = (Pointer) SeqIdFindBest (bsp->id, 0);
2417 vn.next = NULL;
2418
2419 for (sfp = first; sfp != NULL; sfp = sfp->next) {
2420 if (sfp->data.choice == SEQFEAT_PUB) {
2421 if (SeqLocCompare (sfp->location, &vn) == SLC_A_EQ_B) {
2422 if (! asked) {
2423 ans = Message (MSG_YN, "Do you wish to convert full-length publication features to descriptors?");
2424 if (ans == ANS_NO) return;
2425 asked = TRUE;
2426 }
2427 }
2428 }
2429 }
2430
2431 sep = GetBestTopParentForData (entityID, bsp);
2432 for (sfp = first; sfp != NULL; sfp = sfp->next) {
2433 if (sfp->data.choice == SEQFEAT_PUB) {
2434 if (SeqLocCompare (sfp->location, &vn) == SLC_A_EQ_B) {
2435 sfp->idx.deleteme = TRUE;
2436 sfp->data.choice = SEQFEAT_COMMENT;
2437 pdp = (PubdescPtr) sfp->data.value.ptrvalue;
2438 sfp->data.value.ptrvalue = NULL;
2439 sdp = CreateNewDescriptor (sep, Seq_descr_pub);
2440 if (sdp != NULL) {
2441 sdp->data.ptrvalue = (Pointer) pdp;
2442 }
2443 }
2444 }
2445 }
2446
2447 DeleteMarkedObjects (entityID, 0, NULL);
2448 }
2449
2450 extern Uint2 SmartAttachSeqAnnotToSeqEntry (Uint2 entityID, SeqAnnotPtr sap, ValNodePtr PNTR err_list)
2451
2452 {
2453 BioseqPtr bsp;
2454 Int2 genCode;
2455 SeqEntryPtr oldscope;
2456 OMProcControl ompc;
2457 SeqEntryPtr sep;
2458 SeqFeatPtr sfp = NULL;
2459
2460 if (sap == NULL) return entityID;
2461 bsp = GetBioseqReferencedByAnnot (sap, entityID);
2462 if (bsp == NULL) {
2463 oldscope = SeqEntrySetScope (NULL);
2464 if (oldscope != NULL) {
2465 bsp = GetBioseqReferencedByAnnot (sap, entityID);
2466 SeqEntrySetScope (oldscope);
2467 }
2468 }
2469 if (bsp != NULL) {
2470 sep = SeqMgrGetSeqEntryForData (bsp);
2471 entityID = ObjMgrGetEntityIDForChoice (sep);
2472 if (sap->type == 1) {
2473 sfp = (SeqFeatPtr) sap->data;
2474 sep = GetBestTopParentForData (entityID, bsp);
2475 genCode = SeqEntryToGeneticCode (sep, NULL, NULL, 0);
2476 SetEmptyGeneticCodes (sap, genCode);
2477 LookupPublications (sap);
2478 } else if (sap->type == 2) {
2479 TakeTop10Alignments (sap);
2480 }
2481 MemSet ((Pointer) &ompc, 0, sizeof (OMProcControl));
2482 ompc.input_entityID = entityID;
2483 ompc.input_itemID = GetItemIDGivenPointer (entityID, OBJ_BIOSEQ, (Pointer) bsp);
2484 ompc.input_itemtype = OBJ_BIOSEQ;
2485 ompc.output_itemtype = OBJ_SEQANNOT;
2486 ompc.output_data = (Pointer) sap;
2487 if (! AttachDataForProc (&ompc, FALSE)) {
2488 if (err_list == NULL) {
2489 Message (MSG_ERROR, "SmartAttachSeqAnnotToSeqEntry failed");
2490 } else {
2491 ValNodeAddPointer (err_list, 0, StringSave ("SmartAttachSeqAnnotToSeqEntry failed"));
2492 }
2493 } else if (sfp != NULL) {
2494 PromoteXrefs (sfp, bsp, entityID);
2495 PromotePubs (sfp, bsp, entityID);
2496 }
2497 } else {
2498 if (err_list == NULL) {
2499 Message (MSG_ERROR, "Feature table identifiers do not match record");
2500 } else {
2501 ValNodeAddPointer (err_list, 0, StringSave ("Feature table identifiers do not match record"));
2502 }
2503 }
2504 return entityID;
2505 }
2506
2507 typedef struct removeformdata {
2508 FEATURE_FORM_BLOCK
2509
2510 Boolean is_feature;
2511 LisT objlist;
2512 TexT findthis;
2513 TexT fromTxt;
2514 TexT toTxt;
2515 Uint2 itemtype;
2516 Uint2 subtype;
2517 CharPtr extra_string;
2518 ValNodePtr head;
2519 Boolean stringfound;
2520 Char findStr [128];
2521 Boolean take_action_when_string_present;
2522 GrouP string_constraint_type;
2523 ButtoN case_insensitive;
2524 Int4 from;
2525 Int4 to;
2526 ValNodePtr bsplist;
2527 ValNodePtr bssplist;
2528 } RemoveFormData, PNTR RemoveFormPtr;
2529
2530 static Boolean ObjectInRange (SeqFeatPtr sfp, Int4 from, Int4 to)
2531
2532 {
2533 SeqMgrFeatContext context;
2534
2535 if (sfp == NULL || from < 0 || to < 0) return TRUE;
2536 if (SeqMgrGetDesiredFeature (sfp->idx.entityID, NULL, 0, 0, sfp, &context) == sfp) {
2537 if (context.left > to) return FALSE;
2538 if (context.right < from) return FALSE;
2539 }
2540 return TRUE;
2541 }
2542
2543
2544 static void RemoveFeatureCallback (SeqFeatPtr sfp, Pointer userdata)
2545 {
2546 RemoveFormPtr rfp;
2547 SeqIdPtr sip;
2548 BioseqPtr productbsp, productcdna;
2549 BioseqSetPtr productnps;
2550
2551 if (sfp == NULL || userdata == NULL) return;
2552
2553 rfp = (RemoveFormPtr) userdata;
2554 if (rfp == NULL) return;
2555 if (sfp->idx.subtype == rfp->subtype ||
2556 (rfp->subtype == FEATDEF_IMP && IsRealImpFeat (sfp->idx.subtype)) ||
2557 rfp->subtype == ALL_FEATURES)
2558 {
2559 if ((rfp->from == -1 && rfp->to == -1) || ObjectInRange (sfp, rfp->from, rfp->to))
2560 {
2561 if (sfp->data.choice == SEQFEAT_CDREGION)
2562 {
2563 if (sfp->product != NULL)
2564 {
2565 sip = SeqLocId (sfp->product);
2566 if (sip != NULL)
2567 {
2568 productbsp = BioseqFind (sip);
2569 if (productbsp != NULL)
2570 {
2571 ValNodeAddPointer (&(rfp->bsplist), 0, (Pointer) productbsp);
2572 }
2573 }
2574 }
2575 }
2576 else if (sfp->data.choice == SEQFEAT_RNA)
2577 {
2578 if (sfp->product != NULL)
2579 {
2580 sip = SeqLocId (sfp->product);
2581 if (sip != NULL)
2582 {
2583 productcdna = BioseqFind (sip);
2584 if (productcdna != NULL && productcdna->idx.parenttype == OBJ_BIOSEQSET)
2585 {
2586 productnps = (BioseqSetPtr) productcdna->idx.parentptr;
2587 if (productnps != NULL && productnps->_class == BioseqseqSet_class_nuc_prot)
2588 {
2589 ValNodeAddPointer (&(rfp->bssplist), 0, (Pointer) productnps);
2590 }
2591 }
2592 }
2593 }
2594 }
2595 sfp->idx.deleteme = TRUE;
2596 }
2597 }
2598 }
2599
2600 static void RemoveFeatures (SeqEntryPtr sep, RemoveFormPtr rfp)
2601 {
2602 FeaturesWithTextData fd;
2603 Char str [32];
2604 Int4 swap;
2605 long int val;
2606
2607 GetTitle (rfp->findthis, rfp->findStr, sizeof (rfp->findStr) - 1);
2608 fd.search_text = rfp->findStr;
2609 fd.no_text = StringHasNoText (rfp->findStr);
2610 fd.seqFeatChoice = 0;
2611 fd.featDefChoice = 0;
2612 fd.case_insensitive = GetStatus (rfp->case_insensitive);
2613 fd.whole_word = FALSE;
2614 fd.act_when_string_not_present = ! rfp->take_action_when_string_present;
2615 fd.userdata = rfp;
2616 fd.callback = RemoveFeatureCallback;
2617 GetTitle (rfp->fromTxt, str, sizeof (str) - 1);
2618 if ((! StringHasNoText (str)) && sscanf (str, "%ld", &val) == 1 && val >= 0) {
2619 rfp->from = (Int4) val;
2620 } else {
2621 rfp->from = -1;
2622 }
2623 GetTitle (rfp->toTxt, str, sizeof (str) - 1);
2624 if ((! StringHasNoText (str)) && sscanf (str, "%ld", &val) == 1 && val >= 0) {
2625 rfp->to = (Int4) val;
2626 } else {
2627 rfp->to = -1;
2628 }
2629 if (rfp->from > rfp->to) {
2630 swap = rfp->from;
2631 rfp->from = rfp->to;
2632 rfp->to = swap;
2633 }
2634 OperateOnSeqEntryFeaturesWithText (sep, &fd);
2635 DeleteMarkedObjects (rfp->input_entityID, OBJ_SEQENTRY, (Pointer) sep);
2636 }
2637
2638
2639 static Boolean IsUserObjectType (SeqDescrPtr sdp, CharPtr string)
2640 {
2641 UserObjectPtr uop;
2642 ObjectIdPtr oip;
2643
2644 if (sdp == NULL || sdp->choice != Seq_descr_user) return FALSE;
2645 if (StringHasNoText (string)) return TRUE;
2646
2647 uop = (UserObjectPtr) sdp->data.ptrvalue;
2648 if (uop == NULL) return FALSE;
2649 oip = uop->type;
2650 if (oip == NULL || StringICmp (oip->str, string) != 0) return FALSE;
2651 return TRUE;
2652 }
2653
2654
2655 static void RemoveDescriptorCallback (SeqDescrPtr sdp, Pointer userdata)
2656 {
2657 ObjValNodePtr ovp;
2658 RemoveFormPtr rfp;
2659
2660 if (sdp == NULL || userdata == NULL || sdp->extended == 0) return;
2661 rfp = (RemoveFormPtr) userdata;
2662 if (rfp == NULL) return;
2663
2664 ovp = (ObjValNodePtr) sdp;
2665
2666 if (sdp->choice == rfp->subtype)
2667 {
2668 if (sdp->choice != Seq_descr_user || IsUserObjectType (sdp, rfp->extra_string)) {
2669 ovp->idx.deleteme = TRUE;
2670 }
2671 }
2672 }
2673
2674 static void RemoveDescriptors (SeqEntryPtr sep, RemoveFormPtr rfp)
2675 {
2676 DescriptorsWithTextData dd;
2677 Char str [32];
2678 Int4 swap;
2679 long int val;
2680
2681 GetTitle (rfp->findthis, rfp->findStr, sizeof (rfp->findStr) - 1);
2682 dd.search_text = rfp->findStr;
2683 dd.no_text = StringHasNoText (rfp->findStr);
2684 dd.case_insensitive = GetStatus (rfp->case_insensitive);
2685 dd.whole_word = FALSE;
2686 dd.act_when_string_not_present = ! rfp->take_action_when_string_present;
2687 dd.userdata = rfp;
2688 dd.callback = RemoveDescriptorCallback;
2689 GetTitle (rfp->fromTxt, str, sizeof (str) - 1);
2690 if ((! StringHasNoText (str)) && sscanf (str, "%ld", &val) == 1 && val >= 0) {
2691 rfp->from = (Int4) val;
2692 } else {
2693 rfp->from = -1;
2694 }
2695 GetTitle (rfp->toTxt, str, sizeof (str) - 1);
2696 if ((! StringHasNoText (str)) && sscanf (str, "%ld", &val) == 1 && val >= 0) {
2697 rfp->to = (Int4) val;
2698 } else {
2699 rfp->to = -1;
2700 }
2701 if (rfp->from > rfp->to) {
2702 swap = rfp->from;
2703 rfp->from = rfp->to;
2704 rfp->to = swap;
2705 }
2706 OperateOnSeqEntryDescriptorsWithText (sep, &dd);
2707 DeleteMarkedObjects (rfp->input_entityID, OBJ_SEQENTRY, (Pointer) sep);
2708 }
2709
2710 static void DoRemoveAsnObject (ButtoN b)
2711
2712 {
2713 MsgAnswer ans;
2714 BioseqPtr bsp;
2715 BioseqSetPtr bssp;
2716 Uint4 itemID;
2717 OMProcControl ompc;
2718 RemoveFormPtr rfp;
2719 SeqEntryPtr sep;
2720 ValNodePtr tmp;
2721 Int2 val;
2722 ValNodePtr vnp;
2723 Boolean removed_some_features;
2724
2725 rfp = GetObjectExtra (b);
2726 if (rfp == NULL) return;
2727 sep = GetTopSeqEntryForEntityID (rfp->input_entityID);
2728 if (sep == NULL) return;
2729 Hide (rfp->form);
2730 WatchCursor ();
2731 Update ();
2732 if (rfp->is_feature) {
2733 rfp->itemtype = OBJ_SEQFEAT;
2734 } else {
2735 rfp->itemtype = OBJ_SEQDESC;
2736 }
2737
2738 if (rfp->itemtype == 0) return;
2739
2740 removed_some_features = FALSE;
2741
2742 if (GetValue (rfp->string_constraint_type) == 1)
2743 {
2744 rfp->take_action_when_string_present = TRUE;
2745 }
2746 else
2747 {
2748 rfp->take_action_when_string_present = FALSE;
2749 }
2750
2751 val = 1;
2752 for (vnp = rfp->head; vnp != NULL; vnp = vnp->next)
2753 {
2754 if (GetItemStatus (rfp->objlist, val))
2755 {
2756 rfp->subtype = vnp->choice;
2757 rfp->extra_string = NULL;
2758 if (rfp->subtype != 0) {
2759 if (rfp->is_feature) {
2760 RemoveFeatures (sep, rfp);
2761 removed_some_features = TRUE;
2762 } else {
2763 if (rfp->subtype == Seq_descr_user && StringCmp (vnp->data.ptrvalue, "User") != 0) {
2764 rfp->extra_string = vnp->data.ptrvalue;
2765 }
2766 RemoveDescriptors (sep, rfp);
2767 }
2768 }
2769 }
2770 val ++;
2771 }
2772
2773 if (removed_some_features) {
2774 if (rfp->bsplist != NULL) {
2775 ans = Message (MSG_YN, "Remove protein products?");
2776 if (ans == ANS_YES) {
2777 for (tmp = rfp->bsplist; tmp != NULL; tmp = tmp->next) {
2778 bsp = (BioseqPtr) tmp->data.ptrvalue;
2779 itemID = GetItemIDGivenPointer (rfp->input_entityID, OBJ_BIOSEQ, (Pointer) bsp);
2780 if (itemID > 0) {
2781 MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
2782 ompc.do_not_reload_from_cache = TRUE;
2783 ompc.input_entityID = rfp->input_entityID;
2784 ompc.input_itemID = itemID;
2785 ompc.input_itemtype = OBJ_BIOSEQ;
2786 if (! DetachDataForProc (&ompc, FALSE)) {
2787 Message (MSG_POSTERR, "DetachDataForProc failed");
2788 }
2789 SeqMgrDeleteFromBioseqIndex (bsp);
2790 }
2791 }
2792 ans = Message (MSG_YN, "Renormalize Nuc-Prot sets?");
2793 if (ans == ANS_YES)
2794 {
2795 RemoveOrphanProteins (rfp->input_entityID, sep);
2796 RenormalizeNucProtSets (sep, TRUE);
2797 }
2798 }
2799 }
2800 if (rfp->bssplist != NULL) {
2801 ans = Message (MSG_YN, "Remove cDNA nuc-prot products?");
2802 if (ans == ANS_YES) {
2803 for (tmp = rfp->bssplist; tmp != NULL; tmp = tmp->next) {
2804 bssp = (BioseqSetPtr) tmp->data.ptrvalue;
2805 itemID = GetItemIDGivenPointer (rfp->input_entityID, OBJ_BIOSEQSET, (Pointer) bssp);
2806 if (itemID > 0) {
2807 MemSet ((Pointer) (&ompc), 0, sizeof (OMProcControl));
2808 ompc.do_not_reload_from_cache = TRUE;
2809 ompc.input_entityID = rfp->input_entityID;
2810 ompc.input_itemID = itemID;
2811 ompc.input_itemtype = OBJ_BIOSEQSET;
2812 if (! DetachDataForProc (&ompc, FALSE)) {
2813 Message (MSG_POSTERR, "DetachDataForProc failed");
2814 }
2815 }
2816 }
2817 }
2818 }
2819 }
2820 ArrowCursor ();
2821 Update ();
2822 ObjMgrSetDirtyFlag (rfp->input_entityID, TRUE);
2823 ObjMgrSendMsg (OM_MSG_UPDATE, rfp->input_entityID, 0, 0);
2824 ObjMgrDeSelect (0, 0, 0, 0, NULL);
2825 Remove (rfp->form);
2826 }
2827
2828 static void RemoveDefLinesCallback (SeqEntryPtr sep, Pointer mydata, Int4 index, Int2 indent)
2829
2830 {
2831 BioseqPtr bsp;
2832 BioseqSetPtr bssp;
2833 ValNodePtr nextsdp;
2834 Pointer PNTR prevsdp;
2835 ValNodePtr sdp;
2836
2837 if (sep == NULL || sep->data.ptrvalue == NULL) return;
2838 if (IS_Bioseq (sep)) {
2839 bsp = (BioseqPtr) sep->data.ptrvalue;
2840 sdp = bsp->descr;
2841 prevsdp = (Pointer PNTR) &(bsp->descr);
2842 } else if (IS_Bioseq_set (sep)) {
2843 bssp = (BioseqSetPtr) sep->data.ptrvalue;
2844 sdp = bssp->descr;
2845 prevsdp = (Pointer PNTR) &(bssp->descr);
2846 } else return;
2847
2848 while (sdp != NULL) {
2849 nextsdp = sdp->next;
2850 if (sdp->choice == Seq_descr_title)
2851 {
2852 *(prevsdp) = sdp->next;
2853 sdp->next = NULL;
2854 SeqDescFree (sdp);
2855 } else {
2856 prevsdp = (Pointer PNTR) &(sdp->next);
2857 }
2858 sdp = nextsdp;
2859 }
2860 }
2861
2862 extern void RemoveDefLinesToolBtn (ButtoN b)
2863 {
2864 BaseFormPtr bfp;
2865 SeqEntryPtr sep;
2866
2867 bfp = (BaseFormPtr) GetObjectExtra (b);
2868 if (bfp == NULL) return;
2869
2870 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
2871 if (sep == NULL) return;
2872
2873 WatchCursor ();
2874 Update ();
2875
2876 SeqEntryExplore (sep, NULL, RemoveDefLinesCallback);
2877
2878 ArrowCursor ();
2879 Update ();
2880 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
2881 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
2882 ObjMgrDeSelect (0, 0, 0, 0, NULL);
2883 CommonApplyToAllProc (bfp, ADD_TITLE);
2884 }
2885
2886 int LIBCALLBACK SortByVnpChoice (VoidPtr ptr1, VoidPtr ptr2)
2887
2888 {
2889 ValNodePtr vnp1;
2890 ValNodePtr vnp2;
2891
2892 if (ptr1 != NULL && ptr2 != NULL) {
2893 vnp1 = *((ValNodePtr PNTR) ptr1);
2894 vnp2 = *((ValNodePtr PNTR) ptr2);
2895 if (vnp1 != NULL && vnp2 != NULL) {
2896 if (vnp1->choice > vnp2->choice) {
2897 return 1;
2898 } else if (vnp1->choice < vnp2->choice) {
2899 return -1;
2900 } else {
2901 return 0;
2902 }
2903 } else {
2904 return 0;
2905 }
2906 } else {
2907 return 0;
2908 }
2909 }
2910
2911 static void RemoveMessageProc (ForM f, Int2 mssg)
2912
2913 {
2914 RemoveFormPtr rfp;
2915
2916 rfp = (RemoveFormPtr) GetObjectExtra (f);
2917 if (rfp != NULL) {
2918 if (rfp->appmessage != NULL) {
2919 rfp->appmessage (f, mssg);
2920 }
2921 }
2922 }
2923
2924 static void CleanupRemovePage (GraphiC g, VoidPtr data)
2925
2926 {
2927 RemoveFormPtr rfp;
2928
2929 rfp = (RemoveFormPtr) data;
2930 if (rfp != NULL) {
2931 ValNodeFreeData (rfp->head);
2932 ValNodeFree (rfp->bsplist);
2933 ValNodeFree (rfp->bssplist);
2934 }
2935 StdCleanupFormProc (g, data);
2936 }
2937
2938 static CharPtr descNames [] = {
2939 " ", " ", " ", " ", "Name",
2940 "Title", " ", "Comment", "Numbering",
2941 "MapLoc", "PIR", "GenBank", "Publication",
2942 "Region", "User", "SWISS-PROT", "dbXREF",
2943 "EMBL", "Create Date", "Update Date", "PRF",
2944 "PDB", "Heterogen", "BioSource", "MolInfo", NULL
2945 };
2946
2947 /*
2948 #ifdef INTERNAL_NCBI_SEQUIN
2949 #define LISTHEIGHT 16
2950 #else
2951 #define LISTHEIGHT 8
2952 #endif
2953 */
2954
2955 CharPtr MostUsedDescriptorList[] = { "Title" };
2956
2957 static Boolean isMostUsedDescriptor (CharPtr descname)
2958 {
2959 Int2 i;
2960
2961 if (descname == NULL) return FALSE;
2962
2963 for (i=0; i < sizeof (MostUsedDescriptorList) / sizeof (CharPtr); i++)
2964 {
2965 if (StringCmp (descname, MostUsedDescriptorList[i]) == 0)
2966 return TRUE;
2967 }
2968 return FALSE;
2969 }
2970
2971 static int LIBCALLBACK SortMostUsedDescriptorsFirst (VoidPtr ptr1, VoidPtr ptr2)
2972
2973 {
2974 ValNodePtr vnp1;
2975 ValNodePtr vnp2;
2976 CharPtr str1;
2977 CharPtr str2;
2978 Boolean str1_is_most_used;
2979 Boolean str2_is_most_used;
2980
2981 /* Check parameters */
2982
2983 if ((NULL == ptr1) || (NULL == ptr2))
2984 return 0;
2985
2986 vnp1 = *((ValNodePtr PNTR) ptr1);
2987 vnp2 = *((ValNodePtr PNTR) ptr2);
2988 if ((NULL == vnp1) || (NULL == vnp2))
2989 return 0;
2990
2991 str1 = (CharPtr) vnp1->data.ptrvalue;
2992 str2 = (CharPtr) vnp2->data.ptrvalue;
2993 if ((NULL == str1) || (NULL == str2))
2994 return 0;
2995
2996 str1_is_most_used = isMostUsedDescriptor (str1);
2997 str2_is_most_used = isMostUsedDescriptor (str2);
2998
2999 if ((str1_is_most_used && str2_is_most_used)
3000 || (!str1_is_most_used && !str2_is_most_used))
3001 {
3002 return SortVnpByString (ptr1, ptr2);
3003 }
3004 else if (str1_is_most_used)
3005 {
3006 return -1;
3007 }
3008 else
3009 {
3010 return 1;
3011 }
3012 }
3013
3014 extern ValNodePtr BuildDescriptorValNodeList (void)
3015 {
3016 Int4 j;
3017 ValNodePtr vnp;
3018 ValNodePtr head = NULL;
3019
3020 for (j = 1; descNames [j] != NULL; j++) {
3021 if (StringHasNoText (descNames [j])) continue;
3022 vnp = ValNodeNew (head);
3023 if (head == NULL) {
3024 head = vnp;
3025 }
3026 if (vnp != NULL) {
3027 vnp->choice = j;
3028 vnp->data.ptrvalue = StringSave (descNames [j]);
3029 }
3030 }
3031 head = SortValNode (head, SortMostUsedDescriptorsFirst);
3032 return head;
3033 }
3034
3035
3036 static void RemoveAsnObject (IteM i, Boolean feature)
3037
3038 {
3039 BaseFormPtr bfp;
3040 ButtoN b;
3041 GrouP c;
3042 GrouP g;
3043 GrouP h;
3044 ValNodePtr head;
3045 GrouP k;
3046 Int2 listHeight;
3047 GrouP m;
3048 RemoveFormPtr rfp;
3049 SeqEntryPtr sep;
3050 StdEditorProcsPtr sepp;
3051 CharPtr title;
3052 ValNodePtr vnp;
3053 WindoW w;
3054
3055 #ifdef WIN_MAC
3056 bfp = currentFormDataPtr;
3057 #else
3058 bfp = GetObjectExtra (i);
3059 #endif
3060 if (bfp == NULL) return;
3061 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3062 if (sep == NULL) return;
3063 rfp = (RemoveFormPtr) MemNew (sizeof (RemoveFormData));
3064 if (rfp == NULL) return;
3065 if (feature) {
3066 title = "Feature Removal";
3067 } else {
3068 title = "Descriptor Removal";
3069 }
3070 w = FixedWindow (-50, -33, -10, -10, title, StdCloseWindowProc);
3071 SetObjectExtra (w, rfp, CleanupRemovePage);
3072 rfp->form = (ForM) w;
3073 rfp->formmessage = RemoveMessageProc;
3074
3075 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3076 if (sepp != NULL) {
3077 SetActivate (w, sepp->activateForm);
3078 rfp->appmessage = sepp->handleMessages;
3079 }
3080
3081 rfp->input_entityID = bfp->input_entityID;
3082 rfp->input_itemID = bfp->input_itemID;
3083 rfp->input_itemtype = bfp->input_itemtype;
3084
3085 h = HiddenGroup (w, -1, 0, NULL);
3086 SetGroupSpacing (h, 10, 10);
3087
3088 g = HiddenGroup (h, 0, 2, NULL);
3089 rfp->is_feature = feature;
3090 if (feature) {
3091 StaticPrompt (g, "Feature", 0, 0, programFont, 'c');
3092 } else {
3093 StaticPrompt (g, "Descriptor", 0, 0, programFont, 'c');
3094 }
3095 if (indexerVersion) {
3096 listHeight = 16;
3097 } else {
3098 listHeight = 8;
3099 }
3100 rfp->objlist = MultiList (g, 16, listHeight, NULL);
3101 head = NULL;
3102 if (feature) {
3103 head = BuildFeatureValNodeList (TRUE, "All", ALL_FEATURES, TRUE, FALSE);
3104 } else {
3105 head = BuildDescriptorValNodeList();
3106 vnp = ValNodeNew (NULL);
3107 vnp->choice = Seq_descr_user;
3108 vnp->data.ptrvalue = StringSave ("StructuredComment");
3109 ValNodeInsert (&(head->next), vnp, SortVnpByString);
3110 }
3111 if (head != NULL) {
3112
3113 for (vnp = head; vnp != NULL; vnp = vnp->next) {
3114 ListItem (rfp->objlist, (CharPtr) vnp->data.ptrvalue);
3115 }
3116 }
3117 rfp->head = head;
3118 rfp->bsplist = NULL;
3119 rfp->bssplist = NULL;
3120
3121 k = NormalGroup (h, 0, 3, "Optional string constraint", NULL, NULL);
3122 rfp->string_constraint_type = HiddenGroup (k, 0, 2, NULL);
3123 RadioButton (rfp->string_constraint_type, "Remove when text is present");
3124 RadioButton (rfp->string_constraint_type, "Remove when text is not present");
3125 SetValue (rfp->string_constraint_type, 1);
3126 rfp->findthis = DialogText (k, "", 14, NULL);
3127 rfp->case_insensitive = CheckBox (k, "Case Insensitive", NULL);
3128
3129 m = NULL;
3130 if (feature) {
3131 m = HiddenGroup (h, 4, 0, NULL);
3132 StaticPrompt (m, "From", 0, dialogTextHeight, programFont, 'l');
3133 rfp->fromTxt = DialogText (m, "", 6, NULL);
3134 StaticPrompt (m, "To", 0, dialogTextHeight, programFont, 'l');
3135 rfp->toTxt = DialogText (m, "", 6, NULL);
3136 }
3137
3138 c = HiddenGroup (h, 4, 0, NULL);
3139 b = DefaultButton (c, "Accept", DoRemoveAsnObject);
3140 SetObjectExtra (b, rfp, NULL);
3141 PushButton (c, "Cancel", StdCancelButtonProc);
3142
3143 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) k, (HANDLE) c, (HANDLE) m, NULL);
3144 RealizeWindow (w);
3145 Show (w);
3146 Update ();
3147 }
3148
3149 extern void RemoveDescriptor (IteM i)
3150
3151 {
3152 RemoveAsnObject (i, FALSE);
3153 }
3154
3155 #define SLCT_FEAT 1
3156 #define SLCT_DESC 2
3157 #define SLCT_BIOSEQ 3
3158 #define SLCT_PUB 4
3159
3160 typedef struct selectformdata {
3161 FEATURE_FORM_BLOCK
3162
3163 Int2 type;
3164 LisT objlist;
3165 TexT findthis;
3166 Uint2 itemtype;
3167 Uint2 subtype;
3168 ObjMgrPtr omp;
3169 ObjMgrTypePtr omtp;
3170 ValNodePtr head;
3171 Boolean stringfound;
3172 Char findStr [128];
3173 ButtoN when_string_not_present;
3174 ButtoN case_insensitive;
3175 } SelectFormData, PNTR SelectFormPtr;
3176
3177 static void FeatureSelectCallback (SeqFeatPtr sfp, Pointer userdata)
3178 {
3179 Uint1Ptr subtype;
3180 if (sfp == NULL) return;
3181
3182 if (userdata != NULL)
3183 {
3184 subtype = (Uint1Ptr) userdata;
3185 if (*subtype != sfp->idx.subtype) return;
3186 }
3187 ObjMgrAlsoSelect (sfp->idx.entityID, sfp->idx.itemID, OBJ_SEQFEAT, 0, NULL);
3188 }
3189
3190 static void DescriptorSelectCallback (SeqDescrPtr sdp, Pointer userdata)
3191 {
3192 ObjValNodePtr ovp;
3193 Uint1Ptr subtype;
3194
3195 if (sdp == NULL || sdp->extended == 0) return;
3196
3197 ovp = (ObjValNodePtr) sdp;
3198 if (userdata != NULL)
3199 {
3200 subtype = (Uint1Ptr) userdata;
3201 if (*subtype != ovp->idx.subtype) return;
3202 }
3203
3204 ObjMgrAlsoSelect (ovp->idx.entityID, ovp->idx.itemID, OBJ_SEQDESC, 0, NULL);
3205 }
3206
3207 static void BioseqSelectCallback (BioseqPtr bsp, Pointer userdata)
3208 {
3209 Uint1Ptr subtype;
3210
3211 if (bsp == NULL) return;
3212
3213 if (userdata != NULL)
3214 {
3215 subtype = (Uint1Ptr) userdata;
3216 if (*subtype != bsp->idx.subtype) return;
3217 }
3218
3219 ObjMgrAlsoSelect (bsp->idx.entityID, bsp->idx.itemID, bsp->idx.itemtype, 0, NULL);
3220 }
3221
3222
3223 static void DoSelectAsnObject (ButtoN b)
3224
3225 {
3226 SelectFormPtr selfp;
3227 SeqEntryPtr sep;
3228 Int2 val;
3229 ValNodePtr vnp;
3230 FeaturesWithTextData fd;
3231 DescriptorsWithTextData dd;
3232 Uint1 bioseq_choice = Seq_repr_raw;
3233 Uint1 pub_choice = FEATDEF_PUB;
3234
3235 selfp = GetObjectExtra (b);
3236 if (selfp == NULL) return;
3237 sep = GetTopSeqEntryForEntityID (selfp->input_entityID);
3238 if (sep == NULL) return;
3239 Hide (selfp->form);
3240
3241 vnp = NULL;
3242 if (selfp->type == SLCT_FEAT || selfp->type == SLCT_DESC)
3243 {
3244 val = GetValue (selfp->objlist);
3245 if (val > 0) {
3246 vnp = selfp->head;
3247 while (vnp != NULL && val > 1) {
3248 val--;
3249 vnp = vnp->next;
3250 }
3251 }
3252 }
3253
3254 switch (selfp->type) {
3255 case SLCT_FEAT :
3256 GetTitle (selfp->findthis, selfp->findStr, sizeof (selfp->findStr) - 1);
3257 fd.search_text = selfp->findStr;
3258 fd.no_text = StringHasNoText (selfp->findStr);
3259 fd.seqFeatChoice = 0;
3260 fd.featDefChoice = 0;
3261 fd.case_insensitive = GetStatus (selfp->case_insensitive);
3262 fd.whole_word = FALSE;
3263 fd.act_when_string_not_present = GetStatus (selfp->when_string_not_present);
3264 fd.callback = FeatureSelectCallback;
3265 if (vnp == NULL)
3266 {
3267 fd.userdata = NULL;
3268 }
3269 else
3270 {
3271 fd.userdata = (Pointer) &(vnp->choice);
3272 }
3273 OperateOnSeqEntryFeaturesWithText (sep, &fd);
3274 break;
3275 case SLCT_DESC :
3276 GetTitle (selfp->findthis, selfp->findStr, sizeof (selfp->findStr) - 1);
3277 dd.search_text = selfp->findStr;
3278 dd.no_text = StringHasNoText (selfp->findStr);
3279 dd.case_insensitive = GetStatus (selfp->case_insensitive);
3280 dd.whole_word = FALSE;
3281 dd.act_when_string_not_present = GetStatus (selfp->when_string_not_present);
3282 dd.callback = DescriptorSelectCallback;
3283 if (vnp == NULL)
3284 {
3285 dd.userdata = NULL;
3286 }
3287 else
3288 {
3289 dd.userdata = (Pointer) &(vnp->choice);
3290 }
3291 OperateOnSeqEntryDescriptorsWithText (sep, &dd);
3292 break;
3293 case SLCT_BIOSEQ :
3294 VisitBioseqsInSep (sep, (Pointer) &bioseq_choice, BioseqSelectCallback);
3295 break;
3296 case SLCT_PUB:
3297 GetTitle (selfp->findthis, selfp->findStr, sizeof (selfp->findStr) - 1);
3298 fd.search_text = selfp->findStr;
3299 fd.no_text = StringHasNoText (selfp->findStr);
3300 fd.seqFeatChoice = 0;
3301 fd.featDefChoice = 0;
3302 fd.case_insensitive = GetStatus (selfp->case_insensitive);
3303 fd.whole_word = FALSE;
3304 fd.act_when_string_not_present = GetStatus (selfp->when_string_not_present);
3305 fd.callback = FeatureSelectCallback;
3306 fd.userdata = (Pointer) &pub_choice;
3307 OperateOnSeqEntryFeaturesWithText (sep, &fd);
3308 dd.search_text = fd.search_text;
3309 dd.no_text = fd.no_text;
3310 dd.case_insensitive = fd.case_insensitive;
3311 dd.whole_word = fd.whole_word;
3312 dd.act_when_string_not_present = fd.act_when_string_not_present;
3313 dd.callback = DescriptorSelectCallback;
3314 dd.userdata = fd.userdata;
3315 OperateOnSeqEntryDescriptorsWithText (sep, &dd);
3316 break;
3317 default :
3318 Remove (selfp->form);
3319 Update ();
3320 return;
3321 }
3322 WatchCursor ();
3323 Update ();
3324
3325 ArrowCursor ();
3326 Update ();
3327 /* ObjMgrSendMsg (OM_MSG_UPDATE, selfp->input_entityID, 0, 0); */
3328 Remove (selfp->form);
3329 }
3330
3331 static void SelectMessageProc (ForM f, Int2 mssg)
3332
3333 {
3334 SelectFormPtr selfp;
3335
3336 selfp = (SelectFormPtr) GetObjectExtra (f);
3337 if (selfp != NULL) {
3338 if (selfp->appmessage != NULL) {
3339 selfp->appmessage (f, mssg);
3340 }
3341 }
3342 }
3343
3344 static void CleanupSelectPage (GraphiC g, VoidPtr data)
3345
3346 {
3347 SelectFormPtr selfp;
3348
3349 selfp = (SelectFormPtr) data;
3350 if (selfp != NULL) {
3351 ValNodeFreeData (selfp->head);
3352 }
3353 StdCleanupFormProc (g, data);
3354 }
3355
3356 static void SelectAsnObject (IteM i, Int2 type)
3357
3358 {
3359 BaseFormPtr bfp;
3360 ButtoN b;
3361 GrouP c;
3362 GrouP g;
3363 GrouP h;
3364 GrouP k = NULL, m;
3365 ValNodePtr head;
3366 Uint1 j;
3367 Int2 listHeight;
3368 SelectFormPtr selfp;
3369 SeqEntryPtr sep;
3370 StdEditorProcsPtr sepp;
3371 CharPtr title;
3372 ValNodePtr vnp;
3373 WindoW w;
3374
3375 #ifdef WIN_MAC
3376 bfp = currentFormDataPtr;
3377 #else
3378 bfp = GetObjectExtra (i);
3379 #endif
3380 if (bfp == NULL) return;
3381 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3382 if (sep == NULL) return;
3383 selfp = (SelectFormPtr) MemNew (sizeof (SelectFormData));
3384 if (selfp == NULL) return;
3385 switch (type) {
3386 case SLCT_FEAT :
3387 title = "Feature Selection";
3388 break;
3389 case SLCT_DESC :
3390 title = "Descriptor Selection";
3391 break;
3392 case SLCT_BIOSEQ :
3393 title = "Sequence Selection";
3394 break;
3395 case SLCT_PUB:
3396 title = "Publication Selection";
3397 break;
3398 default :
3399 title = "? Selection";
3400 break;
3401 }
3402 w = FixedWindow (-50, -33, -10, -10, title, StdCloseWindowProc);
3403 SetObjectExtra (w, selfp, CleanupSelectPage);
3404 selfp->form = (ForM) w;
3405 selfp->formmessage = SelectMessageProc;
3406
3407 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3408 if (sepp != NULL) {
3409 SetActivate (w, sepp->activateForm);
3410 selfp->appmessage = sepp->handleMessages;
3411 }
3412
3413 selfp->input_entityID = bfp->input_entityID;
3414 selfp->input_itemID = bfp->input_itemID;
3415 selfp->input_itemtype = bfp->input_itemtype;
3416
3417 h = HiddenGroup (w, -1, 0, NULL);
3418 SetGroupSpacing (h, 10, 10);
3419
3420 g = HiddenGroup (h, 0, 2, NULL);
3421 selfp->type = type;
3422 switch (type) {
3423 case SLCT_FEAT :
3424 StaticPrompt (g, "Feature", 0, 0, programFont, 'c');
3425 break;
3426 case SLCT_DESC :
3427 StaticPrompt (g, "Descriptor", 0, 0, programFont, 'c');
3428 break;
3429 case SLCT_BIOSEQ :
3430 StaticPrompt (g, "Sequence", 0, 0, programFont, 'c');
3431 break;
3432 case SLCT_PUB:
3433 StaticPrompt (g, "Publication", 0, 0, programFont, 'c');
3434 break;
3435 default :
3436 break;
3437 }
3438 if (indexerVersion) {
3439 listHeight = 16;
3440 } else {
3441 listHeight = 8;
3442 }
3443
3444 if (type != SLCT_PUB)
3445 {
3446 selfp->objlist = SingleList (g, 16, listHeight, NULL);
3447 }
3448 head = NULL;
3449 if (type == SLCT_FEAT) {
3450 head = BuildFeatureValNodeList (TRUE, NULL, ALL_FEATURES, TRUE, FALSE);
3451 } else if (type == SLCT_DESC) {
3452 for (j = 1; descNames [j] != NULL; j++) {
3453 if (StringHasNoText (descNames [j])) continue;
3454 vnp = ValNodeNew (head);
3455 if (head == NULL) {
3456 head = vnp;
3457 }
3458 if (vnp != NULL) {
3459 vnp->choice = j;
3460 vnp->data.ptrvalue = StringSave (descNames [j]);
3461 }
3462 }
3463 }
3464 if (head != NULL) {
3465 if (type != SLCT_FEAT) {
3466 head = SortValNode (head, SortByVnpChoice);
3467 }
3468 for (vnp = head; vnp != NULL; vnp = vnp->next) {
3469 ListItem (selfp->objlist, (CharPtr) vnp->data.ptrvalue);
3470 }
3471 }
3472 selfp->head = head;
3473
3474 if (selfp->type == SLCT_FEAT || selfp->type == SLCT_DESC || selfp->type == SLCT_PUB)
3475 {
3476 k = HiddenGroup (h, 0, 3, NULL);
3477 StaticPrompt (k, "Optional string constraint", 0, dialogTextHeight, programFont, 'c');
3478 selfp->findthis = DialogText (k, "", 14, NULL);
3479 m = HiddenGroup (k, 2, 0, NULL);
3480 selfp->case_insensitive = CheckBox (m, "Case Insensitive", NULL);
3481 selfp->when_string_not_present = CheckBox (m, "When String Not Present", NULL);
3482 }
3483
3484 c = HiddenGroup (h, 4, 0, NULL);
3485 b = DefaultButton (c, "Accept", DoSelectAsnObject);
3486 SetObjectExtra (b, selfp, NULL);
3487 PushButton (c, "Cancel", StdCancelButtonProc);
3488
3489 if (selfp->type == SLCT_FEAT || selfp->type == SLCT_DESC)
3490 {
3491 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, (HANDLE) k, NULL);
3492 }
3493 else
3494 {
3495 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
3496 }
3497 RealizeWindow (w);
3498 if (type == SLCT_BIOSEQ) {
3499 DoSelectAsnObject (b);
3500 Update ();
3501 return;
3502 }
3503 Show (w);
3504 Update ();
3505 }
3506
3507 extern void SelectDescriptor (IteM i)
3508
3509 {
3510 SelectAsnObject (i, SLCT_DESC);
3511 }
3512
3513 extern void SelectBioseq (IteM i)
3514
3515 {
3516 SelectAsnObject (i, SLCT_BIOSEQ);
3517 }
3518
3519 extern void SelectPubs (IteM i)
3520
3521 {
3522 SelectAsnObject (i, SLCT_PUB);
3523 }
3524
3525 typedef struct fuseformdata {
3526 FEATURE_FORM_BLOCK
3527
3528 LisT objlist;
3529 Uint2 subtype;
3530 ValNodePtr head;
3531 } FuseFormData, PNTR FuseFormPtr;
3532
3533 static SeqLocPtr FuseTwoLocations (Uint2 entityID, SeqLocPtr slp1, SeqLocPtr slp2)
3534 {
3535 Boolean slp1_partial5, slp1_partial3;
3536 Boolean slp2_partial5, slp2_partial3;
3537 Int4 slp1_start_pos, slp1_stop_pos;
3538 Int4 slp2_start_pos, slp2_stop_pos;
3539 SeqLocPtr slp_result = NULL, slp2_copy, slp1_copy, slp_list;
3540 BioseqPtr bsp1, bsp2;
3541
3542 if (slp1 == NULL || slp2 == NULL)
3543 {
3544 return NULL;
3545 }
3546
3547 bsp1 = GetBioseqGivenSeqLoc (slp1, entityID);
3548 bsp2 = GetBioseqGivenSeqLoc (slp2, entityID);
3549
3550 /* preserve partialness of ends */
3551 CheckSeqLocForPartial (slp1, &slp1_partial5, &slp1_partial3);
3552 slp1_start_pos = SeqLocStart (slp1);
3553 slp1_stop_pos = SeqLocStop (slp1);
3554 CheckSeqLocForPartial (slp2, &slp2_partial5, &slp2_partial3);
3555 slp2_start_pos = SeqLocStart (slp2);
3556 slp2_stop_pos = SeqLocStop (slp2);
3557 if (slp1_start_pos > slp2_start_pos)
3558 {
3559 slp1_partial5 = slp2_partial5;
3560 }
3561 if (slp1_stop_pos < slp2_stop_pos)
3562 {
3563 slp1_partial3 = slp2_partial3;
3564 }
3565
3566 if (bsp1 == bsp2)
3567 {
3568 slp_result = SeqLocMerge (bsp1, slp2, slp1, FALSE, TRUE, FALSE);
3569 SetSeqLocPartial (slp_result, slp1_partial5, slp1_partial3);
3570 }
3571 else
3572 {
3573 /* we are dealing with a segmented set, and both locations are segments */
3574 slp1_copy = (SeqLocPtr) AsnIoMemCopy (slp1, (AsnReadFunc) SeqLocAsnRead,
3575 (AsnWriteFunc) SeqLocAsnWrite);
3576 slp2_copy = (SeqLocPtr) AsnIoMemCopy (slp2, (AsnReadFunc) SeqLocAsnRead,
3577 (AsnWriteFunc) SeqLocAsnWrite);
3578 if (slp1_copy != NULL && slp2_copy != NULL)
3579 {
3580 /* if the second location is already a mix, don't create a nested
3581 * mixed location.
3582 */
3583 if (slp2_copy->choice == SEQLOC_MIX)
3584 {
3585 slp_list = (SeqLocPtr) slp2_copy->data.ptrvalue;
3586 slp2_copy->data.ptrvalue = NULL;
3587 slp2_copy = SeqLocFree (slp2_copy);
3588 slp2_copy = slp_list;
3589 }
3590
3591 if (slp1_copy->choice == SEQLOC_MIX)
3592 {
3593 slp_list = slp1_copy->data.ptrvalue;
3594 while (slp_list != NULL && slp_list->next != NULL)
3595 {
3596 slp_list = slp_list->next;
3597 }
3598
3599
3600 if (slp_list == NULL)
3601 {
3602 slp1_copy->data.ptrvalue = slp2_copy;
3603 }
3604 else
3605 {
3606 slp_list->next = slp2_copy;
3607 }
3608 slp_result = slp1_copy;
3609 }
3610 else
3611 {
3612 slp_result = ValNodeNew (NULL);
3613 if (slp_result != NULL)
3614 {
3615 slp_result->choice = SEQLOC_MIX;
3616 slp_result->data.ptrvalue = slp1_copy;
3617 slp1_copy->next = slp2_copy;
3618 }
3619 }
3620 }
3621 }
3622
3623 return slp_result;
3624 }
3625
3626 static void CombineProductFeatures (BioseqPtr pbsp1, BioseqPtr pbsp2, Int4 old_len)
3627 {
3628 SeqAnnotPtr sap1, sap2, last_sap1 = NULL;
3629 SeqFeatPtr sfp2, sfp_new, last_sfp1 = NULL, main_prot = NULL;
3630 Boolean partial5_orig = TRUE, partial3_orig = TRUE;
3631 Boolean partial5_new, partial3_new;
3632 SeqEntryPtr psep;
3633 ProtRefPtr prp;
3634
3635 if (pbsp1 == NULL || pbsp2 == NULL)
3636 {
3637 return;
3638 }
3639
3640 sap2 = pbsp2->annot;
3641 while (sap2 != NULL && sap2->type != 1)
3642 {
3643 sap2 = sap2->next;
3644 }
3645 if (sap2 == NULL || sap2->data == NULL)
3646 {
3647 /* second sequence has no features */
3648 return;
3649 }
3650
3651 sap1 = pbsp1->annot;
3652 while (sap1 != NULL && sap1->type != 1)
3653 {
3654 last_sap1 = sap1;
3655 sap1 = sap1->next;
3656 }
3657 if (sap1 == NULL)
3658 {
3659 sap1 = SeqAnnotNew();
3660 if (sap1 == NULL)
3661 {
3662 return;
3663 }
3664 sap1->type = 1;
3665 sap1->data = NULL;
3666 if (last_sap1 == NULL)
3667 {
3668 pbsp1->annot = sap1;
3669 }
3670 else
3671 {
3672 last_sap1->next = sap1;
3673 }
3674 }
3675
3676 last_sfp1 = sap1->data;
3677 if (last_sfp1 != NULL && last_sfp1->idx.subtype == FEATDEF_PROT)
3678 {
3679 main_prot = last_sfp1;
3680 CheckSeqLocForPartial (main_prot->location, &partial5_orig, &partial3_orig);
3681 }
3682 while (last_sfp1 != NULL && last_sfp1->next != NULL)
3683 {
3684 if (main_prot == NULL && last_sfp1->idx.subtype == FEATDEF_PROT)
3685 {
3686 main_prot = last_sfp1;
3687 CheckSeqLocForPartial (main_prot->location, &partial5_orig, &partial3_orig);
3688 }
3689 last_sfp1 = last_sfp1->next;
3690 }
3691 if (last_sfp1 != NULL && main_prot == NULL && last_sfp1->idx.subtype == FEATDEF_PROT)
3692 {
3693 main_prot = last_sfp1;
3694 CheckSeqLocForPartial (main_prot->location, &partial5_orig, &partial3_orig);
3695 }
3696
3697 partial3_new = partial3_orig;
3698
3699 while (sap2 != NULL)
3700 {
3701 if (sap2->type == 1)
3702 {
3703 for (sfp2 = sap2->data; sfp2 != NULL; sfp2 = sfp2->next)
3704 {
3705 if (sfp2->idx.subtype == FEATDEF_PROT)
3706 {
3707 CheckSeqLocForPartial (sfp2->location, &partial5_new, &partial3_new);
3708 /* do not create additional full-length protein features */
3709 continue;
3710 }
3711 sfp_new = (SeqFeatPtr) AsnIoMemCopy (sfp2, (AsnReadFunc) SeqFeatAsnRead,
3712 (AsnWriteFunc) SeqFeatAsnWrite);
3713 if (sfp_new != NULL)
3714 {
3715 OffsetLocation (sfp_new->location, old_len, pbsp1->id);
3716
3717 if (last_sfp1 == NULL)
3718 {
3719 sap1->data = sfp_new;
3720 }
3721 else
3722 {
3723 last_sfp1->next = sfp_new;
3724 }
3725 last_sfp1 = sfp_new;
3726 }
3727 }
3728 }
3729 sap2 = sap2->next;
3730 }
3731
3732 /* make sure there is one full-length protein feature */
3733 if (main_prot == NULL)
3734 {
3735 psep = SeqMgrGetSeqEntryForData (pbsp1);
3736 main_prot = CreateNewFeature (psep, NULL, SEQFEAT_PROT, NULL);
3737 if (main_prot != NULL)
3738 {
3739 prp = ProtRefNew ();
3740 main_prot->data.value.ptrvalue = (Pointer) prp;
3741 }
3742 }
3743 if (main_prot != NULL)
3744 {
3745 if (main_prot->location == NULL || main_prot->location->choice != SEQLOC_INT)
3746 {
3747 main_prot->location = SeqLocFree (main_prot->location);
3748 main_prot->location = SeqLocIntNew (0, pbsp1->length - 1,
3749 Seq_strand_plus,
3750 SeqIdDup (pbsp1->id));
3751 }
3752 SetSeqLocPartial (main_prot->location, partial5_orig, partial3_new);
3753 main_prot->partial = (Boolean) (partial5_orig || partial3_new);
3754 }
3755 }
3756
3757 static void FuseTwoProducts (SeqFeatPtr sfp1, SeqFeatPtr sfp2, Uint2 entityID)
3758 {
3759 BioseqPtr pbsp1, pbsp2;
3760 CharPtr pstr1, pstr2;
3761 ByteStorePtr byte_store, bs2 = NULL;
3762 Int4 old_length, added_length;
3763 SeqIdPtr sip1;
3764
3765 if (sfp1 == NULL || sfp2 == NULL
3766 || sfp1->idx.subtype != FEATDEF_CDS
3767 || sfp2->idx.subtype != FEATDEF_CDS)
3768 {
3769 return;
3770 }
3771 pbsp1 = BioseqFindFromSeqLoc (sfp1->product);
3772 pbsp2 = BioseqFindFromSeqLoc (sfp2->product);
3773
3774 if (pbsp1 == NULL)
3775 {
3776 sip1 = SeqLocId (sfp1->product);
3777 pbsp1 = BioseqFind (sip1);
3778 if (pbsp1 == NULL)
3779 {
3780 RetranslateOneCDS (sfp1, entityID, TRUE, FALSE);
3781 pbsp1 = BioseqFindFromSeqLoc (sfp1->product);
3782 if (pbsp1 == NULL)
3783 {
3784 sip1 = SeqLocId (sfp1->product);
3785 pbsp1 = BioseqFind (sip1);
3786 }
3787 }
3788 }
3789 if (pbsp1 == NULL)
3790 {
3791 return;
3792 }
3793 pstr1 = BSMerge ((ByteStorePtr)(pbsp1->seq_data), NULL);
3794 old_length = pbsp1->length;
3795
3796 if (pbsp2 == NULL)
3797 {
3798 bs2 = ProteinFromCdRegionEx (sfp2, TRUE, FALSE);
3799 pstr2 = BSMerge (bs2, NULL);
3800 added_length = BSLen (bs2);
3801 }
3802 else
3803 {
3804 pstr2 = BSMerge ((ByteStorePtr)(pbsp2->seq_data), NULL);
3805 added_length = pbsp2->length;
3806 }
3807
3808 byte_store = BSNew (old_length + added_length);
3809 if (byte_store != NULL)
3810 {
3811 BSWrite (byte_store, pstr1, StringLen (pstr1));
3812 BSWrite (byte_store, pstr2, StringLen (pstr2));
3813 pbsp1->seq_data = SeqDataFree (pbsp1->seq_data, pbsp1->seq_data_type);
3814 pbsp1->seq_data = (SeqDataPtr) byte_store;
3815 pbsp1->length += added_length;
3816
3817 /* now copy features from the second protein to the first */
3818 CombineProductFeatures (pbsp1, pbsp2, old_length);
3819
3820 /* remove unused protein */
3821 if (pbsp2 != NULL)
3822 {
3823 pbsp2->idx.deleteme = TRUE;
3824 }
3825 }
3826 bs2 = BSFree (bs2);
3827 }
3828
3829 static void FuseFeatureCallback (BioseqPtr bsp, Pointer userdata)
3830 {
3831 FuseFormPtr ffp;
3832 SeqFeatPtr first = NULL, sfp = NULL;
3833 SeqMgrFeatContext context;
3834 SeqLocPtr slp;
3835
3836 if (bsp == NULL || userdata == NULL)
3837 {
3838 return;
3839 }
3840
3841 ffp = (FuseFormPtr) userdata;
3842
3843 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
3844 while (sfp != NULL)
3845 {
3846 if (sfp->idx.subtype == ffp->subtype ||
3847 (ffp->subtype == FEATDEF_IMP &&
3848 IsRealImpFeat (sfp->idx.subtype)))
3849 {
3850 if (first == NULL)
3851 {
3852 first = sfp;
3853 }
3854 else
3855 {
3856 slp = FuseTwoLocations (ffp->input_entityID, first->location, sfp->location);
3857 first->location = SeqLocFree (first->location);
3858 first->location = slp;
3859 first->partial = CheckSeqLocForPartial (slp, NULL, NULL);
3860 sfp->idx.deleteme = TRUE;
3861 if (sfp->idx.subtype == FEATDEF_CDS)
3862 {
3863 FuseTwoProducts (first, sfp, ffp->input_entityID);
3864 }
3865 }
3866 }
3867 sfp = SeqMgrGetNextFeature (bsp, sfp, 0, 0, &context);
3868 }
3869 }
3870
3871
3872 static void DoFuseFeature (ButtoN b)
3873
3874 {
3875 FuseFormPtr ffp;
3876 SeqEntryPtr sep;
3877 Int2 val;
3878 ValNodePtr vnp;
3879
3880 ffp = (FuseFormPtr) GetObjectExtra (b);
3881 if (ffp == NULL) return;
3882 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
3883 if (sep == NULL) return;
3884 Hide (ffp->form);
3885 WatchCursor ();
3886 Update ();
3887
3888 vnp = NULL;
3889 val = GetValue (ffp->objlist);
3890 if (val > 0) {
3891 vnp = ffp->head;
3892 while (vnp != NULL && val > 1) {
3893 val--;
3894 vnp = vnp->next;
3895 }
3896 }
3897 if (vnp != NULL) {
3898 ffp->subtype = vnp->choice;
3899 VisitBioseqsInSep (sep, ffp, FuseFeatureCallback);
3900 DeleteMarkedObjects (ffp->input_entityID, 0, NULL);
3901 }
3902
3903 ArrowCursor ();
3904 Update ();
3905 ObjMgrSetDirtyFlag (ffp->input_entityID, TRUE);
3906 ObjMgrSendMsg (OM_MSG_UPDATE, ffp->input_entityID, 0, 0);
3907 ObjMgrDeSelect (0, 0, 0, 0, NULL);
3908 Remove (ffp->form);
3909 }
3910
3911 static void FuseMessageProc (ForM f, Int2 mssg)
3912
3913 {
3914 FuseFormPtr ffp;
3915
3916 ffp = (FuseFormPtr) GetObjectExtra (f);
3917 if (ffp != NULL) {
3918 if (ffp->appmessage != NULL) {
3919 ffp->appmessage (f, mssg);
3920 }
3921 }
3922 }
3923
3924 static void CleanupFusePage (GraphiC g, VoidPtr data)
3925
3926 {
3927 FuseFormPtr ffp;
3928
3929 ffp = (FuseFormPtr) data;
3930 if (ffp != NULL) {
3931 ValNodeFreeData (ffp->head);
3932 }
3933 StdCleanupFormProc (g, data);
3934 }
3935
3936 extern void FuseFeature (IteM i)
3937
3938 {
3939 BaseFormPtr bfp;
3940 ButtoN b;
3941 GrouP c;
3942 FeatDefPtr curr;
3943 FuseFormPtr ffp;
3944 GrouP g;
3945 GrouP h;
3946 ValNodePtr head;
3947 Uint1 key;
3948 CharPtr label = NULL;
3949 Int2 listHeight;
3950 SeqEntryPtr sep;
3951 StdEditorProcsPtr sepp;
3952 Uint1 subtype;
3953 ValNodePtr vnp;
3954 WindoW w;
3955
3956 #ifdef WIN_MAC
3957 bfp = currentFormDataPtr;
3958 #else
3959 bfp = GetObjectExtra (i);
3960 #endif
3961 if (bfp == NULL) return;
3962 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
3963 if (sep == NULL) return;
3964 ffp = (FuseFormPtr) MemNew (sizeof (FuseFormData));
3965 if (ffp == NULL) return;
3966 w = FixedWindow (-50, -33, -10, -10, "Fuse Feature", StdCloseWindowProc);
3967 SetObjectExtra (w, ffp, CleanupFusePage);
3968 ffp->form = (ForM) w;
3969 ffp->formmessage = FuseMessageProc;
3970
3971 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3972 if (sepp != NULL) {
3973 SetActivate (w, sepp->activateForm);
3974 ffp->appmessage = sepp->handleMessages;
3975 }
3976
3977 ffp->input_entityID = bfp->input_entityID;
3978 ffp->input_itemID = bfp->input_itemID;
3979 ffp->input_itemtype = bfp->input_itemtype;
3980
3981 h = HiddenGroup (w, -1, 0, NULL);
3982 SetGroupSpacing (h, 10, 10);
3983
3984 g = HiddenGroup (h, 0, 2, NULL);
3985 StaticPrompt (g, "Feature", 0, 0, programFont, 'c');
3986 if (indexerVersion) {
3987 listHeight = 16;
3988 } else {
3989 listHeight = 8;
3990 }
3991 ffp->objlist = SingleList (g, 16, listHeight, NULL);
3992 head = NULL;
3993 curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
3994 while (curr != NULL) {
3995 if (key != FEATDEF_BAD) {
3996 subtype = curr->featdef_key;
3997 if (subtype != FEATDEF_misc_RNA &&
3998 subtype != FEATDEF_precursor_RNA &&
3999 subtype != FEATDEF_mat_peptide &&
4000 subtype != FEATDEF_sig_peptide &&
4001 subtype != FEATDEF_transit_peptide &&
4002 subtype != FEATDEF_Imp_CDS &&
4003 !IsUnwantedFeatureType(subtype)) {
4004 vnp = ValNodeNew (head);
4005 if (head == NULL) {
4006 head = vnp;
4007 }
4008 if (vnp != NULL) {
4009 vnp->choice = subtype;
4010 vnp->data.ptrvalue = StringSave (curr->typelabel);
4011 }
4012 }
4013 }
4014 curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
4015 }
4016 if (head != NULL) {
4017 head = SortValNode (head, SortByVnpChoice);
4018 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4019 ListItem (ffp->objlist, (CharPtr) vnp->data.ptrvalue);
4020 }
4021 }
4022 ffp->head = head;
4023
4024 c = HiddenGroup (h, 4, 0, NULL);
4025 b = DefaultButton (c, "Accept", DoFuseFeature);
4026 SetObjectExtra (b, ffp, NULL);
4027 PushButton (c, "Cancel", StdCancelButtonProc);
4028
4029 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
4030 RealizeWindow (w);
4031 Show (w);
4032 Update ();
4033 }
4034
4035
4036
4037
4038
4039 typedef struct genomeprojiduserdialog {
4040 DIALOG_MESSAGE_BLOCK
4041 DialoG ids;
4042 } GenomeprojidUserDialog, PNTR GenomeprojidUserDialogPtr;
4043
4044 typedef struct genomeprojiduserform {
4045 FEATURE_FORM_BLOCK
4046 SeqEntryPtr sep;
4047 } GenomeprojidUserForm, PNTR GenomeprojidUserFormPtr;
4048
4049 static void UserObjectPtrToGenomeprojidDialog (DialoG d, Pointer data)
4050
4051 {
4052 Char buf [64];
4053 UserFieldPtr curr;
4054 ValNodePtr head = NULL;
4055 ObjectIdPtr oip;
4056 Int4 parentID;
4057 Int4 projectID;
4058 GenomeprojidUserDialogPtr rdp;
4059 UserObjectPtr uop;
4060 Int4 val;
4061
4062 rdp = (GenomeprojidUserDialogPtr) GetObjectExtra (d);
4063 if (rdp == NULL) return;
4064 uop = (UserObjectPtr) data;
4065 if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "GenomeProjectsDB") != 0) {
4066 PointerToDialog (rdp->ids, NULL);
4067 return;
4068 }
4069 projectID = 0;
4070 parentID = 0;
4071 for (curr = uop->data; curr != NULL; curr = curr->next) {
4072 oip = curr->label;
4073 if (oip == NULL) continue;
4074 if (StringICmp (oip->str, "ProjectID") == 0) {
4075 if (curr->choice == 2) {
4076 val = (Int4) curr->data.intvalue;
4077 if (projectID > 0) {
4078 sprintf (buf, "%ld\t%ld", (long) projectID, (long) parentID);
4079 ValNodeCopyStr (&head, 0, buf);
4080 parentID = 0;
4081 }
4082 projectID = val;
4083 }
4084 } else if (StringICmp (oip->str, "ParentID") == 0) {
4085 if (curr->choice == 2) {
4086 val = (Int4) curr->data.intvalue;
4087 parentID = val;
4088 }
4089 }
4090 }
4091 if (projectID > 0) {
4092 sprintf (buf, "%ld\t%ld", (long) projectID, (long) parentID);
4093 ValNodeCopyStr (&head, 0, buf);
4094 }
4095
4096 PointerToDialog (rdp->ids, (Pointer) head);
4097 ValNodeFreeData (head);
4098 }
4099
4100 static Pointer GenomeprojidDialogToUserObjectPtr (DialoG d)
4101
4102 {
4103 Char buf [64];
4104 ValNodePtr head;
4105 Int4 parentID;
4106 Int4 projectID;
4107 CharPtr ptr1;
4108 CharPtr ptr2;
4109 GenomeprojidUserDialogPtr rdp;
4110 CharPtr str;
4111 UserObjectPtr uop;
4112 long int val;
4113 ValNodePtr vnp;
4114
4115 rdp = (GenomeprojidUserDialogPtr) GetObjectExtra (d);
4116 if (rdp == NULL) return NULL;
4117
4118 uop = CreateGenomeProjectsDBUserObject ();
4119 if (uop == NULL) return NULL;
4120
4121 head = (ValNodePtr) DialogToPointer (rdp->ids);
4122 if (head == NULL) return NULL;
4123
4124 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4125 projectID = 0;
4126 parentID = 0;
4127 str = (CharPtr) vnp->data.ptrvalue;
4128 if (StringHasNoText (str)) continue;
4129 StringNCpy_0 (buf, str, sizeof (buf));
4130 ptr1 = StringChr (buf, '\t');
4131 if (ptr1 != NULL) {
4132 *ptr1 = '\0';
4133 ptr1++;
4134 ptr2 = StringChr (ptr1, '\n');
4135 if (ptr2 == NULL) {
4136 ptr2 = StringChr (ptr1, '\t');
4137 }
4138 if (ptr2 != NULL) {
4139 *ptr2 = '\0';
4140 }
4141 if (sscanf (buf, "%ld", &val) == 1 && val > 0) {
4142 projectID = (Int4) val;
4143 if (sscanf (ptr1, "%ld", &val) == 1 && val > 0) {
4144 parentID = (Int4) val;
4145 }
4146 AddIDsToGenomeProjectsDBUserObject (uop, projectID, parentID);
4147 }
4148 }
4149 }
4150
4151 ValNodeFreeData (head);
4152
4153 return uop;
4154 }
4155
4156 static void ValNodePtrToGenomeprojidDialog (DialoG d, Pointer data)
4157
4158 {
4159 ValNodePtr head;
4160 Int2 j;
4161 ValNodePtr list;
4162 CharPtr str;
4163 TagListPtr tlp;
4164 ValNodePtr vnp;
4165
4166 tlp = (TagListPtr) GetObjectExtra (d);
4167 list = (ValNodePtr) data;
4168 if (tlp != NULL) {
4169 head = NULL;
4170 while (list != NULL) {
4171 vnp = ValNodeNew (head);
4172 if (head == NULL) {
4173 head = vnp;
4174 }
4175 if (vnp != NULL) {
4176 str = MemNew (StringLen ((CharPtr) list->data.ptrvalue) + 3);
4177 if (str != NULL) {
4178 StringCpy (str, (CharPtr) list->data.ptrvalue);
4179 StringCat (str, "\n");
4180 }
4181 vnp->data.ptrvalue = str;
4182 }
4183 list = list->next;
4184 }
4185 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
4186 tlp->vnp = head;
4187 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
4188 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
4189 }
4190 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
4191 CorrectBarMax (tlp->bar, tlp->max);
4192 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
4193 }
4194 }
4195
4196 static Pointer GenomeprojidDialogToValNodePtr (DialoG d)
4197
4198 {
4199 Char ch;
4200 ValNodePtr head;
4201 Int2 j;
4202 Int2 len;
4203 ValNodePtr list;
4204 Boolean okay;
4205 CharPtr str;
4206 TagListPtr tlp;
4207 ValNodePtr vnp;
4208
4209 head = NULL;
4210 tlp = (TagListPtr) GetObjectExtra (d);
4211 if (tlp != NULL && tlp->vnp != NULL) {
4212 list = NULL;
4213 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
4214 str = (CharPtr) vnp->data.ptrvalue;
4215 okay = FALSE;
4216 len = StringLen (str);
4217 for (j = 0; j < len; j++) {
4218 ch = str [j];
4219 if (ch != ' ' && ch != '\t' && ch != '\n') {
4220 okay = TRUE;
4221 }
4222 }
4223 if (okay) {
4224 list = ValNodeNew (list);
4225 if (head == NULL) {
4226 head = list;
4227 }
4228 if (list != NULL) {
4229 list->choice = 0;
4230 list->data.ptrvalue = StringSave (str);
4231 }
4232 }
4233 }
4234 }
4235 return (Pointer) head;
4236 }
4237
4238 Uint2 genproj_types [] = {
4239 TAGLIST_TEXT, TAGLIST_TEXT
4240 };
4241
4242 Uint2 genproj_widths [] = {
4243 10, 10, 0
4244 };
4245
4246 static DialoG CreateGenomeProjectsDBDialog (GrouP g)
4247
4248 {
4249 GrouP p;
4250 GenomeprojidUserDialogPtr rdp;
4251 GrouP x;
4252 GrouP y;
4253
4254 p = HiddenGroup (g, -1, 0, NULL);
4255 SetGroupSpacing (p, 10, 10);
4256
4257 rdp = (GenomeprojidUserDialogPtr) MemNew (sizeof (GenomeprojidUserDialog));
4258 if (rdp == NULL) return NULL;
4259
4260 SetObjectExtra (p, rdp, NULL);
4261 rdp->dialog = (DialoG) p;
4262 rdp->todialog = UserObjectPtrToGenomeprojidDialog;
4263 rdp->fromdialog = GenomeprojidDialogToUserObjectPtr;
4264
4265 x = HiddenGroup (p, 0, 2, NULL);
4266 y = HiddenGroup (x, 3, 0, NULL);
4267 StaticPrompt (y, "Project ID", 10 * stdCharWidth, 0, programFont, 'c');
4268 StaticPrompt (y, "Parent ID", 10 * stdCharWidth, 0, programFont, 'c');
4269
4270 rdp->ids = CreateTagListDialog (x, 3, 2, -1,
4271 genproj_types, genproj_widths, NULL,
4272 ValNodePtrToGenomeprojidDialog,
4273 GenomeprojidDialogToValNodePtr);
4274
4275 return (DialoG) p;
4276 }
4277
4278 static void GenomeProjectsDBUserFormMessage (ForM f, Int2 mssg)
4279
4280 {
4281 GenomeprojidUserFormPtr rfp;
4282
4283 rfp = (GenomeprojidUserFormPtr) GetObjectExtra (f);
4284 if (rfp != NULL) {
4285 switch (mssg) {
4286 case VIB_MSG_CLOSE :
4287 Remove (f);
4288 break;
4289 case VIB_MSG_CUT :
4290 StdCutTextProc (NULL);
4291 break;
4292 case VIB_MSG_COPY :
4293 StdCopyTextProc (NULL);
4294 break;
4295 case VIB_MSG_PASTE :
4296 StdPasteTextProc (NULL);
4297 break;
4298 case VIB_MSG_DELETE :
4299 StdDeleteTextProc (NULL);
4300 break;
4301 default :
4302 if (rfp->appmessage != NULL) {
4303 rfp->appmessage (f, mssg);
4304 }
4305 break;
4306 }
4307 }
4308 }
4309
4310 static ForM CreateGenomeProjectsDBDescForm (Int2 left, Int2 top, Int2 width,
4311 Int2 height, CharPtr title, ValNodePtr sdp,
4312 SeqEntryPtr sep, FormActnFunc actproc)
4313
4314 {
4315 ButtoN b;
4316 GrouP c;
4317 GrouP g;
4318 GenomeprojidUserFormPtr rfp;
4319 StdEditorProcsPtr sepp;
4320 WindoW w;
4321
4322 w = NULL;
4323 rfp = (GenomeprojidUserFormPtr) MemNew (sizeof (GenomeprojidUserForm));
4324 if (rfp != NULL) {
4325 w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
4326 SetObjectExtra (w, rfp, StdDescFormCleanupProc);
4327 rfp->form = (ForM) w;
4328 rfp->actproc = actproc;
4329 rfp->formmessage = GenomeProjectsDBUserFormMessage;
4330
4331 rfp->sep = sep;
4332
4333 #ifndef WIN_MAC
4334 CreateStdEditorFormMenus (w);
4335 #endif
4336 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4337 if (sepp != NULL) {
4338 SetActivate (w, sepp->activateForm);
4339 rfp->appmessage = sepp->handleMessages;
4340 }
4341
4342 g = HiddenGroup (w, -1, 0, NULL);
4343 rfp->data = CreateGenomeProjectsDBDialog (g);
4344
4345 c = HiddenGroup (w, 2, 0, NULL);
4346 b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
4347 SetObjectExtra (b, rfp, NULL);
4348 PushButton (c, "Cancel", StdCancelButtonProc);
4349 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
4350 RealizeWindow (w);
4351 }
4352 return (ForM) w;
4353 }
4354
4355 extern Int2 LIBCALLBACK GenomeProjectsDBUserGenFunc (Pointer data);
4356 extern Int2 LIBCALLBACK GenomeProjectsDBUserGenFunc (Pointer data)
4357
4358 {
4359 ObjectIdPtr oip;
4360 OMProcControlPtr ompcp;
4361 OMUserDataPtr omudp;
4362 ObjMgrProcPtr proc;
4363 GenomeprojidUserFormPtr rfp;
4364 ValNodePtr sdp;
4365 SeqEntryPtr sep;
4366 UserObjectPtr uop;
4367 WindoW w;
4368
4369 ompcp = (OMProcControlPtr) data;
4370 w = NULL;
4371 sdp = NULL;
4372 sep = NULL;
4373 uop = NULL;
4374 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4375 proc = ompcp->proc;
4376 switch (ompcp->input_itemtype) {
4377 case OBJ_SEQDESC :
4378 sdp = (ValNodePtr) ompcp->input_data;
4379 if (sdp != NULL && sdp->choice != Seq_descr_user) {
4380 return OM_MSG_RET_ERROR;
4381 }
4382 uop = (UserObjectPtr) sdp->data.ptrvalue;
4383 break;
4384 case OBJ_BIOSEQ :
4385 break;
4386 case OBJ_BIOSEQSET :
4387 break;
4388 case 0 :
4389 break;
4390 default :
4391 return OM_MSG_RET_ERROR;
4392 }
4393 omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
4394 ompcp->input_itemtype, ompcp->proc->procid);
4395 if (omudp != NULL) {
4396 if (StringCmp (proc->procname, "Edit GenomeProjectsDB User Desc") == 0) {
4397 rfp = (GenomeprojidUserFormPtr) omudp->userdata.ptrvalue;
4398 if (rfp != NULL) {
4399 Select (rfp->form);
4400 }
4401 return OM_MSG_RET_DONE;
4402 } else {
4403 return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
4404 }
4405 }
4406 if (uop != NULL) {
4407 oip = uop->type;
4408 if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
4409 if (StringCmp (oip->str, "GenomeProjectsDB") != 0) return OM_MSG_RET_OK;
4410 }
4411 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
4412 w = (WindoW) CreateGenomeProjectsDBDescForm (-50, -33, -10, -10,
4413 "Genome Projects DB", sdp, sep,
4414 StdDescFormActnProc);
4415 rfp = (GenomeprojidUserFormPtr) GetObjectExtra (w);
4416 if (rfp != NULL) {
4417 rfp->input_entityID = ompcp->input_entityID;
4418 rfp->input_itemID = ompcp->input_itemID;
4419 rfp->input_itemtype = ompcp->input_itemtype;
4420 rfp->this_itemtype = OBJ_SEQDESC;
4421 rfp->this_subtype = Seq_descr_user;
4422 rfp->procid = ompcp->proc->procid;
4423 rfp->proctype = ompcp->proc->proctype;
4424 rfp->userkey = OMGetNextUserKey ();
4425 omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
4426 OMPROC_EDIT, rfp->userkey);
4427 if (omudp != NULL) {
4428 omudp->userdata.ptrvalue = (Pointer) rfp;
4429 omudp->messagefunc = StdVibrantEditorMsgFunc;
4430 }
4431 SendMessageToForm (rfp->form, VIB_MSG_INIT);
4432 if (sdp != NULL) {
4433 PointerToDialog (rfp->data, (Pointer) sdp->data.ptrvalue);
4434 SetClosestParentIfDuplicating ((BaseFormPtr) rfp);
4435 }
4436 }
4437 Show (w);
4438 Select (w);
4439 return OM_MSG_RET_DONE;
4440 }
4441
4442
4443 typedef struct dblinkdialog {
4444 DIALOG_MESSAGE_BLOCK
4445 DialoG traceassm;
4446 DialoG biosample;
4447 DialoG probedb;
4448 } DblinkDialog, PNTR DblinkDialogPtr;
4449
4450 typedef struct dblinkform {
4451 FEATURE_FORM_BLOCK
4452 SeqEntryPtr sep;
4453 } DblinkForm, PNTR DblinkFormPtr;
4454
4455 static void UserObjectPtrToDblinkDialog (
4456 DialoG d,
4457 Pointer data
4458 )
4459
4460 {
4461 Char buf [32];
4462 CharPtr PNTR cpp;
4463 UserFieldPtr curr;
4464 DblinkDialogPtr ddp;
4465 ValNodePtr head;
4466 Int4 i, val;
4467 Int4Ptr ip;
4468 Int4 num;
4469 ObjectIdPtr oip;
4470 CharPtr str;
4471 UserObjectPtr uop;
4472
4473 ddp = (DblinkDialogPtr) GetObjectExtra (d);
4474 if (ddp == NULL) return;
4475
4476 uop = (UserObjectPtr) data;
4477 if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "DBLink") != 0) {
4478 PointerToDialog (ddp->traceassm, NULL);
4479 PointerToDialog (ddp->biosample, NULL);
4480 PointerToDialog (ddp->probedb, NULL);
4481 return;
4482 }
4483
4484 for (curr = uop->data; curr != NULL; curr = curr->next) {
4485 oip = curr->label;
4486 if (oip == NULL) continue;
4487 if (StringICmp (oip->str, "Trace Assembly Archive") == 0) {
4488 if (curr->choice == 8) {
4489 num = curr->num;
4490 ip = (Int4Ptr) curr->data.ptrvalue;
4491 if (num > 0 && ip != NULL) {
4492 head = NULL;
4493 for (i = 0; i < num; i++) {
4494 val = ip [i];
4495 if (val > 0) {
4496 sprintf (buf, "%ld", (long) val);
4497 ValNodeCopyStr (&head, 0, buf);
4498 }
4499 }
4500 if (head != NULL) {
4501 PointerToDialog (ddp->traceassm, (Pointer) head);
4502 }
4503 head = ValNodeFreeData (head);
4504 }
4505 }
4506 } else if (StringICmp (oip->str, "Bio Sample") == 0) {
4507 if (curr->choice == 7) {
4508 num = curr->num;
4509 cpp = (CharPtr PNTR) curr->data.ptrvalue;
4510 if (num > 0 && cpp != NULL) {
4511 head = NULL;
4512 for (i = 0; i < num; i++) {
4513 str = cpp [i];
4514 if (StringDoesHaveText (str)) {
4515 ValNodeCopyStr (&head, 0, str);
4516 }
4517 }
4518 if (head != NULL) {
4519 PointerToDialog (ddp->biosample, (Pointer) head);
4520 }
4521 head = ValNodeFreeData (head);
4522 }
4523 }
4524 } else if (StringICmp (oip->str, "ProbeDB") == 0) {
4525 if (curr->choice == 7) {
4526 num = curr->num;
4527 cpp = (CharPtr PNTR) curr->data.ptrvalue;
4528 if (num > 0 && cpp != NULL) {
4529 head = NULL;
4530 for (i = 0; i < num; i++) {
4531 str = cpp [i];
4532 if (StringDoesHaveText (str)) {
4533 ValNodeCopyStr (&head, 0, str);
4534 }
4535 }
4536 if (head != NULL) {
4537 PointerToDialog (ddp->probedb, (Pointer) head);
4538 }
4539 head = ValNodeFreeData (head);
4540 }
4541 }
4542 }
4543 }
4544 }
4545
4546 static Pointer DblinkDialogToUserObjectPtr (
4547 DialoG d
4548 )
4549
4550 {
4551 CharPtr PNTR cpp;
4552 DblinkDialogPtr ddp;
4553 ValNodePtr head, vnp;
4554 Int4 i, num;
4555 Int4Ptr ipp;
4556 Boolean okay = FALSE;
4557 CharPtr str;
4558 UserObjectPtr uop;
4559 long int val;
4560
4561 ddp = (DblinkDialogPtr) GetObjectExtra (d);
4562 if (ddp == NULL) return NULL;
4563
4564 uop = CreateDBLinkUserObject ();
4565 if (uop == NULL) return NULL;
4566
4567 head = (ValNodePtr) DialogToPointer (ddp->traceassm);
4568 if (head != NULL) {
4569 num = 0;
4570 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4571 str = (CharPtr) vnp->data.ptrvalue;
4572 if (StringHasNoText (str)) continue;
4573 num++;
4574 }
4575 if (num > 0) {
4576 ipp = (Int4Ptr) MemNew (sizeof (Int4) * num);
4577 if (ipp != NULL) {
4578 i = 0;
4579 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4580 str = (CharPtr) vnp->data.ptrvalue;
4581 if (StringHasNoText (str)) continue;
4582 if (sscanf (str, "%ld", &val) == 1) {
4583 ipp [i] = (Int4) val;
4584 i++;
4585 }
4586 }
4587 if (i > 0) {
4588 AddTraceAssemblyIDsToDBLinkUserObject (uop, i, ipp);
4589 okay = TRUE;
4590 }
4591 }
4592 }
4593 }
4594 ValNodeFreeData (head);
4595
4596 head = (ValNodePtr) DialogToPointer (ddp->biosample);
4597 if (head != NULL) {
4598 num = 0;
4599 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4600 str = (CharPtr) vnp->data.ptrvalue;
4601 if (StringHasNoText (str)) continue;
4602 num++;
4603 }
4604 if (num > 0) {
4605 cpp = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num);
4606 if (cpp != NULL) {
4607 i = 0;
4608 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4609 str = (CharPtr) vnp->data.ptrvalue;
4610 if (StringHasNoText (str)) continue;
4611 cpp [i] = str;
4612 i++;
4613 }
4614 if (i > 0) {
4615 AddBioSampleIDsToDBLinkUserObject (uop, i, cpp);
4616 okay = TRUE;
4617 }
4618 }
4619 }
4620 }
4621 ValNodeFreeData (head);
4622
4623 head = (ValNodePtr) DialogToPointer (ddp->probedb);
4624 if (head != NULL) {
4625 num = 0;
4626 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4627 str = (CharPtr) vnp->data.ptrvalue;
4628 if (StringHasNoText (str)) continue;
4629 num++;
4630 }
4631 if (num > 0) {
4632 cpp = (CharPtr PNTR) MemNew (sizeof (CharPtr) * num);
4633 if (cpp != NULL) {
4634 i = 0;
4635 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4636 str = (CharPtr) vnp->data.ptrvalue;
4637 if (StringHasNoText (str)) continue;
4638 cpp [i] = str;
4639 i++;
4640 }
4641 if (i > 0) {
4642 AddProbeDBIDsToDBLinkUserObject (uop, i, cpp);
4643 okay = TRUE;
4644 }
4645 }
4646 }
4647 }
4648 ValNodeFreeData (head);
4649
4650 if (! okay) {
4651 uop = UserObjectFree (uop);
4652 }
4653
4654 return uop;
4655 }
4656
4657 static DialoG CreateDblinkDialog (
4658 GrouP g
4659 )
4660
4661 {
4662 DblinkDialogPtr ddp;
4663 GrouP p, x;
4664
4665 p = HiddenGroup (g, -1, 0, NULL);
4666 SetGroupSpacing (p, 10, 10);
4667
4668 ddp = (DblinkDialogPtr) MemNew (sizeof (DblinkDialog));
4669 if (ddp == NULL) return NULL;
4670
4671 SetObjectExtra (p, ddp, NULL);
4672 ddp->dialog = (DialoG) p;
4673 ddp->todialog = UserObjectPtrToDblinkDialog;
4674 ddp->fromdialog = DblinkDialogToUserObjectPtr;
4675
4676 x = HiddenGroup (p, 0, 8, NULL);
4677
4678 StaticPrompt (x, "Trace Assembly", 10 * stdCharWidth, 0, programFont, 'c');
4679 ddp->traceassm = CreateVisibleStringDialog (x, 3, -1, 15);
4680
4681 StaticPrompt (x, "Bio Sample", 10 * stdCharWidth, 0, programFont, 'c');
4682 ddp->biosample = CreateVisibleStringDialog (x, 3, -1, 15);
4683
4684 StaticPrompt (x, "ProbeDB", 10 * stdCharWidth, 0, programFont, 'c');
4685 ddp->probedb = CreateVisibleStringDialog (x, 3, -1, 15);
4686
4687 return (DialoG) p;
4688 }
4689
4690 static void DblinkFormMessage (
4691 ForM f,
4692 Int2 mssg
4693 )
4694
4695 {
4696 DblinkFormPtr dfp;
4697
4698 dfp = (DblinkFormPtr) GetObjectExtra (f);
4699 if (dfp != NULL) {
4700 switch (mssg) {
4701 case VIB_MSG_CLOSE :
4702 Remove (f);
4703 break;
4704 case VIB_MSG_CUT :
4705 StdCutTextProc (NULL);
4706 break;
4707 case VIB_MSG_COPY :
4708 StdCopyTextProc (NULL);
4709 break;
4710 case VIB_MSG_PASTE :
4711 StdPasteTextProc (NULL);
4712 break;
4713 case VIB_MSG_DELETE :
4714 StdDeleteTextProc (NULL);
4715 break;
4716 default :
4717 if (dfp->appmessage != NULL) {
4718 dfp->appmessage (f, mssg);
4719 }
4720 break;
4721 }
4722 }
4723 }
4724
4725 static ForM CreateDblinkDescForm (
4726 Int2 left,
4727 Int2 top,
4728 Int2 width,
4729 Int2 height,
4730 CharPtr title,
4731 ValNodePtr sdp,
4732 SeqEntryPtr sep,
4733 FormActnFunc actproc
4734 )
4735
4736 {
4737 ButtoN b;
4738 DblinkFormPtr dfp;
4739 GrouP c, g;
4740 StdEditorProcsPtr sepp;
4741 WindoW w;
4742
4743 w = NULL;
4744 dfp = (DblinkFormPtr) MemNew (sizeof (DblinkForm));
4745
4746 if (dfp != NULL) {
4747 w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
4748 SetObjectExtra (w, dfp, StdDescFormCleanupProc);
4749 dfp->form = (ForM) w;
4750 dfp->actproc = actproc;
4751 dfp->formmessage = DblinkFormMessage;
4752
4753 dfp->sep = sep;
4754
4755 #ifndef WIN_MAC
4756 CreateStdEditorFormMenus (w);
4757 #endif
4758 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4759 if (sepp != NULL) {
4760 SetActivate (w, sepp->activateForm);
4761 dfp->appmessage = sepp->handleMessages;
4762 }
4763
4764 g = HiddenGroup (w, -1, 0, NULL);
4765 dfp->data = CreateDblinkDialog (g);
4766
4767 c = HiddenGroup (w, 2, 0, NULL);
4768 b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
4769 SetObjectExtra (b, dfp, NULL);
4770 PushButton (c, "Cancel", StdCancelButtonProc);
4771 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
4772 RealizeWindow (w);
4773 }
4774
4775 return (ForM) w;
4776 }
4777
4778 extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data);
4779 extern Int2 LIBCALLBACK DBlinkUserGenFunc (Pointer data)
4780
4781 {
4782 ObjectIdPtr oip;
4783 OMProcControlPtr ompcp;
4784 OMUserDataPtr omudp;
4785 ObjMgrProcPtr proc;
4786 DblinkFormPtr dfp;
4787 ValNodePtr sdp;
4788 SeqEntryPtr sep;
4789 UserObjectPtr uop;
4790 WindoW w;
4791
4792 ompcp = (OMProcControlPtr) data;
4793 w = NULL;
4794 sdp = NULL;
4795 sep = NULL;
4796 uop = NULL;
4797 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4798 proc = ompcp->proc;
4799 switch (ompcp->input_itemtype) {
4800 case OBJ_SEQDESC :
4801 sdp = (ValNodePtr) ompcp->input_data;
4802 if (sdp != NULL && sdp->choice != Seq_descr_user) {
4803 return OM_MSG_RET_ERROR;
4804 }
4805 uop = (UserObjectPtr) sdp->data.ptrvalue;
4806 break;
4807 case OBJ_BIOSEQ :
4808 break;
4809 case OBJ_BIOSEQSET :
4810 break;
4811 case 0 :
4812 break;
4813 default :
4814 return OM_MSG_RET_ERROR;
4815 }
4816 omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
4817 ompcp->input_itemtype, ompcp->proc->procid);
4818 if (omudp != NULL) {
4819 if (StringCmp (proc->procname, "Edit DBLink User Desc") == 0) {
4820 dfp = (DblinkFormPtr) omudp->userdata.ptrvalue;
4821 if (dfp != NULL) {
4822 Select (dfp->form);
4823 }
4824 return OM_MSG_RET_DONE;
4825 } else {
4826 return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
4827 }
4828 }
4829 if (uop != NULL) {
4830 oip = uop->type;
4831 if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
4832 if (StringCmp (oip->str, "DBLink") != 0) return OM_MSG_RET_OK;
4833 }
4834 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
4835 w = (WindoW) CreateDblinkDescForm (-50, -33, -10, -10,
4836 "DBLink", sdp, sep,
4837 StdDescFormActnProc);
4838 dfp = (DblinkFormPtr) GetObjectExtra (w);
4839 if (dfp != NULL) {
4840 dfp->input_entityID = ompcp->input_entityID;
4841 dfp->input_itemID = ompcp->input_itemID;
4842 dfp->input_itemtype = ompcp->input_itemtype;
4843 dfp->this_itemtype = OBJ_SEQDESC;
4844 dfp->this_subtype = Seq_descr_user;
4845 dfp->procid = ompcp->proc->procid;
4846 dfp->proctype = ompcp->proc->proctype;
4847 dfp->userkey = OMGetNextUserKey ();
4848 omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
4849 OMPROC_EDIT, dfp->userkey);
4850 if (omudp != NULL) {
4851 omudp->userdata.ptrvalue = (Pointer) dfp;
4852 omudp->messagefunc = StdVibrantEditorMsgFunc;
4853 }
4854 SendMessageToForm (dfp->form, VIB_MSG_INIT);
4855 if (sdp != NULL) {
4856 PointerToDialog (dfp->data, (Pointer) sdp->data.ptrvalue);
4857 SetClosestParentIfDuplicating ((BaseFormPtr) dfp);
4858 }
4859 }
4860 Show (w);
4861 Select (w);
4862 return OM_MSG_RET_DONE;
4863 }
4864
4865
4866 extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data);
4867
4868 #define REFGENE_ASSEMBLY 1
4869 #define REFGENE_RELATED 2
4870 #define REFGENE_SPLICEVAR 3
4871 #define REFGENE_RELDREK 4
4872 #define REFGENE_REJECT 5
4873 #define REFGENE_IDENTICAL 6
4874 #define REFGENE_UNKNOWN 7
4875
4876 typedef struct refgeneuserdialog {
4877 DIALOG_MESSAGE_BLOCK
4878 GrouP status;
4879 ButtoN generated;
4880 TexT curator;
4881 TexT url;
4882 TexT source;
4883 Int2 indexer;
4884 DialoG fields;
4885 ButtoN pipebtn;
4886 } RefgeneUserDialog, PNTR RefgeneUserDialogPtr;
4887
4888 typedef struct refgeneuserform {
4889 FEATURE_FORM_BLOCK
4890 SeqEntryPtr sep;
4891 } RefgeneUserForm, PNTR RefgeneUserFormPtr;
4892
4893 static ENUM_ALIST(refgene_alist)
4894 {" ", 0},
4895 {"Assembly", REFGENE_ASSEMBLY},
4896 {"Related", REFGENE_RELATED},
4897 {"SpliceVar", REFGENE_SPLICEVAR},
4898 {"RelatedDrek", REFGENE_RELDREK},
4899 {"Reject", REFGENE_REJECT},
4900 {"Identical", REFGENE_IDENTICAL},
4901 {"Unknown", REFGENE_UNKNOWN},
4902 END_ENUM_ALIST
4903
4904 static Uint2 refgene_types [] = {
4905 TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_POPUP
4906 };
4907
4908 static Uint2 refgene_widths [] = {
4909 9, 7, 7, 7, 8, 0
4910 };
4911
4912 static EnumFieldAssocPtr refgene_popups [] = {
4913 NULL, NULL, NULL, NULL, NULL, refgene_alist
4914 };
4915
4916 static CharPtr refgene_labels [] = {
4917 "", "Assembly", "Related", "SpliceVar", "RelatedDrek", "Reject", "IdenticalTo", "Unknown", NULL
4918 };
4919
4920 static CharPtr refgene_fields [] = {
4921 "Accession", "GI", "Start", "Stop", "Comment", "Type", NULL
4922 };
4923
4924 static void AccessionUserFieldPtrToVisStringDialog (DialoG d, Pointer data)
4925
4926 {
4927 CharPtr accession;
4928 CharPtr comment;
4929 UserFieldPtr curr;
4930 UserFieldPtr entry;
4931 Int2 field;
4932 Char fm [16];
4933 Int4 from;
4934 Int4 gi;
4935 ValNodePtr head;
4936 Int2 i;
4937 Int2 j;
4938 CharPtr name;
4939 ObjectIdPtr oip;
4940 CharPtr str;
4941 TagListPtr tlp;
4942 Int4 to;
4943 Char tu [16];
4944 UserFieldPtr ufp;
4945 ValNodePtr vnp;
4946
4947 tlp = (TagListPtr) GetObjectExtra (d);
4948 if (tlp == NULL) return;
4949 str = MemNew (sizeof (Char) * 1024);
4950 head = NULL;
4951 curr = (UserFieldPtr) data;
4952 while (curr != NULL) {
4953 oip = curr->label;
4954 if (oip != NULL) {
4955 field = 0;
4956 for (i = REFGENE_ASSEMBLY; i <= REFGENE_UNKNOWN; i++) {
4957 if (StringICmp (oip->str, refgene_labels [i]) == 0 && curr->choice == 11) {
4958 field = i;
4959 }
4960 }
4961 if (field > 0) {
4962 entry = (UserFieldPtr) curr->data.ptrvalue;
4963 while (entry != NULL && entry->choice == 11) {
4964 accession = NULL;
4965 comment = NULL;
4966 name = NULL;
4967 gi = 0;
4968 from = 0;
4969 to = 0;
4970 ufp = (UserFieldPtr) entry->data.ptrvalue;
4971 while (ufp != NULL) {
4972 oip = ufp->label;
4973 if (oip != NULL && oip->str != NULL) {
4974 if (StringICmp (oip->str, "accession") == 0 && ufp->choice == 1) {
4975 accession = (CharPtr) ufp->data.ptrvalue;
4976 } else if (StringICmp (oip->str, "gi") == 0 && ufp->choice == 2) {
4977 gi = ufp->data.intvalue;
4978 } else if (StringICmp (oip->str, "from") == 0 && ufp->choice == 2) {
4979 from = ufp->data.intvalue;
4980 } else if (StringICmp (oip->str, "to") == 0 && ufp->choice == 2) {
4981 to = ufp->data.intvalue;
4982 } else if (StringICmp (oip->str, "comment") == 0 && ufp->choice == 1) {
4983 comment = (CharPtr) ufp->data.ptrvalue;
4984 } else if (StringICmp (oip->str, "name") == 0 && ufp->choice == 1) {
4985 name = (CharPtr) ufp->data.ptrvalue;
4986 }
4987 }
4988 ufp = ufp->next;
4989 }
4990 if (accession != NULL) {
4991 if (comment == NULL) {
4992 comment = "";
4993 }
4994 fm [0] = '\0';
4995 tu [0] = '\0';
4996 if (from > 0 && to > 0) {
4997 sprintf (fm, "%ld", (long) from);
4998 sprintf (tu, "%ld", (long) to);
4999 }
5000 sprintf (str, "%s\t%ld\t%s\t%s\t%s\t%d\n", accession,
5001 (long) gi, fm, tu, comment, (int) field);
5002 vnp = ValNodeNew (head);
5003 if (head == NULL) {
5004 head = vnp;
5005 }
5006 if (vnp != NULL) {
5007 vnp->data.ptrvalue = StringSave (str);
5008 }
5009 } else if (name != NULL) {
5010 sprintf (str, "\t\t\t\t%s\t%d\n", name, (int) field);
5011 vnp = ValNodeNew (head);
5012 if (head == NULL) {
5013 head = vnp;
5014 }
5015 if (vnp != NULL) {
5016 vnp->data.ptrvalue = StringSave (str);
5017 }
5018 }
5019 entry = entry->next;
5020 }
5021 }
5022 }
5023 curr = curr->next;
5024 }
5025 MemFree (str);
5026 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
5027 tlp->vnp = head;
5028 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
5029 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
5030 }
5031 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
5032 CorrectBarMax (tlp->bar, tlp->max);
5033 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
5034 }
5035
5036 static Pointer VisStringDialogToUserFieldPtr (DialoG d)
5037
5038 {
5039 return NULL;
5040 }
5041
5042 static void UserObjectPtrToRefGeneDialog (DialoG d, Pointer data)
5043
5044 {
5045 UserFieldPtr curr;
5046 Boolean gen;
5047 ObjectIdPtr oip;
5048 RefgeneUserDialogPtr rdp;
5049 Int2 status = 0;
5050 CharPtr str;
5051 UserObjectPtr uop;
5052
5053 rdp = (RefgeneUserDialogPtr) GetObjectExtra (d);
5054 if (rdp == NULL) return;
5055 uop = (UserObjectPtr) data;
5056 if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "RefGeneTracking") != 0) {
5057 SetValue (rdp->status, 0);
5058 PointerToDialog (rdp->fields, NULL);
5059 return;
5060 }
5061 PointerToDialog (rdp->fields, uop->data);
5062 for (curr = uop->data; curr != NULL; curr = curr->next) {
5063 oip = curr->label;
5064 if (oip != NULL && StringICmp (oip->str, "Status") == 0) {
5065 break;
5066 }
5067 }
5068 if (curr != NULL && curr->choice == 1) {
5069 str = (CharPtr) curr->data.ptrvalue;
5070 if (StringICmp (str, "Inferred") == 0) {
5071 status = 1;
5072 } else if (StringICmp (str, "Predicted") == 0) {
5073 status = 2;
5074 } else if (StringICmp (str, "Provisional") == 0) {
5075 status = 3;
5076 } else if (StringICmp (str, "Validated") == 0) {
5077 status = 4;
5078 } else if (StringICmp (str, "Reviewed") == 0) {
5079 status = 5;
5080 } else if (StringICmp (str, "Model") == 0) {
5081 status = 6;
5082 } else if (StringICmp (str, "WGS") == 0) {
5083 status = 7;
5084 } else if (StringICmp (str, "Pipeline") == 0) {
5085 status = 8;
5086 SafeEnable (rdp->pipebtn);
5087 }
5088 }
5089 for (curr = uop->data; curr != NULL; curr = curr->next) {
5090 oip = curr->label;
5091 if (oip != NULL && StringICmp (oip->str, "Generated") == 0) {
5092 break;
5093 }
5094 }
5095 if (curr != NULL && curr->choice == 4) {
5096 gen = curr->data.boolvalue;
5097 SetStatus (rdp->generated, gen);
5098 }
5099 for (curr = uop->data; curr != NULL; curr = curr->next) {
5100 oip = curr->label;
5101 if (oip != NULL && StringICmp (oip->str, "Collaborator") == 0) {
5102 break;
5103 }
5104 }
5105 if (curr != NULL && curr->choice == 1) {
5106 str = (CharPtr) curr->data.ptrvalue;
5107 SetTitle (rdp->curator, str);
5108 }
5109
5110 for (curr = uop->data; curr != NULL; curr = curr->next) {
5111 oip = curr->label;
5112 if (oip != NULL && StringICmp (oip->str, "CollaboratorURL") == 0) {
5113 break;
5114 }
5115 }
5116 if (curr != NULL && curr->choice == 1) {
5117 str = (CharPtr) curr->data.ptrvalue;
5118 SetTitle (rdp->url, str);
5119 }
5120
5121 for (curr = uop->data; curr != NULL; curr = curr->next) {
5122 oip = curr->label;
5123 if (oip != NULL && StringICmp (oip->str, "GenomicSource") == 0) {
5124 break;
5125 }
5126 }
5127 if (curr != NULL && curr->choice == 1) {
5128 str = (CharPtr) curr->data.ptrvalue;
5129 SetTitle (rdp->source, str);
5130 }
5131 SetValue (rdp->status, status);
5132 for (curr = uop->data; curr != NULL; curr = curr->next) {
5133 oip = curr->label;
5134 if (oip != NULL && StringICmp (oip->str, "Indexer") == 0) {
5135 break;
5136 }
5137 }
5138 if (curr != NULL && curr->choice == 2) {
5139 rdp->indexer = (Int2) curr->data.intvalue;
5140 }
5141 }
5142
5143 static void AddIndexerToRefGeneTrackUserObject (UserObjectPtr uop, Int2 indexer)
5144
5145 {
5146 UserFieldPtr curr;
5147 ObjectIdPtr oip;
5148
5149 if (uop == NULL || indexer < 1) return;
5150 oip = uop->type;
5151 if (oip == NULL || StringICmp (oip->str, "RefGeneTracking") != 0) return;
5152
5153 for (curr = uop->data; curr != NULL; curr = curr->next) {
5154 oip = curr->label;
5155 if (oip != NULL && StringICmp (oip->str, "Indexer") == 0) {
5156 break;
5157 }
5158 }
5159
5160 if (curr == NULL) {
5161 curr = UserFieldNew ();
5162 oip = ObjectIdNew ();
5163 oip->str = StringSave ("Indexer");
5164 curr->label = oip;
5165 curr->choice = 2; /* integer */
5166
5167 /* link indexer at beginning of list */
5168
5169 curr->next = uop->data;
5170 uop->data = curr;
5171 }
5172
5173 if (curr == NULL || curr->choice != 2) return;
5174
5175 /* replace any existing indexer indication */
5176
5177 curr->data.intvalue = (Int4) indexer;
5178 }
5179
5180 static Pointer RefGeneDialogToUserObjectPtr (DialoG d)
5181
5182 {
5183 Char ch;
5184 Char curator [256];
5185 Int2 i;
5186 Uint2 j;
5187 size_t len;
5188 Int4 num [6];
5189 Boolean okay;
5190 RefgeneUserDialogPtr rdp;
5191 Char source [64];
5192 Int2 status;
5193 CharPtr str;
5194 TagListPtr tlp;
5195 CharPtr txt [6];
5196 UserObjectPtr uop;
5197 Char url [512];
5198 long int val;
5199 ValNodePtr vnp;
5200
5201 rdp = (RefgeneUserDialogPtr) GetObjectExtra (d);
5202 if (rdp == NULL) return NULL;
5203
5204 uop = CreateRefGeneTrackUserObject ();
5205 if (uop == NULL) return NULL;
5206
5207 status = GetValue (rdp->status);
5208 if (status == 1) {
5209 AddStatusToRefGeneTrackUserObject (uop, "Inferred");
5210 } else if (status == 2) {
5211 AddStatusToRefGeneTrackUserObject (uop, "Predicted");
5212 } else if (status == 3) {
5213 AddStatusToRefGeneTrackUserObject (uop, "Provisional");
5214 } else if (status == 4) {
5215 AddStatusToRefGeneTrackUserObject (uop, "Validated");
5216 } else if (status == 5) {
5217 AddStatusToRefGeneTrackUserObject (uop, "Reviewed");
5218 } else if (status == 6) {
5219 AddStatusToRefGeneTrackUserObject (uop, "Model");
5220 } else if (status == 7) {
5221 AddStatusToRefGeneTrackUserObject (uop, "WGS");
5222 } else if (status == 8) {
5223 AddStatusToRefGeneTrackUserObject (uop, "Pipeline");
5224 }
5225
5226 GetTitle (rdp->source, source, sizeof (source));
5227 if (! StringHasNoText (source)) {
5228 AddSourceToRefGeneTrackUserObject (uop, source);
5229 }
5230
5231 if (GetStatus (rdp->generated)) {
5232 AddGeneratedToRefGeneTrackUserObject (uop, TRUE);
5233 }
5234
5235 GetTitle (rdp->curator, curator, sizeof (curator));
5236 if (! StringHasNoText (curator)) {
5237 AddCuratorToRefGeneTrackUserObject (uop, curator);
5238 }
5239
5240 GetTitle (rdp->url, url, sizeof (url));
5241 if (! StringHasNoText (url)) {
5242 AddCuratorURLToRefGeneTrackUserObject (uop, url);
5243 }
5244
5245 if (rdp->indexer > 0) {
5246 AddIndexerToRefGeneTrackUserObject (uop, rdp->indexer);
5247 }
5248
5249 tlp = (TagListPtr) GetObjectExtra (rdp->fields);
5250 if (tlp != NULL && tlp->vnp != NULL) {
5251 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
5252 str = (CharPtr) vnp->data.ptrvalue;
5253 okay = FALSE;
5254 len = StringLen (str);
5255 for (j = 0; j < len; j++) {
5256 ch = str [j];
5257 if (ch != ' ' && ch != '\t' && ch != '\n') {
5258 okay = TRUE;
5259 }
5260 }
5261 if (okay) {
5262 for (j = 0; j < 6; j++) {
5263 txt [j] = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, j);
5264 num [j] = 0;
5265 }
5266 for (j = 1; j < 4; j++) {
5267 num [j] = 0;
5268 if (txt [j] != NULL && sscanf (txt [j], "%ld", &val) == 1) {
5269 num [j] = val;
5270 }
5271 }
5272 if (txt [5] != NULL && sscanf (txt [5], "%ld", &val) == 1) {
5273 num [5] = val;
5274 }
5275 i = num [5];
5276 if (i >= REFGENE_ASSEMBLY && i <= REFGENE_UNKNOWN) {
5277 if (! StringHasNoText (txt [0])) {
5278 AddAccessionToRefGeneTrackUserObject (uop, refgene_labels [i],
5279 txt [0], num [1], num [2],
5280 num [3], txt [4]);
5281 } else if (! StringHasNoText (txt [4])) {
5282 /* comment by itself goes into name */
5283 AddAccessionToRefGeneTrackUserObject (uop, refgene_labels [i],
5284 NULL, num [1], num [2],
5285 num [3], txt [4]);
5286 }
5287 }
5288 for (j = 0; j < 6; j++) {
5289 txt [j] = MemFree (txt [j]);
5290 }
5291 }
5292 }
5293 }
5294
5295 return uop;
5296 }
5297
5298 static DialoG CreateRefGeneDialog (GrouP g)
5299
5300 {
5301 Int2 i;
5302 PrompT lastppt;
5303 GrouP p;
5304 PrompT ppt;
5305 GrouP q;
5306 RefgeneUserDialogPtr rdp;
5307 TagListPtr tlp;
5308 GrouP x;
5309 GrouP y;
5310 GrouP z;
5311
5312 p = HiddenGroup (g, -1, 0, NULL);
5313 SetGroupSpacing (p, 10, 10);
5314
5315 rdp = (RefgeneUserDialogPtr) MemNew (sizeof (RefgeneUserDialog));
5316 if (rdp == NULL) return NULL;
5317
5318 SetObjectExtra (p, rdp, NULL);
5319 rdp->dialog = (DialoG) p;
5320 rdp->todialog = UserObjectPtrToRefGeneDialog;
5321 rdp->fromdialog = RefGeneDialogToUserObjectPtr;
5322
5323 x = HiddenGroup (p, 4, 0, NULL);
5324 /* StaticPrompt (x, "Status", 0, stdLineHeight, programFont, 'l'); */
5325 rdp->status = HiddenGroup (x, 8, 0, NULL);
5326 SetObjectExtra (rdp->status, rdp, NULL);
5327 RadioButton (rdp->status, "Inferred");
5328 RadioButton (rdp->status, "Predicted");
5329 RadioButton (rdp->status, "Provisional");
5330 RadioButton (rdp->status, "Validated");
5331 RadioButton (rdp->status, "Reviewed");
5332 RadioButton (rdp->status, "Model");
5333 RadioButton (rdp->status, "WGS");
5334 rdp->pipebtn = RadioButton (rdp->status, "Pipeline");
5335 Disable (rdp->pipebtn);
5336
5337 y = HiddenGroup (p, 6, 0, NULL);
5338 rdp->generated = CheckBox (y, "Generated", NULL);
5339 z = HiddenGroup (y, 2, 0, NULL);
5340 StaticPrompt (z, "Curator", 0, dialogTextHeight, programFont, 'l');
5341 rdp->curator = DialogText (z, "", 14, NULL);
5342 StaticPrompt (z, "URL", 0, dialogTextHeight, programFont, 'r');
5343 rdp->url = DialogText (z, "", 14, NULL);
5344 StaticPrompt (y, "Genomic Source", 0, dialogTextHeight, programFont, 'l');
5345 rdp->source = DialogText (y, "", 7, NULL);
5346
5347 rdp->indexer = 0;
5348
5349 q = HiddenGroup (p, -7, 0, NULL);
5350 lastppt = NULL;
5351 ppt = NULL;
5352 for (i = 0; i < 6; i++) {
5353 lastppt = ppt;
5354 ppt = StaticPrompt (q, refgene_fields [i], refgene_widths [i] * stdCharWidth, 0, systemFont, 'c');
5355 }
5356 rdp->fields = CreateTagListDialog (p, 6, 6, STD_TAG_SPACING,
5357 refgene_types, refgene_widths, refgene_popups,
5358 AccessionUserFieldPtrToVisStringDialog,
5359 VisStringDialogToUserFieldPtr);
5360
5361 tlp = (TagListPtr) GetObjectExtra (rdp->fields);
5362 if (tlp != NULL) {
5363 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [4], (HANDLE) lastppt, NULL);
5364 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [5], (HANDLE) ppt, NULL);
5365 }
5366
5367 AlignObjects (ALIGN_CENTER, (HANDLE) x, (HANDLE) y, (HANDLE) q, (HANDLE) rdp->fields, NULL);
5368 return (DialoG) p;
5369 }
5370
5371 static void RefgeneUserFormMessage (ForM f, Int2 mssg)
5372
5373 {
5374 RefgeneUserFormPtr rfp;
5375
5376 rfp = (RefgeneUserFormPtr) GetObjectExtra (f);
5377 if (rfp != NULL) {
5378 switch (mssg) {
5379 case VIB_MSG_CLOSE :
5380 Remove (f);
5381 break;
5382 case VIB_MSG_CUT :
5383 StdCutTextProc (NULL);
5384 break;
5385 case VIB_MSG_COPY :
5386 StdCopyTextProc (NULL);
5387 break;
5388 case VIB_MSG_PASTE :
5389 StdPasteTextProc (NULL);
5390 break;
5391 case VIB_MSG_DELETE :
5392 StdDeleteTextProc (NULL);
5393 break;
5394 default :
5395 if (rfp->appmessage != NULL) {
5396 rfp->appmessage (f, mssg);
5397 }
5398 break;
5399 }
5400 }
5401 }
5402
5403 static ForM CreateRefGeneDescForm (Int2 left, Int2 top, Int2 width,
5404 Int2 height, CharPtr title, ValNodePtr sdp,
5405 SeqEntryPtr sep, FormActnFunc actproc)
5406
5407 {
5408 ButtoN b;
5409 GrouP c;
5410 GrouP g;
5411 RefgeneUserFormPtr rfp;
5412 StdEditorProcsPtr sepp;
5413 WindoW w;
5414
5415 w = NULL;
5416 rfp = (RefgeneUserFormPtr) MemNew (sizeof (RefgeneUserForm));
5417 if (rfp != NULL) {
5418 w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
5419 SetObjectExtra (w, rfp, StdDescFormCleanupProc);
5420 rfp->form = (ForM) w;
5421 rfp->actproc = actproc;
5422 rfp->formmessage = RefgeneUserFormMessage;
5423
5424 rfp->sep = sep;
5425
5426 #ifndef WIN_MAC
5427 CreateStdEditorFormMenus (w);
5428 #endif
5429 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
5430 if (sepp != NULL) {
5431 SetActivate (w, sepp->activateForm);
5432 rfp->appmessage = sepp->handleMessages;
5433 }
5434
5435 g = HiddenGroup (w, -1, 0, NULL);
5436 rfp->data = CreateRefGeneDialog (g);
5437
5438 c = HiddenGroup (w, 2, 0, NULL);
5439 b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
5440 SetObjectExtra (b, rfp, NULL);
5441 PushButton (c, "Cancel", StdCancelButtonProc);
5442 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
5443 RealizeWindow (w);
5444 }
5445 return (ForM) w;
5446 }
5447
5448 extern Int2 LIBCALLBACK RefGeneUserGenFunc (Pointer data)
5449
5450 {
5451 ObjectIdPtr oip;
5452 OMProcControlPtr ompcp;
5453 OMUserDataPtr omudp;
5454 ObjMgrProcPtr proc;
5455 RefgeneUserFormPtr rfp;
5456 ValNodePtr sdp;
5457 SeqEntryPtr sep;
5458 UserObjectPtr uop;
5459 WindoW w;
5460
5461 ompcp = (OMProcControlPtr) data;
5462 w = NULL;
5463 sdp = NULL;
5464 sep = NULL;
5465 uop = NULL;
5466 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
5467 proc = ompcp->proc;
5468 switch (ompcp->input_itemtype) {
5469 case OBJ_SEQDESC :
5470 sdp = (ValNodePtr) ompcp->input_data;
5471 if (sdp != NULL && sdp->choice != Seq_descr_user) {
5472 return OM_MSG_RET_ERROR;
5473 }
5474 uop = (UserObjectPtr) sdp->data.ptrvalue;
5475 break;
5476 case OBJ_BIOSEQ :
5477 break;
5478 case OBJ_BIOSEQSET :
5479 break;
5480 case 0 :
5481 break;
5482 default :
5483 return OM_MSG_RET_ERROR;
5484 }
5485 omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
5486 ompcp->input_itemtype, ompcp->proc->procid);
5487 if (omudp != NULL) {
5488 if (StringCmp (proc->procname, "Edit RefGene UserTrack Desc") == 0) {
5489 rfp = (RefgeneUserFormPtr) omudp->userdata.ptrvalue;
5490 if (rfp != NULL) {
5491 Select (rfp->form);
5492 }
5493 return OM_MSG_RET_DONE;
5494 } else {
5495 return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
5496 }
5497 }
5498 if (uop != NULL) {
5499 oip = uop->type;
5500 if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
5501 if (StringCmp (oip->str, "RefGeneTracking") != 0) return OM_MSG_RET_OK;
5502 }
5503 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
5504 w = (WindoW) CreateRefGeneDescForm (-50, -33, -10, -10,
5505 "Reference Gene Tracking", sdp, sep,
5506 StdDescFormActnProc);
5507 rfp = (RefgeneUserFormPtr) GetObjectExtra (w);
5508 if (rfp != NULL) {
5509 rfp->input_entityID = ompcp->input_entityID;
5510 rfp->input_itemID = ompcp->input_itemID;
5511 rfp->input_itemtype = ompcp->input_itemtype;
5512 rfp->this_itemtype = OBJ_SEQDESC;
5513 rfp->this_subtype = Seq_descr_user;
5514 rfp->procid = ompcp->proc->procid;
5515 rfp->proctype = ompcp->proc->proctype;
5516 rfp->userkey = OMGetNextUserKey ();
5517 omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
5518 OMPROC_EDIT, rfp->userkey);
5519 if (omudp != NULL) {
5520 omudp->userdata.ptrvalue = (Pointer) rfp;
5521 omudp->messagefunc = StdVibrantEditorMsgFunc;
5522 }
5523 SendMessageToForm (rfp->form, VIB_MSG_INIT);
5524 if (sdp != NULL) {
5525 PointerToDialog (rfp->data, (Pointer) sdp->data.ptrvalue);
5526 SetClosestParentIfDuplicating ((BaseFormPtr) rfp);
5527 }
5528 }
5529 Show (w);
5530 Select (w);
5531 return OM_MSG_RET_DONE;
5532 }
5533
5534 extern Int2 LIBCALLBACK StruCommUserGenFunc (Pointer data);
5535
5536 typedef struct strucommuserdialog {
5537 DIALOG_MESSAGE_BLOCK
5538 DialoG fields;
5539 } StruCommUserDialog, PNTR StruCommUserDialogPtr;
5540
5541 typedef struct strucommuserform {
5542 FEATURE_FORM_BLOCK
5543 SeqEntryPtr sep;
5544 } StruCommUserForm, PNTR StruCommUserFormPtr;
5545
5546 static void UserObjectPtrToStruCommDialog (DialoG d, Pointer data)
5547
5548 {
5549 UserFieldPtr curr;
5550 CharPtr field;
5551 ValNodePtr head = NULL;
5552 ObjectIdPtr oip;
5553 StruCommUserDialogPtr sdp;
5554 CharPtr str;
5555 CharPtr tmp;
5556 UserObjectPtr uop;
5557
5558 sdp = (StruCommUserDialogPtr) GetObjectExtra (d);
5559 if (sdp == NULL) return;
5560
5561 uop = (UserObjectPtr) data;
5562 if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "StructuredComment") != 0) {
5563 PointerToDialog (sdp->fields, NULL);
5564 return;
5565 }
5566
5567 for (curr = uop->data; curr != NULL; curr = curr->next) {
5568 if (curr->choice != 1) continue;
5569 oip = curr->label;
5570 if (oip == NULL) continue;
5571 field = oip->str;
5572 if (StringHasNoText (field)) continue;
5573 str = (CharPtr) curr->data.ptrvalue;
5574 if (StringHasNoText (str)) continue;
5575 tmp = MemNew (StringLen (field) + StringLen (str) + 5);
5576 if (tmp == NULL) continue;
5577 sprintf (tmp, "%s\t%s", field, str);
5578 ValNodeAddStr (&head, 0, (Pointer) tmp);
5579 }
5580
5581 PointerToDialog (sdp->fields, (Pointer) head);
5582 ValNodeFreeData (head);
5583 }
5584
5585 static void FixSpecialCharactersInStructuredCommentUserObject (UserObjectPtr uop, BoolPtr changed)
5586 {
5587 UserFieldPtr curr;
5588 CharPtr field;
5589 ValNodePtr find_list = NULL;
5590 ObjectIdPtr oip;
5591 CharPtr str;
5592
5593
5594 if (changed != NULL) {
5595 *changed = FALSE;
5596 }
5597 if (uop == NULL || uop->type == NULL || StringICmp (uop->type->str, "StructuredComment") != 0) {
5598 return;
5599 }
5600
5601 for (curr = uop->data; curr != NULL; curr = curr->next) {
5602 if (curr->choice != 1) continue;
5603 oip = curr->label;
5604 if (oip == NULL) continue;
5605 field = oip->str;
5606 if (StringHasNoText (field)) continue;
5607 str = (CharPtr) curr->data.ptrvalue;
5608 if (StringHasNoText (str)) continue;
5609
5610 SpecialCharFindWithContext ((CharPtr PNTR) (&(oip->str)), &find_list, NULL, NULL);
5611 SpecialCharFindWithContext ((CharPtr PNTR) (&(curr->data.ptrvalue)), &find_list, NULL, NULL);
5612 }
5613 FixSpecialCharactersForStringsInList (find_list, "Special characters are not permitted.", TRUE);
5614 if (find_list != NULL)
5615 {
5616 if (changed != NULL) {
5617 *changed = TRUE;
5618 }
5619 find_list = FreeContextList (find_list);
5620 }
5621 }
5622
5623
5624 static Pointer StruCommDialogToUserObjectPtr (DialoG d)
5625
5626 {
5627 CharPtr field;
5628 ValNodePtr head;
5629 CharPtr item;
5630 UserObjectPtr uop;
5631 StruCommUserDialogPtr sdp;
5632 CharPtr str;
5633 ValNodePtr vnp;
5634 Boolean fixed_special = FALSE;
5635
5636 sdp = (StruCommUserDialogPtr) GetObjectExtra (d);
5637 if (sdp == NULL) return NULL;
5638
5639 uop = CreateStructuredCommentUserObject (NULL, NULL);
5640 if (uop == NULL) return NULL;
5641
5642 head = (ValNodePtr) DialogToPointer (sdp->fields);
5643 if (head == NULL) return NULL;
5644
5645 for (vnp = head; vnp != NULL; vnp = vnp->next) {
5646 str = (CharPtr) vnp->data.ptrvalue;
5647 if (StringHasNoText (str)) continue;
5648 field = ExtractTagListColumn (str, 0);
5649 item = ExtractTagListColumn (str, 1);
5650 if (StringDoesHaveText (field) && StringDoesHaveText (item)) {
5651 AddItemStructuredCommentUserObject (uop, field, item);
5652 }
5653 MemFree (field);
5654 MemFree (item);
5655 }
5656
5657 ValNodeFreeData (head);
5658
5659 FixSpecialCharactersInStructuredCommentUserObject (uop, &fixed_special);
5660 if (fixed_special) {
5661 PointerToDialog (d, uop);
5662 }
5663
5664 return uop;
5665 }
5666
5667 static void ValNodePtrToStruCommDialog (DialoG d, Pointer data)
5668
5669 {
5670 ValNodePtr head;
5671 Int2 j;
5672 ValNodePtr list;
5673 CharPtr str;
5674 TagListPtr tlp;
5675 ValNodePtr vnp;
5676
5677 tlp = (TagListPtr) GetObjectExtra (d);
5678 list = (ValNodePtr) data;
5679 if (tlp != NULL) {
5680 head = NULL;
5681 while (list != NULL) {
5682 vnp = ValNodeNew (head);
5683 if (head == NULL) {
5684 head = vnp;
5685 }
5686 if (vnp != NULL) {
5687 str = MemNew (StringLen ((CharPtr) list->data.ptrvalue) + 3);
5688 if (str != NULL) {
5689 StringCpy (str, (CharPtr) list->data.ptrvalue);
5690 StringCat (str, "\n");
5691 }
5692 vnp->data.ptrvalue = str;
5693 }
5694 list = list->next;
5695 }
5696 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
5697 tlp->vnp = head;
5698 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
5699 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
5700 }
5701 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
5702 CorrectBarMax (tlp->bar, tlp->max);
5703 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
5704 }
5705 }
5706
5707 static Pointer StruCommDialogToValNodePtr (DialoG d)
5708
5709 {
5710 Char ch;
5711 ValNodePtr head;
5712 Int2 j;
5713 Int2 len;
5714 ValNodePtr list;
5715 Boolean okay;
5716 CharPtr str;
5717 TagListPtr tlp;
5718 ValNodePtr vnp;
5719
5720 head = NULL;
5721 tlp = (TagListPtr) GetObjectExtra (d);
5722 if (tlp != NULL && tlp->vnp != NULL) {
5723 list = NULL;
5724 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
5725 str = (CharPtr) vnp->data.ptrvalue;
5726 okay = FALSE;
5727 len = StringLen (str);
5728 for (j = 0; j < len; j++) {
5729 ch = str [j];
5730 if (ch != ' ' && ch != '\t' && ch != '\n') {
5731 okay = TRUE;
5732 }
5733 }
5734 if (okay) {
5735 list = ValNodeNew (list);
5736 if (head == NULL) {
5737 head = list;
5738 }
5739 if (list != NULL) {
5740 list->choice = 0;
5741 list->data.ptrvalue = StringSave ((CharPtr) vnp->data.ptrvalue);
5742 }
5743 }
5744 }
5745 }
5746 return (Pointer) head;
5747 }
5748
5749 Uint2 strccmm_types [] = {
5750 TAGLIST_TEXT, TAGLIST_TEXT
5751 };
5752
5753 Uint2 strccmm_widths [] = {
5754 16, 16, 0
5755 };
5756
5757 static DialoG CreateStruCommDialog (GrouP g)
5758
5759 {
5760 StruCommUserDialogPtr sdp;
5761 GrouP p;
5762 GrouP x;
5763 GrouP y;
5764
5765 p = HiddenGroup (g, -1, 0, NULL);
5766 SetGroupSpacing (p, 10, 10);
5767
5768 sdp = (StruCommUserDialogPtr) MemNew (sizeof (StruCommUserDialog));
5769 if (sdp == NULL) return NULL;
5770
5771 SetObjectExtra (p, sdp, NULL);
5772 sdp->dialog = (DialoG) p;
5773 sdp->todialog = UserObjectPtrToStruCommDialog;
5774 sdp->fromdialog = StruCommDialogToUserObjectPtr;
5775
5776 x = HiddenGroup (p, 0, 2, NULL);
5777 y = HiddenGroup (x, 3, 0, NULL);
5778 StaticPrompt (y, "Field", 16 * stdCharWidth, 0, programFont, 'c');
5779 StaticPrompt (y, "Text", 16 * stdCharWidth, 0, programFont, 'c');
5780 sdp->fields = CreateTagListDialog (x, 8, 2, -1,
5781 strccmm_types, strccmm_widths, NULL,
5782 ValNodePtrToStruCommDialog,
5783 StruCommDialogToValNodePtr);
5784
5785 return (DialoG) p;
5786 }
5787
5788
5789 static Boolean ExportStructuredCommentForm (ForM f, CharPtr filename)
5790 {
5791 StruCommUserFormPtr sfp;
5792 Char path [PATH_MAX];
5793 UserObjectPtr uop;
5794 AsnIoPtr aip;
5795 Boolean rval = FALSE;
5796 #ifdef WIN_MAC
5797 FILE *fp;
5798 #endif
5799
5800 sfp = (StruCommUserFormPtr) GetObjectExtra (f);
5801 if (sfp == NULL) {
5802 return FALSE;
5803 }
5804
5805 uop = DialogToPointer (sfp->data);
5806 if (uop == NULL) {
5807 Message (MSG_ERROR, "Don't have a valid structured comment yet!");
5808 return FALSE;
5809 }
5810
5811 path [0] = '\0';
5812 StringNCpy_0 (path, filename, sizeof (path));
5813 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
5814 #ifdef WIN_MAC
5815 fp = FileOpen (path, "r");
5816 if (fp != NULL) {
5817 FileClose (fp);
5818 } else {
5819 FileCreate (path, "TEXT", "ttxt");
5820 }
5821 #endif
5822 }
5823 aip = AsnIoOpen (path, "w");
5824 if (aip == NULL) {
5825 Message (MSG_ERROR, "Unable to create file %s", path);
5826 } else {
5827 UserObjectAsnWrite (uop, aip, NULL);
5828 AsnIoClose (aip);
5829 rval = TRUE;
5830 }
5831 uop = UserObjectFree (uop);
5832 return rval;
5833 }
5834
5835
5836 static UserObjectPtr StructuredCommentFromTabFile (CharPtr path)
5837 {
5838 FILE *fp;
5839 ValNodePtr table, tmp, header, line;
5840 UserObjectPtr uop = NULL;
5841
5842 fp = FileOpen (path, "r");
5843 if (fp == NULL) {
5844 return NULL;
5845 }
5846
5847 table = ReadTabTableFromFile (fp);
5848 FileClose (fp);
5849 if (table == NULL || table->next == NULL
5850 || table->data.ptrvalue == NULL
5851 || table->next->data.ptrvalue == NULL) {
5852 table = FreeTabTable (table);
5853 return NULL;
5854 }
5855 tmp = FlipTabTableAxes (table);
5856 table = FreeTabTable (table);
5857 table = tmp;
5858
5859 header = table->data.ptrvalue;
5860 if (header == NULL || header->data.ptrvalue == NULL || header->next == NULL) {
5861 table = FreeTabTable (table);
5862 return NULL;
5863 }
5864 line = table->next;
5865
5866 tmp = CreateStructuredCommentsFromRow (header, line->data.ptrvalue, NULL, NULL);
5867 table = FreeTabTable (table);
5868 if (tmp != NULL) {
5869 uop = (UserObjectPtr) tmp->data.ptrvalue;
5870 tmp->data.ptrvalue = NULL;
5871 for (line = tmp->next; line != NULL; line = line->next) {
5872 line->data.ptrvalue = UserObjectFree (line->data.ptrvalue);
5873 }
5874 tmp = ValNodeFree (tmp);
5875 }
5876 return uop;
5877 }
5878
5879
5880 static Boolean ImportStructuredCommentForm (ForM f, CharPtr filename)
5881 {
5882 StruCommUserFormPtr sfp;
5883 Char path [PATH_MAX];
5884 UserObjectPtr uop = NULL;
5885 AsnIoPtr aip = NULL;
5886 Boolean rval = FALSE;
5887
5888 sfp = (StruCommUserFormPtr) GetObjectExtra (f);
5889 if (sfp == NULL) {
5890 return FALSE;
5891 }
5892
5893 path [0] = '\0';
5894 StringNCpy_0 (path, filename, sizeof (path));
5895 if (path [0] == '\0') {
5896 if (!GetInputFileName (path, sizeof (path), "", "TEXT")) {
5897 return FALSE;
5898 }
5899 }
5900
5901 aip = AsnIoOpen (path, "r");
5902 if (aip == NULL) {
5903 Message (MSG_ERROR, "Unable to read file %s", path);
5904 } else {
5905 uop = UserObjectAsnRead (aip, NULL);
5906 AsnIoClose (aip);
5907 if (uop == NULL) {
5908 /* try reading as though it were a table */
5909 uop = StructuredCommentFromTabFile(path);
5910 }
5911 if (uop == NULL) {
5912 Message (MSG_ERROR, "Unable to read structured comment ASN.1 from file");
5913 }
5914 }
5915 if (uop != NULL) {
5916 PointerToDialog (sfp->data, uop);
5917 uop = UserObjectFree (uop);
5918 rval = TRUE;
5919 }
5920 return rval;
5921 }
5922
5923
5924 static void StruCommUserFormMessage (ForM f, Int2 mssg)
5925
5926 {
5927 StruCommUserFormPtr sfp;
5928
5929 sfp = (StruCommUserFormPtr) GetObjectExtra (f);
5930 if (sfp != NULL) {
5931 switch (mssg) {
5932 case VIB_MSG_CLOSE :
5933 Remove (f);
5934 break;
5935 case VIB_MSG_CUT :
5936 StdCutTextProc (NULL);
5937 break;
5938 case VIB_MSG_COPY :
5939 StdCopyTextProc (NULL);
5940 break;
5941 case VIB_MSG_PASTE :
5942 StdPasteTextProc (NULL);
5943 break;
5944 case VIB_MSG_DELETE :
5945 StdDeleteTextProc (NULL);
5946 break;
5947 case VIB_MSG_EXPORT :
5948 ExportStructuredCommentForm (f, NULL);
5949 break;
5950 case VIB_MSG_IMPORT :
5951 ImportStructuredCommentForm (f, NULL);
5952 break;
5953 default :
5954 if (sfp->appmessage != NULL) {
5955 sfp->appmessage (f, mssg);
5956 }
5957 break;
5958 }
5959 }
5960 }
5961
5962
5963 typedef struct replacestruccmt {
5964 UserObjectPtr deleteThis;
5965 UserObjectPtr replaceWith;
5966 } ReplaceStrucCmtData, PNTR ReplaceStrucCmtPtr;
5967
5968
5969 static void ReplaceAllStructuredCommentsCallback (SeqDescrPtr sdp, Pointer data)
5970
5971 {
5972 ReplaceStrucCmtPtr rp;
5973
5974 if ((rp = (ReplaceStrucCmtPtr) data) == NULL || sdp == NULL || sdp->choice != Seq_descr_user) {
5975 return;
5976 }
5977
5978 if (AsnIoMemComp (sdp->data.ptrvalue, rp->deleteThis, (AsnWriteFunc) UserObjectAsnWrite)) {
5979 sdp->data.ptrvalue = UserObjectFree (sdp->data.ptrvalue);
5980 sdp->data.ptrvalue = AsnIoMemCopy (rp->replaceWith, (AsnReadFunc) UserObjectAsnRead, (AsnWriteFunc) UserObjectAsnWrite);
5981 }
5982 }
5983
5984
5985 static void ReplaceAllStructuredCommentsButtonProc (ButtoN b)
5986 {
5987 StruCommUserFormPtr sfp;
5988 SeqEntryPtr sep;
5989 ReplaceStrucCmtData rd;
5990 SeqDescrPtr sdp_orig;
5991 SeqMgrDescContext context;
5992
5993 sfp = (StruCommUserFormPtr) GetObjectExtra (b);
5994 if (sfp == NULL) {
5995 return;
5996 }
5997
5998 rd.replaceWith = DialogToPointer (sfp->data);
5999 if (rd.replaceWith == NULL) {
6000 Message (MSG_ERROR, "Must supply text!");
6001 rd.replaceWith = UserObjectFree (rd.replaceWith);
6002 return;
6003 }
6004
6005 sdp_orig = SeqMgrGetDesiredDescriptor (sfp->input_entityID, NULL, sfp->input_itemID, 0, NULL, &context);
6006 if (sdp_orig == NULL || sdp_orig->choice != Seq_descr_user) {
6007 Message (MSG_ERROR, "Unable to find original descriptor!");
6008 Remove (sfp->form);
6009 rd.replaceWith = UserObjectFree (rd.replaceWith);
6010 return;
6011 }
6012 rd.deleteThis = AsnIoMemCopy (sdp_orig->data.ptrvalue, (AsnReadFunc)UserObjectAsnRead, (AsnWriteFunc) UserObjectAsnWrite);
6013
6014 sep = GetTopSeqEntryForEntityID (sfp->input_entityID);
6015 VisitDescriptorsInSep (sep, &rd, ReplaceAllStructuredCommentsCallback);
6016
6017 rd.deleteThis = UserObjectFree (rd.deleteThis);
6018 rd.replaceWith = UserObjectFree (rd.replaceWith);
6019
6020 ObjMgrSetDirtyFlag (sfp->input_entityID, TRUE);
6021 ObjMgrSendMsg (OM_MSG_UPDATE, sfp->input_entityID,
6022 sfp->input_itemID, sfp->input_itemtype);
6023 Remove (sfp->form);
6024 }
6025
6026
6027 static ForM CreateStruCommDescForm (Int2 left, Int2 top, Int2 width,
6028 Int2 height, CharPtr title, ValNodePtr sdp,
6029 SeqEntryPtr sep, FormActnFunc actproc)
6030
6031 {
6032 ButtoN b;
6033 GrouP c;
6034 GrouP g;
6035 StdEditorProcsPtr sepp;
6036 StruCommUserFormPtr sfp;
6037 WindoW w;
6038
6039 w = NULL;
6040 sfp = (StruCommUserFormPtr) MemNew (sizeof (StruCommUserForm));
6041 if (sfp != NULL) {
6042 w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
6043 SetObjectExtra (w, sfp, StdDescFormCleanupProc);
6044 sfp->form = (ForM) w;
6045 sfp->actproc = actproc;
6046 sfp->formmessage = StruCommUserFormMessage;
6047 sfp->exportform = ExportStructuredCommentForm;
6048 sfp->importform = ImportStructuredCommentForm;
6049 sfp->sep = sep;
6050
6051 #ifndef WIN_MAC
6052 CreateStdEditorFormMenus (w);
6053 #endif
6054 sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
6055 if (sepp != NULL) {
6056 SetActivate (w, sepp->activateForm);
6057 sfp->appmessage = sepp->handleMessages;
6058 }
6059
6060 g = HiddenGroup (w, -1, 0, NULL);
6061 sfp->data = CreateStruCommDialog (g);
6062
6063 c = HiddenGroup (w, 3, 0, NULL);
6064 if (sdp == NULL) {
6065 b = DefaultButton (c, "Accept", StdAcceptFormButtonProc);
6066 SetObjectExtra (b, sfp, NULL);
6067 } else {
6068 b = DefaultButton (c, "Replace This", StdAcceptFormButtonProc);
6069 SetObjectExtra (b, sfp, NULL);
6070 b = PushButton (c, "Replace All", ReplaceAllStructuredCommentsButtonProc);
6071 SetObjectExtra (b, sfp, NULL);
6072 }
6073
6074 PushButton (c, "Cancel", StdCancelButtonProc);
6075
6076 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
6077 RealizeWindow (w);
6078 }
6079 return (ForM) w;
6080 }
6081
6082 extern Int2 LIBCALLBACK StruCommUserGenFunc (Pointer data)
6083
6084 {
6085 ObjectIdPtr oip;
6086 OMProcControlPtr ompcp;
6087 OMUserDataPtr omudp;
6088 ObjMgrProcPtr proc;
6089 ValNodePtr sdp;
6090 SeqEntryPtr sep;
6091 StruCommUserFormPtr sfp;
6092 UserObjectPtr uop;
6093 WindoW w;
6094
6095 ompcp = (OMProcControlPtr) data;
6096 w = NULL;
6097 sdp = NULL;
6098 sep = NULL;
6099 uop = NULL;
6100 if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
6101 proc = ompcp->proc;
6102 switch (ompcp->input_itemtype) {
6103 case OBJ_SEQDESC :
6104 sdp = (ValNodePtr) ompcp->input_data;
6105 if (sdp != NULL && sdp->choice != Seq_descr_user) {
6106 return OM_MSG_RET_ERROR;
6107 }
6108 uop = (UserObjectPtr) sdp->data.ptrvalue;
6109 break;
6110 case OBJ_BIOSEQ :
6111 break;
6112 case OBJ_BIOSEQSET :
6113 break;
6114 case 0 :
6115 break;
6116 default :
6117 return OM_MSG_RET_ERROR;
6118 }
6119 omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
6120 ompcp->input_itemtype, ompcp->proc->procid);
6121 if (omudp != NULL) {
6122 if (StringCmp (proc->procname, "Edit StructuredComment User Desc") == 0) {
6123 sfp = (StruCommUserFormPtr) omudp->userdata.ptrvalue;
6124 if (sfp != NULL) {
6125 Select (sfp->form);
6126 }
6127 return OM_MSG_RET_DONE;
6128 } else {
6129 return OM_MSG_RET_OK; /* not this type, check next registered user object editor */
6130 }
6131 }
6132 if (uop != NULL) {
6133 oip = uop->type;
6134 if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
6135 if (StringCmp (oip->str, "StructuredComment") != 0) return OM_MSG_RET_OK;
6136 }
6137 sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
6138 w = (WindoW) CreateStruCommDescForm (-50, -33, -10, -10,
6139 "Structured Comment", sdp, sep,
6140 StdDescFormActnProc);
6141 sfp = (StruCommUserFormPtr) GetObjectExtra (w);
6142 if (sfp != NULL) {
6143 sfp->input_entityID = ompcp->input_entityID;
6144 sfp->input_itemID = ompcp->input_itemID;
6145 sfp->input_itemtype = ompcp->input_itemtype;
6146 sfp->this_itemtype = OBJ_SEQDESC;
6147 sfp->this_subtype = Seq_descr_user;
6148 sfp->procid = ompcp->proc->procid;
6149 sfp->proctype = ompcp->proc->proctype;
6150 sfp->userkey = OMGetNextUserKey ();
6151 omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
6152 OMPROC_EDIT, sfp->userkey);
6153 if (omudp != NULL) {
6154 omudp->userdata.ptrvalue = (Pointer) sfp;
6155 omudp->messagefunc = StdVibrantEditorMsgFunc;
6156 }
6157 SendMessageToForm (sfp->form, VIB_MSG_INIT);
6158 if (sdp != NULL) {
6159 PointerToDialog (sfp->data, (Pointer) sdp->data.ptrvalue);
6160 SetClosestParentIfDuplicating ((BaseFormPtr) sfp);
6161 }
6162 }
6163 Show (w);
6164 Select (w);
6165 return OM_MSG_RET_DONE;
6166 }
6167
6168
6169 /*
6170 static void TestGeneRefStuff (void)
6171
6172 {
6173 UserObjectPtr uop;
6174 ValNodePtr sdp;
6175
6176 uop = CreateRefGeneTrackUserObject ();
6177 AddAccessionToRefGeneTrackUserObject (uop, "Assembly", "U12345", 57, 29, 1995);
6178 AddAccessionToRefGeneTrackUserObject (uop, "Assembly", "L97531", 142, 66, 963);
6179 AddAccessionToRefGeneTrackUserObject (uop, "Assembly", "M66778", 823, 7677, 343);
6180 AddAccessionToRefGeneTrackUserObject (uop, "Related", "P34345", 445, 0, 0);
6181 AddAccessionToRefGeneTrackUserObject (uop, "Reject", "S19635", 1765, 0, 0);
6182 AddAccessionToRefGeneTrackUserObject (uop, "Related", "Q14884", 664, 35, 97);
6183 sdp = ValNodeNew (NULL);
6184 sdp->choice = Seq_descr_user;
6185 sdp->data.ptrvalue = (Pointer) uop;
6186 if (! ObjMgrRegister (OBJ_SEQDESC, (Pointer) sdp)) {
6187 ErrPostEx (SEV_ERROR, 0, 0, "ObjMgrRegister failed.");
6188 }
6189 }
6190 */
6191
6192 #define CKA_GAPLEN 50 /* max allowed unaligned gap size */
6193
6194 typedef struct cka_acc {
6195 CharPtr accession;
6196 SeqIdPtr sip_whole;
6197 SeqAlignPtr sap;
6198 Int4 start_acc;
6199 Int4 stop_acc;
6200 Int4 start_seq;
6201 Int4 stop_seq;
6202 Uint1 strand;
6203 Int4 num;
6204 struct cka_acc PNTR next;
6205 } CKA_Acc, PNTR CKA_AccPtr;
6206
6207 static Int4 CKA_blast_wordsize;
6208 static FloatHi CKA_blast_expect_value;
6209 static Boolean CKA_blast_allow_repeats;
6210 static Int4 CKA_blast_detailed_wordsize;
6211 static FloatHi CKA_blast_detailed_expect_value;
6212 static Boolean CKA_blast_detailed_allow_repeats;
6213
6214 static SeqAlignPtr CKA_MakeAlign(BioseqPtr bsp, CKA_AccPtr acc_head, LogInfoPtr lip);
6215
6216 static Boolean SPI_GetAccessionFromSeqId(SeqIdPtr sip, Int4Ptr gi, CharPtr PNTR id)
6217 {
6218 Boolean numeric_id_type = FALSE;
6219 Int2 id_len;
6220 GiimPtr gip;
6221 ObjectIdPtr oip;
6222 TextSeqIdPtr textsip;
6223 DbtagPtr dbtag;
6224 PatentSeqIdPtr psip;
6225 PDBSeqIdPtr pdbsip;
6226
6227 *id = NULL;
6228 *gi = 0;
6229
6230 switch (sip->choice) {
6231 case SEQID_GI: case SEQID_GIBBSQ: case SEQID_GIBBMT:
6232 *gi = sip->data.intvalue;
6233 numeric_id_type = TRUE;
6234 break;
6235 case SEQID_GIIM:
6236 gip = (GiimPtr) sip->data.ptrvalue;
6237 *gi = gip->id;
6238 numeric_id_type = TRUE;
6239 break;
6240 case SEQID_LOCAL:
6241 oip = (ObjectIdPtr) sip->data.ptrvalue;
6242
6243 if (oip->str) {
6244 id_len = StringLen(oip->str);
6245 *id = (CharPtr) MemNew(id_len+1);
6246 sprintf(*id, "%s", oip->str);
6247 } else {
6248 *id = (CharPtr) MemNew(6);
6249 sprintf(*id, "%d", oip->id);
6250 }
6251 break;
6252 case SEQID_GENBANK: case SEQID_EMBL: case SEQID_PIR: case SEQID_TPG: case SEQID_TPE: case SEQID_TPD:
6253 case SEQID_SWISSPROT: case SEQID_DDBJ: case SEQID_PRF:
6254 case SEQID_OTHER: case SEQID_GPIPE:
6255 textsip = (TextSeqIdPtr)sip->data.ptrvalue;
6256 id_len = StringLen(textsip->accession);
6257 *id = (CharPtr) MemNew(id_len+1);
6258 if (textsip->version > 0)
6259 sprintf(*id, "%s.%d", textsip->accession, textsip->version);
6260 else
6261 sprintf(*id, "%s", textsip->accession);
6262 break;
6263 case SEQID_GENERAL:
6264 dbtag = (DbtagPtr) sip->data.ptrvalue;
6265 if (dbtag->tag->str == NULL) {
6266 numeric_id_type = TRUE;
6267 *gi = dbtag->tag->id;
6268 } else {
6269 id_len = StringLen(dbtag->tag->str);
6270 *id = (CharPtr) MemNew(id_len+1);
6271 sprintf(*id, "%s", dbtag->tag->str);
6272 }
6273 break;
6274 case SEQID_PATENT:
6275 psip = (PatentSeqIdPtr) sip->data.ptrvalue;
6276 *gi = (Int4) psip->seqid;
6277 numeric_id_type = TRUE;
6278 break;
6279 case SEQID_PDB:
6280 pdbsip = (PDBSeqIdPtr) sip->data.ptrvalue;
6281 id_len = StringLen(pdbsip->mol);
6282 *id = (CharPtr) MemNew(id_len+4);
6283 sprintf(*id, "%s%d", pdbsip->mol, pdbsip->chain);
6284 break;
6285 default: break;
6286 }
6287
6288 return numeric_id_type;
6289 }
6290
6291 static void CKA_FindAllTpaDescr(SeqEntryPtr sep, Pointer data, Int4 index, Int2 indent)
6292 {
6293 CKA_AccPtr acc;
6294 CKA_AccPtr PNTR acc_head;
6295 CKA_AccPtr acc_prev;
6296 BioseqPtr bsp;
6297 SeqMgrDescContext context;
6298 UserFieldPtr curr;
6299 ObjectIdPtr oip;
6300 SeqDescrPtr sdp;
6301 UserFieldPtr ufp;
6302 UserObjectPtr uop;
6303
6304 acc_head = (CKA_AccPtr PNTR)data;
6305 acc_prev = *acc_head;
6306 while (acc_prev != NULL && acc_prev->next != NULL)
6307 {
6308 acc_prev = acc_prev->next;
6309 }
6310 sdp = NULL;
6311 if (IS_Bioseq(sep))
6312 {
6313 bsp = (BioseqPtr)sep->data.ptrvalue;
6314 if (ISA_na(bsp->mol))
6315 {
6316 while ((sdp = SeqMgrGetNextDescriptor(bsp, sdp, Seq_descr_user, &context)) != NULL)
6317 {
6318 uop = (UserObjectPtr)sdp->data.ptrvalue;
6319 if (!StringICmp(uop->type->str, "TpaAssembly"))
6320 {
6321 for (curr = uop->data; curr != NULL; curr = curr->next)
6322 {
6323 if (curr->choice != 11) continue;
6324
6325 acc = (CKA_AccPtr)MemNew(sizeof(CKA_Acc));
6326 acc->sip_whole = SeqIdSetDup(bsp->id);
6327 /* will use these to mark the span for blast2seq */
6328 acc->start_acc = acc->stop_acc = -1;
6329 if (acc_prev == NULL)
6330 *acc_head = acc_prev = acc;
6331 else {
6332 acc_prev->next = acc;
6333 acc_prev = acc;
6334 }
6335
6336 for (ufp = curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
6337 oip = ufp->label;
6338 if (oip == NULL) continue;
6339 if (StringICmp (oip->str, "accession") == 0 && ufp->choice == 1) {
6340 acc->accession = StringSave((CharPtr)ufp->data.ptrvalue);
6341 } else if (StringICmp (oip->str, "from") == 0 && ufp->choice == 2) {
6342 acc->start_acc = (Int4) ufp->data.intvalue;
6343 } else if (StringICmp (oip->str, "to") == 0 && ufp->choice == 2) {
6344 acc->stop_acc = (Int4) ufp->data.intvalue;
6345 }
6346 }
6347 }
6348 }
6349 }
6350 }
6351 }
6352 }
6353
6354 static int LIBCALLBACK CKA_SortAccs(VoidPtr ptr1, VoidPtr ptr2)
6355 {
6356 CKA_AccPtr acc1;
6357 CKA_AccPtr acc2;
6358
6359 acc1 = *((CKA_AccPtr PNTR)ptr1);
6360 acc2 = *((CKA_AccPtr PNTR)ptr2);
6361 if (acc1->start_seq < acc2->start_seq)
6362 return -1;
6363 else if (acc1->start_seq > acc2->start_seq)
6364 return 1;
6365 else if (acc1->stop_seq < acc2->stop_seq)
6366 return -1;
6367 else if (acc1->stop_seq > acc2->stop_seq)
6368 return 1;
6369 else
6370 return 0; /* no alignment */
6371 }
6372
6373 static SeqIdPtr SqnSeqIdFindBestAccession (SeqIdPtr sip)
6374 {
6375 Uint1 order[NUM_SEQID];
6376
6377 if (sip == NULL)
6378 return NULL;
6379 SeqIdBestRank(order, NUM_SEQID);
6380 order[SEQID_GI]=order[SEQID_LOCAL]+2;
6381 order[SEQID_PATENT]=order[SEQID_LOCAL]+1;
6382 return SeqIdSelect (sip, order, NUM_SEQID);
6383 }
6384
6385
6386 static Boolean ValidateTPAHistAlign (BioseqPtr bsp, ValNodePtr PNTR errors)
6387 {
6388 ValNodePtr new_errors;
6389 Boolean retval = TRUE;
6390 SeqAlignPtr salp;
6391
6392 if (bsp == NULL || bsp->hist == NULL || bsp->hist->assembly == NULL) {
6393 return FALSE;
6394 }
6395
6396 for (salp = bsp->hist->assembly; salp != NULL; salp = salp->next) {
6397 AlnMgr2IndexSingleChildSeqAlign(salp);
6398 }
6399
6400 new_errors = ReportCoverageForBioseqSeqHist (bsp);
6401 if (new_errors != NULL) {
6402 ValNodeLink (errors, new_errors);
6403 retval = FALSE;
6404 }
6405 return retval;
6406 }
6407
6408
6409 static Boolean CKA_ValidateSeqAlign(SeqAlignPtr sap, CKA_AccPtr acc_head, Int4 bioseqlen, ValNodePtr PNTR errors)
6410 {
6411 CKA_AccPtr acc;
6412 CKA_AccPtr PNTR accarray;
6413 AMAlignIndex2Ptr amaip;
6414 Int4 first, first_align;
6415 Boolean found;
6416 Int4 gi;
6417 Int4 i;
6418 Int4 j;
6419 Int4 k;
6420 Int4 last;
6421 Int4 longest;
6422 Int4 max;
6423 Int4 n;
6424 Int4 prev;
6425 Boolean retval = TRUE;
6426 CharPtr textid;
6427 Char textid2[42];
6428 CharPtr err_msg;
6429 CharPtr no_cover_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s aligns to %d-%d but next aln is %s to %d-%d\n";
6430 CharPtr no_cover_ok_gap_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s aligns to %d-%d but the next aln is %s to %d-%d;\n the gap is less than %d and is acceptable.\n";
6431 CharPtr bad_start_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s (the first aln) starts at position %d\n";
6432 CharPtr bad_start_ok_gap_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s (the first alignment) starts at position %d, but the gap is less than %d and is acceptable.\n";
6433 CharPtr bad_end_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s (the last aln) goes to %d, bioseq length is %d\n";
6434 CharPtr bad_end_ok_gap_fmt = "Primary accessions do not completely cover the bioseq %s:\n %s (the last alignment) goes to %d, bioseq length is %d, but the gap is less than %d and is acceptable.\n";
6435
6436 if (sap == NULL || sap->saip == NULL || sap->saip->indextype != INDEX_PARENT || errors == NULL)
6437 return FALSE;
6438
6439 amaip = (AMAlignIndex2Ptr)(sap->saip);
6440 for (i=0; i<amaip->numsaps; i++)
6441 {
6442 acc = acc_head;
6443 found = FALSE;
6444 while (acc != NULL && !found)
6445 {
6446 if (amaip->saps[i] == acc->sap)
6447 found = TRUE;
6448 if (!found)
6449 acc = acc->next;
6450 }
6451 if (!found) /* big error */
6452 return FALSE;
6453 acc->num = i+1;
6454 AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], 1, &acc->start_seq, &acc->stop_seq);
6455 AlnMgr2GetNthSeqRangeInSA(amaip->saps[i], 2, &acc->start_acc, &acc->stop_acc);
6456 acc->strand = AlnMgr2GetNthStrand(amaip->saps[i], 2);
6457 acc->start_seq++;
6458 acc->stop_seq++;
6459 acc->start_acc++;
6460 acc->stop_acc++;
6461 }
6462 acc = acc_head;
6463 i = 0;
6464 while (acc != NULL)
6465 {
6466 if (acc->start_seq == 0 && acc->stop_seq == 0)
6467 {
6468 AlnMgr2GetNthSeqRangeInSA(acc->sap, 1, &acc->start_seq, &acc->stop_seq);
6469 AlnMgr2GetNthSeqRangeInSA(acc->sap, 2, &acc->start_acc, &acc->stop_acc);
6470 acc->strand = AlnMgr2GetNthStrand(acc->sap, 2);
6471 acc->start_seq++;
6472 acc->stop_seq++;
6473 acc->start_acc++;
6474 acc->stop_acc++;
6475 }
6476 if (acc->num == 0)
6477 acc->num = amaip->numsaps; /* sort these guys all to the end */
6478 i++;
6479 acc = acc->next;
6480 }
6481 accarray = (CKA_AccPtr PNTR)MemNew(i*sizeof(CKA_AccPtr));
6482 i = 0;
6483 acc = acc_head;
6484 while (acc != NULL)
6485 {
6486 accarray[i] = acc;
6487 i++;
6488 acc = acc->next;
6489 }
6490 HeapSort(accarray, i, sizeof(CKA_AccPtr), CKA_SortAccs);
6491 n=0;
6492 while (accarray[n]->sap == NULL && n < i)
6493 {
6494 n++;
6495 }
6496 SPI_GetAccessionFromSeqId(SqnSeqIdFindBestAccession(accarray[0]->sip_whole), &gi, &textid);
6497 if (textid == NULL)
6498 {
6499 sprintf(textid2, "%d", gi);
6500 textid = textid2;
6501 }
6502 first = last = -1;
6503 prev = -1;
6504 retval = TRUE;
6505 for (j=0; j<i /*&& first <=0*/ ; j++)
6506 {
6507 acc = accarray[j];
6508 if (acc->sap != NULL)
6509 {
6510 if (first == -1) {
6511 first = acc->start_seq;
6512 first_align = j;
6513 }
6514 last = MAX(last, acc->stop_seq);
6515 } else {
6516 continue;
6517 }
6518 if (prev != -1)
6519 {
6520 if (acc->start_seq > prev + CKA_GAPLEN)
6521 {
6522 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (no_cover_fmt) + StringLen (textid) + StringLen (accarray[j-1]->accession)
6523 + StringLen (acc->accession) + 60));
6524 sprintf (err_msg, no_cover_fmt,
6525 textid, accarray[j-1]->accession, accarray[j-1]->start_seq, accarray[j-1]->stop_seq, acc->accession, acc->start_seq, acc->stop_seq);
6526 ValNodeAddPointer (errors, 0, err_msg);
6527 retval = FALSE;
6528 }
6529 else if (acc->start_seq > prev)
6530 {
6531 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (no_cover_ok_gap_fmt) + StringLen (textid)
6532 + StringLen (accarray[j-1]->accession)
6533 + StringLen (acc->accession)
6534 + 75));
6535 sprintf (err_msg, no_cover_ok_gap_fmt,
6536 textid, accarray[j-1]->accession, accarray[j-1]->start_seq, accarray[j-1]->stop_seq, acc->accession, acc->start_seq, acc->stop_seq, CKA_GAPLEN);
6537 ValNodeAddPointer (errors, 0, err_msg);
6538 retval = FALSE;
6539 }
6540 }
6541 prev = acc->stop_seq+1;
6542 }
6543 if (first != 1 || last != bioseqlen)
6544 {
6545 if (first > CKA_GAPLEN)
6546 {
6547 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_start_fmt) + StringLen (textid)
6548 + StringLen (accarray[first_align]->accession)
6549 + 15));
6550 sprintf (err_msg, bad_start_fmt,
6551 textid, accarray[first_align]->accession, accarray[first_align]->start_seq);
6552 ValNodeAddPointer (errors, 0, err_msg);
6553 retval = FALSE;
6554 }
6555 else if (first != 1)
6556 {
6557 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_start_ok_gap_fmt)
6558 + StringLen (textid)
6559 + StringLen (accarray[first_align]->accession)
6560 + 30));
6561 sprintf (err_msg, bad_start_ok_gap_fmt,
6562 textid, accarray[first_align]->accession, accarray[first_align]->start_seq, CKA_GAPLEN);
6563 ValNodeAddPointer (errors, 0, err_msg);
6564 }
6565 max = 0;
6566 for (k=0; k<i; k++)
6567 {
6568 if (accarray[k]->stop_seq > max)
6569 {
6570 max = accarray[k]->stop_seq;
6571 longest = k;
6572 }
6573 }
6574 if (accarray[longest]->stop_seq < bioseqlen-CKA_GAPLEN)
6575 {
6576 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_end_fmt)
6577 + StringLen (textid)
6578 + StringLen (accarray[longest]->accession)
6579 + 30));
6580 sprintf (err_msg, bad_end_fmt,
6581 textid, accarray[longest]->accession, accarray[longest]->stop_seq, bioseqlen);
6582 ValNodeAddPointer (errors, 0, err_msg);
6583 retval = FALSE;
6584 }
6585 else if (accarray[longest]->stop_seq < bioseqlen)
6586 {
6587 err_msg = (CharPtr) MemNew (sizeof (Char) * (StringLen (bad_end_ok_gap_fmt)
6588 + StringLen (textid)
6589 + StringLen (accarray[longest]->accession)
6590 + 45));
6591 sprintf (err_msg, bad_end_ok_gap_fmt,
6592 textid, accarray[longest]->accession, accarray[longest]->stop_seq, bioseqlen, CKA_GAPLEN);
6593 ValNodeAddPointer (errors, 0, err_msg);
6594 }
6595 MemFree(accarray);
6596 accarray = NULL;
6597 }
6598 MemFree(accarray);
6599 return retval;
6600 }
6601
6602 static void FrameVwr (
6603 VieweR vwr,
6604 SegmenT pict
6605 )
6606
6607 {
6608 RecT r;
6609
6610 ResetClip ();
6611 ObjectRect (vwr, &r);
6612 FrameRect (&r);
6613 }
6614
6615 static void CKA_ShowAln(SeqAlignPtr sap, CKA_AccPtr acc_head)
6616 {
6617 CKA_AccPtr acc;
6618 BioseqPtr bsp;
6619 DenseSegPtr dsp;
6620 Boolean found;
6621 GrouP g;
6622 Int4 gi;
6623 Int4 i;
6624 Int4 len;
6625 Int4 numsaps;
6626 SegmenT picture;
6627 SeqAlignPtr salp;
6628 SeqIdPtr sip;
6629 Int4 start;
6630 Int4 start_r;
6631 Int4 stop;
6632 Int4 stop_r;
6633 Char tmp[42];
6634 CharPtr textid;
6635 Char textid2[42];
6636 VieweR v;
6637 WindoW w;
6638
6639 w = FixedWindow(-1, -1, -1, -1, "TPA display", StdCloseWindowProc);
6640 g = HiddenGroup(w, 1, 0, NULL);
6641 v = CreateViewer(g, 750, 300, TRUE, TRUE);
6642 picture = CreatePicture();
6643 salp = (SeqAlignPtr)(sap->segs);
6644 numsaps = 0;
6645 while (salp != NULL)
6646 {
6647 numsaps++;
6648 salp = salp->next;
6649 }
6650 salp = (SeqAlignPtr)(sap->segs);
6651 numsaps++;
6652 dsp = (DenseSegPtr)(salp->segs);
6653 sip = dsp->ids;
6654 SPI_GetAccessionFromSeqId(SqnSeqIdFindBestAccession(sip), &gi, &textid);
6655 if (textid == NULL)
6656 {
6657 sprintf(textid2, "%d", gi);
6658 textid = textid2;
6659 }
6660 bsp = BioseqLockById(sip);
6661 len = bsp->length;
6662 AddRectangle(picture, 0, numsaps*10, (bsp->length*680)/len, numsaps*10-7, 0, TRUE, 0);
6663 sprintf(tmp, "1");
6664 AddLabel(picture, 0-10, numsaps*10-3, tmp, 0, 0, MIDDLE_LEFT, 0);
6665 sprintf(tmp, "%d %s", bsp->length, textid);
6666 AddLabel(picture, ((bsp->length+10)*680)/len, numsaps*10-3, tmp, 0, 0, MIDDLE_RIGHT, 0);
6667 BioseqUnlock(bsp);
6668 i = numsaps-1;
6669 while (salp != NULL)
6670 {
6671 acc = acc_head;
6672 found = FALSE;
6673 while (acc != NULL && !found)
6674 {
6675 if (acc->sap == salp)
6676 found = TRUE;
6677 else
6678 acc = acc->next;
6679 }
6680 AlnMgr2GetNthSeqRangeInSA(salp, 1, &start, &stop);
6681 start_r = (start*680)/len;
6682 stop_r = (stop*680)/len;
6683 AddRectangle(picture, start_r, i*10, stop_r, i*10-7, 0, TRUE, 0);
6684 dsp = (DenseSegPtr)(salp->segs);
6685 sprintf(tmp, "%d", start+1);
6686 AddLabel(picture, start_r-10, i*10-3, tmp, 0, 0, MIDDLE_LEFT, 0);
6687 sprintf(tmp, "%d %s", stop+1, acc->accession);
6688 AddLabel(picture, stop_r+10, i*10-3, tmp, 0, 0, MIDDLE_RIGHT, 0);
6689 salp = salp->next;
6690 i--;
6691 }
6692 AttachPicture(v, picture, 0, 0, UPPER_LEFT, 1, 1, FrameVwr);
6693 Show(w);
6694 }
6695
6696
6697 static void PrintTPAHistErrors (LogInfoPtr lip, ValNodePtr errors)
6698 {
6699 ValNodePtr vnp;
6700
6701 if (lip == NULL || lip->fp == NULL || errors == NULL) return;
6702
6703 for (vnp = errors; vnp != NULL; vnp = vnp->next)
6704 {
6705 fprintf (lip->fp, "%s\n", vnp->data.ptrvalue);
6706 lip->data_in_log = TRUE;
6707 }
6708 fprintf (lip->fp, "\n\n");
6709 }
6710
6711
6712 static void CKA_RunChecker(SeqEntryPtr sep)
6713 {
6714 CKA_AccPtr acc;
6715 CKA_AccPtr acc_head;
6716 CKA_AccPtr acc_head_next;
6717 CKA_AccPtr acc_head_prev;
6718 CKA_AccPtr acc_head_real;
6719 CKA_AccPtr acc_head_tmp;
6720 BioseqPtr bsp;
6721 Boolean found;
6722 Int4 gi;
6723 SeqIdPtr lastid;
6724 SeqAlignPtr sap;
6725 SeqHistPtr shp;
6726 CharPtr textid;
6727 Char textid2[42];
6728 LogInfoPtr lip;
6729 ValNodePtr err_list;
6730 CharPtr err_msg;
6731 CharPtr no_align_fmt = "Accession %s does not align to the bioseq %s.\n";
6732
6733 if (sep == NULL)
6734 {
6735 Message(MSG_ERROR, "Null SeqEntry passed to CKA_RunChecker");
6736 return;
6737 }
6738 acc_head = NULL;
6739 SeqEntryExplore(sep, &acc_head, CKA_FindAllTpaDescr);
6740 lastid = NULL;
6741 if (acc_head == NULL)
6742 {
6743 Message(MSG_ERROR, "No Tpa features found in SeqEntry.");
6744 return;
6745 }
6746
6747 lip = OpenLog ("TPA Alignment Assembly Problems");
6748
6749 acc_head_real = acc_head;
6750 while (acc_head != NULL)
6751 {
6752 lastid = acc_head->sip_whole;
6753 acc_head_prev = acc_head;
6754 acc_head_tmp = acc_head->next;
6755 found = FALSE;
6756 while (!found && acc_head_tmp != NULL)
6757 {
6758 if (SeqIdComp(lastid, acc_head_tmp->sip_whole) != SIC_YES)
6759 found = TRUE;
6760 else
6761 {
6762 acc_head_prev = acc_head_tmp;
6763 acc_head_tmp = acc_head_tmp->next;
6764 }
6765 }
6766 acc_head_next = acc_head_prev->next;
6767 acc_head_prev->next = NULL;
6768 bsp = BioseqLockById(acc_head->sip_whole);
6769 if (ISA_na(bsp->mol))
6770 {
6771 sap = CKA_MakeAlign(bsp, acc_head, lip);
6772 acc = acc_head;
6773 while (acc != NULL && acc->sap == NULL)
6774 {
6775 acc = acc->next;
6776 }
6777 SPI_GetAccessionFromSeqId(SqnSeqIdFindBestAccession(acc_head->sip_whole), &gi, &textid);
6778 if (textid == NULL)
6779 {
6780 sprintf(textid2, "%d", gi);
6781 textid = textid2;
6782 }
6783
6784 err_list = NULL;
6785
6786 /* report each accession that does not align to the bioseq */
6787 acc = acc_head;
6788 while (acc != NULL)
6789 {
6790 if (acc->sap == NULL)
6791 {
6792 err_msg = (CharPtr) MemNew (sizeof(Char) * (StringLen (no_align_fmt) + StringLen (acc->accession) + StringLen (textid)));
6793 sprintf (err_msg, no_align_fmt, acc->accession, textid);
6794 ValNodeAddPointer (&err_list, 0, err_msg);
6795 }
6796 acc = acc->next;
6797 }
6798
6799 if (sap != NULL) {
6800 AlnMgr2IndexLite(sap);
6801 AlnMgr2SortAlnSetByNthRowPos(sap, 1);
6802 /* make seq-hist and add it to record */
6803 if (bsp->hist != NULL)
6804 {
6805 shp = bsp->hist;
6806 if (shp->assembly != NULL)
6807 SeqAlignSetFree(shp->assembly);
6808 shp->assembly = (SeqAlignPtr)(sap->segs);
6809 }
6810 else
6811 {
6812 shp = SeqHistNew();
6813 shp->assembly = (SeqAlignPtr)(sap->segs);
6814 bsp->hist = shp;
6815 }
6816 }
6817
6818 if (ValidateTPAHistAlign(bsp, &err_list))
6819 {
6820 fprintf (lip->fp, "Alignments were successfully created and are being added to %s.\n", textid);
6821 lip->data_in_log = TRUE;
6822 PrintTPAHistErrors (lip, err_list);
6823 err_list = ValNodeFreeData (err_list);
6824 }
6825 else if (sap != NULL)
6826 {
6827 fprintf (lip->fp, "Alignments were created but are not valid. They are being added to %s for review.\n", textid);
6828 lip->data_in_log = TRUE;
6829 PrintTPAHistErrors (lip, err_list);
6830 err_list = ValNodeFreeData (err_list);
6831 }
6832 else if (sap == NULL)
6833 {
6834 fprintf (lip->fp, "No alignments could be created for %s.\n", textid);
6835 lip->data_in_log = TRUE;
6836 PrintTPAHistErrors (lip, err_list);
6837 err_list = ValNodeFreeData (err_list);
6838 acc_head = acc_head_next;
6839 BioseqUnlock (bsp);
6840 continue;
6841 } else {
6842 PrintTPAHistErrors (lip, err_list);
6843 err_list = ValNodeFreeData (err_list);
6844 }
6845
6846 if (sap != NULL) {
6847 sap->segs = NULL;
6848 SeqAlignFree(sap);
6849 }
6850 }
6851 else
6852 {
6853 fprintf (lip->fp, "%s is annotated on a non-nucleotide bioseq.\n", acc_head->accession);
6854 lip->data_in_log = TRUE;
6855 }
6856 BioseqUnlock (bsp);
6857 acc_head = acc_head_next;
6858 }
6859 /*CKA_ShowAln(sap, acc_head_real);*/
6860 while (acc_head_real != NULL)
6861 {
6862 acc_head_tmp = acc_head_real->next;
6863 MemFree(acc_head_real->accession);
6864 SeqIdFree(acc_head_real->sip_whole);
6865 MemFree(acc_head_real);
6866 acc_head_real = acc_head_tmp;
6867 }
6868 CloseLog (lip);
6869 lip = FreeLog (lip);
6870 }
6871
6872
6873 typedef struct seqalignrow {
6874 Int4 start;
6875 Int4 stop;
6876 Uint1 strand;
6877 } SeqAlignRowData, PNTR SeqAlignRowPtr;
6878
6879 static SeqAlignRowPtr SeqAlignRowNew (Int4 start, Int4 stop, Uint1 strand)
6880 {
6881 SeqAlignRowPtr r;
6882 Int4 tmp;
6883
6884 r = (SeqAlignRowPtr) MemNew (sizeof (SeqAlignRowData));
6885 r->start = start;
6886 r->stop = stop;
6887
6888 if (r->start > r->stop) {
6889 tmp = r->start;
6890 r->start = r->stop;
6891 r->stop = tmp;
6892 }
6893 r->strand = strand;
6894 return r;
6895 }
6896
6897
6898 static SeqAlignRowPtr SeqAlignRowCopy (SeqAlignRowPtr orig)
6899 {
6900 SeqAlignRowPtr r = NULL;
6901
6902 if (orig != NULL) {
6903 r = SeqAlignRowNew (orig->start, orig->stop, orig->strand);
6904 }
6905 return r;
6906 }
6907
6908
6909 static SeqAlignRowPtr SeqAlignRowFree (SeqAlignRowPtr r)
6910 {
6911 r = MemFree (r);
6912 return r;
6913 }
6914
6915
6916 static Int4 RowDiff (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
6917 {
6918 Int4 diff = 0;
6919
6920 if (r1 == NULL || r2 == NULL) {
6921 return -1;
6922 }
6923
6924 diff = ABS(r1->start - r2->start) + ABS (r1->stop - r2->stop);
6925 return diff;
6926 }
6927
6928
6929 static Boolean SeqAlignRowConflict (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
6930 {
6931 if (r1 == NULL || r2 == NULL) {
6932 return FALSE;
6933 }
6934 if (r1->start <= r2->start && r1->stop >= r2->start) {
6935 return TRUE;
6936 } else if (r1->start <= r2->stop && r1->stop >= r2->stop) {
6937 return TRUE;
6938 } else if (r2->start <= r1->start && r2->start >= r2->start) {
6939 return TRUE;
6940 } else if (r2->start <= r1->stop && r2->stop >= r2->stop) {
6941 return TRUE;
6942 } else {
6943 return FALSE;
6944 }
6945 }
6946
6947
6948 static Int4 SeqAlignRowLen (SeqAlignRowPtr r)
6949 {
6950 Int4 len = 0;
6951
6952 if (r != NULL) {
6953 len = r->stop - r->start + 1;
6954 }
6955 return len;
6956 }
6957
6958
6959 typedef struct seqalignsort {
6960 SeqAlignRowPtr row1;
6961 SeqAlignRowPtr row2;
6962 SeqAlignPtr salp;
6963 } SeqAlignSortData, PNTR SeqAlignSortPtr;
6964
6965
6966 static SeqAlignSortPtr SeqAlignSortNew (SeqAlignPtr salp)
6967 {
6968 SeqAlignSortPtr s;
6969
6970 if (salp == NULL) {
6971 return NULL;
6972 }
6973
6974 s = (SeqAlignSortPtr) MemNew (sizeof (SeqAlignSortData));
6975 s->salp = SeqAlignDup (salp);
6976
6977 AlnMgr2IndexSingleChildSeqAlign(s->salp);
6978
6979 s->row1 = SeqAlignRowNew (SeqAlignStart (s->salp, 0), SeqAlignStop (s->salp, 0), SeqAlignStrand (s->salp, 0));
6980 s->row2 = SeqAlignRowNew (SeqAlignStart (s->salp, 1), SeqAlignStop (s->salp, 1), SeqAlignStrand (s->salp, 1));
6981
6982 return s;
6983 }
6984
6985
6986 static SeqAlignSortPtr SeqAlignSortFree (SeqAlignSortPtr s)
6987 {
6988 if (s != NULL) {
6989 s->row1 = SeqAlignRowFree (s->row1);
6990 s->row2 = SeqAlignRowFree (s->row2);
6991 s->salp = SeqAlignFree (s->salp);
6992 s = MemFree (s);
6993 }
6994 return s;
6995 }
6996
6997
6998 static SeqAlignSortPtr SeqAlignSortCopy (SeqAlignSortPtr s)
6999 {
7000 SeqAlignSortPtr copy = NULL;
7001
7002 if (s != NULL) {
7003 copy = (SeqAlignSortPtr) MemNew (sizeof (SeqAlignSortData));
7004 copy->salp = SeqAlignDup (s->salp);
7005 AlnMgr2IndexSingleChildSeqAlign(copy->salp);
7006 copy->row1 = SeqAlignRowCopy (s->row1);
7007 copy->row2 = SeqAlignRowCopy (s->row2);
7008 }
7009 return copy;
7010 }
7011
7012
7013 static ValNodePtr SeqAlignSortListNew (SeqAlignPtr salp)
7014 {
7015 ValNodePtr list = NULL;
7016 SeqAlignPtr salp_next;
7017
7018 while (salp != NULL) {
7019 salp_next = salp->next;
7020 salp->next = NULL;
7021 ValNodeAddPointer (&list, 0, SeqAlignSortNew (salp));
7022 salp = salp_next;
7023 }
7024 return list;
7025 }
7026
7027
7028 static ValNodePtr SeqAlignSortListFree (ValNodePtr vnp)
7029 {
7030 ValNodePtr vnp_next;
7031
7032 while (vnp != NULL) {
7033 vnp_next = vnp->next;
7034 vnp->next = NULL;
7035 vnp->data.ptrvalue = SeqAlignSortFree (vnp->data.ptrvalue);
7036 vnp = ValNodeFree (vnp);
7037 vnp = vnp_next;
7038 }
7039 return vnp;
7040 }
7041
7042
7043 static Boolean SeqAlignSortConflict (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
7044 {
7045 if (s1 == NULL || s2 == NULL) {
7046 return FALSE;
7047 } else if (SeqAlignRowConflict (s1->row1, s2->row1)) {
7048 return TRUE;
7049 } else if (SeqAlignRowConflict (s1->row2, s2->row2)) {
7050 return TRUE;
7051 } else {
7052 return FALSE;
7053 }
7054 }
7055
7056
7057 static Int4 SeqAlignSortListLongestInterval (ValNodePtr list)
7058 {
7059 Int4 len, max = 0;
7060 ValNodePtr vnp;
7061 SeqAlignSortPtr s;
7062
7063 for (vnp = list; vnp != NULL; vnp = vnp->next) {
7064 s = vnp->data.ptrvalue;
7065 if (s != NULL && s->row1 != NULL) {
7066 len = SeqAlignRowLen (s->row1);
7067 if (len > max) {
7068 max = len;
7069 }
7070 }
7071 }
7072 return max;
7073 }
7074
7075
7076 static SeqAlignRowPtr SeqAlignRowFromSeqAlignSort (SeqAlignSortPtr s, Int4 row)
7077 {
7078 if (s == NULL) {
7079 return NULL;
7080 } else if (row == 1) {
7081 return s->row1;
7082 } else {
7083 return s->row2;
7084 }
7085 }
7086
7087
7088 static Uint1 SeqAlignSortRowStrand (SeqAlignSortPtr s, Int4 row)
7089 {
7090 Uint1 strand = Seq_strand_plus;
7091 SeqAlignRowPtr r;
7092
7093 r = SeqAlignRowFromSeqAlignSort (s, row);
7094 if (r != NULL) {
7095 strand = r->strand;
7096 }
7097 return strand;
7098 }
7099
7100
7101 static Uint1 SeqAlignSortListFindBestStrand (ValNodePtr vnp, Int4 row)
7102 {
7103 Int4 num_plus = 0, num_minus = 0, num_align, num = 0;
7104 SeqAlignSortPtr s;
7105
7106 /* count the alignments */
7107 num_align = ValNodeLen (vnp);
7108
7109 /* only look at strands from the first half of the alignments */
7110 num_align = num_align / 2;
7111
7112 while (vnp != NULL && num < num_align) {
7113 s = (SeqAlignSortPtr) vnp->data.ptrvalue;
7114 if (s != NULL) {
7115 if (SeqAlignSortRowStrand(s, row) == Seq_strand_minus) {
7116 num_minus++;
7117 } else {
7118 num_plus++;
7119 }
7120 }
7121 vnp = vnp->next;
7122 num++;
7123 }
7124
7125 if (num_minus > num_plus) {
7126 return Seq_strand_minus;
7127 } else {
7128 return Seq_strand_plus;
7129 }
7130 }
7131
7132
7133 static void SeqAlignSortListMarkStrand (ValNodePtr vnp, Int4 row, Uint1 strand)
7134 {
7135 while (vnp != NULL) {
7136 if (SeqAlignSortRowStrand (vnp->data.ptrvalue, row) == strand) {
7137 vnp->choice = 1;
7138 }
7139 vnp = vnp->next;
7140 }
7141 }
7142
7143
7144 static void SeqAlignSortListRemoveMarked (ValNodePtr PNTR list)
7145 {
7146 ValNodePtr remove_list;
7147
7148 if (list == NULL) {
7149 return;
7150 }
7151
7152 remove_list = ValNodeExtractList (list, 1);
7153 remove_list = SeqAlignSortListFree (remove_list);
7154 }
7155
7156
7157 static Uint1 SeqAlignSortListRemoveConflictingStrands (ValNodePtr PNTR list, Int4 row)
7158 {
7159 Uint1 strand;
7160
7161 if (list == NULL) {
7162 return Seq_strand_plus;
7163 }
7164
7165 strand = SeqAlignSortListFindBestStrand (*list, row);
7166 if (strand == Seq_strand_plus) {
7167 SeqAlignSortListMarkStrand (*list, row, Seq_strand_minus);
7168 } else {
7169 SeqAlignSortListMarkStrand (*list, row, Seq_strand_plus);
7170 }
7171
7172 SeqAlignSortListRemoveMarked (list);
7173 return strand;
7174 }
7175
7176
7177 static SeqAlignPtr SeqAlignFromSeqAlignSortList (ValNodePtr vnp)
7178 {
7179 SeqAlignPtr salp_list = NULL, salp_prev = NULL;
7180 SeqAlignSortPtr s;
7181
7182 while (vnp != NULL) {
7183 s = (SeqAlignSortPtr) vnp->data.ptrvalue;
7184 if (s != NULL && s->salp != NULL) {
7185 s->salp->next = NULL;
7186 if (salp_prev == NULL) {
7187 salp_list = s->salp;
7188 } else {
7189 salp_prev->next = s->salp;
7190 }
7191 salp_prev = s->salp;
7192 s->salp->next = NULL;
7193 /* NULL out entry in SeqAlignSort so that it will not be freed later */
7194 s->salp = NULL;
7195 }
7196 vnp = vnp->next;
7197 }
7198 return salp_list;
7199 }
7200
7201
7202 static int CompareSeqAlignRow (SeqAlignRowPtr r1, SeqAlignRowPtr r2)
7203 {
7204 int rval = 0;
7205
7206 if (r1 == NULL && r2 == NULL) {
7207 rval = 0;
7208 } else if (r1 == NULL) {
7209 rval = -1;
7210 } else if (r2 == NULL) {
7211 rval = 1;
7212 } else if (r1->start < r2->start) {
7213 rval = -1;
7214 } else if (r1->start > r2->start) {
7215 rval = 1;
7216 } else if (r1->stop < r2->stop) {
7217 rval = -1;
7218 } else if (r1->stop > r2->stop) {
7219 rval = 1;
7220 } else if (r1->strand < r2->strand) {
7221 rval = -1;
7222 } else if (r1->strand > r2->strand) {
7223 rval = 1;
7224 }
7225 return rval;
7226 }
7227
7228
7229 static int CompareSeqAlignSortPreferRow1 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
7230 {
7231 int rval = 0;
7232 if (s1 == NULL && s2 == NULL) {
7233 rval = 0;
7234 } else if (s1 == NULL) {
7235 rval = -1;
7236 } else if (s2 == NULL) {
7237 rval = 1;
7238 } else if ((rval = CompareSeqAlignRow (s1->row1,s2->row1)) == 0) {
7239 rval = CompareSeqAlignRow (s1->row2, s2->row2);
7240 }
7241 return rval;
7242 }
7243
7244
7245 static int CompareSeqAlignSortPreferRow2 (SeqAlignSortPtr s1, SeqAlignSortPtr s2)
7246 {
7247 int rval = 0;
7248 if (s1 == NULL && s2 == NULL) {
7249 rval = 0;
7250 } else if (s1 == NULL) {
7251 rval = -1;
7252 } else if (s2 == NULL) {
7253 rval = 1;
7254 } else if ((rval = CompareSeqAlignRow (s1->row2,s2->row2)) == 0) {
7255 rval = CompareSeqAlignRow (s1->row1, s2->row1);
7256 }
7257 return rval;
7258 }
7259
7260
7261
7262 static int LIBCALLBACK SortVnpBySeqAlignSortRow1 (VoidPtr ptr1, VoidPtr ptr2)
7263
7264 {
7265 ValNodePtr vnp1;
7266 ValNodePtr vnp2;
7267
7268 if (ptr1 != NULL && ptr2 != NULL) {
7269 vnp1 = *((ValNodePtr PNTR) ptr1);
7270 vnp2 = *((ValNodePtr PNTR) ptr2);
7271 if (vnp1 != NULL && vnp2 != NULL) {
7272 return CompareSeqAlignSortPreferRow1 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
7273 }
7274 }
7275 return 0;
7276 }
7277
7278
7279 static int LIBCALLBACK SortVnpBySeqAlignSortRow2 (VoidPtr ptr1, VoidPtr ptr2)
7280
7281 {
7282 ValNodePtr vnp1;
7283 ValNodePtr vnp2;
7284
7285 if (ptr1 != NULL && ptr2 != NULL) {
7286 vnp1 = *((ValNodePtr PNTR) ptr1);
7287 vnp2 = *((ValNodePtr PNTR) ptr2);
7288 if (vnp1 != NULL && vnp2 != NULL) {
7289 return CompareSeqAlignSortPreferRow2 (vnp1->data.ptrvalue, vnp2->data.ptrvalue);
7290 }
7291 }
7292 return 0;
7293 }
7294
7295
7296 static ValNodePtr SeqAlignSortListMarkRepeats (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
7297 {
7298 ValNodePtr repeat_start, vnp, vnp_mark;
7299 ValNodePtr repeat_list = NULL, tmp_list;
7300 SeqAlignSortPtr s1, s2;
7301 SeqAlignRowPtr interval, r2;
7302 Int4 diff;
7303 Boolean is_repeat;
7304
7305 if (list == NULL || *list == NULL || (*list)->next == NULL) {
7306 return NULL;
7307 }
7308
7309 if (row == 1) {
7310 *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow1);
7311 } else {
7312 *list = ValNodeSort (*list, SortVnpBySeqAlignSortRow2);
7313 }
7314
7315 repeat_start = *list;
7316 s1 = repeat_start->data.ptrvalue;
7317 interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
7318 for (vnp = (*list)->next; vnp != NULL; vnp = vnp->next) {
7319 s2 = vnp->data.ptrvalue;
7320 is_repeat = FALSE;
7321 r2 = SeqAlignRowFromSeqAlignSort (s2, row);
7322
7323 if (interval->start <= r2->start && interval->stop >= r2->stop) {
7324 /* contained */
7325 is_repeat = TRUE;
7326 } else if (r2->start <= interval->start && r2->stop >= interval->stop) {
7327 /* contained */
7328 is_repeat = TRUE;
7329 } else if ((diff = RowDiff (interval, r2)) > -1 && diff < fuzz) {
7330 is_repeat = TRUE;
7331 }
7332 if (is_repeat) {
7333 if (interval->start > r2->start) {
7334 interval->start = r2->start;
7335 }
7336 if (interval->stop < r2->stop) {
7337 interval->stop = r2->stop;
7338 }
7339 } else {
7340 if (repeat_start->next != vnp) {
7341 tmp_list = NULL;
7342 for (vnp_mark = repeat_start; vnp_mark != vnp; vnp_mark = vnp_mark->next) {
7343 /* add copy to list of repeats */
7344 ValNodeAddPointer (&tmp_list, 0, SeqAlignSortCopy (vnp_mark->data.ptrvalue));
7345 /* mark as repeat for this row */
7346 vnp_mark->choice = row;
7347 }
7348 ValNodeAddPointer (&repeat_list, 0, tmp_list);
7349 }
7350 repeat_start = vnp;
7351 s1 = vnp->data.ptrvalue;
7352 interval = SeqAlignRowFree (interval);
7353 interval = SeqAlignRowCopy (SeqAlignRowFromSeqAlignSort(s1, row));
7354 }
7355 }
7356
7357 if (repeat_start->next != NULL) {
7358 tmp_list = NULL;
7359 for (vnp_mark = repeat_start; vnp_mark != vnp; vnp_mark = vnp_mark->next) {
7360 /* add copy to list of repeats */
7361 ValNodeAddPointer (&tmp_list, 0, SeqAlignSortCopy (vnp_mark->data.ptrvalue));
7362 /* mark as repeat for this row */
7363 vnp_mark->choice = row;
7364 }
7365 ValNodeAddPointer (&repeat_list, 0, tmp_list);
7366 }
7367
7368 interval = SeqAlignRowFree (interval);
7369 return repeat_list;
7370 }
7371
7372
7373 static int SeqAlignRowFuzzyCompare (SeqAlignRowPtr r1, SeqAlignRowPtr r2, Int4 fuzz)
7374 {
7375 if (r1 == NULL && r2 == NULL) {
7376 return 0;
7377 } else if (r1 == NULL) {
7378 return -1;
7379 } else if (r2 == NULL) {
7380 return 1;
7381 }
7382
7383 if (r1->stop < r2->start || r1->stop - r2->start < fuzz) {
7384 return -1;
7385 } else if (r2->stop < r1->start || r2->stop - r1->start < fuzz) {
7386 return 1;
7387 } else {
7388 return 0;
7389 }
7390 }
7391
7392
7393 static int SeqAlignSortFuzzyCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
7394 {
7395 if (s1 == NULL && s2 == NULL) {
7396 return 0;
7397 } else if (s1 == NULL) {
7398 return -1;
7399 } else if (s2 == NULL) {
7400 return 1;
7401 } else if (row == 1) {
7402 return SeqAlignRowFuzzyCompare (s1->row1, s2->row1, fuzz);
7403 } else {
7404 return SeqAlignRowFuzzyCompare (s1->row2, s2->row2, fuzz);
7405 }
7406 }
7407
7408
7409 static void SeqAlignSortListRemoveIntervalsOutOfOrder (ValNodePtr PNTR list, Int4 row, Int4 fuzz)
7410 {
7411 ValNodePtr vnp, vnp_prev = NULL;
7412
7413 if (list == NULL) {
7414 return;
7415 }
7416
7417 for (vnp = *list; vnp != NULL; vnp = vnp->next) {
7418 if (vnp_prev != NULL && SeqAlignSortFuzzyCompare (vnp_prev->data.ptrvalue, vnp->data.ptrvalue, row, fuzz) != -1) {
7419 vnp->choice = 1;
7420 } else if (vnp->next != NULL && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->data.ptrvalue, row, fuzz) != -1) {
7421 if (vnp->next->next != NULL
7422 && SeqAlignSortFuzzyCompare (vnp->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) == -1
7423 && SeqAlignSortFuzzyCompare (vnp->next->data.ptrvalue, vnp->next->next->data.ptrvalue, row, fuzz) != -1) {
7424 /* ok to keep this one, we'll toss the next one */
7425 } else {
7426 vnp->choice = 1;
7427 }
7428 }
7429 if (vnp->choice == 0) {
7430 vnp_prev = vnp;
7431 }
7432 }
7433
7434 SeqAlignSortListRemoveMarked (list);
7435 }
7436
7437
7438 static Int4 GetRepeatIntervalFuzz (SeqAlignSortPtr s_repeat, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row)
7439 {
7440 Int4 start_fuzz = 0, end_fuzz = 0;
7441
7442 if (s_repeat == NULL) {
7443 return -1;
7444 }
7445
7446 if (s_before != NULL) {
7447 if (row == 1) {
7448 start_fuzz = ABS (s_repeat->row1->start - s_before->row1->stop);
7449 } else {
7450 start_fuzz = ABS (s_repeat->row2->start - s_before->row2->stop);
7451 }
7452 }
7453 if (s_after != NULL) {
7454 if (row == 1) {
7455 end_fuzz = ABS (s_after->row1->start - s_repeat->row1->stop);
7456 } else {
7457 end_fuzz = ABS (s_after->row2->start - s_repeat->row2->stop);
7458 }
7459 }
7460
7461 return start_fuzz + end_fuzz;
7462 }
7463
7464
7465 static int StrandedSeqAlignSortRowCompare (SeqAlignSortPtr s1, SeqAlignSortPtr s2, Int4 row, Int4 fuzz)
7466 {
7467 SeqAlignRowPtr r1 = NULL, r2 = NULL;
7468 int rval = 0;
7469 Uint1 strand = Seq_strand_plus;
7470
7471 if (s1 == NULL || s2 == NULL) {
7472 return 0;
7473 }
7474
7475 r1 = SeqAlignRowFromSeqAlignSort (s1, row);
7476 r2 = SeqAlignRowFromSeqAlignSort (s2, row);
7477 strand = r1->strand;
7478
7479 if (strand == Seq_strand_minus) {
7480 if (r1->start < r2->start - fuzz) {
7481 rval = 1;
7482 } else if (r1->start >r2->start + fuzz) {
7483 rval = -1;
7484 }
7485 } else {
7486 if (r1->start > r2->start + fuzz) {
7487 rval = 1;
7488 } else if (r1->stop < r2->stop - fuzz) {
7489 rval = -1;
7490 }
7491 }
7492
7493 return rval;
7494 }
7495
7496
7497 static Boolean FindSeqAlignSortWithPoint (ValNodePtr list, Int4 point, Int4 row)
7498 {
7499 ValNodePtr vnp;
7500 SeqAlignRowPtr r;
7501 SeqAlignSortPtr s;
7502 Boolean found = FALSE;
7503
7504 for (vnp = list; vnp != NULL; vnp = vnp->next) {
7505 s = vnp->data.ptrvalue;
7506 r = SeqAlignRowFromSeqAlignSort (s, row);
7507 if (point >= r->start && point <= r->stop) {
7508 found = TRUE;
7509 }
7510 }
7511 return found;
7512 }
7513
7514
7515 static ValNodePtr FindBestRepeat (ValNodePtr PNTR repeat_list, SeqAlignSortPtr s_before, SeqAlignSortPtr s_after, Int4 row, Int4 fuzz)
7516 {
7517 Int4 best_diff = -1, diff;
7518 ValNodePtr vnp, vnp_best = NULL, vnp_best_prev = NULL, vnp_prev = NULL;
7519 SeqAlignSortPtr s_this;
7520
7521 if (repeat_list == NULL || *repeat_list == NULL) {
7522 return NULL;
7523 }
7524
7525 for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
7526 s_this = vnp->data.ptrvalue;
7527
7528 if (StrandedSeqAlignSortRowCompare (s_this, s_before, row, fuzz) < 0
7529 || StrandedSeqAlignSortRowCompare (s_this, s_after, row, fuzz) > 0) {
7530 /* skip - already out of order */
7531 } else {
7532 diff = GetRepeatIntervalFuzz (vnp->data.ptrvalue, s_before, s_after, row);
7533 if (diff > -1 && (best_diff < 0 || best_diff > diff)) {
7534 vnp_best = vnp;
7535 vnp_best_prev = vnp_prev;
7536 best_diff = diff;
7537 }
7538 }
7539 vnp_prev = vnp;
7540 }
7541
7542 if (vnp_best != NULL) {
7543 if (vnp_best_prev == NULL) {
7544 *repeat_list = vnp_best->next;
7545 } else {
7546 vnp_best_prev->next = vnp_best->next;
7547 }
7548 vnp_best->next = NULL;
7549 }
7550
7551 return vnp_best;
7552 }
7553
7554
7555 static void RemoveRepeatsCoincidingWithBest (ValNodePtr PNTR repeat_list, ValNodePtr best, Int4 row, Int4 fuzz)
7556 {
7557 ValNodePtr vnp;
7558 SeqAlignSortPtr s_best, s;
7559 SeqAlignRowPtr r_best, r2;
7560 Boolean is_repeat;
7561 Int4 diff;
7562
7563 if (repeat_list == NULL || *repeat_list == NULL || best == NULL) {
7564 return;
7565 }
7566
7567 s_best = best->data.ptrvalue;
7568 r_best = SeqAlignRowFromSeqAlignSort (s_best, row);
7569
7570 for (vnp = *repeat_list; vnp != NULL; vnp = vnp->next) {
7571 s = vnp->data.ptrvalue;
7572 r2 = SeqAlignRowFromSeqAlignSort (s, row);
7573
7574 is_repeat = FALSE;
7575 if (r_best->start <= r2->start && r_best->stop >= r2->stop) {
7576 /* contained */
7577 is_repeat = TRUE;
7578 } else if (r2->start <= r_best->start && r2->stop >= r_best->stop) {
7579 /* contained */
7580 is_repeat = TRUE;
7581 } else if (r2->stop < r_best->stop || r2->stop - r_best->stop < fuzz) {
7582 is_repeat = TRUE;
7583 } else if ((diff = RowDiff (r_best, r2)) > -1 && diff < fuzz) {
7584 is_repeat = TRUE;
7585 }
7586
7587 if (is_repeat) {
7588 vnp->choice = 1;
7589 }
7590 }
7591 SeqAlignSortListRemoveMarked (repeat_list);
7592 }
7593
7594
7595 static ValNodePtr ExtractLongestSeqAlignRow (ValNodePtr PNTR list, Int4 row)
7596 {
7597 ValNodePtr vnp, vnp_prev = NULL, rval = NULL;
7598 Int4 longest = 0, len;
7599 Boolean found = FALSE;
7600
7601 if (list == NULL || *list == NULL) {
7602 return NULL;
7603 }
7604
7605 for (vnp = *list; vnp != NULL; vnp = vnp->next) {
7606 len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
7607 if (longest < len) {
7608 longest = len;
7609 }
7610 }
7611
7612 for (vnp = *list; vnp != NULL && !found; vnp = vnp->next) {
7613 len = SeqAlignRowLen (SeqAlignRowFromSeqAlignSort (vnp->data.ptrvalue, row));
7614 if (len == longest) {
7615 if (vnp_prev == NULL) {
7616 *list = vnp->next;
7617 } else {
7618 vnp_prev->next = vnp->next;
7619 }
7620 vnp->next = NULL;
7621 rval = vnp;
7622 found = TRUE;
7623 }
7624 vnp_prev = vnp;
7625 }
7626 return rval;
7627 }
7628
7629
7630 static void InsertBestRepeat (ValNodePtr repeat_list, ValNodePtr PNTR sorted_list, Int4 row, Int4 fuzz)
7631 {
7632 ValNodePtr vnp, vnp_prev = NULL, vnp_new;
7633 SeqAlignSortPtr s_repeat, s, s_before = NULL;
7634 Boolean found = TRUE;
7635 SeqAlignRowPtr r1, r2;
7636 Int4 other_row;
7637
7638 if (repeat_list == NULL || sorted_list == NULL) {
7639 return;
7640 }
7641
7642 if (row == 1) {
7643 other_row = 2;
7644 } else {
7645 other_row = 1;
7646 }
7647 if (sorted_list == NULL || *sorted_list == NULL) {
7648 /* keep longest, mark others for removal */
7649 vnp = ExtractLongestSeqAlignRow (&repeat_list, row);
7650 ValNodeLink (sorted_list,vnp);
7651 repeat_list = SeqAlignSortListFree (repeat_list);
7652 } else {
7653 s_repeat = repeat_list->data.ptrvalue;
7654 found = FALSE;
7655 vnp = *sorted_list;
7656
7657 /* find first entry that is after this repeat, and insert before that */
7658 while (vnp != NULL && !found) {
7659 if (SeqAlignSortConflict (s_repeat, vnp->data.ptrvalue)) {
7660 found = TRUE;
7661 break;
7662 }
7663
7664 s = vnp->data.ptrvalue;
7665 r1 = SeqAlignRowFromSeqAlignSort (s, row);
7666 r2 = SeqAlignRowFromSeqAlignSort (s_repeat, row);
7667
7668 if (r1->start == r2->start && r1->stop == r2->stop) {
7669 /* this is a duplicate. throw it away. */
7670 found = TRUE;
7671 break;
7672 }
7673
7674 if (r1->start > r2->start || r2->start - r1->start < fuzz) {
7675 while (repeat_list != NULL) {
7676 /* extract best repeat */
7677 vnp_new = FindBestRepeat (&repeat_list, s_before, vnp->data.ptrvalue, other_row, fuzz);
7678 if (vnp_new == NULL) {
7679 repeat_list = SeqAlignSortListFree (repeat_list);
7680 } else {
7681 RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
7682 vnp_new->next = vnp;
7683 if (vnp_prev == NULL) {
7684 *sorted_list = vnp_new;
7685 } else {
7686 vnp_prev->next = vnp_new;
7687 }
7688 vnp_prev = vnp_new;
7689 s_before = vnp_new->data.ptrvalue;
7690 }
7691 }
7692 found = TRUE;
7693 }
7694 if (!found) {
7695 s_before = vnp->data.ptrvalue;
7696 vnp_prev = vnp;
7697 vnp = vnp->next;
7698 }
7699 }
7700 if (!found) {
7701 while (repeat_list != NULL) {
7702 /* extract best repeat */
7703 vnp_new = FindBestRepeat (&repeat_list, s_before, NULL, other_row, fuzz);
7704 if (vnp_new == NULL) {
7705 repeat_list = SeqAlignSortListFree (repeat_list);
7706 } else {
7707 RemoveRepeatsCoincidingWithBest (&repeat_list, vnp_new, row, fuzz);
7708 vnp_new->next = NULL;
7709 if (vnp_prev == NULL) {
7710 *sorted_list = vnp_new;
7711 } else {
7712 vnp_prev->next = vnp_new;
7713 }
7714 vnp_prev = vnp_new;
7715 s_before = vnp_new->data.ptrvalue;
7716 }
7717 }
7718 }
7719 }
7720
7721 SeqAlignSortListRemoveMarked (&repeat_list);
7722 repeat_list = ValNodeFree (repeat_list);
7723 }
7724
7725
7726 static Int4 FindLongestRepeatInterval (ValNodePtr repeat_list)
7727 {
7728 Int4 len, max = 0;
7729 ValNodePtr vnp_r, vnp;
7730 SeqAlignSortPtr s;
7731
7732 for (vnp_r = repeat_list; vnp_r != NULL; vnp_r = vnp_r->next) {
7733 for (vnp = vnp_r->data.ptrvalue; vnp != NULL; vnp = vnp->next) {
7734 s = vnp->data.ptrvalue;
7735 if (s != NULL && s->row1 != NULL) {
7736 len = SeqAlignRowLen (s->row1);
7737 if (len > max) {
7738 max = len;
7739 }
7740 }
7741 }
7742 }
7743 return max;
7744 }
7745
7746
7747 /* note - we want to sort from highest to lowest */
7748 static int LIBCALLBACK SortVnpByRepeatList (VoidPtr ptr1, VoidPtr ptr2)
7749
7750 {
7751 ValNodePtr vnp1;
7752 ValNodePtr vnp2;
7753 Int4 len1, len2;
7754 int rval = 0;
7755
7756 if (ptr1 != NULL && ptr2 != NULL) {
7757 vnp1 = *((ValNodePtr PNTR) ptr1);
7758 vnp2 = *((ValNodePtr PNTR) ptr2);
7759 if (vnp1 != NULL && vnp2 != NULL) {
7760 len1 = SeqAlignSortListLongestInterval (vnp1->data.ptrvalue);
7761 len2 = SeqAlignSortListLongestInterval (vnp2->data.ptrvalue);
7762 if (len1 < len2) {
7763 rval = 1;
7764 } else if (len2 < len1) {
7765 rval = -1;
7766 }
7767 }
7768 }
7769 return rval;
7770 }
7771
7772
7773
7774
7775 static void SelectBestRepeatsFromList (SeqAlignPtr PNTR salp)
7776 {
7777 ValNodePtr list, vnp;
7778 ValNodePtr row1_repeats, row2_repeats;
7779 Uint1 strand1, strand2;
7780 SeqAlignPtr tmp_salp;
7781 Int4 fuzz = 15;
7782 Int4 missing = 600;
7783 Int4 len1, len2;
7784
7785 if (salp == NULL || *salp == NULL || (*salp)->next == NULL) {
7786 return;
7787 }
7788
7789 list = SeqAlignSortListNew (*salp);
7790
7791 FindSeqAlignSortWithPoint (list, missing, 1);
7792
7793 /* remove conflicting strands for row 1 */
7794 strand1 = SeqAlignSortListRemoveConflictingStrands (&list, 1);
7795
7796 /* remove conflicting strands for row 1 */
7797 strand2 = SeqAlignSortListRemoveConflictingStrands (&list, 2);
7798
7799 FindSeqAlignSortWithPoint (list, missing, 1);
7800
7801 if (list != NULL && list->next != NULL) {
7802 row1_repeats = SeqAlignSortListMarkRepeats (&list, 1, fuzz);
7803 row1_repeats = ValNodeSort (row1_repeats, SortVnpByRepeatList);
7804 row2_repeats = SeqAlignSortListMarkRepeats (&list, 2, fuzz);
7805 row2_repeats = ValNodeSort (row2_repeats, SortVnpByRepeatList);
7806 vnp = ValNodeExtractList (&list, 1);
7807 vnp = SeqAlignSortListFree (vnp);
7808 vnp = ValNodeExtractList (&list, 2);
7809 vnp = SeqAlignSortListFree (vnp);
7810
7811 FindSeqAlignSortWithPoint (list, missing, 1);
7812
7813 /* remove scaffold intervals that are out of order */
7814 list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7815 SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 1, fuzz);
7816 list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
7817 SeqAlignSortListRemoveIntervalsOutOfOrder (&list, 2, fuzz);
7818
7819 FindSeqAlignSortWithPoint (list, missing, 1);
7820
7821 /* Remove overlaps.*/
7822 list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7823 tmp_salp = SeqAlignFromSeqAlignSortList (list);
7824 list = SeqAlignSortListFree (list);
7825 ACT_RemoveInconsistentAlnsFromSet (tmp_salp, 1, 1);
7826 list = SeqAlignSortListNew (tmp_salp);
7827
7828 FindSeqAlignSortWithPoint (list, missing, 1);
7829
7830 len1 = FindLongestRepeatInterval (row1_repeats);
7831 len2 = FindLongestRepeatInterval (row2_repeats);
7832
7833 if (len1 >= len2) {
7834 /* for each repeat on row 1, we want to pick the most consistent interval for row 2 */
7835 list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7836 for (vnp = row1_repeats; vnp != NULL; vnp = vnp->next) {
7837 InsertBestRepeat (vnp->data.ptrvalue, &list, 1, fuzz);
7838 }
7839 row1_repeats = ValNodeFree (row1_repeats);
7840
7841 /* for each repeat on row 2, we want to pick the most consistent interval for row 1 */
7842 list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
7843 for (vnp = row2_repeats; vnp != NULL; vnp = vnp->next) {
7844 InsertBestRepeat (vnp->data.ptrvalue, &list, 2, fuzz);
7845 }
7846 row2_repeats = ValNodeFree (row2_repeats);
7847 } else {
7848 /* for each repeat on row 2, we want to pick the most consistent interval for row 1 */
7849 list = ValNodeSort (list, SortVnpBySeqAlignSortRow2);
7850 for (vnp = row2_repeats; vnp != NULL; vnp = vnp->next) {
7851 InsertBestRepeat (vnp->data.ptrvalue, &list, 2, fuzz);
7852 }
7853 row2_repeats = ValNodeFree (row2_repeats);
7854
7855 /* for each repeat on row 1, we want to pick the most consistent interval for row 2 */
7856 list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7857 for (vnp = row1_repeats; vnp != NULL; vnp = vnp->next) {
7858 InsertBestRepeat (vnp->data.ptrvalue, &list, 1, fuzz);
7859 }
7860 row1_repeats = ValNodeFree (row1_repeats);
7861 }
7862 }
7863
7864 list = ValNodeSort (list, SortVnpBySeqAlignSortRow1);
7865 *salp = SeqAlignFromSeqAlignSortList (list);
7866
7867 list = SeqAlignSortListFree (list);
7868 }
7869
7870
7871 static void amconssetfree(AMConsSetPtr acp)
7872 {
7873 AMConsSetPtr acp_next;
7874
7875 while (acp != NULL)
7876 {
7877 acp_next = acp->next;
7878 MemFree(acp->starts);
7879 MemFree(acp->stops);
7880 MemFree(acp->strands);
7881 MemFree(acp);
7882 acp = acp_next;
7883 }
7884 }
7885
7886 static int LIBCALLBACK CKA_SortForConsistent(VoidPtr ptr1, VoidPtr ptr2)
7887 {
7888 AMConsSetPtr acp1;
7889 AMConsSetPtr acp2;
7890 FloatHi bitscore;
7891 FloatHi evalue;
7892 Int4 number;
7893 SAIndex2Ptr saip1;
7894 SAIndex2Ptr saip2;
7895
7896 acp1 = *((AMConsSetPtr PNTR)ptr1);
7897 acp2 = *((AMConsSetPtr PNTR)ptr2);
7898 saip1 = (SAIndex2Ptr)(acp1->sap->saip);
7899 saip2 = (SAIndex2Ptr)(acp2->sap->saip);
7900 if (saip1->score == 0)
7901 GetScoreAndEvalue(acp1->sap, &saip1->score, &bitscore, &evalue, &number);
7902 if (saip2->score == 0)
7903 GetScoreAndEvalue(acp2->sap, &saip2->score, &bitscore, &evalue, &number);
7904 if (saip1->score > saip2->score)
7905 return -1;
7906 else if (saip1->score < saip2->score)
7907 return 1;
7908 else
7909 return 0;
7910 }
7911
7912
7913 static void CKA_RemoveInconsistentAlnsFromSet(SeqAlignPtr sap_head, Int4 fuzz)
7914 {
7915 AMConsSetPtr acp;
7916 AMConsSetPtr acp_head;
7917 AMConsSetPtr acp_prev;
7918 AMConsSetPtr PNTR acparray;
7919 DenseSegPtr dsp;
7920 Int4 i;
7921 Int4 j;
7922 Int4 k;
7923 Int4 lfuzz;
7924 SeqAlignPtr newsap;
7925 Int4 numrows;
7926 Int4 numsaps;
7927 Int4 orientation;
7928 Int4 row;
7929 SAIndex2Ptr saip;
7930 SeqAlignPtr salp_head;
7931 SeqAlignPtr salp_prev;
7932 SeqAlignPtr sap;
7933 SeqAlignPtr sapnext;
7934 Int4 score;
7935 SeqIdPtr sip;
7936 SeqIdPtr sip_head;
7937 Uint1 strand;
7938
7939 lfuzz = fuzz;
7940 if (fuzz < 0)
7941 fuzz = 1;
7942 sap = (SeqAlignPtr)(sap_head->segs);
7943 if (sap->next == NULL)
7944 return;
7945 dsp = (DenseSegPtr)(sap->segs);
7946 sip_head = dsp->ids;
7947 numrows = AlnMgr2GetNumRows(sap);
7948 acp_head = NULL;
7949 strand = AlnMgr2GetNthStrand(sap, 1);
7950 numsaps = 0;
7951 while (sap != NULL)
7952 {
7953 if (AlnMgr2GetNumRows(sap) != numrows)
7954 {
7955 amconssetfree(acp_head);
7956 return;
7957 }
7958 numsaps++;
7959 acp = (AMConsSetPtr)MemNew(sizeof(AMConsSet));
7960 acp->starts = (Int4Ptr)MemNew(numrows*sizeof(Int4));
7961 acp->stops = (Int4Ptr)MemNew(numrows*sizeof(Int4));
7962 acp->strands = (Uint1Ptr)MemNew(numrows*sizeof(Uint1));
7963 acp->which = (Int4Ptr)MemNew(numrows*sizeof(Int4));
7964 acp->sap = sap;
7965 if (acp_head != NULL)
7966 {
7967 acp_prev->next = acp;
7968 acp_prev = acp;
7969 } else
7970 acp_head = acp_prev = acp;
7971 sip = sip_head;
7972 row = AlnMgr2GetFirstNForSip(sap, sip);
7973 if (row <= 0)
7974 {
7975 amconssetfree(acp_head);
7976 return;
7977 }
7978 if (acp->strands[row] != strand)
7979 {
7980 sapnext = acp->sap->next;
7981 acp->sap->next = NULL;
7982 score = ((SAIndex2Ptr)(acp->sap->saip))->score;
7983 SeqAlignListReverseStrand(acp->sap);
7984 AMAlignIndexFreeEitherIndex(acp->sap);
7985 AlnMgr2IndexSingleChildSeqAlign(acp->sap);
7986 saip = (SAIndex2Ptr)(acp->sap->saip);
7987 saip->score = score;
7988 acp->strands[row] = strand;
7989 acp->sap->next = sapnext;
7990 }
7991 for (i=0; i<numrows; i++)
7992 {
7993 acp->which[i] = row;
7994 AlnMgr2GetNthSeqRangeInSA(sap, i+1, &acp->starts[i], &acp->stops[i]);
7995 acp->strands[i] = AlnMgr2GetNthStrand(sap, i+1);
7996 }
7997 sap = sap->next;
7998 }
7999 acparray = (AMConsSetPtr PNTR)MemNew(numsaps*sizeof(AMConsSetPtr));
8000 acp = acp_head;
8001 i = 0;
8002 while (acp != NULL)
8003 {
8004 acparray[i] = acp;
8005 acp = acp->next;
8006 i++;
8007 }
8008 HeapSort(acparray, numsaps, sizeof(AMConsSetPtr), CKA_SortForConsistent);
8009 /* orientation -1 means that ith is before jth in ALL rows, 1 means ith is after jth in ALL rows */
8010 for (i=0; i<numsaps; i++)
8011 {
8012 if (acparray[i]->used != -1)
8013 {
8014 for (j=i+1; j<numsaps; j++)
8015 {
8016 orientation = 0;
8017 for (k=0; acparray[j]->used != -1 && k<numrows; k++)
8018 {
8019 if (acparray[i]->starts[k] - fuzz < acparray[j]->starts[k])
8020 {
8021 if (acparray[i]->stops[k] - fuzz < acparray[j]->starts[k])
8022 {
8023 if (orientation == 0)
8024 {
8025 if (acparray[i]->strands[k] == Seq_strand_minus)
8026 orientation = 1;
8027 else
8028 orientation = -1;
8029 }
8030 } else
8031 {
8032 if (lfuzz >= 0) /* just mark it for deletion */
8033 acparray[j]->used = -1;
8034 else /* truncate it */
8035 {
8036 if (acparray[j]->stops[k] >
8037 acparray[i]->stops[k] + CKA_blast_wordsize)
8038 {
8039 newsap = AlnMgr2GetSubAlign(acparray[j]->sap, acparray[i]->stops[k]+1,
8040 acparray[j]->stops[k], k+1, TRUE);
8041 AlnMgr2IndexSingleChildSeqAlign(newsap);
8042 SeqAlignFree(acparray[j]->sap);
8043 acparray[j]->sap = newsap;
8044 acparray[j]->starts[k] = acparray[i]->stops[k]+1;
8045 } else
8046 acparray[j]->used = -1;
8047 }
8048 }
8049 } else if (acparray[i]->starts[k] - fuzz > acparray[j]->starts[k])
8050 {
8051 if (acparray[i]->starts[k] + fuzz > acparray[j]->stops[k])
8052 {
8053 if (orientation == 0)
8054 {
8055 if (acparray[i]->strands[k] == Seq_strand_minus)
8056 orientation = -1;
8057 else
8058 orientation = 1;
8059 }
8060 } else
8061 {
8062 if (lfuzz >= 0) /* mark for deletion */
8063 acparray[j]->used = -1;
8064 else /* truncate */
8065 {
8066 if (acparray[j]->starts[k] <
8067 acparray[i]->starts[k] - CKA_blast_wordsize)
8068 {
8069 newsap = AlnMgr2GetSubAlign(acparray[j]->sap, acparray[j]->starts[k], acparray[i]->starts[k]-1, k+1, TRUE);
8070 AlnMgr2IndexSingleChildSeqAlign(newsap);
8071 SeqAlignFree(acparray[j]->sap);
8072 acparray[j]->sap = newsap;
8073 acparray[j]->stops[k] = acparray[i]->starts[k]-1;
8074 } else
8075 acparray[j]->used = -1;
8076 }
8077 }
8078 } else
8079 acparray[j]->used = -1;
8080 }
8081 }
8082 }
8083 }
8084 /* now free all the unused ones, stick the rest back together, reindex, and return */
8085 salp_head = salp_prev = NULL;
8086 for (i=0; i<numsaps; i++)
8087 {
8088 if (acparray[i]->used == -1)
8089 {
8090 SeqAlignFree(acparray[i]->sap);
8091 acparray[i]->sap = NULL;
8092 } else
8093 {
8094 if (salp_head != NULL)
8095 {
8096 salp_prev->next = acparray[i]->sap;
8097 salp_prev = acparray[i]->sap;
8098 salp_prev->next = NULL;
8099 } else
8100 {
8101 salp_head = salp_prev = acparray[i]->sap;
8102 salp_prev->next = NULL;
8103 }
8104 }
8105 }
8106 amconssetfree(acp_head);
8107 MemFree(acparray);
8108 sap_head->segs = (Pointer)(salp_head);
8109 AMAlignIndex2Free2(sap_head->saip);
8110 AlnMgr2IndexLite(sap_head);
8111 }
8112
8113
8114 static BioseqPtr ReadFromTraceDb (CharPtr number)
8115
8116 {
8117 BioseqPtr bsp = NULL;
8118 CONN conn;
8119 time_t currtime, starttime;
8120 FILE *fp;
8121 time_t max = 0;
8122 size_t n_written;
8123 Char path [PATH_MAX];
8124 Char query [64];
8125 SeqEntryPtr sep = NULL;
8126 EIO_Status status;
8127 STimeout timeout;
8128 long int val;
8129
8130 if (StringHasNoText (number)) return NULL;
8131 if (sscanf (number, "%ld", &val) != 1) return NULL;
8132 sprintf (query, "cmd=raw&query=retrieve+fasta+%ld", (long) val);
8133 conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/Traces/trace.cgi",
8134 query, "Sequin", 30, eMIME_T_NcbiData,
8135 eMIME_Fasta, eENCOD_None, 0);
8136 if (conn == NULL) return NULL;
8137 status = CONN_Write (conn, (const void *) query, StringLen (query),
8138 &n_written, eIO_WritePersist);
8139 if (status != eIO_Success) return NULL;
8140 QUERY_SendQuery (conn);
8141
8142 #ifdef OS_MAC
8143 timeout.sec = 0;
8144 timeout.usec = 0;
8145 #else
8146 timeout.sec = 100;
8147 timeout.usec = 0;
8148 #endif
8149
8150 starttime = GetSecs ();
8151 while ((status = CONN_Wait (conn, eIO_Read, &timeout)) != eIO_Success && max < 300) {
8152 currtime = GetSecs ();
8153 max = currtime - starttime;
8154 }
8155
8156 if (status == eIO_Success) {
8157 TmpNam (path);
8158 fp = FileOpen (path, "w");
8159 QUERY_CopyResultsToFile (conn, fp);
8160 FileClose (fp);
8161 /*
8162 LaunchGeneralTextViewer (path, "QueueFastaQueryToURL results");
8163 */
8164 fp = FileOpen (path, "r");
8165 sep = FastaToSeqEntry (fp, TRUE);
8166 FileClose (fp);
8167 FileRemove (path);
8168 if (sep != NULL) {
8169 bsp = FindNucBioseq (sep);
8170 }
8171 }
8172 CONN_Close (conn);
8173
8174 return bsp;
8175 }
8176
8177 static SeqAlignPtr GetNewBlastTPAHistAlignPiece (BioseqPtr bsp1, BioseqPtr bsp2)
8178 {
8179 BLAST_SummaryOptions *options = NULL;
8180 SeqAlignPtr salp = NULL;
8181
8182 BLAST_SummaryOptionsInit(&options);
8183 options->program = eBlastn;
8184 options->use_megablast = TRUE;
8185 options->word_size = CKA_blast_wordsize;
8186 options->cutoff_evalue = CKA_blast_expect_value;
8187 options->hint = eNone;
8188 options->gap_x_dropoff = 30;
8189 options->gap_open = -1;
8190 options->gap_extend = -1;
8191 options->filter_string = StringSave ("F");
8192
8193 BLAST_TwoSequencesSearch(options, bsp1, bsp2, &salp);
8194 BLAST_SummaryOptionsFree(options);
8195
8196 return salp;
8197 }
8198
8199
8200 static SeqAlignPtr GetOldBlastTPAHistAlignPiece (BioseqPtr bsp1, BioseqPtr bsp2)
8201 {
8202 BLAST_OptionsBlkPtr options;
8203 SeqAlignPtr salp;
8204
8205 options = BLASTOptionNew("blastn", TRUE);
8206 options->is_megablast_search = TRUE;
8207 options->gap_open = options->gap_extend = 0;
8208 options->wordsize = CKA_blast_wordsize;
8209 options->expect_value = CKA_blast_expect_value;
8210
8211 salp = BlastTwoSequences(bsp1, bsp2, "blastn", options);
8212 BLASTOptionDelete(options);
8213
8214 return salp;
8215 }
8216
8217
8218 static Boolean IsHUPIDAccession (BioseqPtr bsp)
8219 {
8220 Int4 j, num;
8221 ObjMgrDataPtr omdp;
8222 OMUserDataPtr omudp;
8223 ObjMgrProcPtr ompp = NULL;
8224 ObjMgrPtr omp;
8225 ObjMgrDataPtr PNTR omdpp;
8226 Boolean rval = FALSE;
8227
8228 ompp = NULL;
8229 omp = ObjMgrReadLock();
8230
8231 omdpp = omp->datalist;
8232 if (omdpp != NULL) {
8233 num = omp->currobj;
8234 for (j = 0; j < num && ompp == NULL; j++) {
8235 if (omdpp[j] != NULL && omdpp[j]->datatype == OBJ_BIOSEQ
8236 && omdpp[j]->dataptr == bsp) {
8237
8238 omdp = ObjMgrFindTop (omp, omdpp[j]);
8239 if (omdp != NULL) {
8240 for (omudp = omdp->userdata; omudp != NULL && ompp == NULL; omudp = omudp->next)
8241 {
8242 if (omudp->proctype == OMPROC_FETCH) /* caching function */
8243 {
8244 ompp = ObjMgrProcFind(omp, omudp->procid, NULL, 0);
8245 }
8246 }
8247 }
8248 }
8249 }
8250 }
8251
8252 if (ompp != NULL && StringCmp (ompp->procname, "HUPBioseqFetch") == 0)
8253 {
8254 rval = TRUE;
8255 }
8256
8257 ObjMgrUnlock();
8258 return rval;
8259 }
8260
8261
8262 static SeqAlignPtr CKA_MakeAlign(BioseqPtr bsp, CKA_AccPtr acc_head, LogInfoPtr lip)
8263 {
8264 CKA_AccPtr acc;
8265 CKA_AccPtr acc_new;
8266 CKA_AccPtr acc_new_head_head;
8267 CKA_AccPtr acc_new_head;
8268 CKA_AccPtr acc_new_prev;
8269 SeqAlignPtr allsap;
8270 SeqAlignPtr allsap_prev;
8271 AMAlignIndex2Ptr amaip;
8272 BioseqPtr bsp_tmp = NULL;
8273 Int4 i;
8274 BLAST_SummaryOptions *options = NULL;
8275 SBlastSeqalignArray * seqalign_arr=NULL;
8276 SeqAlignPtr sap_new;
8277 SeqAlignPtr sap_tmp;
8278 SeqAlignPtr sap_tmp_next;
8279 SeqIdPtr sip;
8280 Uint1 strand;
8281 Boolean need_to_unlock = FALSE;
8282
8283 if (bsp == NULL || acc_head == NULL)
8284 return NULL;
8285 acc = acc_head;
8286 allsap = NULL;
8287 allsap_prev = NULL;
8288 acc_new_head_head = acc_new_prev = NULL;
8289 BLAST_SummaryOptionsInit(&options);
8290 options->program = eBlastn;
8291 options->use_megablast = TRUE;
8292 options->word_size = CKA_blast_wordsize;
8293 options->cutoff_evalue = CKA_blast_expect_value;
8294 options->hint = eNone;
8295 options->gap_open = -1;
8296 options->gap_extend = -1;
8297 options->filter_string = StringSave ("F");
8298 while (acc != NULL)
8299 {
8300
8301 if (need_to_unlock)
8302 {
8303 BioseqUnlock (bsp_tmp);
8304 need_to_unlock = FALSE;
8305 }
8306
8307 bsp_tmp = NULL;
8308 if (StringNICmp (acc->accession, "ti", 2) == 0) {
8309 bsp_tmp = ReadFromTraceDb (acc->accession + 2);
8310 } else {
8311 sip = SeqIdFromAccessionDotVersion(acc->accession);
8312 bsp_tmp = BioseqLockById(sip);
8313 if (bsp_tmp != NULL) {
8314 need_to_unlock = TRUE;
8315 if (lip != NULL && lip->fp != NULL && IsHUPIDAccession (bsp_tmp)) {
8316 fprintf (lip->fp, "%s is unreleased accession in TPA Seq-Hist.\n", acc->accession);
8317 lip->data_in_log = TRUE;
8318 }
8319 }
8320 }
8321 if (bsp_tmp == NULL) {
8322 fprintf (lip->fp, "Unable to load %s", acc->accession);
8323 lip->data_in_log = TRUE;
8324 break;
8325 }
8326 if (bsp_tmp->id->next) {
8327 /* find the best accession */
8328 SeqIdPtr sip = SeqIdDup(SqnSeqIdFindBestAccession(bsp_tmp->id));
8329 bsp_tmp->id = SeqIdSetFree(bsp_tmp->id);
8330 bsp_tmp->id = sip;
8331 }
8332 if (!ISA_na(bsp_tmp->mol))
8333 {
8334 if (need_to_unlock)
8335 {
8336 BioseqUnlock(bsp_tmp);
8337 need_to_unlock = FALSE;
8338 }
8339 Message(MSG_ERROR, "%s is not a nucleotide bioseq.", acc->accession);
8340 break;
8341 }
8342 WatchCursor();
8343 if (acc->start_acc >=0 && acc->stop_acc >=0 &&
8344 acc->start_acc < bsp_tmp->length &&
8345 acc->start_acc < bsp_tmp->length) {
8346 SeqLocPtr slp1, slp2;
8347 if (acc->start_acc <= acc->stop_acc) {
8348 slp1 = SeqLocIntNew
8349 (acc->start_acc, acc->stop_acc, Seq_strand_plus, bsp_tmp->id);
8350 } else {
8351 slp1 = SeqLocIntNew
8352 (acc->stop_acc, acc->start_acc, Seq_strand_minus, bsp_tmp->id);
8353 }
8354 slp2 = SeqLocIntNew(0, bsp->length-1, Seq_strand_plus, bsp->id);
8355 acc->sap = NULL;
8356 seqalign_arr = NULL;
8357 BLAST_TwoSeqLocSets (options, slp1, slp2, NULL, &seqalign_arr, NULL, NULL, NULL);
8358 if (seqalign_arr != NULL)
8359 {
8360 acc->sap = seqalign_arr->array[0];
8361 seqalign_arr->array[0] = NULL;
8362 seqalign_arr = SBlastSeqalignArrayFree(seqalign_arr);
8363 }
8364 SeqLocFree(slp1);
8365 SeqLocFree(slp2);
8366 } else {
8367 acc->sap = NULL;
8368 BLAST_TwoSequencesSearch(options, bsp_tmp, bsp, &(acc->sap));
8369 }
8370 ArrowCursor();
8371 acc->start_acc = acc->stop_acc = 0; /* reset, for later usage */
8372 if (acc->sap != NULL)
8373 SPI_flip_sa_list(acc->sap);
8374 acc_new_head = NULL;
8375 if (acc->sap != NULL && acc->sap->next != NULL)
8376 {
8377 if (!CKA_blast_allow_repeats) {
8378 SelectBestRepeatsFromList (&(acc->sap));
8379 }
8380 AlnMgr2IndexLite(acc->sap);
8381 if (!CKA_blast_allow_repeats) {
8382 CKA_RemoveInconsistentAlnsFromSet(acc->sap, -1);
8383 }
8384 sap_tmp = acc->sap;
8385 acc->sap = (SeqAlignPtr)(acc->sap->segs);
8386 sap_tmp->segs = NULL;
8387 SeqAlignFree(sap_tmp);
8388 sap_tmp = acc->sap->next;
8389 acc->sap->next = NULL;
8390 while (sap_tmp != NULL)
8391 {
8392 AlnMgr2IndexSingleChildSeqAlign(sap_tmp);
8393 sap_tmp_next = sap_tmp->next;
8394 sap_tmp->next = NULL;
8395 acc_new = (CKA_AccPtr)MemNew(sizeof(CKA_Acc));
8396 acc_new->accession = StringSave(acc->accession);
8397 acc_new->sip_whole = SeqIdDup(acc->sip_whole);
8398 acc_new->sap = sap_tmp;
8399 sap_tmp = sap_tmp_next;
8400 if (!acc_new_head) {
8401 acc_new_head = acc_new;
8402 }
8403 if (acc_new_prev) {
8404 acc_new_prev->next = acc_new;
8405 }
8406 acc_new_prev = acc_new;
8407 }
8408 } else if (acc->sap != NULL)
8409 AlnMgr2IndexSingleChildSeqAlign(acc->sap);
8410 if (acc->sap != NULL)
8411 {
8412 strand = AlnMgr2GetNthStrand(acc->sap, 1);
8413 if (strand == Seq_strand_minus)
8414 {
8415 SeqAlignListReverseStrand(acc->sap);
8416 SAIndex2Free2(acc->sap->saip);
8417 acc->sap->saip = NULL;
8418 }
8419 }
8420 if (allsap != NULL && acc->sap != NULL)
8421 {
8422 allsap_prev->next = acc->sap;
8423 allsap_prev = allsap_prev->next;;
8424 } else if (acc->sap != NULL)
8425 allsap_prev = allsap = (acc->sap);
8426 acc_new = acc_new_head;
8427 while (acc_new != NULL)
8428 {
8429 strand = AlnMgr2GetNthStrand(acc_new->sap, 1);
8430 if (strand == Seq_strand_minus)
8431 {
8432 SeqAlignListReverseStrand(acc_new->sap);
8433 SAIndex2Free2(acc_new->sap->saip);
8434 acc_new->sap->saip = NULL;
8435 }
8436 if (allsap != NULL)
8437 {
8438 allsap_prev->next = acc_new->sap;
8439 allsap_prev = allsap_prev->next;;
8440 } else
8441 allsap_prev = allsap = acc_new->sap;
8442 acc_new = acc_new->next;
8443 }
8444 if (allsap_prev != NULL)
8445 {
8446 while (allsap_prev->next != NULL)
8447 {
8448 allsap_prev = allsap_prev->next;
8449 }
8450 }
8451 if (need_to_unlock)
8452 {
8453 BioseqUnlock(bsp_tmp);
8454 need_to_unlock = FALSE;
8455 }
8456 acc = acc->next;
8457 if (!acc_new_head_head) {
8458 acc_new_head_head = acc_new_head;
8459 }
8460 }
8461
8462 BLAST_SummaryOptionsFree(options);
8463 if (need_to_unlock)
8464 {
8465 BioseqUnlock (bsp_tmp);
8466 need_to_unlock = FALSE;
8467 }
8468
8469 acc = acc_head;
8470 while (acc->next != NULL)
8471 {
8472 acc = acc->next;
8473 }
8474 acc->next = acc_new_head_head;
8475 if (allsap == NULL)
8476 return NULL;
8477 sap_new = SeqAlignNew();
8478 sap_new->segtype = SAS_DISC;
8479 sap_new->segs = (Pointer)(allsap);
8480 allsap = sap_new;
8481 AlnMgr2IndexLite(allsap);
8482 AlnMgr2SortAlnSetByNthRowPos(allsap, 1);
8483 amaip = (AMAlignIndex2Ptr)(allsap->saip);
8484 for (i=0; i<amaip->numsaps-1; i++)
8485 {
8486 amaip->saps[i]->next = amaip->saps[i+1];
8487 }
8488 amaip->saps[amaip->numsaps-1]->next = NULL;
8489 allsap->segs = (Pointer)(amaip->saps[0]);
8490 return allsap;
8491 }
8492
8493 static void DoCreateSeqHistTPA (IteM i)
8494 {
8495 BaseFormPtr bfp;
8496 SeqEntryPtr sep;
8497
8498 #ifdef WIN_MAC
8499 bfp = currentFormDataPtr;
8500 #else
8501 bfp = GetObjectExtra (i);
8502 #endif
8503 if (bfp == NULL) return;
8504 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8505 if (sep == NULL) return;
8506
8507 CKA_RunChecker(sep);
8508
8509 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8510 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8511 }
8512
8513 extern void CreateSeqHistTPA (IteM i);
8514 extern void CreateSeqHistTPA (IteM i)
8515 {
8516 CKA_blast_wordsize = 28;
8517 CKA_blast_expect_value = 0.000001;
8518 CKA_blast_allow_repeats = FALSE;
8519 DoCreateSeqHistTPA(i);
8520 }
8521
8522 static SeqAlignPtr DeltaSeq2SeqAlign(BioseqPtr bsp)
8523 {
8524 DeltaSeqPtr deltasp;
8525 SeqLocPtr slp;
8526 SeqAlignPtr sap, sap_head = NULL;
8527 DenseSegPtr dsp;
8528 SeqIntPtr intp;
8529 SeqLitPtr litp;
8530 int curr_start = 0;
8531
8532 if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4) {
8533 return NULL;
8534 }
8535 if (!(deltasp = (DeltaSeqPtr) bsp->seq_ext)) {
8536 return NULL;
8537 }
8538
8539 while (deltasp) {
8540 if (deltasp->choice == 1) {
8541 slp = (SeqLocPtr) deltasp->data.ptrvalue;
8542 if (sap_head) {
8543 sap = sap->next = SeqAlignNew();
8544 } else {
8545 sap_head = sap = SeqAlignNew();
8546 }
8547 dsp = DenseSegNew();
8548
8549 sap->type = SAT_PARTIAL;
8550 sap->segtype = SAS_DENSEG;
8551 sap->dim = 2;
8552 sap->segs = (Pointer)(dsp);
8553 dsp->dim = 2;
8554 dsp->numseg = 1;
8555 dsp->lens = (Int4Ptr)MemNew((dsp->numseg)*sizeof(Int4));
8556 dsp->starts = (Int4Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
8557 dsp->strands = (Uint1Ptr)MemNew((dsp->numseg)*(dsp->dim)*sizeof(Int4));
8558
8559 dsp->ids = SeqIdDup(bsp->id);
8560 if (dsp->ids->next) {
8561 /* Dense-seg ids do not support lists, only 1 id per sequence */
8562 SeqIdFree(dsp->ids->next);
8563 dsp->ids->next = NULL;
8564 }
8565 switch (slp->choice) {
8566 case SEQLOC_INT:
8567 intp = (SeqIntPtr) slp->data.ptrvalue;
8568 dsp->starts[0] = curr_start;
8569 dsp->starts[1] = intp->from;
8570 curr_start += dsp->lens[0] = intp->to - intp->from + 1;
8571 dsp->strands[0] = Seq_strand_plus;
8572 dsp->strands[1] = intp->strand;
8573 dsp->ids->next = SeqIdDup(intp->id);
8574 break;
8575 default:
8576 /* exception */
8577 break;
8578 }
8579 } else if (deltasp->choice == 2) {
8580 litp = (SeqLitPtr) deltasp->data.ptrvalue;
8581 if (litp != NULL) {
8582 curr_start += litp->length;
8583 }
8584 }
8585 deltasp = deltasp->next;
8586 }
8587 return sap_head;
8588 }
8589
8590 static void DoDeltaHist (BioseqPtr bsp, Pointer userdata)
8591
8592 {
8593 SeqAlignPtr salp;
8594 SeqHistPtr shp;
8595
8596 if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4) return;
8597 shp = bsp->hist;
8598 if (shp != NULL && shp->assembly != NULL) return;
8599 salp = DeltaSeq2SeqAlign (bsp);
8600 if (salp == NULL) return;
8601 if (shp == NULL) {
8602 shp = SeqHistNew ();
8603 bsp->hist = shp;
8604 }
8605 if (shp == NULL) return;
8606 shp->assembly = salp;
8607 }
8608
8609 extern void CreateSeqHistDelta (IteM i);
8610 extern void CreateSeqHistDelta (IteM i)
8611 {
8612 BaseFormPtr bfp;
8613 SeqEntryPtr sep;
8614
8615 #ifdef WIN_MAC
8616 bfp = currentFormDataPtr;
8617 #else
8618 bfp = GetObjectExtra (i);
8619 #endif
8620 if (bfp == NULL) return;
8621 sep = GetTopSeqEntryForEntityID (bfp->input_entityID);
8622 if (sep == NULL) return;
8623
8624 VisitBioseqsInSep (sep, NULL, DoDeltaHist);
8625
8626 ObjMgrSetDirtyFlag (bfp->input_entityID, TRUE);
8627 ObjMgrSendMsg (OM_MSG_UPDATE, bfp->input_entityID, 0, 0);
8628 }
8629
8630 static TexT blast_wordsize_text = NULL;
8631 static TexT blast_expect_value_text = NULL;
8632 static ButtoN blast_allow_repeats_button = NULL;
8633 static IteM blast_i;
8634
8635 static void DoAcceptBlastOptions (ButtoN b)
8636
8637 {
8638 Char buf [64];
8639 long val1;
8640 FloatHi val2;
8641
8642 GetTitle (blast_wordsize_text, buf, sizeof (buf));
8643 if (sscanf (buf, "%ld", &val1) == 1) {
8644 CKA_blast_wordsize = CKA_blast_detailed_wordsize = (Int4) val1;
8645 }
8646 GetTitle (blast_expect_value_text, buf, sizeof (buf));
8647 if (sscanf (buf, "%lf", &val2) == 1) {
8648 CKA_blast_expect_value = CKA_blast_detailed_expect_value = (FloatHi) val2;
8649 }
8650 CKA_blast_allow_repeats = CKA_blast_detailed_allow_repeats =
8651 (Boolean) GetStatus (blast_allow_repeats_button);
8652 Remove (ParentWindow (b));
8653 DoCreateSeqHistTPA(blast_i);
8654 }
8655
8656 extern void CreateSeqHistTPADetailed (IteM i);
8657 extern void CreateSeqHistTPADetailed (IteM i)
8658 {
8659 GrouP c;
8660 GrouP g;
8661 GrouP h;
8662 WindoW w;
8663 Char buf[64];
8664
8665 blast_i = i;
8666
8667 w = FixedWindow (-50, -33, -10, -10, "Blast Options", NULL);
8668 h = HiddenGroup (w, -1, 0, NULL);
8669 SetGroupSpacing (h, 3, 2);
8670 g = HiddenGroup (h, 2, 0, NULL);
8671
8672 StaticPrompt (g, "Word Size", 0, dialogTextHeight, programFont, 'l');
8673 if (CKA_blast_detailed_wordsize <= 0) {
8674 CKA_blast_detailed_wordsize = 14;
8675 }
8676 CKA_blast_wordsize = CKA_blast_detailed_wordsize;
8677 sprintf(buf, "%d", CKA_blast_wordsize);
8678 blast_wordsize_text = DialogText (g, buf, 10, NULL);
8679
8680 StaticPrompt (g, "Expect Value", 0, dialogTextHeight, programFont, 'l');
8681 if (CKA_blast_detailed_expect_value <= 0.0) {
8682 CKA_blast_detailed_expect_value = 0.001;
8683 }
8684 CKA_blast_expect_value = CKA_blast_detailed_expect_value;
8685 sprintf(buf, "%f", CKA_blast_expect_value);
8686 blast_expect_value_text = DialogText (g, buf, 10, NULL);
8687
8688 blast_allow_repeats_button = CheckBox (g, "Allow Repeats", NULL);
8689 if (CKA_blast_detailed_allow_repeats) {
8690 SetStatus(blast_allow_repeats_button, TRUE);
8691 }
8692
8693 c = HiddenGroup (w, 2, 0, NULL);
8694 SetGroupSpacing (c, 5, 5);
8695 DefaultButton (c, "Accept", DoAcceptBlastOptions);
8696 PushButton (c, "Cancel", StdCancelButtonProc);