2
* ===========================================================================
5
* National Center for Biotechnology Information (NCBI)
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
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
24
* ===========================================================================
28
* Author: Jim Ostell, Jinghui Zhang, Jonathan Kans
30
* Version Creation Date: 10/7/94
37
* --------------------------------------------------------------------------
38
* Date Name Description of modification
39
* ------- ---------- -----------------------------------------------------
42
* Revision 6.36 2001/11/15 18:47:13 kans
43
* fix to unindexed get next descriptor
45
* Revision 6.35 2001/11/15 18:34:52 kans
46
* added GetNextDescriptorUnindexed, requires AssignIDsInEntity be called first
48
* Revision 6.34 2001/07/06 17:27:38 kans
49
* AssignIDs does not clear deleteme flag
51
* Revision 6.33 2000/12/18 14:48:07 tatiana
54
* Revision 6.32 2000/02/07 16:48:34 kans
55
* fixed setting of context->index in SeqMgrGetNextFeatureByID
57
* Revision 6.31 2000/02/01 22:25:44 kans
58
* indexed speedup now returns features in itemID order, not position order, to allow simple diff of e2index
60
* Revision 6.30 2000/01/07 03:01:42 kans
61
* indexed speedup only if raw bioseq not part of segmented bioseq
63
* Revision 6.29 2000/01/07 02:48:13 kans
64
* useSeqMgrIndexes now works with get_feats_location and get_feats_product, should be suitable for e2index speedup
66
* Revision 6.28 2000/01/07 00:56:02 kans
67
* targeted bioseq presents features right after bioseq is visited
69
* Revision 6.27 2000/01/07 00:18:25 kans
70
* targeted bioseq gather visits each seqannot, presents features in seqannot index
72
* Revision 6.26 2000/01/06 23:32:13 kans
73
* targeted bioseq gather visits each seqfeat, checks against feature/bioseq index
75
* Revision 6.25 1999/11/30 17:07:51 egorov
76
* Protect against dividing by zero.
78
* Revision 6.24 1999/10/29 18:06:26 kans
79
* added GetPointerForIDs (with SW)
81
* Revision 6.23 1999/09/30 18:33:09 kans
82
* delete marked objects corrects gatherindex.prevlink on remaining objects
84
* Revision 6.22 1999/09/29 21:10:53 kans
85
* delete marked seqannot also frees seqannot if it has no remaining sap->data components
87
* Revision 6.21 1999/09/29 18:24:53 kans
88
* added DeleteMarkedObjects
90
* Revision 6.20 1999/09/28 18:10:15 kans
91
* added DeleteMarkedObjectsProc callback - not yet tested
93
* Revision 6.19 1999/09/28 12:10:24 kans
94
* finished implementing lightweight GatherObjectsInEntity
96
* Revision 6.18 1999/09/27 22:02:45 kans
97
* further implementation of lightweight gather replacement
99
* Revision 6.17 1999/09/27 17:46:59 kans
100
* uses GatherIndex structure
102
* Revision 6.16 1999/09/26 20:44:25 kans
103
* implemented most of VisitProc callbacks
105
* Revision 6.15 1999/09/26 00:17:14 kans
106
* VisitObjectsInEntity prototype added
108
* Revision 6.14 1999/09/25 01:46:08 kans
109
* AssignIDsInEntity split into internal function that can also call callback, EXTRA_OBJMGR_FIELDS values assigned to some objects
111
* Revision 6.13 1999/09/07 17:59:52 kans
112
* AssignIDsInEntity takes datatype and dataptr for when entityID is 0, allowing unlinked components to be updated
114
* Revision 6.12 1999/09/07 17:13:09 kans
115
* added AssignIDsInEntity
117
* Revision 6.11 1999/09/01 14:41:26 shavirin
118
* Adjusted functions gather_align_data() and get_align_ends() to accept
119
* discontinuous alignment type.
121
* Revision 6.10 1999/07/26 20:55:52 ostell
122
* added recursive support for SAS_DISC SeqAlign
124
* Revision 6.9 1999/03/16 13:17:28 ostell
125
* changes in SeqLocOffset() to deal with multi-interval seqloc which is
126
* a subset of a feature.
128
* Revision 6.8 1999/01/13 23:34:19 kans
129
* added GatherSpecificProcLaunch
131
* Revision 6.7 1998/08/24 18:27:07 kans
132
* removed solaris -v -fd warnings
134
* Revision 6.6 1998/06/23 16:53:37 zjing
135
* modify function check_reverse_strand
137
* Revision 6.5 1998/03/10 20:43:28 kans
138
* IGCCBuild now handles delta seqs
140
* Revision 6.4 1998/03/02 22:15:35 zjing
141
* fix gap collection in the minus strand in function gather_align_data
143
* Revision 6.3 1997/11/19 22:14:48 ostell
144
* added support for multithreaded programs
146
* Revision 6.2 1997/10/10 17:01:37 kans
147
* support for individual elements of OBJ_BIOSEQ_DELTA
149
* Revision 6.1 1997/09/30 19:59:35 zjing
150
* bug fixes in gather_align_data
152
* Revision 6.0 1997/08/25 18:05:46 madden
153
* Revision changed to 6.0
155
* Revision 5.15 1997/08/13 18:43:46 zjing
156
* correct errors in gather_align_data for tblastn and tblastx
158
* Revision 5.14 1997/07/01 15:16:33 zjing
159
* fix the strand in gathering continous std-seg
161
* Revision 5.13 1997/06/19 18:37:47 vakatov
162
* [WIN32,MSVC++] Adopted for the "NCBIOBJ.LIB" DLL'ization
164
* Revision 5.12 1997/04/23 12:44:49 zjing
165
* correct a bug for tblastn display
167
* Revision 5.10 1997/03/17 21:22:00 kans
168
* detach bioseq/bioseq set didn't unlink gcp->sep->next
170
* Revision 5.9 1997/01/15 17:25:45 zjing
171
* a kludge fix for ck_extreme to display the features across zero properly
173
* Revision 5.8 1996/12/16 19:43:37 ostell
174
* added an attachment/replacement of a Seq-loc to a feature in AttachDataProc
176
* Revision 5.7 1996/11/05 18:00:03 zjing
177
* fix the problem of integer overflow for gather_align_data and speed up the process
179
* Revision 5.6 1996/08/29 01:18:34 ostell
180
* added GatherAddExtraLoc for codebreak and trna.atncodon mapping
182
* Revision 5.5 1996/08/09 20:28:55 epstein
183
* eliminate update_seq_loc()
185
* Revision 5.4 1996/08/06 19:56:03 kans
186
* for SEQLOC_WHOLE, must call SeqIdFindBest on bsp->id
188
* Revision 5.3 1996/06/17 21:49:42 zjing
189
* fix in gather_align_data for multiple alignments
191
* Revision 5.2 1996/06/10 18:35:36 zjing
192
* fix in get_end_diag_val
194
* Revision 5.1 1996/06/10 15:08:53 epstein
195
* replace make_seq_loc() with SeqLocIntNew() and make_pnt_loc with SeqLocPntNew()
197
* Revision 5.0 1996/05/28 13:23:23 ostell
198
* Set to revision 5.0
200
* Revision 4.30 1996/05/22 20:35:25 ostell
201
* changed GatherProcLaunch to cycle through proceedures in priority
202
* order looking for OM_MSG_RET_DONE return, instead of just launching
203
* the first one found.
205
* Revision 4.29 1996/05/06 14:49:12 zjing
206
* fix a strand in load_align_data
208
* Revision 4.28 1996/04/24 20:12:13 ostell
209
* removed an uncessary variable
211
* Revision 4.27 1996/04/08 15:44:02 kans
212
* IGCC build scopes on omdp->choice or scope->scope
214
* Revision 4.26 1996/03/08 18:12:38 zjing
215
* fix in check_reverse_strand for gather_align_data
217
* Revision 4.25 1996/02/28 04:53:06 ostell
218
* added ObjMgrHold suport
220
* Revision 4.23 1996/01/22 13:28:11 kans
221
* cast first parameter of MemSet to (Pointer) for SunOS compiler
223
* Revision 4.22 1996/01/03 23:01:04 ostell
224
* added GatherOverWrite() to support find/replace external to Gather
226
* Revision 4.21 1995/12/22 20:12:01 ostell
227
* added protection for NULL pointer on scope in IGCCBuild
229
* Revision 4.20 1995/12/22 14:42:30 ostell
230
* added do_not_reload_from_cache to GatherScope
231
* modified calls to support it
232
* changed default behavior of gather to load and reclock entities
234
* Revision 4.19 1995/12/20 22:55:36 kans
235
* bsp added to FocusSeqEntry, and MemSet (OBJ_MAX+1) bug fixed (JZ)
237
* Revision 4.18 1995/12/20 19:19:39 ostell
238
* added GatherContext.igccp field
239
* added FocusSeqEntry() function
241
* Revision 4.17 1995/12/20 15:05:15 zjing
242
* Fix gather_align_data to get the end gaps in master sequence
244
* Revision 4.16 1995/12/15 15:17:07 kans
245
* bsp is now initialized in IGCCBuild
247
* Revision 4.15 1995/12/15 02:47:01 ostell
248
* fix to scoping for multiple records with same SeqId
250
* Revision 4.14 1995/12/14 21:43:04 ostell
251
* added scope protection to IGCCBuild to protect against mulitple copies
253
* Revision 4.13 1995/12/13 19:28:13 ostell
254
* more support for OBJ_SEQHIST_ALIGN
256
* Revision 4.12 1995/12/13 18:50:42 ostell
257
* added support for OBJ_SEQHIST_ALIGN
259
* Revision 4.11 1995/11/21 23:08:38 ostell
260
* added support in GatherContext for gatherstack
262
* Revision 4.10 1995/11/06 21:29:03 ostell
263
* added newid and convert_loc to GatherScope, and new_loc to GatherContext
264
* added functions ReMapIntFuzz and SeqLocReMap to support them
265
* This allows SeqLocs on features to be copied into a remapped form by gather
267
* Revision 4.9 1995/10/06 19:25:24 ostell
268
* added fields "ignore_top" and "stop_on_annot" to GatherScope
269
* if "ignore_top" is TRUE, features on seglevel 0 are ignored
270
* if "stop_on_annot" is TRUE, segments are traversed to a maximum depth
271
* of gsp->seglevel, but traversing is stopped as soon as an annotation is
274
* Revision 4.8 1995/10/01 20:51:28 kans
275
* made GatherItemByDataProc static
277
* Revision 4.7 1995/09/30 03:38:31 ostell
278
* Changed ObjMgrMessage functions to pass a structure
279
* Added support for selecting regions
280
* Added ability to remove entity when no more views on it
282
* Revision 4.6 1995/09/27 19:50:09 zjing
285
* Revision 4.1 1995/08/16 17:48:34 kans
286
* add a chain parameter for gather Seq-align (jz)
288
* Revision 4.0 1995/07/26 13:49:01 ostell
289
* force revision to 4.0
291
* Revision 1.38 1995/07/10 15:51:59 kans
292
* changes in gather_align_data (zjing)
294
* Revision 1.37 1995/07/08 15:22:09 ostell
295
* Set ObjMgrDirtyFlag on Attach..,Detach..,ReplaceDataForProc
297
* Revision 1.36 1995/06/02 17:53:17 kans
298
* add gather range to gather bioseq
300
* Revision 1.35 1995/06/01 21:53:55 kans
301
* support for Seq-align (zjing)
303
* Revision 1.34 1995/05/19 15:49:37 kans
304
* fixed bug in mapping minus strand intervals
306
* Revision 1.33 1995/05/15 21:46:05 ostell
312
* ==========================================================================
321
static Boolean NEAR GatherSeqEntryFunc PROTO((SeqEntryPtr sep, InternalGCCPtr igccp, Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope, Pointer PNTR prevlink));
322
static Boolean NEAR GatherItemFunc PROTO((Uint2 entityID, Uint2 itemID, Uint2 itemtype,
323
Pointer userdata, GatherItemProc userfunc, Pointer dataptr,
324
Boolean do_not_reload_from_cache));
325
static Boolean NEAR GatherAddToStack PROTO((GatherContextPtr gcp));
326
static void NEAR GatherAddExtraLoc PROTO((GatherContextPtr gcp, SeqLocPtr slp));
328
static void NEAR GatherAddExtraLoc (GatherContextPtr gcp, SeqLocPtr slp)
332
gcp->extra_loc_cnt++;
333
if (gcp->extra_loc_cnt > gcp->extra_loc_total)
335
tmp = gcp->extra_loc;
336
gcp->extra_loc = MemNew((size_t)(sizeof(SeqLocPtr) *(gcp->extra_loc_total + 5)));
337
MemMove (gcp->extra_loc, tmp,(size_t)(sizeof(SeqLocPtr) *
338
(gcp->extra_loc_total)));
340
gcp->extra_loc_total += 5;
342
gcp->extra_loc[gcp->extra_loc_cnt - 1] = slp;
346
static Boolean NEAR GatherAddToStack (GatherContextPtr gcp)
348
GatherElementPtr tmp;
354
if (gcp->numstack <= gcp->indent) /* expand stack */
356
oldsize = gcp->numstack;
357
tmp = gcp->gatherstack;
358
gcp->numstack = oldsize + 20;
359
gcp->gatherstack = MemNew((size_t)(sizeof(GatherElement) * (gcp->numstack)));
362
MemCopy(gcp->gatherstack, tmp, (size_t)(sizeof(GatherElement) * (oldsize)));
367
tmp = gcp->gatherstack + gcp->indent;
368
tmp->itemID = gcp->itemID;
369
tmp->itemtype = gcp->thistype;
370
tmp->tempload = gcp->tempload;
371
tmp->thisitem = gcp->thisitem;
376
static Boolean ck_extreme(SeqLocPtr slp, BoolPtr across_zero)
382
*across_zero = FALSE;
386
case SEQLOC_PACKED_PNT:
387
case SEQLOC_PACKED_INT:
393
while((one_loc = SeqLocFindNext(slp, one_loc))!=NULL)
395
if(SeqLocStart(one_loc) == 0)
397
if(has_prev && SeqLocStrand(one_loc) != Seq_strand_minus)
399
else if(!has_prev && SeqLocStrand(one_loc) == Seq_strand_minus)
402
if(one_loc->choice == SEQLOC_NULL)
413
static Boolean ck_parts_overlap(SeqLocPtr slp, SeqLocPtr seq_loc)
418
while((one_loc = SeqLocFindNext(slp, one_loc))!=NULL)
420
if(one_loc->choice != SEQLOC_NULL)
422
if(SeqLocCompare(one_loc, seq_loc) != SLC_NO_MATCH)
431
/*****************************************************************************
433
* SeqLocOffset(seq_loc, sfp_loc, range, offset)
434
* returns FALSE if seq_loc does not overlap sfp_loc
435
* else fills in range structure mapping sfp_loc to seq_loc
436
* adds offset to final values
437
* if (ends) will assure that left is always <= right
439
*****************************************************************************/
440
NLM_EXTERN Boolean SeqLocOffset (SeqLocPtr seq_loc, SeqLocPtr sfp_loc, GatherRangePtr range, Int4 offset)
442
Uint1 strand_loc, strand_sfp;
447
Int4 toffset, l, r, t;
448
Boolean ltrunc, rtrunc;
451
if (seq_loc == NULL || sfp_loc == NULL || range == NULL) {
456
if(ck_extreme(sfp_loc, &across_zero))
460
si.from = SeqLocStart(sfp_loc);
461
si.to = SeqLocStop(sfp_loc);
462
si.strand = SeqLocStrand(sfp_loc);
463
si.id = SeqLocId(sfp_loc);
464
sl.choice = SEQLOC_INT;
465
sl.data.ptrvalue = &si;
468
else if(!ck_parts_overlap(sfp_loc, seq_loc))
473
strand_sfp = SeqLocStrand(sfp_loc);
480
while ((tslp = SeqLocFindNext(seq_loc, tslp)) != NULL)
482
if (SeqLocCompare(tslp, sfp_loc)) {
484
strand_loc = SeqLocStrand(tslp);
486
t = GetOffsetInLoc(sfp_loc, tslp, SEQLOC_LEFT_END);
487
if (t == -1) { /* truncated */
488
if (strand_loc == Seq_strand_minus)
489
t = toffset + SeqLocLen(tslp) - 1;
499
else if ((t + toffset) < l)
505
t = GetOffsetInLoc(sfp_loc, tslp, SEQLOC_RIGHT_END);
508
if (strand_loc == Seq_strand_minus)
511
t = toffset + SeqLocLen (tslp) - 1;
518
else if ((t + toffset) > r)
525
toffset += SeqLocLen(tslp);
528
if (r == -1) /* didn't find it */
531
range->l_trunc = ltrunc;
532
range->r_trunc = rtrunc;
533
range->left = l + offset;
534
range->right = r + offset;
536
strand_loc = SeqLocStrand(seq_loc);
538
if (strand_loc == Seq_strand_minus)
539
range->strand = StrandCmp(strand_sfp);
542
if(strand_sfp == Seq_strand_unknown)
543
strand_sfp = Seq_strand_plus;
544
range->strand = strand_sfp;
547
if(range->left > range->right)
550
range->left = range->right;
558
/*****************************************************************************
562
*****************************************************************************/
563
NLM_EXTERN IntFuzzPtr ReMapIntFuzz(IntFuzzPtr ifp, Boolean rev, SeqLocPtr seq_loc, SeqLocPtr sfp_loc, Int4 offset)
565
IntFuzzPtr newfuzz=NULL;
572
if (ifp == NULL) return newfuzz;
574
newfuzz = MemNew(sizeof(IntFuzz));
575
MemCopy(newfuzz, ifp, sizeof(IntFuzz));
579
case 1: /* plus/minus - no changes */
580
case 3: /* percent - no changes */
583
vn.choice = SEQLOC_INT;
585
vn.data.ptrvalue = &si;
586
MemSet((Pointer)(&si), 0, sizeof(SeqInt));
587
si.id = SeqLocId(sfp_loc);
590
newfuzz = MemFree(newfuzz);
593
si.strand = SeqLocStrand(sfp_loc);
594
if (! SeqLocOffset(seq_loc, &vn, &range, offset))
596
newfuzz = MemFree(newfuzz);
600
newfuzz->a = range.right; /* max */
601
newfuzz->b = range.left; /* min */
604
if (rev) /* reverse/complement */
608
case 1: /* greater than */
611
case 2: /* less than */
614
case 3: /* to right of residue */
617
case 4: /* to left of residue */
625
case 5: /* alternate positions */
626
vn.choice = SEQLOC_PNT;
628
vn.data.ptrvalue = &sp;
629
MemSet((Pointer)(&si), 0, sizeof(SeqPnt));
630
sp.id = SeqLocId(sfp_loc);
633
newfuzz = MemFree(newfuzz);
636
sp.strand = SeqLocStrand(sfp_loc);
638
newfuzz->alt = MemNew((size_t)(sizeof(Int4) * ifp->b));
641
for (i = 0; i < ifp->a; i++)
643
sp.point = ifp->alt[i];
645
if (SeqLocOffset(seq_loc, &vn, &range, offset))
647
newfuzz->alt[newfuzz->a] = range.left;
653
newfuzz = IntFuzzFree(newfuzz);
657
newfuzz = MemFree(newfuzz);
665
NLM_EXTERN SeqLocPtr SeqLocReMap (SeqIdPtr newid, SeqLocPtr seq_loc, SeqLocPtr head, Int4 offset, Boolean rev)
670
SeqLocPtr newhead = NULL, last=NULL, tmp, slp, prev, next, thead;
673
PackSeqPntPtr pspp, pspp2;
674
SeqBondPtr sbp, sbp2;
675
Int4 numpnt, i, tpos, intcnt, othercnt;
677
Boolean dropped_first, dropped_last, was_equiv = FALSE;
678
IntFuzzPtr ifp, ifp1, ifp2;
682
if ((head == NULL) || (seq_loc == NULL) || (newid == NULL)) return NULL;
684
if (! SeqLocOffset(seq_loc, head, &range, offset))
687
switch (head->choice)
689
case SEQLOC_PACKED_PNT:
690
pspp = (PackSeqPntPtr)(head->data.ptrvalue);
691
numpnt = PackSeqPntNum(pspp);
694
sp.strand = pspp->strand;
697
vn.choice = SEQLOC_PNT;
698
vn.data.ptrvalue = &sp;
700
pspp2 = PackSeqPntNew();
701
the_strand = range.strand;
702
intcnt = 0; /* use for included points */
703
othercnt = 0; /* use for exclued points */
704
for (i = 0; i < numpnt; i++)
706
sp.point = PackSeqPntGet(pspp, i);
708
if (SeqLocOffset(seq_loc, &vn, &range, offset))
711
PackSeqPntPut(pspp2, range.left);
716
if (! intcnt) /* no points in region */
718
PackSeqPntFree(pspp2);
722
if (rev) /* rev comp */
725
pspp2 = PackSeqPntNew();
726
numpnt = PackSeqPntNum(pspp);
728
for (i = numpnt; i >= 0; i--) /* reverse order */
730
tpos = PackSeqPntGet(pspp, i);
731
PackSeqPntPut(pspp2, tpos);
733
PackSeqPntFree(pspp);
735
pspp2->id = SeqIdDup(newid);
736
pspp2->strand = the_strand;
737
pspp2->fuzz = ReMapIntFuzz(pspp->fuzz, rev, seq_loc, head, offset);
739
newhead = ValNodeNew(NULL);
740
newhead->choice = SEQLOC_PACKED_PNT;
741
newhead->data.ptrvalue = (Pointer)pspp2;
743
case SEQLOC_WHOLE: /* whole */
744
newhead = ValNodeNew(NULL);
746
sip2->id = SeqIdDup(newid);
747
sip2->from = range.left;
748
sip2->to = range.right;
749
sip2->strand = range.strand;
753
ifp->choice = 4; /* lim */
754
ifp->a = 1; /* greater than */
761
ifp->choice = 4; /* lim */
762
ifp->a = 2; /* less than */
766
newhead->choice = SEQLOC_INT;
767
newhead->data.ptrvalue = (Pointer)sip2;
769
case SEQLOC_PNT: /* pnt */
770
spp = (SeqPntPtr)(head->data.ptrvalue);
773
spp2->id = SeqIdDup(newid);
774
spp2->point = range.left;
775
spp2->strand = range.strand;
776
spp2->fuzz = ReMapIntFuzz(spp->fuzz, rev, seq_loc, head, offset);
778
newhead = ValNodeNew(NULL);
779
newhead->choice = SEQLOC_PNT;
780
newhead->data.ptrvalue = (Pointer)spp2;
782
case SEQLOC_INT: /* int */
783
sip = (SeqIntPtr)(head->data.ptrvalue);
786
sip2->id = SeqIdDup(newid);
787
sip2->strand = range.strand;
788
sip2->from = range.left;
789
sip2->to = range.right;
791
if (rev) /* reverse ends if seq_loc on complement */
806
ifp->choice = 4; /* lim */
807
ifp->a = 1; /* greater than */
812
sip2->if_to = ReMapIntFuzz(ifp2, rev, seq_loc, head, offset);
818
ifp->choice = 4; /* lim */
819
ifp->a = 2; /* less than */
824
sip2->if_from = ReMapIntFuzz(ifp1, rev, seq_loc, head, offset);
827
newhead = ValNodeNew(NULL);
828
newhead->choice = SEQLOC_INT;
829
newhead->data.ptrvalue = (Pointer)sip2;
831
case SEQLOC_BOND: /* bond -- 2 seqs */
833
sbp = (SeqBondPtr)(head->data.ptrvalue);
834
vn.choice = SEQLOC_PNT;
835
vn.data.ptrvalue = sbp->a;
837
tmp = SeqLocReMap (newid, seq_loc, (SeqLocPtr)(&vn), offset, rev);
841
sbp2->a = (SeqPntPtr)(tmp->data.ptrvalue);
846
vn.data.ptrvalue = sbp->b;
847
tmp = SeqLocReMap (newid, seq_loc, (SeqLocPtr)(&vn), offset, rev);
853
sbp2->a = (SeqPntPtr)(tmp->data.ptrvalue);
856
sbp2->b = (SeqPntPtr)(tmp->data.ptrvalue);
862
newhead = ValNodeNew(NULL);
863
newhead->choice = SEQLOC_BOND;
864
newhead->data.ptrvalue = sbp2;
867
case SEQLOC_FEAT: /* feat -- can't track yet */
868
case SEQLOC_NULL: /* NULL */
869
case SEQLOC_EMPTY: /* empty */
871
case SEQLOC_EQUIV: /* does it stay equiv? */
873
case SEQLOC_MIX: /* mix -- more than one seq */
874
case SEQLOC_PACKED_INT: /* packed int */
877
dropped_first = FALSE;
878
dropped_last = FALSE;
879
for (slp = (SeqLocPtr)(head->data.ptrvalue); slp != NULL; slp = next)
882
if (slp->choice == SEQLOC_NULL) /* special case */
885
if ((prev != NULL) && (next != NULL))
887
if (prev->choice != SEQLOC_NULL)
889
tmp = ValNodeNew(NULL);
890
tmp->choice = SEQLOC_NULL;
895
tmp = SeqLocReMap (newid, seq_loc, slp, offset, rev);
898
dropped_last = FALSE;
901
if ((prev->choice == SEQLOC_INT) && (tmp->choice == SEQLOC_INT))
903
sip = (SeqIntPtr)(prev->data.ptrvalue);
904
sip2 = (SeqIntPtr)(tmp->data.ptrvalue);
906
if ((sip->strand == Seq_strand_minus) &&
907
(sip2->strand == Seq_strand_minus))
909
if (sip->from == (sip2->to + 1))
911
sip->from = sip2->from;
912
sip->if_from = sip2->if_from;
913
sip2->if_from = NULL;
914
tmp = SeqLocFree(tmp);
917
else if((sip->strand != Seq_strand_minus) &&
918
(sip2->strand != Seq_strand_minus))
920
if (sip->to == (sip2->from - 1))
923
sip->if_to = sip2->if_to;
925
tmp = SeqLocFree(tmp);
929
else if ((prev->choice == SEQLOC_NULL) && (tmp->choice == SEQLOC_NULL))
931
tmp = SeqLocFree(tmp);
934
else if (tmp->choice == SEQLOC_NULL)
936
tmp = SeqLocFree(tmp);
939
if (tmp != NULL) /* still have one? */
951
dropped_first = TRUE;
958
if (prev->choice == SEQLOC_NULL) /* ends with NULL */
961
for (slp = thead; slp->next != NULL; slp = slp->next)
970
thead = SeqLocFree(thead);
978
for (slp = thead; slp != NULL; slp = slp->next)
980
if (slp->choice == SEQLOC_INT)
985
if ((intcnt + othercnt) > 1)
987
newhead = ValNodeNew(NULL);
988
if (head->choice == SEQLOC_EQUIV)
989
newhead->choice = SEQLOC_EQUIV;
993
newhead->choice = SEQLOC_PACKED_INT;
995
newhead->choice = SEQLOC_MIX;
998
rev = FALSE; /* KLUDGE: turn off reordering */
1000
newhead->data.ptrvalue = (Pointer)thead;
1001
else /* reverse order */
1004
while (thead != NULL)
1007
for (slp = thead; slp->next != NULL; slp = slp->next)
1016
newhead->data.ptrvalue = (Pointer)slp;
1023
else /* only one SeqLoc left */
1026
if ((! was_equiv) && ((dropped_first) || (dropped_last)))
1027
{ /* add Int_fuzz when intervals are dropped */
1030
was_equiv = dropped_first;
1031
dropped_first = dropped_last;
1032
dropped_last = was_equiv;
1037
while ((slp = SeqLocFindNext(newhead, slp)) != NULL)
1039
if ((tmp == NULL) && (dropped_first)) /* first one */
1041
switch (slp->choice)
1045
ifp->choice = 4; /* lim */
1046
ifp->a = 2; /* assume lt */
1047
sip = (SeqIntPtr)(slp->data.ptrvalue);
1048
if (sip->strand != Seq_strand_minus)
1050
sip->if_from = IntFuzzFree(sip->if_from);
1055
sip->if_to = IntFuzzFree(sip->if_to);
1057
ifp->a = 1; /* gt */
1067
if ((tmp != NULL) && (dropped_last))
1069
switch (tmp->choice)
1073
ifp->choice = 4; /* lim */
1074
ifp->a = 1; /* assume gt */
1075
sip = (SeqIntPtr)(tmp->data.ptrvalue);
1076
if (sip->strand != Seq_strand_minus)
1078
sip->if_from = IntFuzzFree(sip->if_from);
1083
sip->if_to = IntFuzzFree(sip->if_to);
1085
ifp->a = 2; /* lt */
1103
/** citttype is currently 0, or 1=OBJ_SEQFEAT_CIT **/
1105
static Boolean NEAR GatherPub(InternalGCCPtr gccp, ValNodePtr vnp,
1106
Uint1 cittype, Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
1108
GatherContextPtr gcp;
1111
Int2 LocateItem = 0;
1112
Pointer LocateData = NULL;
1115
if (vnp == NULL) return TRUE;
1118
gsp = &(gccp->scope);
1121
thistype = OBJ_SEQFEAT_CIT;
1125
if (gsp->ignore[thistype])
1130
if (gccp->locatetype == thistype)
1132
LocateItem = gccp->locateID;
1133
LocateData = gccp->locatePtr;
1136
gcp->parentitem = tparent;
1137
gcp->parenttype = ttype;
1139
gccp->itemIDs[thistype]++;
1141
if (LocateItem == gccp->itemIDs[thistype])
1143
if (LocateData == (Pointer)vnp)
1147
gcp->itemID = gccp->itemIDs[thistype];
1148
gcp->thisitem = (Pointer)vnp;
1149
gcp->thistype = thistype;
1150
gcp->prevlink = prevlink;
1151
GatherAddToStack(gcp);
1152
if (! (*(gccp->userfunc))(gcp))
1154
if (LocateItem) return FALSE;
1155
if (LocateData != NULL) return FALSE;
1161
static Boolean NEAR GatherPubSet(InternalGCCPtr gccp, ValNodePtr vnp,
1162
Uint1 cittype, Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
1164
GatherContextPtr gcp;
1167
Int2 LocateItem = 0;
1168
Pointer LocateData = NULL;
1172
if (vnp == NULL) return TRUE;
1175
gsp = &(gccp->scope);
1177
if (gsp->ignore[OBJ_PUB_SET])
1182
if (gccp->locatetype == OBJ_PUB_SET)
1184
LocateItem = gccp->locateID;
1185
LocateData = gccp->locatePtr;
1188
gcp->previtem = NULL;
1189
gcp->prevtype = OBJ_PUB_SET;
1190
gcp->parentitem = tparent;
1191
gcp->parenttype = ttype;
1192
thistype = OBJ_PUB_SET;
1194
gccp->itemIDs[OBJ_PUB_SET]++;
1195
if (LocateItem == gccp->itemIDs[OBJ_PUB_SET])
1197
if (LocateData == (Pointer)vnp)
1200
gcp->itemID = gccp->itemIDs[OBJ_PUB_SET];
1201
gcp->thisitem = (Pointer)vnp;
1202
gcp->thistype = thistype;
1203
GatherAddToStack(gcp);
1207
gcp->prevlink = prevlink;
1208
if (! (*(gccp->userfunc))(gcp))
1210
if (LocateItem) return FALSE;
1211
if (LocateData != NULL) return FALSE;
1215
prevlink = &(vnp->data.ptrvalue);
1216
gcp->previtem = NULL;
1217
gcp->prevtype = OBJ_PUB;
1219
for (vnp2 = (ValNodePtr)(vnp->data.ptrvalue); vnp2 != NULL; vnp2 = vnp2->next)
1221
if (! GatherPub(gccp, vnp2, cittype, thistype, (Pointer)vnp,
1222
prevlink, in_scope))
1224
prevlink = (Pointer PNTR)&(vnp2->next);
1225
gcp->previtem = (Pointer)vnp2;
1233
static Boolean NEAR GatherSeqIds(InternalGCCPtr gccp, SeqIdPtr sip,
1234
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
1236
GatherContextPtr gcp;
1239
Int2 LocateItem = 0;
1240
Pointer LocateData = NULL;
1243
if (sip == NULL) return TRUE;
1246
gsp = &(gccp->scope);
1248
if (gsp->ignore[OBJ_SEQID])
1251
if (gccp->locatetype == OBJ_SEQID)
1253
LocateItem = gccp->locateID;
1254
LocateData = gccp->locatePtr;
1259
gcp->previtem = NULL;
1260
gcp->prevtype = OBJ_SEQID;
1261
gcp->parentitem = tparent;
1262
gcp->parenttype = ttype;
1263
thistype = OBJ_SEQID;
1267
gccp->itemIDs[OBJ_SEQID]++;
1268
if (LocateItem == gccp->itemIDs[OBJ_SEQID])
1270
if (LocateData == (Pointer)sip)
1274
gcp->itemID = gccp->itemIDs[OBJ_SEQID];
1275
gcp->thisitem = (Pointer)sip;
1276
gcp->thistype = thistype;
1277
gcp->prevlink = prevlink;
1278
GatherAddToStack(gcp);
1279
if (! (*(gccp->userfunc))(gcp))
1281
if (LocateItem) return FALSE;
1282
if (LocateData != NULL) return FALSE;
1285
gcp->previtem = (Pointer)sip;
1286
prevlink = (Pointer PNTR)&(sip->next);
1293
static Boolean NEAR GatherSeqDescr(InternalGCCPtr gccp, ValNodePtr vnp,
1294
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
1296
GatherContextPtr gcp;
1299
Int2 LocateItem = 0;
1300
Pointer LocateData = NULL;
1303
if (vnp == NULL) return TRUE;
1306
gsp = &(gccp->scope);
1308
if (gsp->ignore[OBJ_SEQDESC])
1311
if (gccp->locatetype == OBJ_SEQDESC)
1313
LocateItem = gccp->locateID;
1314
LocateData = gccp->locatePtr;
1317
if ((LocateItem) || (LocateData != NULL)) /* fetching an item */
1323
takeit = in_scope; /* if ! in_scope don't take it */
1324
if (gccp->bsp != NULL) /* gsp->target set a Bioseq */
1326
if (tparent != (Pointer)(gccp->bsp))
1328
if (! ObjMgrIsChild(tparent, (Pointer)(gccp->bsp)))
1329
takeit = FALSE; /* not in propagation path */
1331
gcp->propagated = TRUE;
1336
gcp->previtem = NULL;
1337
gcp->prevtype = OBJ_SEQDESC;
1338
gcp->parentitem = tparent;
1339
gcp->parenttype = ttype;
1340
thistype = OBJ_SEQDESC;
1344
gccp->itemIDs[OBJ_SEQDESC]++;
1345
if (LocateItem == gccp->itemIDs[OBJ_SEQDESC])
1347
if (LocateData == (Pointer)vnp)
1351
gcp->itemID = gccp->itemIDs[OBJ_SEQDESC];
1352
gcp->thisitem = (Pointer)vnp;
1353
gcp->thistype = thistype;
1354
gcp->prevlink = prevlink;
1355
GatherAddToStack(gcp);
1356
if (! (*(gccp->userfunc))(gcp))
1358
if (LocateItem) return FALSE;
1359
if (LocateData != NULL) return FALSE;
1362
gcp->previtem = (Pointer)vnp;
1363
prevlink = (Pointer PNTR)&(vnp->next);
1366
gcp->propagated = FALSE; /* reset propagated flag */
1372
static Int4 get_site_offset(SeqLocPtr slp, SeqLocPtr head, Int4 r_len)
1374
Uint1 m_strand, s_strand;
1376
m_strand = SeqLocStrand(slp);
1377
s_strand = SeqLocStrand(slp);
1379
if(m_strand == 0 || s_strand ==0)
1381
if(m_strand == 3 || s_strand == 3)
1384
if(m_strand == s_strand)
1387
if(m_strand == Seq_strand_plus && s_strand == Seq_strand_minus)
1394
static Boolean process_packed_pnt(SeqLocPtr slp, SeqLocPtr head, Int4 r_len, Int4 offset, GatherContextPtr gcp, Int2Ptr max_interval)
1398
Int4 site_offset; /*for treating restriction site as an interval*/
1400
Int4 m_start, m_stop;
1405
GatherRangePtr trdp, lrdp;
1407
Boolean is_end = FALSE;
1409
if(head->choice !=SEQLOC_PACKED_PNT)
1412
if(!SeqIdForSameBioseq(SeqLocId(slp), SeqLocId(head)))
1414
m_strand = SeqLocStrand(slp);
1415
site_offset = get_site_offset(slp, head, (r_len-1));
1416
rev = (SeqLocStrand(slp) == Seq_strand_minus);
1420
m_start = SeqLocStart(slp);
1421
m_stop = SeqLocStop(slp);
1422
pspp = head->data.ptrvalue;
1428
while( !is_end && ((site = PackSeqPntGet(pspp, index))!= -1))
1431
if (ctr >= (*max_interval))
1434
lrdp = (GatherRangePtr)MemNew((size_t)((*max_interval + 20) * sizeof(GatherRange)));
1435
MemCopy(lrdp, trdp, (size_t)(*max_interval * sizeof(GatherRange)));
1437
*max_interval += 20;
1440
is_end = (site > m_stop);
1441
if(site >= m_start && site <=m_stop)
1443
site += site_offset;
1445
pos = offset + (m_stop - site);
1447
pos = offset + (site - m_start);
1455
max = MAX(pos, max);
1456
min = MIN(pos, min);
1458
lrdp[ctr].left = pos;
1459
lrdp[ctr].right = pos;
1460
lrdp[ctr].l_trunc = FALSE;
1461
lrdp[ctr].r_trunc = FALSE;
1462
lrdp[ctr].strand = m_strand;
1467
if (ctr) /* got some */
1469
gcp->extremes.left = min;
1470
gcp->extremes.right = max;
1471
gcp->extremes.l_trunc = FALSE;
1472
gcp->extremes.r_trunc = FALSE;
1473
gcp->extremes.strand = m_strand;
1475
gcp->num_interval = (Int2)ctr;
1476
if (rev) /* reverse order on rev location */
1482
MemCopy(&trange, &(lrdp[i]), sizeof(GatherRange));
1483
MemCopy(&(lrdp[i]), &(lrdp[ctr]), sizeof(GatherRange));
1484
MemCopy(&(lrdp[ctr]), &trange, sizeof(GatherRange));
1494
/* functions to speed up targeted feature gather by using seqmgr explore index */
1496
static ObjMgrDataPtr GatherGetOmdpForBioseq (BioseqPtr bsp)
1502
if (bsp == NULL) return NULL;
1503
omdp = (ObjMgrDataPtr) bsp->omdp;
1504
if (omdp != NULL) return omdp;
1505
omp = ObjMgrWriteLock ();
1506
omdp = ObjMgrFindByData (omp, bsp);
1508
bsp->omdp = (Pointer) omdp;
1512
static SeqFeatPtr LIBCALL SeqMgrGetNextFeatureByID (BioseqPtr bsp, SeqFeatPtr curr,
1513
Uint1 seqFeatChoice, Uint1 featDefChoice,
1514
SeqMgrFeatContext PNTR context)
1517
BioseqExtraPtr bspextra;
1519
SMFeatItemPtr PNTR featsByID;
1525
if (context == NULL) return NULL;
1528
if (bsp == NULL) return NULL;
1529
omdp = GatherGetOmdpForBioseq (bsp);
1530
if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
1532
context->omdp = (Pointer) omdp;
1536
omdp = (ObjMgrDataPtr) context->omdp;
1537
if (omdp == NULL) return NULL;
1538
bspextra = (BioseqExtraPtr) omdp->extradata;
1539
if (bspextra == NULL) return NULL;
1540
featsByID = bspextra->featsByID;
1541
if (featsByID == NULL || bspextra->numfeats < 1) return NULL;
1543
entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
1547
while (i < bspextra->numfeats) {
1548
item = featsByID [i];
1553
seqfeattype = curr->data.choice;
1554
if ((seqFeatChoice == 0 || seqfeattype == seqFeatChoice) &&
1555
(featDefChoice == 0 || item->subtype == featDefChoice) &&
1557
context->entityID = entityID;
1558
context->itemID = item->itemID;
1559
context->sfp = curr;
1560
context->sap = item->sap;
1561
context->bsp = item->bsp;
1562
context->label = item->label;
1563
context->left = item->left;
1564
context->right = item->right;
1565
context->dnaStop = item->dnaStop;
1566
context->partialL = item->partialL;
1567
context->partialR = item->partialR;
1568
context->farloc = item->farloc;
1569
context->strand = item->strand;
1570
context->seqfeattype = seqfeattype;
1571
context->featdeftype = item->subtype;
1572
context->numivals = item->numivals;
1573
context->ivals = item->ivals;
1574
context->userdata = NULL;
1575
context->omdp = (Pointer) omdp;
1586
static Boolean NEAR ExploreSeqFeat (
1587
InternalGCCPtr gccp,
1593
SeqMgrFeatContext fcontext;
1594
GatherContextPtr gcp;
1600
/* gccp->locatetype is known to be NULL if target used */
1602
if (gccp == NULL || bsp == NULL) return TRUE;
1605
gsp = &(gccp->scope);
1607
if (gsp->ignore [OBJ_SEQFEAT]) return TRUE;
1608
if (gsp->ignore [OBJ_SEQFEAT_CIT]) {
1614
gcp->num_interval = 0;
1616
if (gsp->get_feats_location) {
1617
sfp = SeqMgrGetNextFeatureByID (bsp, NULL, 0, 0, &fcontext);
1618
while (sfp != NULL) {
1620
gcp->previtem = NULL;
1621
gcp->prevtype = OBJ_SEQFEAT;
1623
gcp->parentitem = sfp->idx.parentptr;
1624
gcp->parenttype = sfp->idx.parenttype;
1626
gcp->itemID = sfp->idx.itemID;
1627
gcp->thisitem = (Pointer) sfp;
1628
gcp->thistype = OBJ_SEQFEAT;
1629
gcp->prevlink = sfp->idx.prevlink;
1631
gcp->product = FALSE;
1633
GatherAddToStack (gcp);
1634
if (! (*(gccp->userfunc)) (gcp)) return FALSE;
1636
if (sfp->cit != NULL && takecit) {
1637
if (! GatherPubSet (gccp, sfp->cit, 1, OBJ_SEQFEAT, (Pointer) sfp,
1638
(Pointer PNTR) &(sfp->cit), in_scope))
1642
sfp = SeqMgrGetNextFeatureByID (bsp, sfp, 0, 0, &fcontext);
1646
if (gsp->get_feats_product) {
1647
for (vnp = SeqMgrGetSfpProductList (bsp); vnp != NULL; vnp = vnp->next) {
1648
sfp = (SeqFeatPtr) vnp->data.ptrvalue;
1651
gcp->previtem = NULL;
1652
gcp->prevtype = OBJ_SEQFEAT;
1654
gcp->parentitem = sfp->idx.parentptr;
1655
gcp->parenttype = sfp->idx.parenttype;
1657
gcp->itemID = sfp->idx.itemID;
1658
gcp->thisitem = (Pointer) sfp;
1659
gcp->thistype = OBJ_SEQFEAT;
1660
gcp->prevlink = sfp->idx.prevlink;
1662
gcp->product = TRUE;
1664
GatherAddToStack (gcp);
1665
if (! (*(gccp->userfunc)) (gcp)) return FALSE;
1667
if (sfp->cit != NULL && takecit) {
1668
if (! GatherPubSet (gccp, sfp->cit, 1, OBJ_SEQFEAT, (Pointer) sfp,
1669
(Pointer PNTR) &(sfp->cit), in_scope))
1676
/* ignoring sfp->cit on non-targeted records, not keeping counter in synch */
1681
static Boolean NEAR GatherSeqFeat(InternalGCCPtr gccp, SeqFeatPtr sfp,
1682
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Uint1 sfptype)
1684
GatherContextPtr gcp;
1686
Boolean takeit=TRUE,
1687
takecit, checkseq=FALSE;
1688
SeqLocPtr slp, head, tslp, target[2];
1689
GatherRangePtr rdp, trdp, lrdp;
1690
Int4 offset, totlen, left_end;
1691
Boolean rev, revs[2];
1692
Int2 ctr, max_interval, i, numcheck, j;
1694
Int2 LocateItem = 0;
1695
Pointer LocateData = NULL;
1697
Boolean is_packed_pnt = FALSE; /*is the seq-loc a packed point?*/
1698
Boolean stop_now, convert_loc = FALSE;
1706
SeqFeatPtr prevsfp = NULL;
1708
if (sfp == NULL) return TRUE;
1711
gsp = &(gccp->scope);
1713
if (gsp->ignore[sfptype])
1716
if (gccp->locatetype == sfptype)
1718
LocateItem = gccp->locateID;
1719
LocateData = gccp->locatePtr;
1724
if (gsp->target != NULL)
1728
target[0] = gsp->target;
1729
revs[0] = gccp->rev;
1730
if (gccp->segloc != NULL)
1733
target[1] = gccp->segloc;
1736
rdp = &(gcp->extremes);
1737
offset = gsp->offset;
1738
max_interval = gccp->max_interval;
1741
convert_loc = gsp->convert_loc;
1745
if (gsp->ignore[OBJ_SEQFEAT_CIT])
1750
gcp->prevtype = sfptype;
1751
gcp->parentitem = tparent;
1752
gcp->parenttype = ttype;
1753
gcp->num_interval = 0;
1758
gcp->previtem = (Pointer) prevsfp;
1759
gccp->itemIDs[sfptype]++;
1760
if (LocateItem == gccp->itemIDs[sfptype])
1762
if (LocateData == (Pointer)sfp)
1765
gcp->itemID = gccp->itemIDs[sfptype];
1771
gcp->thisitem = (Pointer)sfp;
1772
gcp->thistype = thistype;
1773
gcp->prevlink = prevlink;
1774
gcp->product = FALSE;
1775
head = sfp->location;
1776
if (checkseq) /* find by SeqLoc overlap */
1779
is_packed_pnt = (head->choice == SEQLOC_PACKED_PNT);
1780
for (j = 0; ((j < numcheck) && (! takeit) && (!stop_now)); j++)
1784
if (gsp->get_feats_location)
1788
if(process_packed_pnt(slp, head, 0, offset, gcp, &(gccp->max_interval)))
1795
takeit = SeqLocOffset(slp, head, rdp, offset);
1798
if ((! takeit) && (gsp->get_feats_product))
1800
head = sfp->product;
1801
takeit = SeqLocOffset(slp, head, rdp, offset);
1803
gcp->product = TRUE;
1806
if ((takeit) && (! gsp->nointervals) && (!stop_now)) /* map intervals in loc */
1810
while ((tslp = SeqLocFindNext(head, tslp)) != NULL)
1812
if (ctr >= max_interval)
1815
lrdp = (GatherRangePtr)MemNew((size_t)((max_interval + 20) * sizeof(GatherRange)));
1816
MemCopy(lrdp, trdp, (size_t)(max_interval * sizeof(GatherRange)));
1819
gccp->max_interval = max_interval;
1822
if (SeqLocOffset(slp, tslp, &(lrdp[ctr]), offset))
1825
if (ctr) /* got some */
1827
gcp->num_interval = ctr;
1828
if (rev) /* reverse order on rev location */
1834
MemCopy(&trange, &(lrdp[i]), sizeof(GatherRange));
1835
MemCopy(&(lrdp[i]), &(lrdp[ctr]), sizeof(GatherRange));
1836
MemCopy(&(lrdp[ctr]), &trange, sizeof(GatherRange));
1843
if ((takeit) && (convert_loc) && (! stop_now)) /* convert SeqLoc */
1845
gcp->new_loc = SeqLocReMap(newid, slp, head, offset, rev);
1846
if (gsp->get_feats_location)
1848
gcp->extra_loc_cnt = 0;
1849
if (sfp->data.choice == SEQFEAT_CDREGION)
1851
cdr = (CdRegionPtr)(sfp->data.value.ptrvalue);
1852
for (cbp = cdr->code_break; cbp != NULL;
1855
tslp = SeqLocReMap(newid, slp, cbp->loc, offset, rev);
1856
GatherAddExtraLoc(gcp, tslp);
1859
else if (sfp->data.choice == SEQFEAT_RNA)
1861
rrp = (RnaRefPtr)(sfp->data.value.ptrvalue);
1862
if ((rrp->ext.choice == 2) &&
1863
(rrp->ext.value.ptrvalue != NULL)) /* tRNA */
1865
trp = (tRNAPtr)(rrp->ext.value.ptrvalue);
1866
if (trp->anticodon != NULL)
1868
tslp = SeqLocReMap(newid, slp, trp->anticodon,
1870
GatherAddExtraLoc(gcp, tslp);
1881
if (gccp->segcnt) /* which segment was it in? */
1884
for (i = 0; i < gccp->segcnt; i++)
1886
totlen = left_end + gccp->seglens[i];
1887
if ((rdp->left >= left_end) && (rdp->left < totlen))
1888
gccp->found_annot[i] = TRUE;
1889
else if ((rdp->right >= left_end) && (rdp->right < totlen))
1890
gccp->found_annot[i] = TRUE;
1895
GatherAddToStack(gcp);
1896
if (! (*(gccp->userfunc))(gcp))
1898
if (LocateItem) return FALSE;
1899
if (LocateData != NULL) return FALSE;
1901
if ((sfp->cit != NULL) && (takecit))
1903
if (! GatherPubSet(gccp, sfp->cit, 1, thistype, (Pointer)sfp,
1904
(Pointer PNTR)&(sfp->cit), in_scope))
1907
gcp->prevtype = thistype;
1908
gcp->parentitem = tparent;
1909
gcp->parenttype = ttype;
1913
else /* out of scope */
1916
if (sfp->cit != NULL) /* just run the counter */
1918
if (! GatherPubSet(gccp, sfp->cit, 1, thistype, (Pointer)sfp,
1919
(Pointer PNTR)&(sfp->cit), in_scope))
1922
gcp->prevtype = thistype;
1923
gcp->parentitem = tparent;
1924
gcp->parenttype = ttype;
1929
prevlink = (Pointer PNTR)&(sfp->next);
1935
static Uint1 align_strand_get(Uint1Ptr strands, Int2 order)
1940
return strands[order];
1943
static Boolean check_reverse_strand(Uint1 loc_strand, Uint1 a_strand)
1945
if(loc_strand == Seq_strand_minus || a_strand == Seq_strand_minus)
1946
return (loc_strand != a_strand);
1951
/****************************************************************************
1953
* get_align_ends(): map the two ends of the alignment
1955
*****************************************************************************
1958
static void load_start_stop(Int4Ptr start, Int4Ptr stop, Int4 c_start, Int4 c_stop)
1967
*start = MIN(*start, c_start);
1968
*stop = MAX(*stop, c_stop);
1972
static Int2 get_master_order(SeqIdPtr ids, SeqIdPtr sip)
1976
for(i =0; ids!=NULL; ids = ids->next, ++i)
1978
if(SeqIdForSameBioseq(ids, sip))
1984
NLM_EXTERN Boolean get_align_ends(SeqAlignPtr align, SeqIdPtr id,
1985
Int4Ptr start, Int4Ptr stop, Uint1Ptr strand)
1989
Int4 c_start, c_stop;
1998
switch(align->segtype) {
1999
case 5: /* Discontinuous alignment */
2001
sap = (SeqAlignPtr)(align->segs);
2003
for(; sap != NULL; sap = sap->next) {
2004
if(!get_align_ends(sap, id, &c_start, &c_stop, strand))
2006
load_start_stop(start, stop, c_start, c_stop);
2008
return (*start != -1);
2010
case 2: /*DenseSeg*/
2011
dsp = (DenseSegPtr)(align->segs);
2015
i = get_master_order(dsp->ids, id);
2020
for(n =0; n<dsp->numseg; ++n) {
2021
c_start = dsp->starts[n*(dsp->dim) +i];
2022
if(c_start != -1) { /*check for a non-gapped region*/
2023
c_stop = c_start + dsp->lens[n] -1;
2024
load_start_stop(start, stop, c_start, c_stop);
2027
*strand = align_strand_get(dsp->strands, i);
2028
return (*start != -1);
2031
ssp = (StdSegPtr)(align->segs);
2034
for (loc = ssp->loc; loc!=NULL && !is_found; loc=loc->next) {
2035
if(loc->choice != SEQLOC_EMPTY) {
2040
is_found=SeqIdForSameBioseq(SeqLocId(loc), id);
2042
load_start_stop(start, stop, SeqLocStart(loc), SeqLocStop(loc));
2043
*strand = SeqLocStrand(loc);
2049
return (*start != -1);
2052
ddp = (DenseDiagPtr)(align->segs);
2057
i = get_master_order(ddp->id, id);
2059
c_start = ddp->starts[i];
2060
c_stop = ddp->starts[i] + ddp->len -1;
2061
*strand = align_strand_get(ddp->strands, i);
2062
load_start_stop(start, stop, c_start, c_stop);
2066
return (*start != -1);
2074
static void LinkAlignData(AlignDataPtr PNTR head, AlignDataPtr adp)
2083
while(curr->next != NULL)
2089
static void LinkAlignRangeToAlignData(AlignDataPtr adp, AlignRangePtr arp)
2094
if(adp->arp == NULL)
2097
adp->last->next = arp;
2101
static AlignDataPtr get_adp_node(AlignDataPtr head, Int2 order, Uint2 chain)
2107
if(head->order == order && head->chain == chain)
2116
static void load_align_data(AlignDataPtr PNTR head, Int4 start, Int4 stop, Uint1 strand, SeqIdPtr sip, Boolean rev, Int2 seg_type, GatherRange t_range, Boolean ck_interval, Int2 order, Uint2 chain)
2122
adp = get_adp_node(*head, order, chain);
2125
if(strand == Seq_strand_minus)
2126
strand = Seq_strand_plus;
2128
strand = Seq_strand_minus;
2132
adp = MemNew(sizeof(AlignData));
2136
MemCopy((&adp->extremes), &t_range, sizeof(GatherRange));
2137
adp->extremes.strand = strand;
2138
if(seg_type != GAP_SEG)
2140
adp->seqends.start = start;
2141
adp->seqends.stop = stop;
2145
adp->seqends.start = -1;
2146
adp->seqends.stop = -1;
2148
adp->seqends.strand = strand;
2151
LinkAlignData(head, adp);
2155
left = adp->extremes.left;
2156
right = adp->extremes.right;
2157
if(t_range.left < left)
2159
adp->extremes.left = t_range.left;
2160
adp->extremes.l_trunc = t_range.l_trunc;
2162
if(t_range.right > right)
2164
adp->extremes.right = t_range.right;
2165
adp->extremes.r_trunc = t_range.r_trunc;
2167
if(seg_type != GAP_SEG)
2169
if(adp->seqends.start == -1)
2171
adp->seqends.start = start;
2172
adp->seqends.stop = stop;
2176
adp->seqends.start = MIN(start, adp->seqends.start);
2177
adp->seqends.stop = MAX(stop, adp->seqends.stop);
2185
arp = MemNew(sizeof(AlignRange));
2186
arp->segtype = (Uint1)seg_type;
2187
MemCopy(&(arp->gr), &t_range, sizeof(GatherRange));
2188
arp->sr.start = start;
2189
arp->sr.stop = stop;
2190
arp->sr.strand = strand;
2191
LinkAlignRangeToAlignData(adp, arp);
2196
static Boolean get_end_diag_val(DenseSegPtr dsp, Int2 m_order, Int2 k_seg, Int4Ptr start, Int4Ptr stop, Boolean first)
2200
Boolean increase = TRUE;
2206
k = dsp->numseg-1 -k_seg;
2210
for(i =0; i<dsp->numseg; ++i)
2212
if(dsp->starts[dim*k+m_order] != -1)
2214
*start = dsp->starts[dim*k+m_order];
2215
*stop = *start + dsp->lens[k] -1;
2226
static void load_trunc_info(SeqLocPtr slp, GatherRangePtr grp)
2229
Boolean f_trunc = FALSE, t_trunc = FALSE;
2232
if(slp == NULL || grp == NULL)
2234
if(slp->choice != SEQLOC_INT)
2236
sint = slp->data.ptrvalue;
2239
ifp = sint->if_from;
2242
if(ifp->choice == 4 && ifp->a == 2)
2248
if(ifp->choice == 4 && ifp->a == 1)
2253
grp->l_trunc = f_trunc;
2254
grp->r_trunc = t_trunc;
2255
if(grp->strand != sint->strand)
2257
if(grp->strand == Seq_strand_minus || sint->strand == Seq_strand_minus)
2259
grp->l_trunc = t_trunc;
2260
grp->r_trunc = f_trunc;
2265
/**************************************************************
2268
**************************************************************/
2270
static Boolean is_end_gaps_for_master(DenseSegPtr dsp, Int2 m_order, Int2 k_seg, Int2 j_seg, Boolean left)
2273
Boolean is_gap = FALSE;
2276
/*get the first non-gap segment*/
2280
k = dsp->numseg-1 - k_seg;
2282
for(i = 0; i<dsp->numseg; ++i)
2284
if(dsp->starts[(dsp->dim)*k+m_order] != -1)
2300
static Uint1 get_master_strand_for_continous_ssp (StdSegPtr ssp, SeqIdPtr m_sip)
2306
for(loc= ssp->loc; loc!=NULL; loc = loc->next)
2308
if(SeqIdMatch(SeqLocId(loc), m_sip))
2310
if(loc->choice != SEQLOC_EMPTY)
2311
return SeqLocStrand(loc);
2321
static Int2 get_ssp_numseg (StdSegPtr ssp)
2334
static StdSegPtr get_nth_ssp (StdSegPtr ssp, Int2 order)
2350
static Boolean is_fuzz_loc (SeqLocPtr slp)
2357
while((t_slp = SeqLocFindNext(slp, t_slp)) != NULL)
2359
if(t_slp->choice == SEQLOC_INT)
2361
sint = t_slp->data.ptrvalue;
2362
if(sint->if_from || sint->if_to)
2365
else if(t_slp->choice == SEQLOC_PNT)
2367
spp = t_slp->data.ptrvalue;
2376
static Int4 calculate_mag_val (StdSegPtr ssp, SeqIdPtr m_sip, BoolPtr inverse)
2378
SeqLocPtr m_slp, s_slp;
2386
for(slp = ssp->loc; slp != NULL; slp = slp->next)
2388
if(SeqIdMatch(SeqLocId(slp), m_sip))
2394
if(m_slp && s_slp && SeqLocLen(m_slp) && SeqLocLen(s_slp))
2396
if(!is_fuzz_loc(m_slp) && !is_fuzz_loc(s_slp))
2398
if(SeqLocLen(m_slp) > SeqLocLen(s_slp))
2400
mag_val = SeqLocLen(m_slp)/SeqLocLen(s_slp);
2401
if(SeqLocLen(m_slp)%SeqLocLen(s_slp) == 0)
2409
mag_val = SeqLocLen(s_slp)/SeqLocLen(m_slp);
2410
if(SeqLocLen(s_slp)%SeqLocLen(m_slp) == 0)
2426
static Int4 modify_offset (SeqLocPtr m_loc, SeqLocPtr s_loc, Int4 m_offset, Int4Ptr left_over)
2435
m_len = SeqLocLen(m_loc);
2436
s_len = SeqLocLen(s_loc);
2441
if(m_len/s_len == 3)
2443
*left_over = m_offset%3;
2445
*left_over = 3 - (*left_over);
2448
return ((m_offset * s_len) /m_len + 1);
2450
return ((m_offset * s_len) /m_len);
2455
static Uint1 get_DenseSeg_strand(DenseSegPtr dsp, Int2 order)
2459
if(dsp == NULL || dsp->strands == NULL)
2462
for(i = 0; i<dsp->numseg; ++i)
2464
if(dsp->starts[dim * i + order] != -1)
2465
return (dsp->strands[dim*i + order]);
2471
NLM_EXTERN AlignDataPtr gather_align_data(SeqLocPtr m_slp, SeqAlignPtr align,
2472
Int4 offset, Boolean ck_interval,
2475
SeqIdPtr m_sip, sip;
2476
Uint1 m_strand, strand, c_strand;
2480
Int2 i, m_order, k, numseg, t_numseg;
2483
Boolean is_found = FALSE;
2484
Int4 start, stop, c_start, c_stop;
2485
Int4 m_start, m_stop;
2486
Int4 master_pos; /*position of the master sequence*/
2487
Int4 off_start, off_stop;
2489
GatherRange gr, t_range;
2490
SeqLocPtr a_slp, loc;
2491
AlignDataPtr head = NULL, curr;
2493
Int4 h_start, h_stop;
2494
Boolean inc_left_mgap; /*include the left gaps on the master sequence*/
2495
Boolean inc_right_mgap; /*include the right gaps on the master sequence*/
2496
Boolean left_end_gap, right_end_gap;
2500
Boolean cont; /*is it a continous segment ? */
2502
Int4 mag_val; /*the magnification value */
2503
SeqLocPtr master_loc, m_loc;
2512
m_sip = SeqLocId(m_slp);
2513
if(!get_align_ends(align, m_sip, &start, &stop, &c_strand))
2516
a_slp = SeqLocIntNew(start, stop, c_strand, m_sip);
2517
if(!SeqLocOffset(m_slp, a_slp, &gr, offset)) {
2522
if(align->segtype == 2)
2524
else if(align->segtype == 3) {
2525
cont = (align->type == 3);
2528
mag_val = calculate_mag_val (ssp, m_sip, &inverse);
2535
m_strand = SeqLocStrand(m_slp);
2536
m_start = SeqLocStart(m_slp);
2537
m_stop = SeqLocStop(m_slp);
2541
switch(align->segtype) {
2543
case 5: /* Discontinuous alignment */
2544
for(sap = (SeqAlignPtr) align->segs; sap != NULL; sap = sap->next) {
2545
curr = gather_align_data(m_slp, sap, offset, ck_interval, map);
2546
LinkAlignData(&head, curr);
2550
case 2: /*for DenseSegs*/
2551
dsp = (DenseSegPtr)(align->segs);
2552
m_order = get_master_order(dsp->ids, m_sip);
2553
ma_strand = get_DenseSeg_strand(dsp, m_order);
2554
rev = check_reverse_strand(m_strand, c_strand);
2561
get_end_diag_val(dsp, m_order, k, &h_start, &h_stop, TRUE);
2562
if(!(h_stop < m_start || h_start > m_stop)) /*it is within the range*/
2563
inc_left_mgap = TRUE;
2565
inc_left_mgap = FALSE;
2567
get_end_diag_val(dsp, m_order, k, &h_start, &h_stop, FALSE);
2568
if(!(h_stop < m_start || h_start > m_stop)) /*it is within the range*/
2569
inc_right_mgap = TRUE;
2571
inc_right_mgap = FALSE;
2573
for(numseg = 0; numseg<dsp->numseg; ++numseg) {
2574
if(dsp->lens[k] >0) {
2575
s1 = (Int4)k*(Int4)(dsp->dim)+(Int4)m_order;
2576
master_pos = dsp->starts[s1];
2578
if(master_pos == -1) { /*gap in the master sequence. It is an insertion*/
2580
left_end_gap = is_end_gaps_for_master(dsp, m_order, k_seg, k, TRUE);
2581
right_end_gap = is_end_gaps_for_master(dsp, m_order, k_seg, k, FALSE);
2582
if(left_end_gap && inc_left_mgap && !map) {
2584
t_range.left = offset;
2585
t_range.right = offset + dsp->lens[k] -1;
2586
offset += dsp->lens[k];
2588
if(right_end_gap && inc_right_mgap && !map) {
2590
t_range.left = t_range.right +1;
2591
t_range.right = t_range.left + dsp->lens[k] -1;
2593
if(!left_end_gap && !right_end_gap) {
2595
if((strand != Seq_strand_minus && rev) || (strand == Seq_strand_minus && rev == FALSE))
2598
update_seq_loc(c_stop, c_stop, 0, a_slp);
2600
update_seq_loc(c_start, c_start, 0, a_slp);
2601
collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
2605
t_range.right = t_range.left+dsp->lens[k]-1;
2606
offset += dsp->lens[k];
2612
} else {/*master is not a gap*/
2613
c_start = dsp->starts[s1];
2614
c_stop = c_start + dsp->lens[k] -1;
2615
update_seq_loc(c_start, c_stop, 0, a_slp);
2616
collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
2618
off_start = MAX(0, (m_start - c_start));
2619
off_stop = MAX(0, (c_stop - m_stop));
2623
for(sip = dsp->ids, i=0; sip!=NULL; sip = sip->next, ++i) {
2625
start = dsp->starts[k*(dsp->dim) +i];
2627
/*multiple pairwise, ignore the master and the gap in the master*/
2630
else if(master_pos == -1 && start == -1)
2635
strand = align_strand_get(dsp->strands, i);
2637
stop = start + dsp->lens[k] -1;
2638
if(master_pos == -1 && map) { /*master sequence*/
2641
t_range.right = dsp->lens[k];
2643
if(check_reverse_strand(c_strand, strand)) {
2655
stop = dsp->lens[k];
2657
load_align_data(&head, start, stop, strand, sip, rev, seg_type, t_range, ck_interval, i, 1);
2670
ssp = (StdSegPtr)(align->segs);
2672
c_strand = get_master_strand_for_continous_ssp (ssp, m_sip);
2673
rev = check_reverse_strand(m_strand, c_strand);
2674
numseg = get_ssp_numseg (ssp);
2679
for(t_numseg = 0; t_numseg <numseg; ++t_numseg) {
2680
ssp = get_nth_ssp ((StdSegPtr)(align->segs), k);
2682
for(loc= ssp->loc, i=0; loc!=NULL && !is_found; ++i, loc = loc->next) {
2683
if(SeqIdMatch(SeqLocId(loc), m_sip)) {
2686
if(loc->choice == SEQLOC_EMPTY)
2689
master_pos = SeqLocStart(loc);
2690
is_found = SeqLocOffset(m_slp, loc, &t_range, offset);
2696
for(loc= ssp->loc, i = 0; loc!=NULL; ++i, loc = loc->next) {
2698
if(loc->choice != SEQLOC_EMPTY)
2699
len = SeqLocLen(loc);
2703
/*both segments are gaps */
2705
if(len == -1 && master_pos == -1)
2708
if(loc != NULL && (is_found || master_pos == -1)) {
2710
if(master_pos == -1) {/*the master is a gap, it is an insertion*/
2711
if(m_strand == Seq_strand_minus)
2712
update_seq_loc(c_start, c_start, 0, a_slp);
2714
update_seq_loc(c_stop, c_stop, 0, a_slp);
2715
collect = SeqLocOffset(m_slp, a_slp, &t_range, offset);
2720
t_range.right = t_range.left+len * mag_val -1;
2721
offset += len * mag_val;
2723
t_range.right = t_range.left+len / mag_val -1;
2724
offset += len / mag_val;
2731
c_start = SeqLocStart(master_loc);
2732
c_stop = SeqLocStop(master_loc);
2734
off_start = MAX(0, (m_start - c_start));
2735
off_stop = MAX(0, (c_stop - m_stop));
2739
for(loc = ssp->loc, i= 0; loc != NULL; loc = loc->next, ++i) {
2741
if(map && i == m_order)
2744
left = t_range.left;
2745
right = t_range.right;
2746
if(loc->choice == SEQLOC_EMPTY) {/*it is a gap */
2750
stop = inverse ? (len /mag_val) : (len * mag_val);
2752
stop = inverse ? SeqLocLen(master_loc) * mag_val : SeqLocLen(master_loc)/mag_val;
2755
start = SeqLocStart(loc);
2756
stop = SeqLocStop(loc);
2757
strand = SeqLocStrand(loc);
2758
if(master_pos == -1 && map) {
2760
t_range.right = SeqLocLen(loc);
2762
if(check_reverse_strand(strand, c_strand)) {
2763
start += modify_offset(master_loc, loc, off_stop, &leftover);
2764
t_range.left += leftover;
2765
stop -= modify_offset(master_loc, loc, off_start, &leftover);
2766
t_range.right += leftover;
2768
start += modify_offset(master_loc, loc, off_start, &leftover);
2769
t_range.left += leftover;
2770
stop -= modify_offset(master_loc, loc, off_stop, &leftover);
2771
t_range.right += leftover;
2773
/* if(check_reverse_strand(c_strand, strand))
2786
load_align_data(&head, start, stop, strand, SeqLocId(loc), rev, seg_type, t_range, ck_interval, i, 1);
2787
t_range.left = left;
2788
t_range.right = right;
2799
} else { /*end of if (count) */
2805
for(loc= ssp->loc, i=0; loc!=NULL && !is_found;) {
2806
if(SeqLocOffset(m_slp, loc, &t_range, offset)) {
2817
off_start = MAX(0, (m_start - SeqLocStart(loc)));
2818
off_stop = MAX(0, (SeqLocStop(loc) - m_stop));
2819
c_strand = SeqLocStrand(loc);
2821
rev = check_reverse_strand(c_strand, m_strand);
2824
for(loc = ssp->loc,i=0; loc != NULL; loc = loc->next,++i) {
2825
sip = SeqLocId(loc);
2826
if(!map|| (m_order !=i)) {
2827
start = SeqLocStart(loc);
2828
stop = SeqLocStop(loc);
2829
strand = SeqLocStrand(loc);
2830
left = t_range.left;
2831
right = t_range.right;
2832
if(check_reverse_strand(strand, c_strand)) {
2833
start += modify_offset(m_loc, loc, off_stop, &leftover);
2834
t_range.left += leftover;
2835
stop -= modify_offset(m_loc, loc, off_start, &leftover);
2836
t_range.right += leftover;
2838
start += modify_offset(m_loc, loc, off_start, &leftover);
2839
t_range.left += leftover;
2840
stop -= modify_offset(m_loc, loc, off_stop, &leftover);
2841
t_range.right += leftover;
2843
load_trunc_info(loc, &t_range);
2844
load_align_data(&curr, start, stop, strand, sip, rev, STD_SEG, t_range, ck_interval, i, chain);
2845
t_range.left = left;
2846
t_range.right = right;
2850
LinkAlignData(&head, curr);
2857
ddp = (DenseDiagPtr)(align->segs);
2862
m_order = get_master_order(ddp->id, m_sip);
2864
c_strand = align_strand_get(ddp->strands, m_order);
2865
c_start = ddp->starts[m_order];
2866
c_stop = c_start + ddp->len -1;
2867
update_seq_loc(c_start, c_stop, 0, a_slp);
2868
if(SeqLocOffset(m_slp, a_slp, &t_range, offset)) {
2869
rev = check_reverse_strand(m_strand, c_strand);
2870
off_start = MAX(0, (m_start-c_start));
2871
off_stop = MAX(0, (c_stop - m_stop));
2872
for(sip = ddp->id, i=0; sip!=NULL; sip = sip->next, ++i) {
2873
if(!map|| i != m_order) {
2874
start = ddp->starts[i];
2875
stop = start + ddp->len -1;
2876
strand = align_strand_get(ddp->strands, i);
2877
if(check_reverse_strand(strand, c_strand)) {
2884
load_align_data(&curr, start, stop, strand, sip, rev, DIAG_SEG, t_range, ck_interval, i, chain);
2889
LinkAlignData(&head, curr);
2903
static Boolean NEAR GatherSeqAlign(InternalGCCPtr gccp, SeqAlignPtr sap,
2904
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Boolean check, Uint1 obj_type)
2906
GatherContextPtr gcp;
2908
Int2 LocateItem = 0;
2909
Pointer LocateData = NULL;
2911
SeqLocPtr slp, target[2];
2912
Boolean takeit=TRUE, checkseq = FALSE;
2915
Boolean check_interval;
2917
SeqAlignPtr prevsap = NULL;
2919
if (sap == NULL) return TRUE;
2921
if(obj_type != OBJ_SEQALIGN && obj_type != OBJ_SEQHIST_ALIGN)
2925
gsp = &(gccp->scope);
2927
if (gsp->ignore[obj_type])
2930
if (gccp->locatetype == obj_type)
2932
LocateItem = gccp->locateID;
2933
LocateData = gccp->locatePtr;
2936
thistype = obj_type;
2939
if (gsp->target != NULL && check)
2942
target[0] = gsp->target;
2943
if (gccp->segloc != NULL)
2946
target[1] = gccp->segloc;
2948
offset = gsp->offset;
2952
check_interval = (gsp->nointervals == FALSE);
2955
gccp->itemIDs[obj_type]++;
2956
if (LocateItem == gccp->itemIDs[obj_type])
2958
if (LocateData == (Pointer)sap)
2963
gcp->previtem = (Pointer)prevsap;
2964
gcp->prevtype = thistype;
2965
gcp->parentitem = tparent;
2966
gcp->parenttype = ttype;
2967
gcp->itemID = gccp->itemIDs[obj_type];
2968
gcp->prevlink = prevlink;
2969
gcp->thisitem = (Pointer)sap;
2970
gcp->thistype = thistype;
2971
GatherAddToStack(gcp);
2975
for (j =0; ((j<numcheck) && (!takeit)); j++)
2978
FreeAlignData(gcp->adp);
2980
adp = gather_align_data(slp, sap, offset, check_interval, gsp->mapinsert);
2992
if (! (*(gccp->userfunc))(gcp))
2999
if (! (*(gccp->userfunc))(gcp))
3002
if (LocateItem) return FALSE;
3003
if (LocateData) return FALSE;
3006
if (sap->segtype == SAS_DISC)
3009
if (! GatherSeqAlign(gccp, (SeqAlignPtr)(sap->segs),
3010
thistype, (Pointer)sap, &(sap->segs),
3011
in_scope, check, OBJ_SEQALIGN))
3020
prevlink = (Pointer PNTR)&(sap->next);
3026
static Boolean NEAR GatherSeqGraph(InternalGCCPtr gccp, SeqGraphPtr sgp,
3027
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
3029
GatherContextPtr gcp;
3031
Int2 LocateItem = 0;
3032
Pointer LocateData = NULL;
3035
if (sgp == NULL) return TRUE;
3038
gsp = &(gccp->scope);
3040
if (gsp->ignore[OBJ_SEQGRAPH])
3043
LocateItem = gccp->locateID;
3044
LocateData = gccp->locatePtr;
3046
thistype = OBJ_SEQGRAPH;
3047
gcp->previtem = NULL;
3048
gcp->prevtype = thistype;
3049
gcp->parentitem = tparent;
3050
gcp->parenttype = ttype;
3054
gccp->itemIDs[OBJ_SEQGRAPH]++;
3055
if (LocateItem == gccp->itemIDs[OBJ_SEQGRAPH])
3057
if (LocateData == (Pointer)sgp)
3062
gcp->itemID = gccp->itemIDs[OBJ_SEQGRAPH];
3063
gcp->thisitem = (Pointer)sgp;
3064
gcp->thistype = thistype;
3065
GatherAddToStack(gcp);
3066
gcp->prevlink = prevlink;
3067
if (! (*(gccp->userfunc))(gcp))
3069
if (LocateItem) return FALSE;
3070
if (LocateData != NULL) return FALSE;
3073
gcp->previtem = (Pointer)sgp;
3074
prevlink = (Pointer PNTR)&(sgp->next);
3080
static Boolean NEAR GatherSeqAnnot(InternalGCCPtr gccp, SeqAnnotPtr sap,
3081
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope)
3083
GatherContextPtr gcp;
3085
SeqAnnotPtr prevsap = NULL;
3086
Int2 LocateItem = 0;
3087
Pointer LocateData = NULL;
3090
if (sap == NULL) return TRUE;
3093
gsp = &(gccp->scope);
3095
if (gsp->ignore[OBJ_SEQANNOT])
3098
if ((! gsp->currlevel) && (gsp->ignore_top))
3101
if (gccp->locatetype == OBJ_SEQANNOT)
3103
LocateItem = gccp->locateID;
3104
LocateData = gccp->locatePtr;
3111
thistype = OBJ_SEQANNOT;
3112
gccp->itemIDs[OBJ_SEQANNOT]++;
3113
if (LocateItem == gccp->itemIDs[OBJ_SEQANNOT])
3115
if (LocateData == (Pointer)sap)
3118
gcp->thisitem = (Pointer)sap;
3119
gcp->thistype = thistype;
3120
gcp->itemID = gccp->itemIDs[OBJ_SEQANNOT];
3121
GatherAddToStack(gcp);
3125
gcp->previtem = (Pointer) prevsap;
3126
gcp->prevtype = thistype;
3127
gcp->parentitem = tparent;
3128
gcp->parenttype = ttype;
3129
gcp->prevlink = prevlink;
3130
if (! (*(gccp->userfunc))(gcp))
3132
if (LocateItem) return FALSE;
3133
if (LocateData != NULL) return FALSE;
3140
case 1: /* feature table */
3141
if (gccp->useSeqMgrIndexes) {
3142
/* now sending targeted features all at once regardless of packaging - so do nothing here */
3144
if (! GatherSeqFeat(gccp, (SeqFeatPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope, OBJ_SEQFEAT))
3148
case 2: /* alignments */
3149
if (! GatherSeqAlign(gccp, (SeqAlignPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope, TRUE, OBJ_SEQALIGN))
3152
case 3: /* graphs */
3153
if (! GatherSeqGraph(gccp, (SeqGraphPtr)(sap->data), thistype, (Pointer)sap, &(sap->data), in_scope))
3161
prevlink = (Pointer PNTR)&(sap->next);
3169
static Boolean NEAR GatherSeqHist(InternalGCCPtr gccp, SeqHistPtr hist,
3170
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink, Boolean in_scope, Boolean check_seq)
3172
GatherContextPtr gcp;
3174
Int2 LocateItem = 0;
3175
Pointer LocateData = NULL;
3178
if(hist == NULL) return TRUE;
3181
gsp = &(gccp->scope);
3183
if(gsp->ignore[OBJ_SEQHIST])
3186
if (gccp->locatetype == OBJ_SEQHIST)
3188
LocateItem = gccp->locateID;
3189
LocateData = gccp->locatePtr;
3194
gccp->itemIDs[OBJ_SEQHIST]++;
3195
thistype = OBJ_SEQHIST;
3196
if (LocateItem == gccp->itemIDs[OBJ_SEQHIST])
3198
if (LocateData == (Pointer)(hist))
3201
gcp->thistype = thistype;
3202
gcp->thisitem = (Pointer)(hist);
3203
gcp->itemID = gccp->itemIDs[OBJ_SEQHIST];
3204
GatherAddToStack(gcp);
3208
gcp->previtem = NULL;
3210
gcp->parentitem = (Pointer)tparent;
3211
gcp->parenttype = ttype;
3212
gcp->prevlink = prevlink;
3214
if (! (*(gccp->userfunc))(gcp))
3216
if (LocateItem) return FALSE;
3217
if (LocateData != NULL) return FALSE;
3219
if((hist->assembly!=NULL) && (!gsp->ignore[OBJ_SEQHIST_ALIGN]))
3220
GatherSeqAlign(gccp,(SeqAlignPtr)(hist->assembly), thistype,
3221
(Pointer)(hist),(Pointer PNTR)&(hist->assembly),
3222
in_scope, check_seq, OBJ_SEQHIST_ALIGN);
3231
static Boolean NEAR GatherBioseqFunc (InternalGCCPtr gccp, BioseqPtr bsp,
3232
Pointer parent, Uint2 parenttype, SeqEntryPtr prev,
3233
Pointer PNTR prevlink, SeqEntryPtr curr, Boolean in_scope)
3235
GatherContextPtr gcp;
3237
Boolean takeit, in_range=TRUE, rev, free_seg, trunc_l, trunc_r;
3238
Int2 LocateItem = 0, segctr, first_seg, last_seg;
3239
Pointer LocateData = NULL;
3241
SeqLocPtr head, slp, target=NULL, tslp, segloc;
3242
SeqLocPtr targets[2];
3243
Int4 offset, toffset, seglen, tlen;
3245
Uint1 thistype, segtype;
3247
Boolean match_target = TRUE, do_seg, is_delta;
3249
Pointer dataptr; /* used for OBJ_BIOSEQ_SEG and OBJ_BIOSEQ_DELTA */
3255
gsp = &(gccp->scope);
3259
if (gsp->ignore[OBJ_BIOSEQ])
3261
else if ((takeit) && (gsp->target != NULL))
3263
if (bsp != gccp->bsp)
3267
gccp->itemIDs[OBJ_BIOSEQ]++;
3268
gcp->itemID = gccp->itemIDs[OBJ_BIOSEQ];
3269
if (gccp->locatetype == OBJ_BIOSEQ)
3271
LocateItem = gccp->locateID;
3272
LocateData = gccp->locatePtr;
3273
if (LocateItem == gccp->itemIDs[OBJ_BIOSEQ])
3275
if (LocateData == (Pointer)bsp)
3279
thistype = OBJ_BIOSEQ;
3280
gcp->thistype = thistype;
3281
gcp->thisitem = (Pointer)bsp;
3282
GatherAddToStack(gcp);
3284
if (gsp->target != NULL)
3286
match_target = FALSE;
3287
vn.choice = SEQLOC_WHOLE;
3288
vn.data.ptrvalue = SeqIdFindBest (bsp->id, 0);
3290
targets[0] = gsp->target;
3291
if (gccp->segloc != NULL)
3294
targets[1] = gccp->segloc;
3296
for (j =0; !match_target && j<numcheck; j++)
3298
if(SeqLocOffset(targets[j], &vn, &(gcp->extremes), gsp->offset))
3299
match_target = TRUE;
3306
gcp->previtem = prev;
3307
gcp->prevtype = OBJ_SEQENTRY;
3308
gcp->parentitem = parent;
3309
gcp->parenttype = parenttype;
3310
gcp->thistype = thistype;
3311
gcp->thisitem = (Pointer)bsp;
3312
gcp->prevlink = prevlink;
3314
/*if (gsp->target != NULL)
3317
vn.choice = SEQLOC_WHOLE;
3318
vn.data.ptrvalue = bsp->id;
3320
targets[0] = gsp->target;
3321
if (gccp->segloc != NULL)
3324
targets[1] = gccp->segloc;
3326
for (j =0; !takeit && j<numcheck; j++)
3328
if(SeqLocOffset(targets[j], &vn, &(gcp->extremes), gsp->offset))
3332
takeit = match_target;
3336
if (! (*(gccp->userfunc))(gcp))
3338
if (LocateItem) return FALSE;
3339
if (LocateData != NULL) return FALSE;
3345
if ((bsp->repr == Seq_repr_map) && (! gsp->ignore[OBJ_BIOSEQ_MAPFEAT]))
3347
if (! GatherSeqFeat(gccp, (SeqFeatPtr)(bsp->seq_ext), thistype, (Pointer)bsp, &(bsp->seq_ext), in_scope, OBJ_BIOSEQ_MAPFEAT))
3351
do_seg = FALSE; /* assume no pointer processing */
3353
if (! gsp->ignore[OBJ_BIOSEQ_SEG])
3355
if ((bsp->repr == Seq_repr_seg) ||
3356
(bsp->repr == Seq_repr_ref))
3360
segtype = OBJ_BIOSEQ_SEG;
3364
if (! gsp->ignore[OBJ_BIOSEQ_DELTA])
3366
if (bsp->repr == Seq_repr_delta)
3370
segtype = OBJ_BIOSEQ_DELTA;
3374
if (do_seg) /* process segment, ref, delta sequence .ext */
3376
if (bsp->repr == Seq_repr_seg)
3379
vn.choice = SEQLOC_MIX;
3380
vn.data.ptrvalue = bsp->seq_ext;
3383
else if (bsp->repr == Seq_repr_ref)
3384
head = (SeqLocPtr)(bsp->seq_ext);
3387
dsp = (DeltaSeqPtr)(bsp->seq_ext); /* real data is here */
3388
head = DeltaSeqsToSeqLocs(dsp); /* this for mapping only */
3397
rdp = &(gcp->extremes);
3399
if (gsp->target != NULL) /* may have to map */
3401
if (gccp->segloc != NULL)
3403
segloc = gccp->segloc;
3404
first_seg = gccp->first_seg;
3405
last_seg = gccp->last_seg;
3409
segloc = SeqLocCopyPart(head, SeqLocStart(gsp->target),
3410
SeqLocStop(gsp->target), SeqLocStrand(gsp->target),
3411
TRUE, &(first_seg), &(last_seg));
3415
toffset = SeqLocStart(gsp->target); /* partial first seg */
3420
if ((toffset + SeqLocLen(gsp->target)) < BioseqGetLen(bsp))
3425
tlen = SeqLocLen(segloc);
3430
last_seg = first_seg;
3437
if (gccp->locatetype == segtype)
3439
LocateItem = gccp->locateID;
3440
LocateData = gccp->locatePtr;
3443
gcp->previtem = NULL;
3445
gcp->parentitem = (Pointer)bsp;
3446
gcp->parenttype = thistype;
3447
gcp->thistype = segtype;
3448
gcp->prevlink = (Pointer PNTR)&(bsp->seq_ext);
3449
offset = gsp->offset;
3453
rdp->l_trunc = FALSE;
3454
rdp->r_trunc = FALSE;
3455
while ((slp = SeqLocFindNext(head, slp)) != NULL)
3457
if ((is_delta) && (segctr)) /* not first one */
3459
dsp = dsp->next; /* move up dsp */
3461
ErrPostEx(SEV_FATAL,0,0,"GatherDeltaSeq: dsp is NULL");
3464
seglen = SeqLocLen (slp);
3467
dataptr = (Pointer)dsp;
3469
dataptr = (Pointer)slp;
3471
gccp->itemIDs[segtype]++;
3472
if (gccp->locatetype == segtype)
3474
if (LocateItem == gccp->itemIDs[segtype])
3476
if (LocateData == dataptr)
3482
if (segloc != NULL) /* adjust to target? */
3484
if ((first_seg > segctr) || (last_seg < segctr))
3489
tslp = SeqLocFindNext(segloc, tslp);
3491
rdp->l_trunc = FALSE;
3492
rdp->r_trunc = FALSE;
3494
if (segctr == first_seg)
3496
offset = gsp->offset; /* allow for partial */
3500
rdp->l_trunc = TRUE;
3505
rdp->l_trunc = TRUE;
3508
else if (segctr == last_seg)
3513
rdp->r_trunc = TRUE;
3518
rdp->r_trunc = TRUE;
3522
seglen = SeqLocLen(tslp);
3526
rdp->right = offset + tlen - 1;
3527
rdp->left = rdp->right - seglen + 1;
3532
rdp->right = offset + seglen - 1;
3534
rdp->strand = SeqLocStrand(tslp);
3541
rdp->right = offset + seglen - 1;
3542
rdp->strand = SeqLocStrand(slp);
3545
if (in_range) /* always in_range if no target */
3547
gcp->thisitem = dataptr;
3548
gcp->itemID = gccp->itemIDs[segtype];
3549
GatherAddToStack(gcp);
3552
if ((! (*(gccp->userfunc))(gcp)) || (LocateItem) ||
3553
(LocateData != NULL))
3563
gcp->prevlink = (Pointer PNTR)&(((ValNodePtr)(dataptr))->next);
3564
gcp->previtem = dataptr;
3565
gcp->prevtype = segtype;
3576
if(!GatherSeqHist(gccp, bsp->hist, thistype, (Pointer)bsp, (Pointer PNTR)&(bsp->hist), in_scope, match_target))
3579
if (! GatherSeqDescr(gccp, bsp->descr, thistype, (Pointer)bsp,
3580
(Pointer PNTR)&(bsp->descr), in_scope))
3583
if (! GatherSeqAnnot(gccp, bsp->annot, thistype, (Pointer)bsp,
3584
(Pointer PNTR)&(bsp->annot), in_scope))
3587
/* now send targeted features all at once regardless of packaging */
3588
if (gccp->useSeqMgrIndexes && bsp == gccp->bsp) {
3589
if (! ExploreSeqFeat (gccp, bsp, in_scope)) {
3599
static Boolean NEAR GatherBioseqSetFunc (InternalGCCPtr gccp, BioseqSetPtr bsp,
3600
Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope,
3601
Pointer PNTR prevlink, SeqEntryPtr curr)
3603
GatherContextPtr gcp;
3605
Boolean takeit=TRUE, tscope, checkscope;
3606
SeqEntryPtr sep, prevsep = NULL, scope = NULL;
3607
Int2 LocateItem = 0;
3608
Pointer LocateData = NULL;
3615
gsp = &(gccp->scope);
3617
if (gsp->ignore[OBJ_BIOSEQSET])
3619
else if (! in_scope)
3623
if ((scope != NULL) && (! in_scope))
3628
gccp->itemIDs[OBJ_BIOSEQSET]++;
3629
gcp->itemID = gccp->itemIDs[OBJ_BIOSEQSET];
3631
if (gccp->locatetype == OBJ_BIOSEQSET)
3633
if ((gccp->locateID == gccp->itemIDs[OBJ_BIOSEQSET]) ||
3634
((Pointer)bsp == gccp->locatePtr))
3637
LocateItem = gccp->locateID;
3638
LocateData = gccp->locatePtr;
3642
thistype = OBJ_BIOSEQSET;
3643
gcp->thistype = thistype;
3644
gcp->thisitem = (Pointer)bsp;
3645
GatherAddToStack(gcp);
3650
gcp->previtem = prev;
3651
gcp->prevtype = OBJ_SEQENTRY;
3652
gcp->parentitem = parent;
3653
gcp->parenttype = parenttype;
3654
gcp->prevlink = prevlink;
3657
if (! (*(gccp->userfunc))(gcp))
3659
if (LocateItem) return FALSE;
3660
if (LocateData != NULL) return FALSE;
3663
if (! GatherSeqDescr(gccp, bsp->descr, thistype, (Pointer)bsp,
3664
(Pointer PNTR)&(bsp->descr), in_scope))
3667
if (! GatherSeqAnnot(gccp, bsp->annot, thistype, (Pointer)bsp,
3668
(Pointer PNTR)&(bsp->annot), in_scope))
3672
prevlink = (Pointer PNTR)&(bsp->seq_set);
3673
for (sep = bsp->seq_set; sep != NULL; sep = sep->next)
3675
gcp->previtem = prevsep;
3676
gcp->prevtype = OBJ_SEQENTRY;
3677
gcp->parentitem = (Pointer)bsp;
3678
gcp->parenttype = thistype;
3679
gcp->prevlink = prevlink;
3689
if (! GatherSeqEntryFunc(sep, gccp, (Pointer)bsp, OBJ_BIOSEQSET, prevsep, tscope, prevlink))
3694
if (tscope == TRUE) /* just found it */
3696
checkscope = FALSE; /* don't look anymore */
3697
tscope = FALSE; /* the siblings not in scope */
3698
gsp->scope = NULL; /* no more to look */
3700
else if (gsp->scope == NULL) /* found lower down */
3708
prevlink = (Pointer PNTR)&(sep->next);
3711
gcp->indent--; /* reset to original indent level */
3715
static Boolean NEAR GatherSeqEntryFunc (SeqEntryPtr sep, InternalGCCPtr igccp,
3716
Pointer parent, Uint2 parenttype, SeqEntryPtr prev, Boolean in_scope,
3717
Pointer PNTR prevlink)
3724
if (! GatherBioseqFunc(igccp, (BioseqPtr)(sep->data.ptrvalue), parent, parenttype, prev, prevlink, sep, in_scope))
3729
if (! GatherBioseqSetFunc(igccp, (BioseqSetPtr)(sep->data.ptrvalue), parent, parenttype, prev, in_scope, prevlink, sep))
3736
static Boolean NEAR GatherSeqSubCit(InternalGCCPtr gccp, CitSubPtr csp,
3737
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
3739
GatherContextPtr gcp;
3741
Boolean doit = TRUE;
3742
Int2 LocateItem = 0;
3743
Pointer LocateData = NULL;
3745
if (csp == NULL) return TRUE;
3748
gsp = &(gccp->scope);
3750
if (gsp->ignore[OBJ_SEQSUB_CIT])
3753
gccp->itemIDs[OBJ_SEQSUB_CIT]++;
3755
if (gccp->locatetype == OBJ_SEQSUB_CIT)
3757
LocateItem = gccp->locateID;
3758
LocateData = gccp->locatePtr;
3759
if ((gccp->itemIDs[OBJ_SEQSUB_CIT] != LocateItem) &&
3760
(LocateData != (Pointer)csp))
3764
gcp->previtem = NULL;
3766
gcp->parentitem = tparent;
3767
gcp->parenttype = ttype;
3768
gcp->thisitem = (Pointer)csp;
3769
gcp->thistype = OBJ_SEQSUB_CIT;
3770
gcp->prevlink = prevlink;
3771
gcp->itemID = gccp->itemIDs[OBJ_SEQSUB_CIT];
3772
GatherAddToStack(gcp);
3777
if (! (*(gccp->userfunc))(gcp))
3779
if (LocateItem) return FALSE;
3780
if (LocateData) return FALSE;
3786
static Boolean NEAR GatherSeqSubContact(InternalGCCPtr gccp, ContactInfoPtr cip,
3787
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
3789
GatherContextPtr gcp;
3791
Int2 LocateItem = 0;
3792
Pointer LocateData = NULL;
3793
Boolean doit = TRUE;
3795
if (cip == NULL) return TRUE;
3798
gsp = &(gccp->scope);
3800
if (gsp->ignore[OBJ_SEQSUB_CONTACT])
3803
gccp->itemIDs[OBJ_SEQSUB_CONTACT]++;
3805
if (gccp->locatetype == OBJ_SEQSUB_CONTACT)
3807
LocateItem = gccp->locateID;
3808
LocateData = gccp->locatePtr;
3809
if ((gccp->itemIDs[OBJ_SEQSUB_CONTACT] != LocateItem) &&
3810
((Pointer)cip != LocateData))
3814
gcp->previtem = NULL;
3816
gcp->parentitem = tparent;
3817
gcp->parenttype = ttype;
3818
gcp->thisitem = (Pointer)cip;
3819
gcp->thistype = OBJ_SEQSUB_CONTACT;
3820
gcp->prevlink = prevlink;
3821
gcp->itemID = gccp->itemIDs[OBJ_SEQSUB_CONTACT];
3822
GatherAddToStack(gcp);
3826
if (! (*(gccp->userfunc))(gcp))
3828
if (LocateItem) return FALSE;
3829
if (LocateData != NULL) return FALSE;
3835
static Boolean NEAR GatherSubBlock(InternalGCCPtr gccp, SubmitBlockPtr sbp,
3836
Uint1 ttype, Pointer tparent, Pointer PNTR prevlink)
3838
GatherContextPtr gcp;
3840
Int2 LocateItem = 0;
3841
Pointer LocateData = NULL;
3842
Boolean doit = TRUE;
3844
if (sbp == NULL) return TRUE;
3847
gsp = &(gccp->scope);
3849
if (gsp->ignore[OBJ_SUBMIT_BLOCK])
3852
gccp->itemIDs[OBJ_SUBMIT_BLOCK]++;
3854
if (gccp->locatetype != 0) {
3856
if (gccp->locatetype == OBJ_SUBMIT_BLOCK)
3858
LocateItem = gccp->locateID;
3859
LocateData = gccp->locatePtr;
3860
if (gccp->itemIDs[OBJ_SUBMIT_BLOCK] == LocateItem)
3862
if (LocateData == (Pointer)sbp)
3867
gcp->previtem = NULL;
3869
gcp->parentitem = tparent;
3870
gcp->parenttype = ttype;
3871
gcp->thisitem = (Pointer)sbp;
3872
gcp->thistype = OBJ_SUBMIT_BLOCK;
3873
gcp->prevlink = prevlink;
3874
gcp->itemID = gccp->itemIDs[OBJ_SUBMIT_BLOCK];
3875
GatherAddToStack(gcp);
3879
if (! (*(gccp->userfunc))(gcp))
3881
if (LocateItem) return FALSE;
3882
if (LocateData != NULL) return FALSE;
3887
if (! GatherSeqSubContact(gccp, sbp->contact, OBJ_SUBMIT_BLOCK,
3888
(Pointer)sbp, (Pointer PNTR)&(sbp->contact)))
3891
if (! GatherSeqSubCit(gccp, sbp->cit, OBJ_SUBMIT_BLOCK,
3892
(Pointer)sbp, (Pointer PNTR)&(sbp->cit)))
3900
static Boolean NEAR GatherSeqSubmit (InternalGCCPtr gccp, SeqSubmitPtr ssp, Boolean in_scope)
3902
GatherContextPtr gcp;
3904
Boolean takeit=TRUE, tscope, checkscope;
3905
SeqEntryPtr sep, prevsep = NULL, scope = NULL;
3906
Int2 LocateItem = 0;
3907
Pointer LocateData = NULL;
3909
Pointer PNTR prevlink;
3915
gsp = &(gccp->scope);
3917
if (gsp->ignore[OBJ_SEQSUB])
3919
else if (! in_scope)
3923
if ((scope != NULL) && (! in_scope))
3928
gccp->itemIDs[OBJ_SEQSUB]++;
3929
gcp->itemID = gccp->itemIDs[OBJ_SEQSUB];
3931
if (gccp->locatetype == OBJ_SEQSUB)
3933
if ((gccp->locateID == gccp->itemIDs[OBJ_SEQSUB]) ||
3934
(gccp->locatePtr == (Pointer)ssp))
3937
LocateItem = gccp->locateID;
3938
LocateData = gccp->locatePtr;
3942
thistype = OBJ_SEQSUB;
3943
gcp->thistype = thistype;
3944
gcp->thisitem = (Pointer)ssp;
3945
GatherAddToStack(gcp);
3950
gcp->previtem = NULL;
3952
gcp->parentitem = NULL;
3953
gcp->parenttype = 0;
3954
gcp->thisitem = (Pointer)ssp;
3955
gcp->thistype = thistype;
3956
gcp->prevlink = NULL;
3959
if (! (*(gccp->userfunc))(gcp))
3961
if (LocateItem) return FALSE;
3962
if (LocateData != NULL) return FALSE;
3966
if (! GatherSubBlock(gccp, ssp->sub, thistype, (Pointer)ssp,
3967
(Pointer PNTR)&(ssp->sub)))
3971
prevlink = (Pointer PNTR)&(ssp->data);
3973
switch(ssp->datatype)
3975
case 1: /* Seq-entrys */
3977
for (sep = (SeqEntryPtr)(ssp->data); sep != NULL; sep = sep->next)
3979
gcp->previtem = prevsep;
3980
gcp->prevtype = OBJ_SEQENTRY;
3981
gcp->parentitem = (Pointer)ssp;
3982
gcp->parenttype = thistype;
3983
gcp->prevlink = prevlink;
3993
if (! GatherSeqEntryFunc(sep, gccp, (Pointer)ssp, OBJ_SEQSUB, prevsep, tscope, prevlink))
3998
if (tscope == TRUE) /* just found it */
4000
checkscope = FALSE; /* don't look anymore */
4001
tscope = FALSE; /* the siblings not in scope */
4002
gsp->scope = NULL; /* no more to look */
4004
else if (gsp->scope == NULL) /* found lower down */
4012
prevlink = (Pointer PNTR)&(sep->next);
4015
case 2: /* Seq-annots */
4016
if (! GatherSeqAnnot(gccp, (SeqAnnotPtr)(ssp->data), thistype,
4017
(Pointer)ssp,(Pointer PNTR)&(ssp->data), in_scope))
4021
case 3: /* SeqIds */
4022
if (! GatherSeqIds(gccp, (SeqIdPtr)(ssp->data), thistype,
4023
(Pointer)ssp,(Pointer PNTR)&(ssp->data)))
4030
gcp->indent--; /* reset to original indent level */
4034
/*****************************************************************************
4036
* GatherBioseqPartsFunc(gccp, top)
4037
* gets parts not contained in "top" for segmented entry
4039
*****************************************************************************/
4040
static Boolean NEAR GatherBioseqPartsFunc (InternalGCCPtr gccp, Pointer top)
4042
GatherContextPtr gcp;
4043
GatherScopePtr gsp, tgsp;
4044
GatherScope scopebuf;
4045
SeqLocPtr slp, head;
4055
gsp = &(gccp->scope);
4057
if (gsp->seglevels <= gsp->currlevel)
4061
head = gccp->segloc;
4064
MemCopy(tgsp, gsp, sizeof(GatherScope));
4068
tgsp->ignore [OBJ_BIOSEQ] = TRUE;
4072
retval = FALSE; /*??*/
4074
while ((slp = SeqLocFindNext(head, slp)) != NULL)
4078
sip = SeqLocId(slp);
4079
tbsp = BioseqLockById(sip);
4080
len = SeqLocLen(slp);
4082
if (len >= 0 && tbsp != NULL)
4085
if ((gsp->stop_on_annot) && (ctr < gccp->segcnt))
4087
if (gccp->found_annot[ctr]) /* already found annot here */
4094
if (! ObjMgrIsChild(top, (Pointer)tbsp)) /* in set we just did? */
4096
sep = SeqEntryFind(sip);
4097
retval = GatherSeqEntry(sep, gcp->userdata, gccp->userfunc, tgsp);
4103
else if (tbsp != NULL)
4106
tgsp->offset += len;
4113
static Boolean WholeLocOnBioseq (BioseqPtr bsp, SeqLocPtr slp)
4119
if (bsp == NULL || slp == NULL) return FALSE;
4121
sip = SeqLocId (slp);
4122
if (sip == NULL) return FALSE;
4123
if (! SeqIdIn (sip, bsp->id)) return FALSE;
4125
if (slp->choice == SEQLOC_WHOLE) return TRUE;
4126
if (slp->choice == SEQLOC_INT) {
4127
sintp = (SeqIntPtr) slp->data.ptrvalue;
4128
if (sintp != NULL &&
4130
sintp->to == bsp->length - 1) return TRUE;
4136
static Boolean NEAR IGCCBuild (InternalGCCPtr ip, ObjMgrDataPtr omdp, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
4138
Boolean in_scope = TRUE;
4140
BioseqPtr bsp = NULL;
4145
ObjMgrDataPtr newomdp = NULL;
4146
Boolean reload_from_cache = TRUE; /* default behavior */
4148
SeqLocPtr loc = NULL;
4151
if ((omdp == NULL) || (userfunc == NULL)) return FALSE;
4153
MemSet((Pointer)(ip), 0, sizeof(InternalGCC));
4156
if (scope != NULL) /* check for turning off reload from cache */
4158
if (scope->do_not_reload_from_cache)
4159
reload_from_cache = FALSE;
4162
if ((omdp->tempload == TL_CACHED) && (reload_from_cache)) /* must reload from cache */
4164
newomdp = BioseqReload(omdp, TRUE);
4165
if (newomdp == NULL)
4167
ErrPostEx(SEV_ERROR,0,0,"IGCCBuild: Couldn't reload data from cache.");
4170
ip->reloaded = TRUE;
4175
if(scope->scope != NULL)
4177
ErrPostEx(SEV_ERROR,0,0,"IGCCBuild: Scope invalid, data reloaded from cache.");
4178
ObjMgrLock(omdp->datatype, omdp->dataptr, FALSE);
4184
ObjMgrLock(omdp->datatype, omdp->dataptr, TRUE); /* just lock it */
4187
ip->gc.userdata = userdata;
4188
ip->userfunc = userfunc;
4190
MemCopy(&(ip->scope), scope, sizeof(GatherScope));
4191
ip->gc.entityID = omdp->EntityID;
4192
ip->gc.tempload = omdp->tempload;
4193
ip->gc.seglevel = ip->scope.currlevel;
4194
ip->gc.igccp = (Pointer)ip;
4195
if (ObjMgrCheckHold())
4198
if (ip->scope.target != NULL)
4200
sip = SeqLocId(ip->scope.target);
4202
/* first check if target in the SeqEntry -- necessary if multiple versions with same id */
4203
if ((omdp->choicetype == OBJ_SEQENTRY && omdp->choice != NULL) ||
4204
(scope != NULL && scope->scope != NULL))
4206
oldsep = SeqEntryGetScope(); /* save any current scope */
4207
if (omdp->choicetype == OBJ_SEQENTRY) {
4208
SeqEntrySetScope(omdp->choice);
4210
SeqEntrySetScope(scope->scope);
4212
bsp = BioseqFindCore(sip);
4213
if (bsp != NULL) /* yes it is in here */
4214
bsp = BioseqLockById(sip);
4215
SeqEntrySetScope(oldsep);
4218
if (bsp == NULL) /* out of scope? */
4219
bsp = BioseqLockById(sip);/* try again */
4222
if (SeqLocStrand(ip->scope.target) == Seq_strand_minus)
4224
if ((ip->scope.seglevels > ip->scope.currlevel)
4225
&& (bsp != NULL)) /* get seg parts? */
4229
if (bsp->repr == Seq_repr_seg)
4231
fake.choice = SEQLOC_MIX;
4233
fake.data.ptrvalue = bsp->seq_ext;
4235
} else if (bsp->repr == Seq_repr_delta && bsp->seq_ext_type == 4) {
4236
dsp = (DeltaSeqPtr) bsp->seq_ext;
4237
loc = DeltaSeqsToSeqLocs (dsp);
4240
else if (bsp->repr == Seq_repr_ref)
4241
slp = (SeqLocPtr)(bsp->seq_ext);
4243
ip->segloc = SeqLocCopyPart(slp, SeqLocStart(ip->scope.target),
4244
SeqLocStop(ip->scope.target), SeqLocStrand(ip->scope.target),
4245
TRUE, &(ip->first_seg), &(ip->last_seg));
4247
if (ip->scope.stop_on_annot)
4250
slp = NULL; ctr = 0;
4251
while ((slp = SeqLocFindNext(ip->segloc, slp)) != NULL)
4256
ip->seglens = MemNew((size_t)(sizeof(Int4) * ctr));
4257
ip->found_annot = MemNew((size_t)(sizeof(Boolean) * ctr));
4259
slp = NULL; ctr = 0;
4260
while ((slp = SeqLocFindNext(ip->segloc, slp)) != NULL)
4262
ip->seglens[ctr] = SeqLocLen(slp);
4263
if (ip->seglens[ctr] < 0)
4264
ip->seglens[ctr] = 0;
4269
loc = SeqLocFree (loc);
4272
/* if targeted gather, try to use feature indexing for speed */
4273
if (bsp != NULL && bsp->repr == Seq_repr_raw &&
4274
SeqMgrGetParentOfPart (bsp, NULL) == NULL &&
4275
ip->segloc == NULL && ip->scope.useSeqMgrIndexes &&
4276
(ip->scope.get_feats_location || ip->scope.get_feats_product) &&
4277
(! (ip->scope.ignore [OBJ_SEQFEAT]))) {
4279
/* target must be whole or full length interval on bioseq */
4280
if (! WholeLocOnBioseq (bsp, ip->scope.target)) return TRUE;
4282
entityID = ObjMgrGetEntityIDForPointer (bsp);
4284
/* index features if not already done */
4285
if (SeqMgrFeaturesAreIndexed (entityID) == 0) {
4286
SeqMgrIndexFeatures (entityID, NULL);
4289
if (SeqMgrFeaturesAreIndexed (entityID) != 0) {
4290
ip->useSeqMgrIndexes = TRUE;
4298
NLM_EXTERN AlignDataPtr FreeAlignData(AlignDataPtr adp)
4301
AlignRangePtr arp, arp_next;
4308
arp_next = arp->next;
4322
static Boolean IGCCclear(InternalGCCPtr ip)
4324
if (ip == NULL) return TRUE;
4326
BioseqUnlock(ip->bsp);
4327
ObjMgrLock(ip->omdp->datatype, ip->omdp->dataptr, FALSE); /* unlock the entity */
4329
MemFree(ip->gc.rdp);
4330
FreeAlignData(ip->gc.adp);
4332
SeqLocFree(ip->segloc);
4333
MemFree(ip->seglens);
4334
MemFree(ip->found_annot);
4335
MemFree(ip->gc.gatherstack);
4336
MemFree(ip->gc.extra_loc);
4341
static void GatherEntityFunc (ObjMgrDataPtr omdp, InternalGCCPtr gccp, Boolean in_scope)
4347
ptr = omdp->dataptr;
4349
switch (omdp->choicetype)
4352
GatherSeqEntryFunc(vnp, gccp, NULL, 0, NULL, in_scope, NULL);
4356
switch (omdp->datatype)
4359
GatherBioseqFunc(gccp, (BioseqPtr)ptr, NULL, 0, NULL, NULL,
4364
GatherBioseqSetFunc(gccp, (BioseqSetPtr)ptr, NULL, 0, NULL,
4365
in_scope, NULL, NULL);
4369
GatherSeqDescr(gccp, (ValNodePtr)ptr, 0, NULL, NULL,in_scope);
4373
GatherSeqAnnot(gccp, (SeqAnnotPtr)ptr, 0,NULL,NULL, in_scope);
4376
case OBJ_ANNOTDESC: /* NOT SUPPORTED YET */
4380
GatherSeqFeat(gccp, (SeqFeatPtr)ptr, 0, NULL, NULL, in_scope, OBJ_SEQFEAT);
4384
GatherSeqAlign(gccp, (SeqAlignPtr)ptr, 0, NULL, NULL, in_scope, TRUE, OBJ_SEQALIGN);
4387
case OBJ_SEQHIST_ALIGN:
4388
GatherSeqAlign(gccp, (SeqAlignPtr)ptr, 0, NULL, NULL, in_scope, TRUE, OBJ_SEQHIST_ALIGN);
4392
GatherSeqGraph(gccp, (SeqGraphPtr)ptr, 0, NULL, NULL, in_scope);
4396
GatherSeqSubmit (gccp, (SeqSubmitPtr) ptr, in_scope);
4399
case OBJ_SUBMIT_BLOCK:
4400
GatherSubBlock(gccp, (SubmitBlockPtr)ptr,0,NULL,NULL);
4403
case OBJ_SEQSUB_CONTACT:
4404
GatherSeqSubContact(gccp, (ContactInfoPtr)ptr,0, NULL, NULL);
4407
case OBJ_BIOSEQ_MAPFEAT: /* NOT SUPPORTED YET */
4410
case OBJ_BIOSEQ_SEG: /* NOT SEPARATELY SUPPORTED */
4413
case OBJ_SEQHIST: /* NOT SEPARATELY SUPPORTED */
4414
GatherSeqHist(gccp, (SeqHistPtr)ptr, 0, NULL, NULL, in_scope, TRUE);
4418
GatherPub(gccp, (ValNodePtr)ptr, 0, 0, NULL,NULL, in_scope);
4421
case OBJ_SEQFEAT_CIT: /* NOT SEPARATELY SUPPORTED */
4424
case OBJ_SEQSUB_CIT:
4425
GatherSeqSubCit(gccp, (CitSubPtr)ptr,0, NULL, NULL);
4429
GatherPubSet(gccp, (ValNodePtr)ptr, 0, 0, NULL,NULL, in_scope);
4433
GatherSeqIds(gccp, (SeqIdPtr)ptr,0,NULL,NULL);
4443
/*****************************************************************************
4445
* FocusSeqEntry (sep, scope)
4446
* zeros out all fields in scope
4447
* sets scope.target, .scope, .propagate_desciptors appropriately for
4450
* target is the bioseq
4451
* entityID is the containing set if any
4452
* scope.scope is null
4455
* entityID is the containing set if any
4456
* scope.scope is sep
4457
* propagate_descriptors is TRUE
4459
* return of FOCUS_INITIALIZED means scope is initialized
4460
* return of FOCUS_NOT_NEEDED means send NULL for GatherScope.. you
4461
* don't need to scope for this SeqEntryPtr
4462
* return of FOCUS_ERROR means it could not be initialized
4464
*****************************************************************************/
4465
NLM_EXTERN Int2 LIBCALL FocusSeqEntry (SeqEntryPtr sep, GatherScopePtr scope)
4467
Int2 retval = FOCUS_ERROR;
4474
if ((sep == NULL) || (scope == NULL))
4477
MemSet((Pointer)scope, 0, sizeof(GatherScope));
4479
omp = ObjMgrReadLock();
4480
omdp = ObjMgrFindByData(omp, sep->data.ptrvalue);
4481
if (omdp == NULL) goto erret;
4483
if (omdp->parentptr == NULL)
4485
retval = FOCUS_NOT_NEEDED;
4491
slp = ValNodeNew(NULL);
4492
slp->choice = SEQLOC_WHOLE;
4493
bsp = (BioseqPtr) sep->data.ptrvalue;
4494
sip = SeqIdDup (SeqIdFindBest (bsp->id, 0));
4495
slp->data.ptrvalue = sip;
4496
scope->target = slp;
4501
omdp = ObjMgrFindTop(omp, omdp);
4502
if (omdp->tempload == TL_CACHED)
4504
ErrPostEx(SEV_ERROR, 0,0, "FocusSeqEntry: Scope to BioseqSet on Cached record");
4508
retval = FOCUS_INITIALIZED;
4514
/*****************************************************************************
4516
* GatherSeqEntry (sep, userdata, userproc, scope)
4518
*****************************************************************************/
4519
NLM_EXTERN Boolean LIBCALL GatherSeqEntry (SeqEntryPtr sep, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
4523
if ((sep == NULL) || (userfunc == NULL)) return FALSE;
4525
entityID = ObjMgrGetEntityIDForChoice(sep);
4527
return GatherEntity (entityID, userdata, userfunc, scope);
4530
/*****************************************************************************
4532
* GatherEntity (entityID, userdata, userproc, scope)
4534
*****************************************************************************/
4535
NLM_EXTERN Boolean LIBCALL GatherEntity (Uint2 entityID, Pointer userdata, GatherItemProc userfunc, GatherScopePtr scope)
4540
Boolean reloaded_from_cache = FALSE;
4543
if ((! entityID) || (userfunc == NULL)) return FALSE;
4545
omp = ObjMgrReadLock();
4546
omdp = ObjMgrGetDataStruct (omp, entityID);
4549
if (omdp == NULL) return FALSE;
4551
if (! IGCCBuild(&igcc, omdp, userdata, userfunc, scope))
4554
omdp = igcc.omdp; /* could have been reloaded */
4555
if (igcc.scope.scope != NULL)
4557
in_scope = ObjMgrIsChild((igcc.scope.scope->data.ptrvalue), (omdp->dataptr));
4559
else /* no scope set.. all in scope */
4562
GatherEntityFunc(omdp, &igcc, in_scope);
4564
if ((igcc.segloc != NULL) && (igcc.scope.scope == NULL)) /* get segs first */
4565
GatherBioseqPartsFunc(&igcc, omdp->dataptr);
4568
return IGCCclear(&igcc);
4570
/**************************************************************************
4572
* callback used by GatherItemIDByData
4574
***************************************************************************/
4575
static Boolean GatherItemByDataProc (GatherContextPtr gcp)
4579
ptr = (Uint2Ptr)(gcp->userdata);
4585
/*****************************************************************************
4587
* GatherItemIDByData (entityID, itemtype, dataptr)
4588
* Looks in entityID for an element of itemtype that matches the pointer
4590
* if found, returns the itemID
4592
* itemtype is as defined in objmgr.h for OBJ_
4594
*****************************************************************************/
4595
NLM_EXTERN Uint2 LIBCALL GatherItemIDByData (Uint2 entityID, Uint2 itemtype, Pointer dataptr)
4599
GatherData(entityID, dataptr, itemtype, (Pointer)(&itemID), GatherItemByDataProc);
4604
/*****************************************************************************
4606
* GatherData (entityID, itemID, itemtype, userdata, userproc)
4607
* Get an item by entityID, itemtype, and a Pointer of itemtype
4608
* GatherContext.seglevel and GatherContext.propagated will not be
4609
* set on the callback.
4611
* Sets in_scope to FALSE so that the callback is not called
4612
* Scope is NULL, so in_scope is never TRUE
4613
* Sets ignore TRUE for everything not needed to find item
4614
* Sets locatetype and locateID, which are checked in the traversal
4616
*****************************************************************************/
4617
NLM_EXTERN Boolean LIBCALL GatherData (Uint2 entityID, Pointer dataptr, Uint2 itemtype,
4618
Pointer userdata, GatherItemProc userfunc)
4620
return GatherItemFunc (entityID, 0, itemtype, userdata, userfunc, dataptr, FALSE);
4623
/*****************************************************************************
4625
* GatherItem (entityID, itemID, itemtype, userdata, userproc)
4626
* Get an item by entityID, itemID, itemtype
4627
* GatherContext.seglevel and GatherContext.propagated will not be
4628
* set on the callback.
4630
* Sets in_scope to FALSE so that the callback is not called
4631
* Scope is NULL, so in_scope is never TRUE
4632
* Sets ignore TRUE for everything not needed to find item
4633
* Sets locatetype and locateID, which are checked in the traversal
4635
*****************************************************************************/
4636
NLM_EXTERN Boolean LIBCALL GatherItem (Uint2 entityID, Uint2 itemID, Uint2 itemtype,
4637
Pointer userdata, GatherItemProc userfunc)
4639
return GatherItemFunc (entityID, itemID, itemtype, userdata, userfunc, NULL, FALSE);
4642
/*****************************************************************************
4644
* GatherItemFunc (entityID, itemID, itemtype, userdata, userproc, dataptr)
4645
* Get an item by entityID, itemID, itemtype if dataptr is NULL
4646
* else it matches entityID, itemtype, dataptr (of type itemtype)
4647
* GatherContext.seglevel and GatherContext.propagated will not be
4648
* set on the callback.
4650
* Sets in_scope to FALSE so that the callback is not called
4651
* Scope is NULL, so in_scope is never TRUE
4652
* Sets ignore TRUE for everything not needed to find item
4653
* Sets locatetype and locateID, which are checked in the traversal
4655
*****************************************************************************/
4656
static Boolean NEAR GatherItemFunc (Uint2 entityID, Uint2 itemID, Uint2 itemtype,
4657
Pointer userdata, GatherItemProc userfunc, Pointer dataptr,
4658
Boolean do_not_reload_from_cache)
4666
if (userfunc == NULL) return FALSE;
4668
if (itemtype >= OBJ_MAX) return FALSE;
4670
omp = ObjMgrReadLock();
4671
omdp = ObjMgrGetDataStruct(omp, entityID);
4674
if (omdp == NULL) return FALSE;
4676
MemSet((Pointer)(&gs), 0, sizeof(GatherScope));
4677
gs.do_not_reload_from_cache = do_not_reload_from_cache;
4678
MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)((OBJ_MAX)*sizeof(Boolean)));
4679
gs.ignore[itemtype] = FALSE;
4680
switch (itemtype) /* add higher levels if necessary */
4682
case OBJ_SEQFEAT_CIT:
4683
gs.ignore[OBJ_SEQFEAT] = FALSE;
4684
gs.ignore[OBJ_PUB_SET] = FALSE;
4686
gs.ignore[OBJ_SEQANNOT] = FALSE;
4689
gs.ignore[OBJ_SEQANNOT] = FALSE;
4691
case OBJ_SEQHIST_ALIGN:
4692
gs.ignore[OBJ_SEQHIST] = FALSE;
4695
gs.ignore[OBJ_SEQANNOT] = FALSE;
4697
case OBJ_SEQSUB_CONTACT:
4698
case OBJ_SEQSUB_CIT:
4699
gs.ignore[OBJ_SUBMIT_BLOCK] = FALSE;
4700
case OBJ_SUBMIT_BLOCK:
4701
gs.ignore[OBJ_SEQSUB] = FALSE;
4705
if (! IGCCBuild(&igcc, omdp, userdata, userfunc, &gs))
4708
omdp = igcc.omdp; /* could have been reloaded */
4710
igcc.locatetype = (Uint1)itemtype;
4711
igcc.locateID = itemID;
4712
igcc.locatePtr = dataptr;
4715
GatherEntityFunc(omdp, &igcc, FALSE);
4717
return IGCCclear(&igcc);
4720
typedef struct gatherdatastruct {
4721
OMProcControlPtr ompcp;
4725
static Boolean GatherDataProc (GatherContextPtr gcp)
4727
OMProcControlPtr ompcp;
4730
gdsp = (GDSPtr)(gcp->userdata);
4731
ompcp = gdsp->ompcp;
4733
ompcp->input_data = gcp->thisitem;
4735
switch (gcp->thistype)
4739
if (gcp->sep != NULL)
4741
ompcp->input_choice = gcp->sep;
4742
ompcp->input_choicetype = OBJ_SEQENTRY;
4748
gdsp->succeeded = TRUE;
4752
static Boolean ReplaceDataProc (GatherContextPtr gcp)
4757
OMProcControlPtr ompcp;
4758
Pointer oldptr, newptr;
4760
SeqEntryPtr sep=NULL;
4763
gdsp = (GDSPtr)(gcp->userdata);
4764
ompcp = gdsp->ompcp;
4765
newptr = ompcp->output_data;
4767
oldptr = gcp->thisitem;
4769
omp = ObjMgrReadLock();
4770
omtp = ObjMgrTypeFind(omp, gcp->thistype, NULL, NULL);
4775
ErrPostEx(SEV_ERROR,0,0,"ReplaceDataProc: can't find type [%d]", (int)gcp->thistype);
4779
if (! GatherOverWrite(oldptr, newptr, gcp->thistype)) /* overwrite the old data object */
4782
if (ompcp->output_entityID) /* remove with objmgr? */
4784
omp = ObjMgrReadLock();
4785
omdp = ObjMgrGetDataStruct (omp, ompcp->output_entityID);
4790
if ((gcp->thistype == OBJ_BIOSEQ) || (gcp->thistype == OBJ_BIOSEQSET))
4792
if (ObjMgrWholeEntity(omdp, ompcp->output_itemID, ompcp->output_itemtype))
4793
ObjMgrDelete(ompcp->output_itemtype, ompcp->output_data);
4800
(*(omtp->freefunc))(ompcp->output_data);
4802
gdsp->succeeded = TRUE;
4807
static Boolean DetachDataProc (GatherContextPtr gcp)
4809
OMProcControlPtr ompcp;
4810
Pointer next = NULL, ptr;
4813
gdsp = (GDSPtr)(gcp->userdata);
4814
ompcp = gdsp->ompcp;
4816
ptr = gcp->thisitem;
4817
ompcp->input_data = ptr;
4819
switch (gcp->thistype)
4823
if (gcp->sep != NULL)
4825
ompcp->input_choice = gcp->sep;
4826
ompcp->input_choicetype = OBJ_SEQENTRY;
4827
next = gcp->sep->next;
4828
gcp->sep->next = NULL;
4832
case OBJ_BIOSEQ_SEG:
4834
case OBJ_SEQFEAT_CIT:
4839
next = (Pointer)(((ValNodePtr)(ptr))->next);
4840
(((ValNodePtr)(ptr))->next) = NULL;
4842
case OBJ_BIOSEQ_MAPFEAT:
4844
next = (Pointer)(((SeqFeatPtr)(ptr))->next);
4845
(((SeqFeatPtr)(ptr))->next) = NULL;
4848
next = (Pointer)(((SeqAnnotPtr)(ptr))->next);
4849
(((SeqAnnotPtr)(ptr))->next) = NULL;
4852
case OBJ_SEQHIST_ALIGN:
4853
next = (Pointer)(((SeqAlignPtr)(ptr))->next);
4854
(((SeqAlignPtr)(ptr))->next) = NULL;
4857
next = (Pointer)(((SeqGraphPtr)(ptr))->next);
4858
(((SeqGraphPtr)(ptr))->next) = NULL;
4863
if (ompcp->whole_entity) /* nothing to detach from */
4866
if (gcp->prevlink != NULL)
4867
*(gcp->prevlink) = next;
4869
ObjMgrDetach(gcp->thistype, ptr);
4871
gdsp->succeeded = TRUE;
4876
static void AddAnAnnot(SeqAnnotPtr PNTR head, Pointer ptr)
4878
SeqAnnotPtr prev, sap;
4880
if (head == NULL) return;
4881
sap = (SeqAnnotPtr)ptr;
4889
for (prev = (*head); prev->next != NULL; prev = prev->next)
4896
static Boolean AddToSeqAnnot (SeqAnnotPtr sap, Int2 the_type, Pointer addptr)
4901
Pointer PNTR prevlink = NULL;
4903
if (sap == NULL) return FALSE;
4906
sap->type = (Uint1)the_type;
4908
if (sap->type != (Uint1)the_type)
4911
if (sap->data == NULL)
4912
prevlink = &(sap->data);
4917
case 1: /* feature table */
4918
for (sfp = (SeqFeatPtr)(sap->data); sfp->next != NULL; sfp = sfp->next)
4920
prevlink = (Pointer PNTR)&(sfp->next);
4922
case 2: /* alignments */
4923
for (salp = (SeqAlignPtr)(sap->data); salp->next != NULL; salp = salp->next)
4925
prevlink = (Pointer PNTR)&(salp->next);
4928
for (sgp = (SeqGraphPtr)(sap->data); sgp->next != NULL; sgp = sgp->next)
4930
prevlink = (Pointer PNTR)&(sgp->next);
4934
if (prevlink != NULL)
4940
static void AddToAnnot(SeqAnnotPtr PNTR head, Int2 the_type, Pointer addptr)
4942
SeqAnnotPtr sap, prev=NULL;
4944
if (head == NULL) return;
4946
for (sap = *head; sap != NULL; sap = sap->next)
4948
if (sap->type == the_type)
4955
sap = SeqAnnotNew();
4956
sap->type = (Uint1)the_type;
4963
AddToSeqAnnot(sap, the_type, addptr);
4968
static ValNodePtr PubFromDescr(ValNodePtr desc)
4970
ValNodePtr vnp2, vnp;
4973
if (desc->choice != Seq_descr_pub)
4976
pdp = (PubdescPtr)(desc->data.ptrvalue);
4982
if (vnp == NULL) return vnp;
4984
if (vnp->next != NULL)
4987
vnp = ValNodeNew(NULL);
4988
vnp->choice = PUB_Equiv;
4989
vnp->data.ptrvalue = vnp2;
4995
static ValNodePtr DescrFromPub(ValNodePtr pub)
5001
if (pub->choice == PUB_Equiv)
5003
vnp = (ValNodePtr)(pub->data.ptrvalue);
5008
vnp = ValNodeNew(NULL);
5009
vnp->choice = Seq_descr_pub;
5010
vnp->data.ptrvalue = (Pointer)pdp;
5014
static Boolean AttachDataProc (GatherContextPtr gcp)
5016
OMProcControlPtr ompcp;
5017
Pointer ptr, newptr;
5018
Uint2 into, newtype;
5019
Boolean no_good = FALSE, into_seqentry = FALSE;
5021
ObjMgrDataPtr omdp=NULL;
5033
gdsp = (GDSPtr)(gcp->userdata);
5034
ompcp = gdsp->ompcp;
5036
ptr = gcp->thisitem; /* insert before or into this */
5037
ompcp->input_data = ptr;
5039
into = gcp->thistype;
5040
newtype = ompcp->output_itemtype;
5041
newptr = ompcp->output_data;
5043
omp = ObjMgrWriteLock();
5044
omdp = ObjMgrFindByData(omp, newptr);
5050
if (gcp->sep != NULL)
5052
ompcp->input_choice = gcp->sep;
5053
ompcp->input_choicetype = OBJ_SEQENTRY;
5054
into_seqentry = TRUE;
5064
ssp = (SeqSubmitPtr)(ptr);
5071
ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
5074
if (ssp->datatype == 0)
5076
if (ssp->datatype != 1)
5081
if (omdp->choice == NULL)
5083
omdp->choice = ValNodeNew(NULL);
5084
omdp->choicetype = OBJ_SEQENTRY;
5085
omdp->choice->data.ptrvalue = newptr;
5086
if (newtype == OBJ_BIOSEQ)
5087
omdp->choice->choice = 1;
5089
omdp->choice->choice = 2;
5091
ValNodeLink((ValNodePtr PNTR)&(ssp->data), omdp->choice);
5092
ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
5095
vnp = (ValNodePtr)newptr;
5097
if (vnp->choice == PUB_Sub)
5099
if (ssp->sub == NULL)
5100
ssp->sub = SubmitBlockNew();
5101
if (ssp->sub->cit == NULL)
5103
ssp->sub->cit = (CitSubPtr)(vnp->data.ptrvalue);
5110
if (ssp->datatype == 0)
5112
if (ssp->datatype != 1)
5117
ValNodeLink((ValNodePtr PNTR)&(ssp->data), omdp->choice);
5118
ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
5121
if (ssp->datatype == 0)
5123
if (ssp->datatype != 2)
5128
AddAnAnnot((SeqAnnotPtr PNTR)&(ssp->data), newptr);
5131
if (ssp->datatype == 0)
5133
if (ssp->datatype != 2)
5138
AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 1, newptr);
5141
if (ssp->datatype == 0)
5143
if (ssp->datatype != 2)
5148
AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 2, newptr);
5151
if (ssp->datatype == 0)
5153
if (ssp->datatype != 2)
5158
AddToAnnot((SeqAnnotPtr PNTR)&(ssp->data), 3, newptr);
5160
case OBJ_SUBMIT_BLOCK:
5161
if (ssp->sub == NULL)
5162
ssp->sub = (SubmitBlockPtr)newptr;
5166
case OBJ_SEQSUB_CONTACT:
5167
if (ssp->sub == NULL)
5168
ssp->sub = SubmitBlockNew();
5169
if (ssp->sub->contact == NULL)
5170
ssp->sub->contact = (ContactInfoPtr)newptr;
5179
case OBJ_SUBMIT_BLOCK:
5180
sbp = (SubmitBlockPtr)(ptr);
5184
vnp = (ValNodePtr)newptr;
5186
if (vnp->choice == PUB_Sub)
5188
if (sbp->cit == NULL)
5190
sbp->cit = (CitSubPtr)(vnp->data.ptrvalue);
5196
case OBJ_SEQSUB_CONTACT:
5197
if (sbp->contact == NULL)
5198
sbp->contact = (ContactInfoPtr)newptr;
5208
bssp = (BioseqSetPtr)(ptr);
5215
ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
5218
if (omdp->choice == NULL)
5220
omdp->choice = ValNodeNew(NULL);
5221
omdp->choicetype = OBJ_SEQENTRY;
5222
omdp->choice->data.ptrvalue = newptr;
5223
if (newtype == OBJ_BIOSEQ)
5224
omdp->choice->choice = 1;
5226
omdp->choice->choice = 2;
5228
ValNodeLink(&(bssp->seq_set), omdp->choice);
5229
ObjMgrConnectFunc(omp, newtype, newptr, into, ptr);
5232
ValNodeLink(&(bssp->descr), (ValNodePtr)newptr);
5234
case OBJ_PUB: /* make a pubdesc */
5235
case OBJ_SEQFEAT_CIT:
5236
vnp = DescrFromPub((ValNodePtr)newptr);
5237
ValNodeLink(&(bssp->descr), vnp);
5240
ValNodeLink(&(bssp->seq_set), newptr);
5243
AddAnAnnot(&(bssp->annot), newptr);
5246
AddToAnnot(&(bssp->annot), 1, newptr);
5249
case OBJ_SEQHIST_ALIGN:
5250
AddToAnnot(&(bssp->annot), 2, newptr);
5253
AddToAnnot(&(bssp->annot), 3, newptr);
5261
bsp = (BioseqPtr)(ptr);
5268
ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: Not entity for Bioseq(Set)");
5271
if (omdp->choice == NULL)
5273
omdp->choice = ValNodeNew(NULL);
5274
omdp->choicetype = OBJ_SEQENTRY;
5275
omdp->choice->data.ptrvalue = newptr;
5276
if (newtype == OBJ_BIOSEQ)
5277
omdp->choice->choice = 1;
5279
omdp->choice->choice = 2;
5281
if ((gcp->parentitem != NULL) && (gcp->prevlink != NULL))
5283
omdp->choice->next = *(gcp->prevlink);
5284
*(gcp->prevlink) = omdp->choice;
5285
ObjMgrConnectFunc(omp, newtype, newptr, gcp->parenttype, gcp->parentitem);
5291
ValNodeLink(&(bsp->descr), (ValNodePtr)newptr);
5293
case OBJ_PUB: /* make a pubdesc */
5294
case OBJ_SEQFEAT_CIT:
5295
vnp = DescrFromPub((ValNodePtr)newptr);
5296
ValNodeLink(&(bsp->descr), vnp);
5299
if ((gcp->parentitem != NULL) && (gcp->prevlink != NULL))
5301
omdp->choice->next = *(gcp->prevlink);
5302
*(gcp->prevlink) = omdp->choice;
5303
ObjMgrConnectFunc(omp, newtype, newptr, gcp->parenttype, gcp->parentitem);
5309
AddAnAnnot(&(bsp->annot), newptr);
5312
AddToAnnot(&(bsp->annot), 1, newptr);
5315
case OBJ_SEQHIST_ALIGN:
5316
AddToAnnot(&(bsp->annot), 2, newptr);
5319
AddToAnnot(&(bsp->annot), 3, newptr);
5322
if (bsp->hist == NULL)
5324
bsp->hist = (SeqHistPtr)newptr;
5333
vnp = (ValNodePtr)newptr;
5337
vnp = DescrFromPub(vnp);
5339
if (gcp->prevlink != NULL)
5341
vnp->next = *(gcp->prevlink);
5342
*(gcp->prevlink) = vnp;
5352
case OBJ_SEQFEAT_CIT:
5354
vnp = (ValNodePtr)newptr;
5358
vnp = PubFromDescr(vnp);
5365
if (gcp->prevlink != NULL)
5367
vnp->next = *(gcp->prevlink);
5368
*(gcp->prevlink) = vnp;
5379
sap = (SeqAnnotPtr)ptr;
5383
if (! AddToSeqAnnot(sap, 1, newptr))
5387
case OBJ_SEQHIST_ALIGN:
5388
if (! AddToSeqAnnot(sap, 2, newptr))
5392
if (! AddToSeqAnnot(sap, 3, newptr))
5396
sap = (SeqAnnotPtr)newptr;
5397
if (gcp->prevlink != NULL)
5399
sap->next = *(gcp->prevlink);
5400
*(gcp->prevlink) = sap;
5410
case OBJ_BIOSEQ_MAPFEAT:
5412
sfp = (SeqFeatPtr)ptr;
5416
newptr = (Pointer)PubFromDescr((ValNodePtr)newptr);
5418
if (sfp->cit == NULL)
5420
sfp->cit = ValNodeNew(NULL);
5421
sfp->cit->choice = 1;
5423
ValNodeLink((ValNodePtr PNTR)&(sfp->cit->data.ptrvalue), (ValNodePtr)newptr);
5426
sfp = (SeqFeatPtr)newptr;
5427
if (gcp->prevlink != NULL)
5429
sfp->next = *(gcp->prevlink);
5430
*(gcp->prevlink) = sfp;
5436
SeqLocFree(sfp->location); /* make assumption */
5437
sfp->location = (ValNodePtr)newptr;
5445
case OBJ_SEQHIST_ALIGN:
5450
case OBJ_SEQHIST_ALIGN:
5451
salp = (SeqAlignPtr)newptr;
5452
if (gcp->prevlink != NULL)
5454
salp->next = *(gcp->prevlink);
5455
*(gcp->prevlink) = salp;
5469
sgp = (SeqGraphPtr)newptr;
5470
if (gcp->prevlink != NULL)
5472
sgp->next = *(gcp->prevlink);
5473
*(gcp->prevlink) = sgp;
5495
ErrPostEx(SEV_ERROR,0,0,"AttachDataProc: [%d] into [%d]", (int)newtype, (int)into);
5499
gdsp->succeeded = TRUE;
5507
ObjMgrDelete(omdp->datatype, omdp->dataptr);
5514
static Boolean CopyDataProc (GatherContextPtr gcp)
5516
OMProcControlPtr ompcp;
5521
Boolean was_choice = FALSE;
5524
gdsp = (GDSPtr)(gcp->userdata);
5525
ompcp = gdsp->ompcp;
5527
ptr = gcp->thisitem;
5528
type = gcp->thistype;
5529
ompcp->input_data = ptr;
5531
switch (gcp->thistype)
5535
if (gcp->sep != NULL)
5537
ompcp->input_choice = gcp->sep;
5538
ptr = (Pointer)(gcp->sep);
5539
ompcp->input_choicetype = OBJ_SEQENTRY;
5540
type = OBJ_SEQENTRY;
5548
omp = ObjMgrReadLock();
5549
omtp = ObjMgrTypeFind(omp, type, NULL, NULL);
5554
ErrPostEx(SEV_ERROR,0,0,"CopyDataProc: can't find type [%d]", (int)type);
5558
ptr2 = AsnIoMemCopy(ptr, omtp->asnread, omtp->asnwrite);
5561
gdsp->succeeded = TRUE;
5565
ompcp->output_data = ptr2;
5566
ompcp->output_itemtype = type;
5570
ompcp->output_choice = ptr2;
5571
ompcp->output_choicetype = type;
5572
ompcp->output_data = ((ValNodePtr)(ptr2))->data.ptrvalue;
5573
ompcp->output_itemtype = gcp->thistype;
5575
switch (ompcp->output_itemtype)
5577
case OBJ_BIOSEQSET: /* these types Add to the ObjMgr themselves */
5582
ObjMgrAdd(ompcp->output_itemtype, ompcp->output_data);
5589
static Boolean NEAR GenericGatherDataForProc (OMProcControlPtr ompcp, Boolean sel, Int2 func)
5593
Boolean retval = FALSE, data_changed = FALSE;
5594
static CharPtr funcs [5] = {
5595
"GatherDataForProc",
5596
"DetachDataForProc",
5597
"AttachDataForProc",
5599
"ReplaceDataForProc" };
5604
gds.succeeded = retval;
5609
ssp = ObjMgrGetSelected();
5613
ErrPostEx(SEV_ERROR,0,0,"%s: Nothing was selected", funcs[func]);
5617
ompcp->input_entityID = ssp->entityID;
5618
ompcp->input_itemID = ssp->itemID;
5619
ompcp->input_itemtype = ssp->itemtype;
5622
if (func == 1) /* detach: changes selection */
5623
ObjMgrDeSelect(ompcp->input_entityID, ompcp->input_itemID, ompcp->input_itemtype, 0, NULL);
5625
omp = ObjMgrReadLock();
5626
omdp = ObjMgrGetDataStruct (omp, ompcp->input_entityID);
5631
ErrPostEx(SEV_ERROR,0,0,"%s: can't match entityID", funcs[func]);
5635
if ((ompcp->input_itemID <= 1) &&
5636
((ompcp->input_itemtype == 0) || (ompcp->input_itemtype == omdp->datatype))) /* top level */
5638
ompcp->input_choice = omdp->choice;
5639
ompcp->input_choicetype = omdp->choicetype;
5640
ompcp->input_itemtype = omdp->datatype;
5641
ompcp->input_data = omdp->dataptr;
5642
ompcp->whole_entity = TRUE;
5643
if ((func == 0) || (func == 1)) /* gather or detach */
5652
if (func == 4) /* replace */
5654
if (ompcp->input_itemtype != ompcp->output_itemtype)
5656
ErrPostEx(SEV_ERROR,0,0,"%s: input type %d != output type %d",
5657
funcs[func], (int)(ompcp->input_itemtype), (int)(ompcp->output_itemtype));
5661
if (ompcp->output_data == NULL)
5663
ErrPostEx(SEV_ERROR,0,0,"%s: no output_data", funcs[func]);
5671
gip = GatherDataProc;
5674
gip = DetachDataProc;
5675
data_changed = TRUE;
5678
gip = AttachDataProc;
5679
data_changed = TRUE;
5685
gip = ReplaceDataProc;
5686
data_changed = TRUE;
5691
retval = GatherItemFunc (ompcp->input_entityID, ompcp->input_itemID,
5692
ompcp->input_itemtype,(Pointer)(&gds), gip, NULL, ompcp->do_not_reload_from_cache);
5695
ErrPostEx(SEV_ERROR,0,0,"%s: can't do the gather", funcs[func]);
5697
retval = gds.succeeded;
5699
if ((retval) && (data_changed)) /* set the dirty flag */
5701
ObjMgrSetDirtyFlag(ompcp->input_entityID, TRUE);
5706
/****************************************************************************
5708
* GatherDataForProc(ompcp, sel)
5710
* fills in data, choice, and choictype in OMProcControlPtr
5711
* sets ompcp->whole_entity TRUE if appropriate
5712
* returns TRUE if it did it
5713
* if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
5714
* returns FALSE if nothing selected.. Does ErrPostEx() for it
5716
****************************************************************************/
5717
NLM_EXTERN Boolean LIBCALL GatherDataForProc (OMProcControlPtr ompcp, Boolean sel)
5719
return GenericGatherDataForProc(ompcp, sel, 0);
5722
/****************************************************************************
5724
* DetachDataForProc(ompcp, sel)
5726
* fills in data, choice, and choictype in OMProcControlPtr
5727
* sets ompcp->whole_entity TRUE if appropriate
5728
* returns TRUE if it did it
5729
* if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
5730
* returns FALSE if nothing selected.. Does ErrPostEx() for it
5731
* Detaches data item from surrounding data if necessary
5733
****************************************************************************/
5734
NLM_EXTERN Boolean LIBCALL DetachDataForProc (OMProcControlPtr ompcp, Boolean sel)
5736
return GenericGatherDataForProc(ompcp, sel, 1);
5739
/****************************************************************************
5741
* AttachDataForProc(ompcp, sel)
5743
* fills in data, choice, and choictype in OMProcControlPtr
5744
* sets ompcp->whole_entity TRUE if appropriate
5745
* returns TRUE if it did it
5746
* if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
5747
* returns FALSE if nothing selected.. Does ErrPostEx() for it
5748
* Attaches data in output section of ompcp into the input section
5750
****************************************************************************/
5751
NLM_EXTERN Boolean LIBCALL AttachDataForProc (OMProcControlPtr ompcp, Boolean sel)
5753
return GenericGatherDataForProc(ompcp, sel, 2);
5756
/****************************************************************************
5758
* CopyDataForProc(ompcp, sel)
5760
* fills in data, choice, and choictype in OMProcControlPtr
5761
* sets ompcp->whole_entity TRUE if appropriate
5762
* returns TRUE if it did it
5763
* if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
5764
* returns FALSE if nothing selected.. Does ErrPostEx() for it
5765
* Attaches copy of data in output section of ompcp
5767
****************************************************************************/
5768
NLM_EXTERN Boolean LIBCALL CopyDataForProc (OMProcControlPtr ompcp, Boolean sel)
5770
return GenericGatherDataForProc(ompcp, sel, 3);
5773
/****************************************************************************
5775
* ReplaceDataForProc(ompcp, sel)
5777
* fills in data, choice, and choictype in OMProcControlPtr
5778
* sets ompcp->whole_entity TRUE if appropriate
5779
* returns TRUE if it did it
5780
* if (sel == TRUE), fills in ompcp with data from ObjMgrGetSelect first.
5781
* returns FALSE if nothing selected.. Does ErrPostEx() for it
5782
* Replaces data in input section of ompcp with the output section
5783
* Data in input section is deleted
5785
****************************************************************************/
5786
NLM_EXTERN Boolean LIBCALL ReplaceDataForProc (OMProcControlPtr ompcp, Boolean sel)
5788
return GenericGatherDataForProc(ompcp, sel, 4);
5791
/*****************************************************************************
5793
* GatherProcLaunch(proctype, sel, entityID, itemID, itemtype,
5794
* inputtype, subinputtype, outputtype, suboutputtype)
5795
* looks for ALL proctype in priority order that
5796
* matches inputtype and outputtype
5797
* if (sel) then fills in entityID,itemID,itemtype with currently selected
5800
* uses the function arguments
5801
* locates the data pointer, determines the subtype (if any)
5802
* then finds the process that will return OM_MSG_RET_DONE in priority order
5803
* 0 on outputtype, inputsubtype, outputsubtype matches any
5804
* if subtype can be matched on input/output, takes in preference over
5808
* 1) To launch an editor for the currently selected item
5809
* GatherProcLaunch(OMPROC_EDIT,TRUE,0,0,0,0,0,0,0);
5810
* 2) To launch an editor to create a new seq_descr of type pub
5811
* GatherProcLaunch(OMPROC_EDIT,FALSE,0,0,0,OBJ_SEQDESC,Seq_descr_pub,0,0);
5812
* 3) To launch an editor for a specific seq_descr
5813
* GatherProcLaunch(OMPROC_EDIT,FALSE,2,1,4,0,0,0,0);
5814
* (where the 3 numbers identify the seq_descr)
5815
* 4)To launch an editor which will create a new seq_descr and attach it
5816
* to the currently selected Bioseq
5817
* GatherProcLaunch(OMPROC_EDIT,TRUE,0,0,0,OBJ_SEQDESC,Seq_descr_pub,0,0)
5818
* Note in this case ompcp->input_entityid, .input_itemid, input_itemtype
5819
* well refer to a Bioseq. The editor should check the input_itemtype
5820
* and decide if it can attach it's output to it, or if it is an
5821
* input type mismatch error.
5822
* 5) To launch an editor which will create a new seq_descr and attach to
5824
* (Same as (4) but sel=FALSE, and entitid,itemid,itemtype filled in
5829
* All this means the function will be called with OMProcControlPtr (ompcp)
5830
* fields filled in (input_entityid, input_itemid, input_itemtype) as:
5831
* 1) Create new one, place in desktop = 0,0,0
5832
* 2) Edit old one, non-zero values, with input_itemtype matching the type
5834
* 3) Create a new one, attach it to something else, non-zero values,
5835
* with input_itemtype not matching the type of the editor.
5837
* Functions to install the returned values are for the cases above:
5838
* 1) ObjMgrRegister()
5839
* 2) GatherReplaceDataForProc()
5840
* 3) GatherAttachDataForProc()
5842
* returns the return from the proc, or OM_MSG_RET_NOPROC if not found
5844
*****************************************************************************/
5845
NLM_EXTERN Int2 GatherProcLaunch (Uint2 proctype, Boolean sel, Uint2 entityID, Uint2 itemID,
5846
Uint2 itemtype, Uint2 inputtype, Uint2 subinputtype, Uint2 outputtype, Uint2 suboutputtype)
5850
ObjMgrProcPtr ompp=NULL;
5852
Boolean retval, do_general_proc = FALSE;
5854
Int2 procval = OM_MSG_RET_NOPROC;
5856
MemSet((Pointer)(&ompc), 0, sizeof(OMProcControl));
5858
ompc.input_entityID = entityID;
5859
ompc.input_itemID = itemID;
5860
ompc.input_itemtype = itemtype;
5862
retval = GatherDataForProc(&ompc, sel);
5864
if (sel && (! retval))
5865
return OM_MSG_RET_ERROR;
5867
if (entityID && (! retval))
5868
return OM_MSG_RET_ERROR;
5870
if (! inputtype) /* not set on input */
5871
inputtype = ompc.input_itemtype; /* could now be filled in */
5873
omp = NULL; /* do all temporary read locks */
5874
if ((! subinputtype) && (inputtype == ompc.input_itemtype)
5875
&& (ompc.input_data != NULL))
5877
omtp = ObjMgrTypeFind(omp, inputtype, NULL, NULL);
5879
subinputtype = (*(omtp->subtypefunc))(ompc.input_data);
5882
while ((ompp = ObjMgrProcFindNext(omp, proctype, inputtype, outputtype, ompp)) != NULL)
5884
if (ompp->subinputtype == subinputtype)
5887
procval = (*(ompp->func))((Pointer)&ompc);
5890
case OM_MSG_RET_ERROR:
5893
case OM_MSG_RET_DEL:
5897
case OM_MSG_RET_DONE:
5903
else if (! ompp->subinputtype) /* general proc found */
5904
do_general_proc = TRUE;
5907
if (do_general_proc) /* specific proc failed, try a general one */
5909
while ((ompp = ObjMgrProcFindNext(omp, proctype, inputtype, outputtype, ompp)) != NULL)
5911
if (! ompp->subinputtype)
5914
procval = (*(ompp->func))((Pointer)&ompc);
5917
case OM_MSG_RET_ERROR:
5920
case OM_MSG_RET_DEL:
5924
case OM_MSG_RET_DONE:
5938
NLM_EXTERN Int2 GatherSpecificProcLaunch (Uint2 procid, CharPtr procname, Uint2 proctype,
5939
Boolean sel, Uint2 entityID, Uint2 itemID, Uint2 itemtype)
5943
ObjMgrProcPtr ompp=NULL;
5945
Int2 procval = OM_MSG_RET_NOPROC;
5949
MemSet((Pointer)(&ompc), 0, sizeof(OMProcControl));
5951
ompc.input_entityID = entityID;
5952
ompc.input_itemID = itemID;
5953
ompc.input_itemtype = itemtype;
5955
retval = GatherDataForProc(&ompc, sel);
5957
if (sel && (! retval))
5958
return OM_MSG_RET_ERROR;
5960
if (entityID && (! retval))
5961
return OM_MSG_RET_ERROR;
5963
ompp = ObjMgrProcFind (omp, procid, procname, proctype);
5965
return OM_MSG_RET_ERROR;
5968
procval = (*(ompp->func))((Pointer)&ompc);
5971
case OM_MSG_RET_ERROR:
5974
case OM_MSG_RET_DEL:
5978
case OM_MSG_RET_DONE:
5988
/*****************************************************************
5990
* GatherOverWrite (oldptr, newptr, type)
5992
* overwrites oldptr with contents of newptr
5993
* sets any "next" pointers contained in newptr to point to the same
5994
* chain as those in oldptr did
5995
* this function is used for making a varient copy of an object, then
5996
* replacing it in another object without changing points to or from
5998
*******************************************************************/
5999
NLM_EXTERN Boolean LIBCALL GatherOverWrite (Pointer oldptr, Pointer newptr, Uint2 type)
6002
Pointer dest, next=NULL, oldsrc;
6005
if ((oldptr == NULL) || (newptr == NULL))
6012
size = sizeof(SeqSubmit);
6014
case OBJ_SUBMIT_BLOCK:
6015
size = sizeof(SubmitBlock);
6017
case OBJ_SEQSUB_CONTACT:
6018
size = sizeof(ContactInfo);
6020
case OBJ_SEQSUB_CIT:
6021
size = sizeof(CitSub);
6024
size = sizeof(SeqHist);
6027
size = sizeof(BioseqSet);
6030
size = sizeof(Bioseq);
6033
case OBJ_BIOSEQ_SEG:
6035
case OBJ_SEQFEAT_CIT:
6040
vnp = (ValNodePtr)oldptr;
6041
oldsrc = &(vnp->data);
6042
size = sizeof(DataVal);
6043
vnp = (ValNodePtr)newptr;
6044
newptr = &(vnp->data);
6046
case OBJ_BIOSEQ_MAPFEAT:
6048
size = sizeof(SeqFeat);
6049
next = (Pointer)(((SeqFeatPtr)(oldptr))->next);
6050
(((SeqFeatPtr)(oldptr))->next) = NULL;
6051
(((SeqFeatPtr)(newptr))->next) = (SeqFeatPtr)next;
6054
size = sizeof(SeqAnnot);
6055
next = (Pointer)(((SeqAnnotPtr)(oldptr))->next);
6056
(((SeqAnnotPtr)(oldptr))->next) = NULL;
6057
(((SeqAnnotPtr)(newptr))->next) = (SeqAnnotPtr)next;
6060
case OBJ_SEQHIST_ALIGN:
6061
size = sizeof(SeqAlign);
6062
next = (Pointer)(((SeqAlignPtr)(oldptr))->next);
6063
(((SeqAlignPtr)(oldptr))->next) = NULL;
6064
(((SeqAlignPtr)(newptr))->next) = (SeqAlignPtr)next;
6067
size = sizeof(SeqGraph);
6068
next = (Pointer)(((SeqGraphPtr)(oldptr))->next);
6069
(((SeqGraphPtr)(oldptr))->next) = NULL;
6070
(((SeqGraphPtr)(newptr))->next) = (SeqGraphPtr)next;
6073
ErrPostEx(SEV_ERROR,0,0,"ObjMgrOverWrite: unsupported type %d",
6081
dest = MemNew(size); /* temporary buffer for copies */
6084
ErrPostEx(SEV_ERROR,0,0,"ObjMgrOverWrite: can't allocate buffer");
6088
MemCopy(dest, oldsrc, size); /* replace the contents */
6089
MemCopy(oldsrc, newptr, size);
6090
MemCopy(newptr, dest, size);
6099
/*****************************************************************************/
6101
/* AssignIDsInEntity/VisitObjectsInEntity section */
6103
typedef struct internalacc {
6105
Int2 itemIDs [OBJ_MAX];
6107
GatherObjectProc callback;
6109
BoolPtr objMgrFilter;
6110
} InternalACC, PNTR InternalACCPtr;
6112
static void AssignIDs (InternalACCPtr iap, GatherIndexPtr gip, Uint1 itemtype, Uint1 subtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6115
if (iap == NULL || gip == NULL) return;
6117
if (iap->assignIDs) {
6118
gip->entityID = iap->entityID;
6119
gip->itemID = iap->itemIDs [itemtype];
6120
gip->itemtype = itemtype;
6121
gip->subtype = subtype;
6122
/* gip->deleteme = 0; */
6123
gip->parenttype = parenttype;
6124
gip->parentptr = parent;
6125
gip->prevlink = prevlink;
6129
static Boolean VisitCallback (InternalACCPtr iap, Pointer dataptr, Uint1 itemtype, Uint1 subtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6134
if (dataptr == NULL || iap == NULL || itemtype >= OBJ_MAX) return TRUE;
6136
if (iap->callback != NULL) {
6137
if (iap->objMgrFilter == NULL || iap->objMgrFilter [itemtype]) {
6138
go.entityID = iap->entityID;
6139
go.itemID = iap->itemIDs [itemtype];
6140
go.itemtype = itemtype;
6141
go.subtype = subtype;
6142
go.parenttype = parenttype;
6143
go.dataptr = dataptr;
6144
go.parentptr = parent;
6145
go.prevlink = prevlink;
6146
go.userdata = iap->userdata;
6147
if (! iap->callback (&go)) return FALSE;
6154
static Boolean VisitSeqEntry (InternalACCPtr iap, SeqEntryPtr sep, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink);
6156
static Boolean VisitPub (InternalACCPtr iap, ValNodePtr pub, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6159
if (iap == NULL || pub == NULL) return TRUE;
6160
(iap->itemIDs [itemtype])++;
6162
if (iap->callback != NULL) {
6163
if (! VisitCallback (iap, (Pointer) pub, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6169
static Boolean VisitPubSet (InternalACCPtr iap, ValNodePtr vnp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6172
Uint1 itemtype = OBJ_PUB_SET;
6175
if (iap == NULL || vnp == NULL) return TRUE;
6176
(iap->itemIDs [itemtype])++;
6178
if (iap->callback != NULL) {
6179
if (! VisitCallback (iap, (Pointer) vnp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6182
prevlink = (Pointer PNTR) &(vnp->data.ptrvalue);
6183
for (pub = (ValNodePtr) vnp->data.ptrvalue; pub != NULL; pub = pub->next) {
6184
if (! VisitPub (iap, pub, OBJ_SEQFEAT_CIT, (Pointer) vnp, itemtype, prevlink)) return FALSE;
6185
prevlink = (Pointer PNTR) &(pub->next);
6191
static Boolean VisitSeqFeat (InternalACCPtr iap, SeqFeatPtr sfp, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6194
if (iap == NULL || sfp == NULL) return TRUE;
6196
if ((! iap->assignIDs) && iap->callback != NULL) {
6197
if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
6202
while (sfp != NULL) {
6203
(iap->itemIDs [itemtype])++;
6205
if (iap->assignIDs) {
6206
AssignIDs (iap, &(sfp->idx), itemtype, FindFeatDefType (sfp), parent, parenttype, prevlink);
6209
if (iap->callback != NULL) {
6210
if (! VisitCallback (iap, (Pointer) sfp, itemtype, sfp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6213
if (sfp->cit != NULL) {
6214
if (! VisitPubSet (iap, sfp->cit, (Pointer) sfp, itemtype, (Pointer PNTR) &(sfp->cit))) return FALSE;
6217
prevlink = (Pointer PNTR) &(sfp->next);
6224
static Uint2 nextAlignID = 0;
6226
static Boolean VisitSeqAlign (InternalACCPtr iap, SeqAlignPtr sap, Uint1 itemtype, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6229
if (iap == NULL || sap == NULL) return TRUE;
6231
if ((! iap->assignIDs) && iap->callback != NULL) {
6232
if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
6237
while (sap != NULL) {
6238
(iap->itemIDs [itemtype])++;
6240
if (iap->assignIDs) {
6241
AssignIDs (iap, &(sap->idx), itemtype, sap->type, parent, parenttype, prevlink);
6242
if (sap->alignID == 0) {
6244
sap->alignID = nextAlignID;
6248
if (iap->callback != NULL) {
6249
if (! VisitCallback (iap, (Pointer) sap, itemtype, sap->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6252
if (sap->segtype == SAS_DISC) {
6253
if (! VisitSeqAlign (iap, (SeqAlignPtr) sap->segs, OBJ_SEQALIGN, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->segs))) return FALSE;
6256
prevlink = (Pointer PNTR) &(sap->next);
6263
static Boolean VisitSeqGraph (InternalACCPtr iap, SeqGraphPtr sgp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6266
Uint1 itemtype = OBJ_SEQGRAPH;
6268
if (iap == NULL || sgp == NULL) return TRUE;
6270
if ((! iap->assignIDs) && iap->callback != NULL) {
6271
if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
6276
while (sgp != NULL) {
6277
(iap->itemIDs [itemtype])++;
6279
if (iap->assignIDs) {
6280
AssignIDs (iap, &(sgp->idx), itemtype, 0, parent, parenttype, prevlink);
6283
if (iap->callback != NULL) {
6284
if (! VisitCallback (iap, (Pointer) sgp, itemtype, sgp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6287
prevlink = (Pointer PNTR) &(sgp->next);
6294
static Boolean VisitSeqAnnot (InternalACCPtr iap, SeqAnnotPtr sap, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6297
Uint1 itemtype = OBJ_SEQANNOT;
6299
if (iap == NULL || sap == NULL) return TRUE;
6301
while (sap != NULL) {
6302
(iap->itemIDs [itemtype])++;
6304
if (iap->assignIDs) {
6305
AssignIDs (iap, &(sap->idx), itemtype, sap->type, parent, parenttype, prevlink);
6308
if (iap->callback != NULL) {
6309
if (! VisitCallback (iap, (Pointer) sap, itemtype, sap->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6312
switch (sap->type) {
6313
case 1 : /* feature table */
6314
if (! VisitSeqFeat (iap, (SeqFeatPtr) sap->data, OBJ_SEQFEAT, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
6316
case 2 : /* alignments */
6317
if (! VisitSeqAlign (iap, (SeqAlignPtr) sap->data, OBJ_SEQALIGN, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
6319
case 3 : /* graphs */
6320
if (! VisitSeqGraph (iap, (SeqGraphPtr) sap->data, (Pointer) sap, itemtype, (Pointer PNTR) &(sap->data))) return FALSE;
6326
prevlink = (Pointer PNTR) &(sap->next);
6333
static Boolean VisitSeqDescr (InternalACCPtr iap, SeqDescrPtr sdp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6336
Uint1 itemtype = OBJ_SEQDESC;
6339
if (iap == NULL || sdp == NULL) return TRUE;
6341
if ((! iap->assignIDs) && iap->callback != NULL) {
6342
if (iap->objMgrFilter != NULL && (! iap->objMgrFilter [itemtype])) {
6347
while (sdp != NULL) {
6348
(iap->itemIDs [itemtype])++;
6350
if (iap->assignIDs) {
6351
if (sdp->extended != 0) {
6352
ovp = (ObjValNodePtr) sdp;
6353
AssignIDs (iap, &(ovp->idx), itemtype, sdp->choice, parent, parenttype, prevlink);
6355
ErrPostEx (SEV_ERROR, 0, 0, "Descriptor item %d is not an ObjValNode",
6356
(int) iap->itemIDs [itemtype]);
6360
if (iap->callback != NULL) {
6361
if (sdp->extended != 0) {
6362
ovp = (ObjValNodePtr) sdp;
6363
if (! VisitCallback (iap, (Pointer) sdp, itemtype, ovp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6367
prevlink = (Pointer PNTR) &(sdp->next);
6374
static Boolean VisitSeqHist (InternalACCPtr iap, SeqHistPtr shp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6377
Uint1 itemtype = OBJ_SEQHIST;
6379
if (iap == NULL || shp == NULL) return TRUE;
6380
(iap->itemIDs [itemtype])++;
6382
if (iap->callback != NULL) {
6383
if (! VisitCallback (iap, (Pointer) shp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6386
VisitSeqAlign (iap, shp->assembly, OBJ_SEQHIST_ALIGN, (Pointer) shp, itemtype, (Pointer PNTR) &(shp->assembly));
6391
static Boolean VisitSeqIds (InternalACCPtr iap, SeqIdPtr sip, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6394
Uint1 itemtype = OBJ_SEQID;
6396
if (iap == NULL || sip == NULL) return TRUE;
6398
while (sip != NULL) {
6399
(iap->itemIDs [itemtype])++;
6401
if (iap->callback != NULL) {
6402
if (! VisitCallback (iap, (Pointer) sip, itemtype, sip->choice, parent, parenttype, prevlink)) return FALSE;
6405
prevlink = (Pointer PNTR) &(sip->next);
6412
static Boolean VisitDelta (InternalACCPtr iap, DeltaSeqPtr dsp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6415
Uint1 itemtype = OBJ_BIOSEQ_DELTA;
6417
if (iap == NULL || dsp == NULL) return TRUE;
6419
while (dsp != NULL) {
6420
(iap->itemIDs [itemtype])++;
6422
if (iap->callback != NULL) {
6423
if (! VisitCallback (iap, (Pointer) dsp, itemtype, dsp->choice, parent, parenttype, prevlink)) return FALSE;
6426
prevlink = (Pointer PNTR) &(dsp->next);
6433
static Boolean VisitSegment (InternalACCPtr iap, SeqLocPtr head, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6436
Uint1 itemtype = OBJ_BIOSEQ_SEG;
6439
if (iap == NULL || head == NULL) return TRUE;
6442
while ((slp = SeqLocFindNext (head, slp)) != NULL) {
6443
(iap->itemIDs [itemtype])++;
6445
if (iap->callback != NULL) {
6446
if (! VisitCallback (iap, (Pointer) slp, itemtype, slp->choice, parent, parenttype, prevlink)) return FALSE;
6448
prevlink = (Pointer PNTR) &(slp->next);
6454
static Boolean VisitBioseq (InternalACCPtr iap, BioseqPtr bsp, SeqEntryPtr curr, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6458
Uint1 itemtype = OBJ_BIOSEQ;
6461
if (iap == NULL || bsp == NULL) return TRUE;
6462
(iap->itemIDs [itemtype])++;
6464
if (iap->assignIDs) {
6465
AssignIDs (iap, &(bsp->idx), itemtype, bsp->repr, parent, parenttype, prevlink);
6466
bsp->seqentry = curr;
6469
if (iap->callback != NULL) {
6470
if (! VisitCallback (iap, (Pointer) bsp, itemtype, bsp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6473
switch (bsp->repr) {
6475
if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_MAPFEAT]) {
6476
if (! VisitSeqFeat (iap, (SeqFeatPtr) bsp->seq_ext, OBJ_BIOSEQ_MAPFEAT, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
6480
if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_SEG]) {
6481
vn.choice = SEQLOC_MIX;
6483
vn.data.ptrvalue = bsp->seq_ext;
6486
if (! VisitSegment (iap, head, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
6490
if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_SEG]) {
6491
head = (SeqLocPtr) bsp->seq_ext;
6492
if (! VisitSegment (iap, head, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
6495
case Seq_repr_delta :
6496
if (iap->objMgrFilter == NULL || iap->objMgrFilter [OBJ_BIOSEQ_DELTA]) {
6497
if (! VisitDelta (iap, (DeltaSeqPtr) bsp->seq_ext, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->seq_ext))) return FALSE;
6504
if (! VisitSeqHist (iap, bsp->hist, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->hist))) return FALSE;
6506
if (! VisitSeqDescr (iap, bsp->descr, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->descr))) return FALSE;
6508
if (! VisitSeqAnnot (iap, bsp->annot, (Pointer) bsp, itemtype, (Pointer PNTR) &(bsp->annot))) return FALSE;
6513
static Boolean VisitBioseqSet (InternalACCPtr iap, BioseqSetPtr bssp, SeqEntryPtr curr, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6516
Uint1 itemtype = OBJ_BIOSEQSET;
6519
if (iap == NULL || bssp == NULL) return TRUE;
6520
(iap->itemIDs [itemtype])++;
6522
if (iap->assignIDs) {
6523
AssignIDs (iap, &(bssp->idx), itemtype, bssp->_class, parent, parenttype, prevlink);
6524
bssp->seqentry = curr;
6527
if (iap->callback != NULL) {
6528
if (! VisitCallback (iap, (Pointer) bssp, itemtype, bssp->idx.subtype, parent, parenttype, prevlink)) return FALSE;
6531
if (! VisitSeqDescr (iap, bssp->descr, (Pointer) bssp, itemtype, (Pointer PNTR) &(bssp->descr))) return FALSE;
6533
if (! VisitSeqAnnot (iap, bssp->annot, (Pointer) bssp, itemtype, (Pointer PNTR) &(bssp->annot))) return FALSE;
6535
prevlink = (Pointer PNTR) &(bssp->seq_set);
6536
for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6537
if (! VisitSeqEntry (iap, sep, (Pointer) bssp, itemtype, prevlink)) return FALSE;
6538
prevlink = (Pointer PNTR) &(sep->next);
6544
static Boolean VisitSeqEntry (InternalACCPtr iap, SeqEntryPtr sep, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6547
if (iap == NULL || sep == NULL) return TRUE;
6549
if (IS_Bioseq (sep)) {
6550
if (! VisitBioseq (iap, (BioseqPtr) sep->data.ptrvalue, sep, parent, parenttype, prevlink)) return FALSE;
6551
} else if (IS_Bioseq_set (sep)) {
6552
if (! VisitBioseqSet (iap, (BioseqSetPtr) sep->data.ptrvalue, sep, parent, parenttype, prevlink)) return FALSE;
6558
static Boolean VisitSeqSubCit (InternalACCPtr iap, CitSubPtr csp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6561
Uint1 itemtype = OBJ_SEQSUB_CIT;
6563
if (iap == NULL || csp == NULL) return TRUE;
6564
(iap->itemIDs [itemtype])++;
6566
if (iap->callback != NULL) {
6567
if (! VisitCallback (iap, (Pointer) csp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6573
static Boolean VisitSeqSubContact (InternalACCPtr iap, ContactInfoPtr cip, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6576
Uint1 itemtype = OBJ_SEQSUB_CONTACT;
6579
if (iap == NULL || cip == NULL) return TRUE;
6580
(iap->itemIDs [itemtype])++;
6582
if (iap->callback != NULL) {
6583
if (! VisitCallback (iap, (Pointer) cip, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6589
static Boolean VisitSubBlock (InternalACCPtr iap, SubmitBlockPtr sbp, Pointer parent, Uint2 parenttype, Pointer PNTR prevlink)
6592
Uint1 itemtype = OBJ_SUBMIT_BLOCK;
6594
if (iap == NULL || sbp == NULL) return TRUE;
6595
(iap->itemIDs [itemtype])++;
6597
if (iap->callback != NULL) {
6598
if (! VisitCallback (iap, (Pointer) sbp, itemtype, 0, parent, parenttype, prevlink)) return FALSE;
6601
if (! VisitSeqSubContact (iap, sbp->contact, (Pointer) sbp, itemtype, (Pointer PNTR) &(sbp->contact))) return FALSE;
6603
if (! VisitSeqSubCit (iap, sbp->cit, (Pointer) sbp, itemtype, (Pointer PNTR) &(sbp->cit))) return FALSE;
6608
static Boolean VisitSeqSubmit (InternalACCPtr iap, SeqSubmitPtr ssp)
6611
Uint1 itemtype = OBJ_SEQSUB;
6612
Pointer PNTR prevlink;
6615
if (iap == NULL || ssp == NULL) return TRUE;
6616
(iap->itemIDs [itemtype])++;
6618
if (iap->assignIDs) {
6619
AssignIDs (iap, &(ssp->idx), itemtype, 0, NULL, 0, NULL);
6622
if (iap->callback != NULL) {
6623
if (! VisitCallback (iap, (Pointer) ssp, itemtype, 0, NULL, 0, NULL)) return FALSE;
6626
if (! VisitSubBlock (iap, ssp->sub, (Pointer) ssp, itemtype, (Pointer PNTR) &(ssp->sub))) return FALSE;
6628
prevlink = (Pointer PNTR) &(ssp->data);
6629
switch (ssp->datatype) {
6630
case 1 : /* Seq-entrys */
6631
for (sep = (SeqEntryPtr) ssp->data; sep != NULL; sep = sep->next) {
6632
if (! VisitSeqEntry (iap, sep, (Pointer) ssp, itemtype, prevlink)) return FALSE;
6633
prevlink = (Pointer PNTR) &(sep->next);
6636
case 2 : /* Seq-annots */
6637
if (! VisitSeqAnnot (iap, (SeqAnnotPtr) ssp->data, (Pointer) ssp, itemtype, prevlink)) return FALSE;
6639
case 3 : /* SeqIds */
6640
if (! VisitSeqIds (iap, (SeqIdPtr) ssp->data, (Pointer) ssp, itemtype, prevlink)) return FALSE;
6649
/*****************************************************************************
6651
* AssignIDsInEntity (entityID, datatype, dataptr)
6652
* Assigns entityID/itemID/itemtype, parent pointer, and prevlink to several
6653
* data objects. If entityID is > 0 it looks up the registered datatype and
6654
* dataptr from the object manager. Otherwise it uses the remaining parameters,
6655
* assigning entityID 0 to the unregistered components.
6657
* GatherObjectsInEntity (entityID, datatype, dataptr, callback, userdata, objMgrFilter)
6658
* Calls callback for objects within entity. If the objMgrFilter parameter is NULL,
6659
* every object type is visited, otherwise the array length should be OBJ_MAX, and
6660
* the elements are from the OBJ_ list.
6662
*****************************************************************************/
6664
static Boolean VisitEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr,
6665
Boolean assignIDs, GatherObjectProc callback,
6666
Pointer userdata, BoolPtr objMgrFilter)
6673
MemSet ((Pointer) &iac, 0, sizeof (InternalACC));
6674
iac.entityID = entityID;
6675
iac.assignIDs = assignIDs;
6676
iac.callback = callback;
6677
iac.userdata = userdata;
6678
iac.objMgrFilter = objMgrFilter;
6681
omp = ObjMgrReadLock ();
6682
omdp = ObjMgrGetDataStruct (omp, entityID);
6684
if (omdp == NULL) return FALSE;
6685
if (omdp->choicetype == OBJ_SEQENTRY) {
6686
datatype = omdp->choicetype;
6687
dataptr = omdp->choice;
6689
datatype = omdp->datatype;
6690
dataptr = omdp->dataptr;
6694
if (datatype == 0 || dataptr == NULL) return FALSE;
6698
VisitSeqEntry (&iac, (SeqEntryPtr) dataptr, NULL, 0, NULL);
6701
VisitBioseq (&iac, (BioseqPtr) dataptr, NULL, NULL, 0, NULL);
6703
case OBJ_BIOSEQSET :
6704
VisitBioseqSet (&iac, (BioseqSetPtr) dataptr, NULL, NULL, 0, NULL);
6707
VisitSeqDescr (&iac, (SeqDescrPtr) dataptr, NULL, 0, NULL);
6710
VisitSeqAnnot (&iac, (SeqAnnotPtr) dataptr, NULL, 0, NULL);
6713
VisitSeqFeat (&iac, (SeqFeatPtr) dataptr, OBJ_SEQFEAT, NULL, 0, NULL);
6716
VisitSeqAlign (&iac, (SeqAlignPtr) dataptr, OBJ_SEQALIGN, NULL, 0, NULL);
6719
VisitSeqGraph (&iac, (SeqGraphPtr) dataptr, NULL, 0, NULL);
6722
VisitSeqSubmit (&iac, (SeqSubmitPtr) dataptr);
6724
case OBJ_SUBMIT_BLOCK :
6725
VisitSubBlock (&iac, (SubmitBlockPtr) dataptr, NULL, 0, NULL);
6727
case OBJ_SEQSUB_CONTACT :
6728
VisitSeqSubContact (&iac, (ContactInfoPtr) dataptr, NULL, 0, NULL);
6731
VisitSeqHist (&iac, (SeqHistPtr) dataptr, NULL, 0, NULL);
6733
case OBJ_SEQHIST_ALIGN :
6734
VisitSeqAlign (&iac, (SeqAlignPtr) dataptr, OBJ_SEQHIST_ALIGN, NULL, 0, NULL);
6737
VisitPub (&iac, (ValNodePtr) dataptr, OBJ_PUB, NULL, 0, NULL);
6739
case OBJ_SEQSUB_CIT :
6740
VisitSeqSubCit (&iac, (CitSubPtr) dataptr, NULL, 0, NULL);
6743
VisitSeqIds (&iac, (SeqIdPtr) dataptr, NULL, 0, NULL);
6752
NLM_EXTERN Boolean LIBCALL AssignIDsInEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr)
6755
return VisitEntity (entityID, datatype, dataptr, TRUE, NULL, NULL, NULL);
6758
NLM_EXTERN Boolean LIBCALL GatherObjectsInEntity (Uint2 entityID, Uint2 datatype, Pointer dataptr,
6759
GatherObjectProc callback, Pointer userdata, BoolPtr objMgrFilter)
6762
if (callback == NULL) return FALSE;
6763
return VisitEntity (entityID, datatype, dataptr, FALSE, callback, userdata, objMgrFilter);
6766
/*****************************************************************************
6768
* GetNextDescriptorUnindexed (bsp, choice, curr)
6769
* After AssignIDsInEntity, gets next descriptor up the set hierarchy.
6771
*****************************************************************************/
6773
NLM_EXTERN SeqDescrPtr GetNextDescriptorUnindexed (
6780
BioseqSetPtr bssp = NULL;
6784
if (bsp == NULL || choice == 0) return NULL;
6792
while (sdp != NULL) {
6793
if (sdp->choice == choice) return sdp;
6797
if (curr == NULL || curr->extended == 0) return NULL;
6798
ovp = (ObjValNodePtr) curr;
6799
if (ovp->idx.parenttype == OBJ_BIOSEQ) {
6800
bsp = (BioseqPtr) ovp->idx.parentptr;
6801
if (bsp == NULL) return NULL;
6802
if (bsp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
6803
bssp = (BioseqSetPtr) ovp->idx.parentptr;
6804
} else if (ovp->idx.parenttype == OBJ_BIOSEQSET) {
6805
bssp = (BioseqSetPtr) ovp->idx.parentptr;
6806
if (bssp == NULL) return NULL;
6807
if (bssp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
6808
bssp = (BioseqSetPtr) ovp->idx.parentptr;
6811
while (bssp != NULL) {
6812
for (sdp = bssp->descr; sdp != NULL; sdp = sdp->next) {
6813
if (sdp->choice == choice) return sdp;
6815
if (bssp->idx.parenttype != OBJ_BIOSEQSET) return NULL;
6816
bssp = (BioseqSetPtr) bsp->idx.parentptr;
6821
typedef struct getptrforid {
6826
} GetPtrForId, PNTR GetPtrForIdPtr;
6828
static Boolean GetPointerProc (GatherObjectPtr gop)
6833
if (gop == NULL) return TRUE;
6834
gfp = (GetPtrForIdPtr) gop->userdata;
6835
if (gfp == NULL) return TRUE;
6836
if (gfp->itemID != gop->itemID || gfp->itemtype != gop->itemtype) return TRUE;
6837
gfp->dataptr = gop->dataptr;
6841
NLM_EXTERN Pointer LIBCALL GetPointerForIDs (Uint2 entityID, Uint2 itemID, Uint2 itemtype)
6845
Boolean objMgrFilter [OBJ_MAX];
6847
if (itemtype >= OBJ_MAX) return NULL;
6849
MemSet ((Pointer) objMgrFilter, FALSE, sizeof (objMgrFilter));
6850
objMgrFilter [itemtype] = TRUE;
6851
gfi.entityID = entityID;
6852
gfi.itemID = itemID;
6853
gfi.itemtype = itemtype;
6856
GatherObjectsInEntity (entityID, 0, NULL, GetPointerProc, &gfi, objMgrFilter);
6861
/*****************************************************************************
6863
* DeleteMarkedObjects (entityID, datatype, dataptr)
6864
* Unlinks and removes all objects whose GatherIndex.deleteme flag is not 0.
6866
*****************************************************************************/
6868
static void DeleteMarkedSeqFeat (SeqFeatPtr sfp, Pointer PNTR prevlink)
6873
while (sfp != NULL) {
6876
if (sfp->idx.deleteme != 0) {
6877
*prevlink = sfp->next;
6881
sfp->idx.prevlink = prevlink;
6882
prevlink = (Pointer PNTR) &(sfp->next);
6889
static void DeleteMarkedSeqAlign (SeqAlignPtr sap, Pointer PNTR prevlink)
6894
while (sap != NULL) {
6897
if (sap->idx.deleteme != 0) {
6898
*prevlink = sap->next;
6902
sap->idx.prevlink = prevlink;
6903
prevlink = (Pointer PNTR) &(sap->next);
6910
static void DeleteMarkedSeqGraph (SeqGraphPtr sgp, Pointer PNTR prevlink)
6915
while (sgp != NULL) {
6918
if (sgp->idx.deleteme != 0) {
6919
*prevlink = sgp->next;
6923
sgp->idx.prevlink = prevlink;
6924
prevlink = (Pointer PNTR) &(sgp->next);
6931
static void DeleteMarkedSeqAnnot (SeqAnnotPtr sap, Pointer PNTR prevlink)
6936
while (sap != NULL) {
6939
if (sap->idx.deleteme == 0) {
6940
switch (sap->type) {
6942
DeleteMarkedSeqFeat ((SeqFeatPtr) sap->data, (Pointer PNTR) &(sap->data));
6945
DeleteMarkedSeqAlign ((SeqAlignPtr) sap->data, (Pointer PNTR) &(sap->data));
6948
DeleteMarkedSeqGraph ((SeqGraphPtr) sap->data, (Pointer PNTR) &(sap->data));
6953
if (sap->data == NULL) {
6954
sap->idx.deleteme = 1;
6958
if (sap->idx.deleteme != 0) {
6959
*prevlink = sap->next;
6963
sap->idx.prevlink = prevlink;
6964
prevlink = (Pointer PNTR) &(sap->next);
6971
static void DeleteMarkedSeqDescr (SeqDescrPtr sdp, Pointer PNTR prevlink)
6977
while (sdp != NULL) {
6980
ovp = (ObjValNodePtr) sdp;
6981
if (sdp->extended != 0 && ovp->idx.deleteme != 0) {
6982
*prevlink = sdp->next;
6986
if (sdp->extended != 0) {
6987
ovp->idx.prevlink = prevlink;
6989
prevlink = (Pointer PNTR) &(sdp->next);
6996
static void DeleteMarkedSeqEntry (SeqEntryPtr sep, Pointer PNTR prevlink)
7004
while (sep != NULL) {
7010
if (IS_Bioseq (sep)) {
7012
bsp = (BioseqPtr) sep->data.ptrvalue;
7014
if (bsp->idx.deleteme != 0) {
7017
DeleteMarkedSeqDescr (bsp->descr, (Pointer PNTR) &(bsp->descr));
7018
DeleteMarkedSeqAnnot (bsp->annot, (Pointer PNTR) &(bsp->annot));
7022
} else if (IS_Bioseq_set (sep)) {
7024
bssp = (BioseqSetPtr) sep->data.ptrvalue;
7026
if (bssp->idx.deleteme != 0) {
7029
DeleteMarkedSeqDescr (bssp->descr, (Pointer PNTR) &(bssp->descr));
7030
DeleteMarkedSeqAnnot (bssp->annot, (Pointer PNTR) &(bssp->annot));
7031
DeleteMarkedSeqEntry (bssp->seq_set, (Pointer PNTR) &(bssp->seq_set));
7036
*prevlink = sep->next;
7041
bsp->idx.prevlink = prevlink;
7042
} else if (bssp != NULL) {
7043
bssp->idx.prevlink = prevlink;
7045
prevlink = (Pointer PNTR) &(sep->next);
7051
NLM_EXTERN Boolean DeleteMarkedObjects (Uint2 entityID, Uint2 datatype, Pointer dataptr)
7058
SeqEntryPtr sep = NULL;
7062
omp = ObjMgrReadLock ();
7063
omdp = ObjMgrGetDataStruct (omp, entityID);
7065
if (omdp == NULL) return FALSE;
7066
if (omdp->choicetype == OBJ_SEQENTRY) {
7067
datatype = omdp->choicetype;
7068
dataptr = omdp->choice;
7070
datatype = omdp->datatype;
7071
dataptr = omdp->dataptr;
7075
if (datatype == 0 || dataptr == NULL) return FALSE;
7079
sep = (SeqEntryPtr) dataptr;
7082
bsp = (BioseqPtr) dataptr;
7083
sep = bsp->seqentry;
7085
case OBJ_BIOSEQSET :
7086
bssp = (BioseqSetPtr) dataptr;
7087
sep = bssp->seqentry;
7090
ssp = (SeqSubmitPtr) dataptr;
7091
if (ssp->datatype == 1) {
7092
sep = (SeqEntryPtr) ssp->data;
7099
if (sep == NULL) return FALSE;
7101
DeleteMarkedSeqEntry (sep, (Pointer PNTR) &sep);