~ubuntu-branches/ubuntu/precise/ncbi-tools6/precise

« back to all changes in this revision

Viewing changes to api/seqmgr.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2005-03-27 12:00:15 UTC
  • mfrom: (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050327120015-embhesp32nj73p9r
Tags: 6.1.20041020-3
* Fix FTBFS under GCC 4.0 caused by inconsistent use of "static" on
  functions.  (Closes: #295110.)
* Add a watch file, now that we can.  (Upstream's layout needs version=3.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*   
30
30
* Version Creation Date: 9/94
31
31
*
32
 
* $Revision: 6.171 $
 
32
* $Revision: 6.222 $
33
33
*
34
34
* File Description:  Manager for Bioseqs and BioseqSets
35
35
*
39
39
* -------  ----------  -----------------------------------------------------
40
40
*
41
41
* $Log: seqmgr.c,v $
 
42
* Revision 6.222  2004/09/07 18:50:47  bollin
 
43
* added new overlap type: RANGE_MATCH - left and right must match exactly
 
44
*
 
45
* Revision 6.221  2004/09/03 13:43:58  bollin
 
46
* added SegMgrGetLocationSupersetmRNA function
 
47
*
 
48
* Revision 6.220  2004/08/20 19:05:49  kans
 
49
* RecordFeaturesInBioseqs errors back to warning now that unindexed features are picked up by the validator
 
50
*
 
51
* Revision 6.219  2004/08/20 13:45:23  kans
 
52
* allocate ctmp again for second errpost on bad feature indexing location - was dangling
 
53
*
 
54
* Revision 6.218  2004/08/19 18:53:26  kans
 
55
* SeqMgr indexing messages raised from WARNING to ERROR
 
56
*
 
57
* Revision 6.217  2004/08/19 17:18:43  kans
 
58
* RecordFeaturesInBioseqs posts error if left or right are -1
 
59
*
 
60
* Revision 6.216  2004/06/22 17:37:25  kans
 
61
* added FreeSeqIdGiCache
 
62
*
 
63
* Revision 6.215  2004/05/13 19:38:08  kans
 
64
* SeqLocMergeExEx takes ignore_mixed so gene by overlap can ignore trans splicing confusion
 
65
*
 
66
* Revision 6.214  2004/05/04 17:34:23  bollin
 
67
* initialize variables
 
68
*
 
69
* Revision 6.213  2004/02/24 20:57:44  kans
 
70
* added genesByLocusTag field, SeqMgrGetNextGeneByLocusTag function, now that locus_tag should be a unique identifier
 
71
*
 
72
* Revision 6.212  2003/12/12 20:59:48  kans
 
73
* added StrandsMatch to consolate code after TestForOverlap, allow both on candidate to be treated as plus
 
74
*
 
75
* Revision 6.211  2003/11/13 21:59:24  kans
 
76
* GetSeqIdForGI separates SEQID_OTHER from other types, so RefSeq takes higher priority over General
 
77
*
 
78
* Revision 6.210  2003/10/24 19:49:11  kans
 
79
* operon feature of equal range sorted before gene, mRNA, CDS
 
80
*
 
81
* Revision 6.209  2003/10/23 17:40:01  kans
 
82
* added SeqMgrGetOverlappingOperon and bspextra operonsByPos and numoperons fields
 
83
*
 
84
* Revision 6.208  2003/10/02 16:12:31  bollin
 
85
* added COMMON_INTERVAL overlap type to TestForOverlap
 
86
*
 
87
* Revision 6.207  2003/09/22 17:27:29  kans
 
88
* strip RNA- prefix, not just - on RNAs
 
89
*
 
90
* Revision 6.206  2003/09/22 16:13:20  kans
 
91
* LockFarComponentsEx takes new SeqLocPtr parameter
 
92
*
 
93
* Revision 6.205  2003/09/22 15:55:06  kans
 
94
* all rna context labels were searched for dash, now just trna
 
95
*
 
96
* Revision 6.204  2003/08/04 20:41:20  kans
 
97
* SeqMgrProcessNonIndexedBioseq needed to reset version to 0 each time through outer loop (EY)
 
98
*
 
99
* Revision 6.203  2003/04/03 22:40:09  kans
 
100
* feature index location problem now reports latest identifier in record to make it easier to find problem
 
101
*
 
102
* Revision 6.202  2003/03/10 20:55:08  kans
 
103
* LockAllSegments calls LockAllBioseqs if component was itself far delta or seg
 
104
*
 
105
* Revision 6.201  2003/02/12 14:20:46  kans
 
106
* added IsNonGappedLiteral, used to allow compressed deltas as (previously always raw) parts of segsets
 
107
*
 
108
* Revision 6.200  2003/01/29 22:01:16  kans
 
109
* corrected printing in CountGapsInDeltaSeq
 
110
*
 
111
* Revision 6.199  2003/01/21 20:15:00  kans
 
112
* support for SeqMgrSetSeqIdSetFunc and GetSeqIdSetForGI needed for validator
 
113
*
 
114
* Revision 6.198  2002/12/17 17:30:10  kans
 
115
* CountGapsInDeltaSeq calls NextLitLength to sum up adjacent non-gap SeqLits, used to break up long literals or isolate small runs of ambiguous (uncompressible) sequence
 
116
*
 
117
* Revision 6.197  2002/12/03 23:09:03  kans
 
118
* added TestFeatOverlap
 
119
*
 
120
* Revision 6.196  2002/11/21 16:28:50  kans
 
121
* fixed test for INTERVAL_OVERLAP
 
122
*
 
123
* Revision 6.195  2002/11/04 21:11:58  kans
 
124
* SIMPLE_OVERLAP check now is more inclusive
 
125
*
 
126
* Revision 6.194  2002/10/23 12:57:53  kans
 
127
* do not report cds or rna already set if gps
 
128
*
 
129
* Revision 6.193  2002/06/11 14:41:20  kans
 
130
* added support for locus_tag
 
131
*
 
132
* Revision 6.192  2002/06/10 13:50:42  kans
 
133
* added SeqMgrSetLenFunc, SeqMgrSetAccnVerFunc
 
134
*
 
135
* Revision 6.191  2002/06/07 21:24:57  kans
 
136
* update entityID/omdp index in BioseqReloadFunc, ObjMgrConnectFunc, ObjMgrDetachFunc
 
137
*
 
138
* Revision 6.190  2002/06/03 17:02:27  kans
 
139
* SeqMgrGetBestOverlappingFeat calls SeqLocMergeEx for CHECK_INTERVALS without fusing joints
 
140
*
 
141
* Revision 6.189  2002/05/08 18:58:09  kans
 
142
* itemID is Uint4
 
143
*
 
144
* Revision 6.188  2002/05/07 16:16:58  kans
 
145
* Uint4 counts so as not to allocate array based on Uint2 wrapped around number
 
146
*
 
147
* Revision 6.187  2002/04/12 20:42:37  kans
 
148
* LookupFarSeqIDs has separate parameter for alignments and history
 
149
*
 
150
* Revision 6.186  2002/03/18 22:38:23  kans
 
151
* added SeqMgrGetAllOverlappingFeatures
 
152
*
 
153
* Revision 6.185  2002/03/14 18:30:00  kans
 
154
* index featsByRev on the fly if not already done when requested
 
155
*
 
156
* Revision 6.184  2002/03/14 16:40:02  kans
 
157
* SeqMgrIndexFeaturesEx takes dorevfeats, SeqMgrExploreFeaturesRev and featsByRev added for asn2gb
 
158
*
 
159
* Revision 6.183  2002/03/07 16:12:29  kans
 
160
* TrimLocInSegment for asn2gb master style to constrain feature locations within the part sequence range used by the contig
 
161
*
 
162
* Revision 6.182  2002/02/27 23:21:51  kans
 
163
* do not SeqLocMerge to get left and right extremes - it was needed for trans splicing but broke (gene) features spanning the origin
 
164
*
 
165
* Revision 6.181  2002/02/14 19:10:44  kans
 
166
* added SeqMgrGetPROTgivenProduct, index protein->product
 
167
*
 
168
* Revision 6.180  2002/02/07 14:34:51  kans
 
169
* added LOCATION_SUBSET type, use in CDS-mRNA overlap check to subclassify problem
 
170
*
 
171
* Revision 6.179  2002/02/01 21:55:48  kans
 
172
* wrong test for hit already past location to check hierarchy
 
173
*
 
174
* Revision 6.178  2002/01/23 19:26:00  kans
 
175
* swap ivals if minus strand, check internal exon boundaries only if > 1 interval
 
176
*
 
177
* Revision 6.177  2002/01/22 21:22:52  kans
 
178
* CheckInternalExonBoundaries for CHECK_INTERVALS overlap test
 
179
*
 
180
* Revision 6.176  2002/01/07 19:28:25  kans
 
181
* pass result of SeqLocMerge to GetOffsetInNearBioseq to get left and right even with trans spliced feature
 
182
*
 
183
* Revision 6.175  2001/12/28 13:33:16  kans
 
184
* LookupFarSeqIDs uses smp->seq_id_precache_func
 
185
*
 
186
* Revision 6.174  2001/12/28 13:19:11  kans
 
187
* added seq_id_precache_func, SeqMgrSetPreCache, LookupFarSeqIDs
 
188
*
 
189
* Revision 6.173  2001/12/27 17:01:53  kans
 
190
* FetchFromSeqIdGiCache can take NULL sipp
 
191
*
 
192
* Revision 6.172  2001/12/26 15:29:22  kans
 
193
* FetchFromSeqIdGiCache and RecordInSeqIdGiCache are extern
 
194
*
42
195
* Revision 6.171  2001/12/17 12:48:06  kans
43
196
* sort by position callback tests for numivals > 0
44
197
*
1214
1367
                        }
1215
1368
                        omdp = ObjMgrFindTop(omp, omp->datalist[j]);
1216
1369
                        ObjMgrUnlock();
 
1370
                        ObjMgrDeleteIndexOnEntityID (omp, oldomdp->EntityID);
1217
1371
                        omdp->EntityID = oldomdp->EntityID;
1218
1372
                        oldomdp->EntityID = 0;
 
1373
                        ObjMgrAddIndexOnEntityID (omp, omdp->EntityID, omdp);
1219
1374
 
1220
1375
                        omudp = omdp->userdata;
1221
1376
                        while (omudp != NULL)
1760
1915
static Int2 seqidcount = 0;
1761
1916
static TNlmRWlock sid_RWlock = NULL;
1762
1917
 
1763
 
static void RecordInSeqIdGiCache (Int4 gi, SeqIdPtr sip)
 
1918
NLM_EXTERN void RecordInSeqIdGiCache (Int4 gi, SeqIdPtr sip)
1764
1919
 
1765
1920
{
1766
1921
        ValNodePtr vnp, tmp;
1861
2016
  return 0;
1862
2017
}
1863
2018
 
1864
 
static Boolean FetchFromSeqIdGiCache (Int4 gi, SeqIdPtr PNTR sipp)
1865
 
 
1866
 
{
1867
 
        ValNodePtr vnp;
 
2019
NLM_EXTERN void FreeSeqIdGiCache (void)
 
2020
 
 
2021
{
 
2022
  Int4           ret;
 
2023
  SeqIdBlockPtr  sibp;
 
2024
  ValNodePtr     vnp;
 
2025
 
 
2026
  ret = NlmRWwrlock(sgi_RWlock);
 
2027
  if (ret != 0) {
 
2028
    ErrPostEx(SEV_ERROR,0,0,"FreeSeqIdGiCache: RWwrlock error [%ld]", (long) ret);
 
2029
    return;
 
2030
  }
 
2031
 
 
2032
  seqidcount = 0;
 
2033
  seqidgiarray = MemFree (seqidgiarray);
 
2034
 
 
2035
  for (vnp = seqidgicache; vnp != NULL; vnp = vnp->next) {
 
2036
    sibp = (SeqIdBlockPtr) vnp->data.ptrvalue;
 
2037
    if (sibp == NULL) continue;
 
2038
    sibp->sip = SeqIdFree (sibp->sip);
 
2039
  }
 
2040
  seqidgicache = ValNodeFreeData (seqidgicache);
 
2041
 
 
2042
  ret = NlmRWunlock(sgi_RWlock);
 
2043
  if (ret != 0) {
 
2044
    ErrPostEx(SEV_ERROR,0,0,"FreeSeqIdGiCache: RWwrlock error [%ld]", (long) ret);
 
2045
    return;
 
2046
  }
 
2047
}
 
2048
 
 
2049
NLM_EXTERN Boolean FetchFromSeqIdGiCache (Int4 gi, SeqIdPtr PNTR sipp)
 
2050
 
 
2051
{
 
2052
        ValNodePtr vnp, tmp;
1868
2053
        SeqIdBlockPtr sibp = NULL;
1869
2054
        Int2 i;
1870
2055
        Int2 left, right, mid;
1871
2056
        Int4 compare, ret;
1872
2057
        Boolean done = FALSE;
1873
2058
 
1874
 
        if (sipp == NULL) return done;
1875
 
        *sipp = NULL;
 
2059
        if (sipp != NULL) {
 
2060
          *sipp = NULL;
 
2061
        }
1876
2062
        if (seqidgicache == NULL) return done;
1877
2063
 
1878
2064
        if (seqidgiarray == NULL) {
1895
2081
                          for (vnp = seqidgicache; vnp != NULL && seqidcount > 24000;
1896
2082
                               vnp = vnp->next, seqidcount--) continue;
1897
2083
                          if (vnp != NULL) {
 
2084
                            for (tmp = vnp->next; tmp != NULL; tmp = tmp->next) {
 
2085
                              sibp = (SeqIdBlockPtr) tmp->data.ptrvalue;
 
2086
                              if (sibp == NULL) continue;
 
2087
                              sibp->sip = SeqIdFree (sibp->sip);
 
2088
                            }
1898
2089
                            vnp->next = ValNodeFreeData (vnp->next);
1899
2090
                          }
1900
2091
                        }
1949
2140
                }
1950
2141
                if (left > right + 1 && sibp != NULL) {
1951
2142
                        if (sibp->sip != NULL) {
1952
 
                                *sipp = SeqIdDup (sibp->sip);
 
2143
                                if (sipp != NULL) {
 
2144
                                        *sipp = SeqIdDup (sibp->sip);
 
2145
                                }
1953
2146
                                sibp->touch = GetSecs ();
1954
2147
                        }
1955
2148
                        done = TRUE;
1973
2166
        ObjMgrProcPtr ompp;
1974
2167
        OMProcControl ompc;
1975
2168
        Int2 ret;
1976
 
        SeqIdPtr sip, sip2=NULL, other=NULL, gb=NULL;
 
2169
        SeqIdPtr sip, sip2=NULL, otherh=NULL, otherl = NULL, gb=NULL;
1977
2170
        ValNode vn;
1978
2171
 
1979
2172
 
1996
2189
                        case SEQID_GIBBMT:
1997
2190
                  case SEQID_PATENT:
1998
2191
                        case SEQID_GENERAL:
1999
 
                                                other = sip;
 
2192
                                                otherl = sip;
2000
2193
                                                break;
2001
2194
                                        case SEQID_GI:
2002
2195
                                           break;
2013
2206
                                                gb = sip;
2014
2207
                                                break;
2015
2208
                                        default:
2016
 
                                                if (other == NULL)
2017
 
                                                        other = sip;
 
2209
                                                if (otherh == NULL)
 
2210
                                                        otherh = sip;
2018
2211
                                                break;
2019
2212
                    }
2020
2213
                }
2023
2216
 
2024
2217
        if (gb != NULL)
2025
2218
                sip2 = gb;
2026
 
        else if (other != NULL)
2027
 
                sip2 = other;
 
2219
        else if (otherh != NULL)
 
2220
                sip2 = otherh;
 
2221
        else if (otherl != NULL)
 
2222
                sip2 = otherl;
2028
2223
 
2029
2224
        if (sip2 != NULL)
2030
2225
                return SeqIdDup(sip2);
2268
2463
NLM_EXTERN ValNodePtr LIBCALL BioseqContextGetSeqDescr (BioseqContextPtr bcp, Int2 type, ValNodePtr curr, SeqEntryPtr PNTR the_sep)    /* the last one you used */
2269
2464
{
2270
2465
        Int2 i;
2271
 
        ValNodePtr tmp;
 
2466
        ValNodePtr tmp = NULL;
2272
2467
        Boolean found = FALSE;
2273
2468
        BioseqPtr bsp;
2274
2469
        BioseqSetPtr bssp;
2790
2985
        SeqInt si;
2791
2986
        ValNode vn;
2792
2987
        SeqIdPtr sip;
2793
 
        Uint2 entityID, itemID;
 
2988
        Uint2 entityID;
 
2989
        Uint2 itemID;
2794
2990
 
2795
2991
        if (region == NULL) return FALSE;
2796
2992
 
2984
3180
*      returns TRUE if values in argument were set.
2985
3181
*
2986
3182
*****************************************************************************/
 
3183
static Boolean NextLitLength (DeltaSeqPtr next, Int4Ptr lenp)
 
3184
 
 
3185
{
 
3186
  SeqLitPtr  slp;
 
3187
 
 
3188
  if (lenp == NULL) return FALSE;
 
3189
  *lenp = 0;
 
3190
  if (next == NULL || next->choice != 2) return FALSE;
 
3191
  slp = (SeqLitPtr) next->data.ptrvalue;
 
3192
  if (slp == NULL || slp->seq_data == NULL) return FALSE;
 
3193
  *lenp = slp->length;
 
3194
  return TRUE;
 
3195
}
 
3196
 
2987
3197
NLM_EXTERN Boolean LIBCALL CountGapsInDeltaSeq (BioseqPtr bsp, Int4Ptr num_segs, Int4Ptr num_gaps, Int4Ptr known_residues, Int4Ptr num_gaps_faked, CharPtr buf, Int4 buflen)
2988
3198
{
2989
3199
        Boolean retval = FALSE;
2993
3203
                len = 0,
2994
3204
                fake_gaps = 0,
2995
3205
                from = 0, 
2996
 
                tlen = 0;
2997
 
        DeltaSeqPtr dsp;
 
3206
                tlen = 0,
 
3207
                nxtlen;
 
3208
        DeltaSeqPtr dsp, next;
2998
3209
        SeqLocPtr slocp;
2999
3210
        SeqLitPtr slp;
3000
3211
        IntFuzzPtr ifp;
3009
3220
        retval = TRUE;  /* can function */
3010
3221
 
3011
3222
 
3012
 
        for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = dsp->next)
 
3223
        for (dsp = (DeltaSeqPtr)(bsp->seq_ext); dsp != NULL; dsp = next)
3013
3224
        {
 
3225
                next = dsp->next;
3014
3226
                segs++;
3015
3227
                from = len + 1;
3016
3228
                switch (dsp->choice)
3048
3260
                                if (slp->seq_data != NULL)
3049
3261
                                {
3050
3262
                                        residues += slp->length;
 
3263
                                        while (NextLitLength (next, &nxtlen)) {
 
3264
                                                tlen += nxtlen;
 
3265
                                                len  += nxtlen;
 
3266
                                                residues += nxtlen;
 
3267
                                                next = next->next;
 
3268
                                        }
3051
3269
                                        if (buf) {
3052
3270
                                                sprintf(tmp, "* %8ld %8ld: contig of %ld bp in length~", (long) from, (long) len, (long) tlen);
3053
3271
                                                blen = (Int2) MIN ((Int4) buflen, (Int4) sizeof (tmp));
3080
3298
                                                }
3081
3299
                                        }
3082
3300
                                        if (!unk && buf) {
3083
 
                                                sprintf(tmp, "* %8ld %ld: gap of %8ld bp~", (long) from, (long) len, (long) tlen);
 
3301
                                                sprintf(tmp, "* %8ld %8ld: gap of %ld bp~", (long) from, (long) len, (long) tlen);
3084
3302
                                                blen = (Int2) MIN ((Int4) buflen, (Int4) sizeof (tmp));
3085
3303
                                                diff = LabelCopy(buf, tmp, blen);
3086
3304
                                                buflen -= diff;
3296
3514
        Boolean indexed;
3297
3515
        TextSeqIdPtr tsip;
3298
3516
        SeqMgrPtr smp;
3299
 
        Int2 version = 0;
 
3517
        Int2 version;
3300
3518
        Boolean sort_now = TRUE;
3301
3519
 
3302
3520
        smp = SeqMgrReadLock();
3332
3550
                        if (bsp->id != NULL)
3333
3551
                        {
3334
3552
                                indexed = TRUE;
 
3553
                                version = 0;
3335
3554
                                for (sip = bsp->id; sip != NULL; sip = sip->next)
3336
3555
                                {
3337
3556
                                        oldchoice = 0;
3909
4128
  bspextra->featsByID = MemFree (bspextra->featsByID);
3910
4129
  bspextra->featsBySfp = MemFree (bspextra->featsBySfp);
3911
4130
  bspextra->featsByPos = MemFree (bspextra->featsByPos);
 
4131
  bspextra->featsByRev = MemFree (bspextra->featsByRev);
3912
4132
  bspextra->featsByLabel = MemFree (bspextra->featsByLabel);
3913
4133
 
3914
4134
  bspextra->genesByPos = MemFree (bspextra->genesByPos);
3916
4136
  bspextra->CDSsByPos = MemFree (bspextra->CDSsByPos);
3917
4137
  bspextra->pubsByPos = MemFree (bspextra->pubsByPos);
3918
4138
  bspextra->orgsByPos = MemFree (bspextra->orgsByPos);
 
4139
  bspextra->operonsByPos = MemFree (bspextra->operonsByPos);
 
4140
 
 
4141
  bspextra->genesByLocusTag = MemFree (bspextra->genesByLocusTag);
3919
4142
 
3920
4143
  /* free list of descriptor information */
3921
4144
 
3979
4202
  bspextra->numCDSs = 0;
3980
4203
  bspextra->numpubs = 0;
3981
4204
  bspextra->numorgs = 0;
 
4205
  bspextra->numoperons = 0;
3982
4206
  bspextra->numsegs = 0;
3983
4207
 
3984
4208
  bspextra->min = INT4_MAX;
4151
4375
 
4152
4376
/*****************************************************************************
4153
4377
*
 
4378
*   IsNonGappedLiteral(BioseqPtr bsp)
 
4379
*      Returns TRUE if bsp is a delta seq is composed only of Seq-lits with
 
4380
*      actual sequence data.  These are now made to allow optimal compression
 
4381
*      of otherwise raw sequences with runs of ambiguous bases.
 
4382
*
 
4383
*****************************************************************************/
 
4384
 
 
4385
NLM_EXTERN Boolean IsNonGappedLiteral (BioseqPtr bsp)
 
4386
 
 
4387
{
 
4388
  DeltaSeqPtr  dsp;
 
4389
  SeqLitPtr    slitp;
 
4390
 
 
4391
  if (bsp == NULL || bsp->repr != Seq_repr_delta) return FALSE;
 
4392
  if (bsp->seq_ext_type != 4 || bsp->seq_ext == NULL) return FALSE;
 
4393
 
 
4394
  for (dsp = (DeltaSeqPtr) bsp->seq_ext; dsp != NULL; dsp = dsp->next) {
 
4395
    if (dsp->choice != 2) return FALSE; /* not Seq-lit */
 
4396
    slitp = (SeqLitPtr) dsp->data.ptrvalue;
 
4397
    if (slitp == NULL) return FALSE;
 
4398
    if (slitp->seq_data == NULL || slitp->length == 0) return FALSE; /* gap */
 
4399
  }
 
4400
 
 
4401
  return TRUE;
 
4402
}
 
4403
 
 
4404
/*****************************************************************************
 
4405
*
4154
4406
*   FindAppropriateBioseq finds the segmented bioseq if location is join on parts
4155
4407
*
4156
4408
*****************************************************************************/
4178
4430
 
4179
4431
    /* first see if this is raw local part of segmented bioseq */
4180
4432
 
4181
 
    if (bsp != NULL && bsp->repr == Seq_repr_raw) {
 
4433
    if (bsp != NULL && (bsp->repr == Seq_repr_raw || IsNonGappedLiteral (bsp))) {
4182
4434
      omdp = SeqMgrGetOmdpForBioseq (bsp);
4183
4435
      if (omdp != NULL && omdp->datatype == OBJ_BIOSEQ) {
4184
4436
        bspextra = (BioseqExtraPtr) omdp->extradata;
4285
4537
  Char              buf [80];
4286
4538
  Int2              compare;
4287
4539
  Uint2             entityID;
4288
 
  Int2              i;
 
4540
  Int4              i;
4289
4541
  Int4              numsegs;
4290
4542
  ObjMgrDataPtr     omdp;
4291
4543
  BioseqPtr         parent;
4583
4835
  return NULL;
4584
4836
}
4585
4837
 
4586
 
NLM_EXTERN SMFeatItemPtr LIBCALL SeqMgrFindSMFeatItemByID (Uint2 entityID, BioseqPtr bsp, Uint2 itemID)
 
4838
NLM_EXTERN SMFeatItemPtr LIBCALL SeqMgrFindSMFeatItemByID (Uint2 entityID, BioseqPtr bsp, Uint4 itemID)
4587
4839
 
4588
4840
{
4589
4841
  SMFeatItemPtr PNTR  array;
4666
4918
}
4667
4919
 
4668
4920
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetDesiredFeature (Uint2 entityID, BioseqPtr bsp,
4669
 
                                                       Uint2 itemID, Uint2 index, SeqFeatPtr sfp,
 
4921
                                                       Uint4 itemID, Uint4 index, SeqFeatPtr sfp,
4670
4922
                                                       SeqMgrFeatContext PNTR context)
4671
4923
 
4672
4924
{
4861
5113
  return NULL;
4862
5114
}
4863
5115
 
4864
 
static SMDescItemPtr SeqMgrFindSMDescItemByIndex (BioseqExtraPtr bspextra, Uint2 index)
 
5116
static SMDescItemPtr SeqMgrFindSMDescItemByIndex (BioseqExtraPtr bspextra, Uint4 index)
4865
5117
 
4866
5118
{
4867
5119
  SMDescItemPtr PNTR  array;
4894
5146
}
4895
5147
 
4896
5148
NLM_EXTERN ValNodePtr LIBCALL SeqMgrGetDesiredDescriptor (Uint2 entityID, BioseqPtr bsp,
4897
 
                                                          Uint2 itemID, Uint2 index, ValNodePtr sdp,
 
5149
                                                          Uint4 itemID, Uint4 index, ValNodePtr sdp,
4898
5150
                                                          SeqMgrDescContext PNTR context)
4899
5151
 
4900
5152
{
4964
5216
  ValNodePtr      lastalign;
4965
5217
  SMSeqIdxPtr     segpartail;
4966
5218
  Int4            cumulative;
4967
 
  Uint2           bspcount;
4968
 
  Uint2           aligncount;
4969
 
  Uint2           descrcount;
4970
 
  Uint2           featcount;
 
5219
  Uint4           bspcount;
 
5220
  Uint4           aligncount;
 
5221
  Uint4           descrcount;
 
5222
  Uint4           featcount;
4971
5223
  Int4            seqlitid;
4972
5224
  Boolean         flip;
4973
5225
} ExtraIndex, PNTR ExtraIndexPtr;
4975
5227
static void SetDescriptorCounts (ValNodePtr sdp, ExtraIndexPtr exindx, Pointer thisitem, Uint2 thistype)
4976
5228
 
4977
5229
{
4978
 
  Uint2          count = 0;
 
5230
  Uint4          count = 0;
4979
5231
  ObjMgrDataPtr  omdp;
4980
5232
 
4981
5233
  /* count bioseq or bioseq set descriptors, to calculate omdp.lastDescrItemID */
5114
5366
  return NULL;
5115
5367
}
5116
5368
 
 
5369
static void FindGPS (BioseqSetPtr bssp, Pointer userdata)
 
5370
 
 
5371
{
 
5372
  BoolPtr  is_gpsP;
 
5373
 
 
5374
  if (bssp == NULL || bssp->_class != BioseqseqSet_class_gen_prod_set) return;
 
5375
  is_gpsP = (BoolPtr) userdata;
 
5376
  *is_gpsP = TRUE;
 
5377
}
 
5378
 
5117
5379
static void ProcessFeatureProducts (SeqFeatPtr sfp, Uint2 itemID, GatherObjectPtr gop)
5118
5380
 
5119
5381
{
5134
5396
  ValNode         vn;
5135
5397
 
5136
5398
  if (sfp == NULL || sfp->product == NULL) return;
5137
 
  if (sfp->data.choice != SEQFEAT_CDREGION && sfp->data.choice != SEQFEAT_RNA) return;
 
5399
  if (sfp->data.choice != SEQFEAT_CDREGION &&
 
5400
      sfp->data.choice != SEQFEAT_RNA &&
 
5401
      sfp->data.choice != SEQFEAT_PROT) return;
5138
5402
 
5139
5403
  sip = SeqLocId (sfp->product);
5140
5404
  if (sip == NULL) return;
5167
5431
    {
5168
5432
      GatherContext     gc;
5169
5433
      GatherContextPtr  gcp;
 
5434
      Boolean           is_gps = FALSE;
 
5435
      SeqEntryPtr       sep;
5170
5436
      MemSet ((Pointer) &gc, 0, sizeof (GatherContext));
5171
5437
      gcp = &gc;
5172
5438
      gc.entityID = gop->entityID;
5173
5439
      gc.itemID = gop->itemID;
5174
5440
      gc.thistype = gop->itemtype;
5175
 
      ErrPostItem (SEV_WARNING, 0, 0,
5176
 
                   "SeqMgr indexing cds or rna progenitor already set - Feature: %s - Location [%s] - Product [%s]",
5177
 
                   buf, loclbl, prodlbl);
 
5441
      sep = GetTopSeqEntryForEntityID (gop->entityID);
 
5442
      VisitSetsInSep (sep, (Pointer) &is_gps, FindGPS);
 
5443
      if (! is_gps) {
 
5444
        ErrPostItem (SEV_WARNING, 0, 0,
 
5445
                     "SeqMgr indexing cds or rna progenitor already set - Feature: %s - Location [%s] - Product [%s]",
 
5446
                     buf, loclbl, prodlbl);
 
5447
      }
5178
5448
    }
5179
5449
    MemFree (ctmp);
5180
5450
    MemFree (ptmp);
5188
5458
 
5189
5459
  ValNodeAddPointer (&(bspextra->prodlisthead), 0, (Pointer) sfp);
5190
5460
 
5191
 
  if (sfp->data.choice == SEQFEAT_RNA) return;
 
5461
  if (sfp->data.choice == SEQFEAT_RNA || sfp->data.choice == SEQFEAT_PROT) return;
5192
5462
 
5193
5463
  /* if protFeat exists it was set by exhaustive gather on protein bioseq */
5194
5464
 
5232
5502
 
5233
5503
static void RecordOneFeature (BioseqExtraPtr bspextra, ObjMgrDataPtr omdp,
5234
5504
                              BioseqPtr bsp, ExtraIndexPtr exindx, SeqFeatPtr sfp,
5235
 
                              Int4 left, Int4 right, Uint2 itemID, Uint2 subtype,
 
5505
                              Int4 left, Int4 right, Uint4 itemID, Uint2 subtype,
5236
5506
                              Boolean farloc, Boolean ignore)
5237
5507
 
5238
5508
{
5239
5509
  Char            buf [129];
5240
5510
  SMFeatBlockPtr  curr;
 
5511
  Int4            from;
5241
5512
  Int2            i;
5242
5513
  SMFeatItemPtr   item;
5243
5514
  Int4Ptr         ivals;
5247
5518
  CharPtr         ptr;
5248
5519
  SeqIdPtr        sip;
5249
5520
  SeqLocPtr       slp = NULL;
 
5521
  Uint1           strand;
 
5522
  Int4            swap;
 
5523
  Int4            to;
5250
5524
 
5251
5525
  if (bspextra == NULL || omdp == NULL || bsp == NULL || exindx == NULL || sfp == NULL) return;
5252
5526
 
5292
5566
        FeatDefLabel (sfp, buf, sizeof (buf) - 1, OM_LABEL_CONTENT);
5293
5567
        ptr = buf;
5294
5568
        if (sfp->data.choice == SEQFEAT_RNA) {
5295
 
          ptr = StringChr (buf, '-');
 
5569
          ptr = StringStr (buf, "RNA-");
5296
5570
          if (ptr != NULL) {
5297
 
            ptr++;
 
5571
            ptr += 4;
5298
5572
          } else {
5299
5573
            ptr = buf;
5300
5574
          }
5329
5603
        single_interval = (Boolean) (item->subtype == FEATDEF_GENE ||
5330
5604
                                     item->subtype == FEATDEF_PUB);
5331
5605
        */
5332
 
        loc = SeqLocMergeEx (bsp, sfp->location, NULL, FALSE, FALSE, FALSE, FALSE);
 
5606
        loc = SeqLocMergeExEx (bsp, sfp->location, NULL, FALSE, FALSE, FALSE, FALSE, TRUE);
5333
5607
 
5334
5608
        if (exindx->flip) {
5335
5609
          sip = SeqIdFindBest (bsp->id, 0);
5342
5616
        if (exindx->flip) {
5343
5617
          item->strand = StrandCmp (item->strand);
5344
5618
        }
 
5619
        strand = item->strand;
5345
5620
 
5346
5621
        slp = NULL;
5347
5622
        while ((slp = SeqLocFindNext (loc, slp)) != NULL) {
5354
5629
          slp = NULL;
5355
5630
          i = 0;
5356
5631
          while ((slp = SeqLocFindNext (loc, slp)) != NULL) {
5357
 
            ivals [i] = SeqLocStart (slp);
 
5632
            from = SeqLocStart (slp);
 
5633
            to = SeqLocStop (slp);
 
5634
            if (strand == Seq_strand_minus) {
 
5635
              swap = from;
 
5636
              from = to;
 
5637
              to = swap;
 
5638
            }
 
5639
            ivals [i] = from;
5358
5640
            i++;
5359
 
            ivals [i] = SeqLocStop (slp);
 
5641
            ivals [i] = to;
5360
5642
            i++;
5361
5643
          }
5362
5644
        }
5398
5680
  SeqFeatPtr      sfp = NULL;
5399
5681
  SeqAlignPtr     sal = NULL;
5400
5682
  SeqLocPtr       slp;
 
5683
  Int4            swap;
5401
5684
  SeqFeatPtr      tmp;
5402
5685
  Boolean         usingLocalBsp = FALSE;
5403
5686
  ValNode         vn;
5525
5808
      {
5526
5809
        GatherContext     gc;
5527
5810
        GatherContextPtr  gcp;
 
5811
        Char              lastbspid [41];
 
5812
        SeqIdPtr          sip;
5528
5813
        MemSet ((Pointer) &gc, 0, sizeof (GatherContext));
5529
5814
        gcp = &gc;
5530
5815
        gc.entityID = gop->entityID;
5531
5816
        gc.itemID = gop->itemID;
5532
5817
        gc.thistype = gop->itemtype;
 
5818
        lastbspid [0] = '\0';
 
5819
        if (exindx->lastbsp != NULL) {
 
5820
          sip = SeqIdFindBest (exindx->lastbsp->id, 0);
 
5821
          if (sip != NULL) {
 
5822
            SeqIdWrite (sip, lastbspid, PRINTID_FASTA_LONG, sizeof (lastbspid));
 
5823
          }
 
5824
        }
5533
5825
        ErrPostItem (SEV_WARNING, 0, 0,
5534
 
                     "SeqMgr indexing feature location problem - Feature: %s - Location [%s]",
5535
 
                     buf, loclbl);
 
5826
                     "SeqMgr indexing feature location problem - Feature: %s - Location [%s] - Record [%s]",
 
5827
                     buf, loclbl, lastbspid);
5536
5828
      }
5537
5829
    } else {
5538
5830
      /*
5566
5858
  /* get extreme left and right extents of feature location on near bioseqs */
5567
5859
  /* merge here to get correct extremes even in case of trans-splicing */
5568
5860
 
 
5861
  /* but this broke the handling of genes spanning the origin, so cannot do */
 
5862
  /*
5569
5863
  slp = SeqLocMergeEx (bsp, sfp->location, NULL, TRUE, TRUE, FALSE, FALSE);
5570
 
  left = GetOffsetInNearBioseq (sfp->location, bsp, SEQLOC_LEFT_END);
5571
 
  right = GetOffsetInNearBioseq (sfp->location, bsp, SEQLOC_RIGHT_END);
 
5864
  */
 
5865
  slp = sfp->location;
 
5866
  left = GetOffsetInNearBioseq (slp, bsp, SEQLOC_LEFT_END);
 
5867
  right = GetOffsetInNearBioseq (slp, bsp, SEQLOC_RIGHT_END);
 
5868
  /*
5572
5869
  SeqLocFree (slp);
5573
 
  if (left == -1 || right == -1) return TRUE;
 
5870
  */
 
5871
  if (left == -1 || right == -1) {
 
5872
    GatherContext     gc;
 
5873
    GatherContextPtr  gcp;
 
5874
    Char              lastbspid [41];
 
5875
    SeqIdPtr          sip;
 
5876
    MemSet ((Pointer) &gc, 0, sizeof (GatherContext));
 
5877
    gcp = &gc;
 
5878
    gc.entityID = gop->entityID;
 
5879
    gc.itemID = gop->itemID;
 
5880
    gc.thistype = gop->itemtype;
 
5881
    lastbspid [0] = '\0';
 
5882
    if (exindx->lastbsp != NULL) {
 
5883
      sip = SeqIdFindBest (exindx->lastbsp->id, 0);
 
5884
      if (sip != NULL) {
 
5885
        SeqIdWrite (sip, lastbspid, PRINTID_FASTA_LONG, sizeof (lastbspid));
 
5886
      }
 
5887
    }
 
5888
    FeatDefLabel (sfp, buf, sizeof (buf) - 1, OM_LABEL_CONTENT);
 
5889
    ctmp = SeqLocPrint (sfp->location);
 
5890
    loclbl = ctmp;
 
5891
    if (loclbl == NULL) {
 
5892
      loclbl = "?";
 
5893
    }
 
5894
    ErrPostItem (SEV_WARNING, 0, 0,
 
5895
                 "SeqMgr indexing feature mapping problem - Feature: %s - Location [%s] - Record [%s]",
 
5896
                 buf, loclbl, lastbspid);
 
5897
    MemFree (ctmp);
 
5898
    return TRUE;
 
5899
  }
5574
5900
 
5575
5901
  /* if indexing protein bioseq, store largest protein feature */
5576
5902
 
5636
5962
      left -= bsp->length;
5637
5963
    }
5638
5964
 
 
5965
    /* some trans-spliced locations can confound GetOffsetInNearBioseq, so normalize here */
 
5966
 
 
5967
    if (left > right) {
 
5968
      swap = left;
 
5969
      left = right;
 
5970
      right = swap;
 
5971
    }
 
5972
 
5639
5973
    RecordOneFeature (bspextra, omdp, bsp, exindx, sfp, left,
5640
5974
                      right, gop->itemID, gop->subtype, usingLocalBsp, FALSE);
5641
5975
 
5818
6152
*   SortFeatItemListByID callback sorts array into feature item table by itemID
5819
6153
*   SortFeatItemListBySfp sorts by feature pointer
5820
6154
*   SortFeatItemListByPos sorts by feature position
 
6155
*   SortFeatItemListByRev sorts by reverse feature position
5821
6156
*
5822
6157
*****************************************************************************/
5823
6158
 
5917
6252
  return 0;
5918
6253
}
5919
6254
 
 
6255
static int LIBCALLBACK SortFeatItemListByLocusTag (VoidPtr vp1, VoidPtr vp2)
 
6256
 
 
6257
{
 
6258
  int                 compare;
 
6259
  GeneRefPtr          grp1;
 
6260
  GeneRefPtr          grp2;
 
6261
  SeqFeatPtr          sfp1;
 
6262
  SeqFeatPtr          sfp2;
 
6263
  SMFeatItemPtr PNTR  spp1 = vp1;
 
6264
  SMFeatItemPtr PNTR  spp2 = vp2;
 
6265
  SMFeatItemPtr       sp1;
 
6266
  SMFeatItemPtr       sp2;
 
6267
 
 
6268
  if (spp1 == NULL || spp2 == NULL) return 0;
 
6269
  sp1 = *((SMFeatItemPtr PNTR) spp1);
 
6270
  sp2 = *((SMFeatItemPtr PNTR) spp2);
 
6271
  if (sp1 == NULL || sp2 == NULL) return 0;
 
6272
 
 
6273
  sfp1 = sp1->sfp;
 
6274
  sfp2 = sp2->sfp;
 
6275
  if (sfp1 == NULL || sfp2 == NULL) return 0;
 
6276
 
 
6277
  if (sfp1->data.choice != SEQFEAT_GENE || sfp2->data.choice != SEQFEAT_GENE) return 0;
 
6278
  grp1 = (GeneRefPtr) sfp1->data.value.ptrvalue;
 
6279
  grp2 = (GeneRefPtr) sfp2->data.value.ptrvalue;
 
6280
  if (grp1 == NULL || grp2 == NULL) return 0;
 
6281
 
 
6282
  /* sort by locus_tag */
 
6283
 
 
6284
  compare = StringICmp (grp1->locus_tag, grp2->locus_tag);
 
6285
  if (compare > 0) {
 
6286
    return 1;
 
6287
  } else if (compare < 0) {
 
6288
    return -1;
 
6289
  }
 
6290
 
 
6291
  /* sort by locus if locus_tag is identical */
 
6292
 
 
6293
  compare = StringICmp (grp1->locus, grp2->locus);
 
6294
  if (compare > 0) {
 
6295
    return 1;
 
6296
  } else if (compare < 0) {
 
6297
    return -1;
 
6298
  }
 
6299
 
 
6300
  /* for duplicated genes that cross origin, put ignored item last for binary search */
 
6301
 
 
6302
  if (sp1->ignore) {
 
6303
    return 1;
 
6304
  } else if (sp2->ignore) {
 
6305
    return -1;
 
6306
  }
 
6307
 
 
6308
  return 0;
 
6309
}
 
6310
 
5920
6311
static int LIBCALLBACK SortFeatItemListByPos (VoidPtr vp1, VoidPtr vp2)
5921
6312
 
5922
6313
{
5955
6346
    return -1; /* was 1 */
5956
6347
  } else if (sp1->right < sp2->right) {
5957
6348
    return 1; /* was -1 */
5958
 
 
5959
 
  /* given identical extremes, put gene features first */
5960
 
 
5961
 
  } else if (sp1->subtype == FEATDEF_GENE && sp2->subtype != FEATDEF_GENE) {
 
6349
  }
 
6350
 
 
6351
  /* given identical extremes, put operon features first */
 
6352
 
 
6353
  if (sp1->subtype == FEATDEF_operon && sp2->subtype != FEATDEF_operon) {
 
6354
    return -1;
 
6355
  } else if (sp2->subtype == FEATDEF_operon && sp1->subtype != FEATDEF_operon) {
 
6356
    return 1;
 
6357
  }
 
6358
 
 
6359
  /* then gene features */
 
6360
 
 
6361
  if (sp1->subtype == FEATDEF_GENE && sp2->subtype != FEATDEF_GENE) {
5962
6362
    return -1;
5963
6363
  } else if (sp2->subtype == FEATDEF_GENE && sp1->subtype != FEATDEF_GENE) {
5964
6364
    return 1;
6077
6477
  return 0;
6078
6478
}
6079
6479
 
 
6480
static int LIBCALLBACK SortFeatItemListByRev (VoidPtr vp1, VoidPtr vp2)
 
6481
 
 
6482
{
 
6483
  Int2                compare;
 
6484
  CdRegionPtr         crp1;
 
6485
  CdRegionPtr         crp2;
 
6486
  Int2                i;
 
6487
  Int2                j;
 
6488
  Int2                k;
 
6489
  Int2                numivals;
 
6490
  SeqAnnotPtr         sap1;
 
6491
  SeqAnnotPtr         sap2;
 
6492
  SMFeatItemPtr PNTR  spp1 = vp1;
 
6493
  SMFeatItemPtr PNTR  spp2 = vp2;
 
6494
  SMFeatItemPtr       sp1;
 
6495
  SMFeatItemPtr       sp2;
 
6496
  SeqFeatPtr          sfp1;
 
6497
  SeqFeatPtr          sfp2;
 
6498
  Uint1               subtype1;
 
6499
  Uint1               subtype2;
 
6500
 
 
6501
  if (spp1 == NULL || spp2 == NULL) return 0;
 
6502
  sp1 = *((SMFeatItemPtr PNTR) spp1);
 
6503
  sp2 = *((SMFeatItemPtr PNTR) spp2);
 
6504
  if (sp1 == NULL || sp2 == NULL) return 0;
 
6505
 
 
6506
  /* feature with largest right extreme is first */
 
6507
 
 
6508
  if (sp1->right < sp2->right) {
 
6509
    return 1;
 
6510
  } else if (sp1->right > sp2->right) {
 
6511
    return -1;
 
6512
 
 
6513
  /* reversing order so that longest feature is first */
 
6514
 
 
6515
  } else if (sp1->left < sp2->left) {
 
6516
    return -1;
 
6517
  } else if (sp1->left > sp2->left) {
 
6518
    return 1;
 
6519
  }
 
6520
 
 
6521
  /* given identical extremes, put operon features first */
 
6522
 
 
6523
  if (sp1->subtype == FEATDEF_operon && sp2->subtype != FEATDEF_operon) {
 
6524
    return -1;
 
6525
  } else if (sp2->subtype == FEATDEF_operon && sp1->subtype != FEATDEF_operon) {
 
6526
    return 1;
 
6527
  }
 
6528
 
 
6529
  /* then gene features */
 
6530
 
 
6531
  if (sp1->subtype == FEATDEF_GENE && sp2->subtype != FEATDEF_GENE) {
 
6532
    return -1;
 
6533
  } else if (sp2->subtype == FEATDEF_GENE && sp1->subtype != FEATDEF_GENE) {
 
6534
    return 1;
 
6535
  }
 
6536
 
 
6537
  /* then rna features */
 
6538
 
 
6539
  subtype1 = FindFeatFromFeatDefType (sp1->subtype);
 
6540
  subtype2 = FindFeatFromFeatDefType (sp2->subtype);
 
6541
 
 
6542
  if (subtype1 == SEQFEAT_RNA && subtype2 != SEQFEAT_RNA) {
 
6543
    return -1;
 
6544
  } else if (subtype2 == SEQFEAT_RNA && subtype1 != SEQFEAT_RNA) {
 
6545
    return 1;
 
6546
  }
 
6547
 
 
6548
  /* then cds features */
 
6549
 
 
6550
  if (sp1->subtype == FEATDEF_CDS && sp2->subtype != FEATDEF_CDS) {
 
6551
    return -1;
 
6552
  } else if (sp2->subtype == FEATDEF_CDS && sp1->subtype != FEATDEF_CDS) {
 
6553
    return 1;
 
6554
  }
 
6555
 
 
6556
  /* next compare internal intervals */
 
6557
 
 
6558
  numivals = MIN (sp1->numivals, sp2->numivals);
 
6559
  if (numivals > 0 && sp1->ivals != NULL && sp2->ivals != NULL) {
 
6560
    for (i = 0, j = sp1->numivals * 2, k = sp2->numivals * 2; i < numivals; i++) {
 
6561
 
 
6562
      /* check right interval */
 
6563
 
 
6564
      k--;
 
6565
      j--;
 
6566
      if (sp1->ivals [j] < sp2->ivals [k]) {
 
6567
        return 1;
 
6568
      } else if (sp1->ivals [j] > sp2->ivals [k]) {
 
6569
        return -1;
 
6570
      }
 
6571
 
 
6572
      /* check left interval */
 
6573
 
 
6574
      k--;
 
6575
      j--;
 
6576
      if (sp1->ivals [j] < sp2->ivals [k]) {
 
6577
        return -1;
 
6578
      } else if (sp1->ivals [j] > sp2->ivals [k]) {
 
6579
        return 1;
 
6580
      }
 
6581
    }
 
6582
  }
 
6583
 
 
6584
  /* one with fewer intervals goes first */
 
6585
 
 
6586
  if (sp1->numivals > sp2->numivals) {
 
6587
    return 1;
 
6588
  } else if (sp1->numivals < sp2->numivals) {
 
6589
    return -1;
 
6590
  }
 
6591
 
 
6592
  /* next compare other feature subtypes */
 
6593
 
 
6594
  if (sp1->subtype < sp2->subtype) {
 
6595
    return -1;
 
6596
  } else if (sp1->subtype > sp2->subtype) {
 
6597
    return 1;
 
6598
  }
 
6599
 
 
6600
  /* if identical cds ranges, compare codon_start */
 
6601
 
 
6602
  if (sp1->subtype == FEATDEF_CDS && sp2->subtype == FEATDEF_CDS) {
 
6603
    sfp1 = sp1->sfp;
 
6604
    sfp2 = sp2->sfp;
 
6605
    if (sfp1 != NULL && sfp2 != NULL) {
 
6606
      crp1 = (CdRegionPtr) sfp1->data.value.ptrvalue;
 
6607
      crp2 = (CdRegionPtr) sfp2->data.value.ptrvalue;
 
6608
      if (crp1 != NULL && crp2 != NULL) {
 
6609
        if (crp1->frame > 1 || crp2->frame > 1) {
 
6610
          if (crp1->frame < crp2->frame) {
 
6611
            return -1;
 
6612
          } else if (crp1->frame < crp2->frame) {
 
6613
            return 1;
 
6614
          }
 
6615
        }
 
6616
      }
 
6617
    }
 
6618
  }
 
6619
 
 
6620
  /* then compare feature label */
 
6621
 
 
6622
  compare = StringCmp (sp1->label, sp2->label);
 
6623
  if (compare > 0) {
 
6624
    return 1;
 
6625
  } else if (compare < 0) {
 
6626
    return -1;
 
6627
  }
 
6628
 
 
6629
  /* compare parent seq-annot by itemID (was sap pointer value) */
 
6630
 
 
6631
  sap1 = sp1->sap;
 
6632
  sap2 = sp2->sap;
 
6633
  if (sap1 != NULL && sap2 != NULL) {
 
6634
    if (sap1->idx.itemID > sap2->idx.itemID) {
 
6635
      return 1;
 
6636
    } else if (sap1->idx.itemID < sap2->idx.itemID) {
 
6637
      return -1;
 
6638
    }
 
6639
  }
 
6640
 
 
6641
  /* last comparison to make it absolutely deterministic */
 
6642
 
 
6643
  if (sp1->itemID > sp2->itemID) {
 
6644
    return 1;
 
6645
  } else if (sp1->itemID < sp2->itemID) {
 
6646
    return -1;
 
6647
  }
 
6648
 
 
6649
  return 0;
 
6650
}
 
6651
 
6080
6652
/*****************************************************************************
6081
6653
*
6082
6654
*   IndexSegmentedParts callback builds index to speed up mapping
6143
6715
 
6144
6716
  /* check for raw part packaged with segmented bioseq */
6145
6717
 
6146
 
  if (bsp->repr == Seq_repr_raw && lastsegbsp != NULL && *lastsegbsp != NULL) {
 
6718
  if ((bsp->repr == Seq_repr_raw || IsNonGappedLiteral (bsp)) && lastsegbsp != NULL && *lastsegbsp != NULL) {
6147
6719
    omdp = SeqMgrGetOmdpForBioseq (bsp);
6148
6720
    if (omdp == NULL) return;
6149
6721
 
6219
6791
*
6220
6792
*****************************************************************************/
6221
6793
 
6222
 
static void IndexRecordedFeatures (SeqEntryPtr sep)
 
6794
static void IndexRecordedFeatures (SeqEntryPtr sep, Boolean dorevfeats)
6223
6795
 
6224
6796
{
6225
6797
  BioseqPtr           bsp;
6231
6803
  SMFeatItemPtr PNTR  featsByID;
6232
6804
  SMFeatItemPtr PNTR  featsBySfp;
6233
6805
  SMFeatItemPtr PNTR  featsByPos;
 
6806
  SMFeatItemPtr PNTR  featsByRev;
6234
6807
  SMFeatItemPtr PNTR  featsByLabel;
 
6808
  SMFeatItemPtr PNTR  genesByLocusTag;
 
6809
  SMFeatItemPtr PNTR  genesByPos;
6235
6810
  Int4                i;
6236
6811
  Int4                j;
6237
6812
  SMFeatItemPtr       item;
6238
6813
  BioseqPtr           nuc;
6239
6814
  Int4                numfeats;
 
6815
  Int4                numgenes;
6240
6816
  ObjMgrDataPtr       omdp;
6241
6817
  Int4                pt;
6242
6818
  SeqLocPtr           segloc;
6249
6825
    bssp = (BioseqSetPtr) sep->data.ptrvalue;
6250
6826
    if (bssp == NULL) return;
6251
6827
    for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
6252
 
      IndexRecordedFeatures (sep);
 
6828
      IndexRecordedFeatures (sep, dorevfeats);
6253
6829
    }
6254
6830
    return;
6255
6831
  }
6331
6907
        bspextra->CDSsByPos = SeqMgrBuildFeatureIndex (bsp, &(bspextra->numCDSs), 0, FEATDEF_CDS);
6332
6908
        bspextra->pubsByPos = SeqMgrBuildFeatureIndex (bsp, &(bspextra->numpubs), 0, FEATDEF_PUB);
6333
6909
        bspextra->orgsByPos = SeqMgrBuildFeatureIndex (bsp, &(bspextra->numorgs), 0, FEATDEF_BIOSRC);
6334
 
 
 
6910
        bspextra->operonsByPos = SeqMgrBuildFeatureIndex (bsp, &(bspextra->numoperons), 0, FEATDEF_operon);
 
6911
      }
 
6912
 
 
6913
      if (dorevfeats) {
 
6914
        featsByRev = (SMFeatItemPtr PNTR) MemNew (sizeof (SMFeatItemPtr) * (numfeats + 1));
 
6915
        bspextra->featsByRev = featsByRev;
 
6916
 
 
6917
        if (featsByRev != NULL) {
 
6918
          for (i = 0; i < numfeats; i++) {
 
6919
            featsByRev [i] = featsByID [i];
 
6920
          }
 
6921
 
 
6922
          /* optionally sort all features by feature reverse location on bioseq */
 
6923
 
 
6924
          HeapSort ((VoidPtr) featsByRev, (size_t) numfeats, sizeof (SMFeatItemPtr), SortFeatItemListByRev);
 
6925
        }
6335
6926
      }
6336
6927
 
6337
6928
      featsByLabel = (SMFeatItemPtr PNTR) MemNew (sizeof (SMFeatItemPtr) * (numfeats + 1));
6346
6937
 
6347
6938
        HeapSort ((VoidPtr) featsByLabel, (size_t) numfeats, sizeof (SMFeatItemPtr), SortFeatItemListByLabel);
6348
6939
      }
 
6940
 
 
6941
      genesByPos = bspextra->genesByPos;
 
6942
      numgenes = bspextra->numgenes;
 
6943
      if (genesByPos != NULL && numgenes > 0) {
 
6944
 
 
6945
        genesByLocusTag = (SMFeatItemPtr PNTR) MemNew (sizeof (SMFeatItemPtr) * (numgenes + 1));
 
6946
        bspextra->genesByLocusTag = genesByLocusTag;
 
6947
 
 
6948
        if (genesByLocusTag != NULL) {
 
6949
          for (i = 0; i < numgenes; i++) {
 
6950
            genesByLocusTag [i] = genesByPos [i];
 
6951
          }
 
6952
 
 
6953
          /* sort by locus_tag value */
 
6954
 
 
6955
          HeapSort ((VoidPtr) genesByLocusTag, (size_t) numgenes, sizeof (SMFeatItemPtr), SortFeatItemListByLocusTag);
 
6956
        }
 
6957
      }
6349
6958
    }
6350
6959
  }
6351
6960
 
6368
6977
 
6369
6978
          /* map to segmented bioseq coordinates if necessary */
6370
6979
 
6371
 
          segloc = SeqLocMergeEx (nuc, dnaloc, NULL, FALSE, TRUE, FALSE, FALSE);
 
6980
          segloc = SeqLocMergeExEx (nuc, dnaloc, NULL, FALSE, TRUE, FALSE, FALSE, TRUE);
6372
6981
 
6373
6982
          SeqLocFree (dnaloc);
6374
6983
          if (segloc != NULL) {
6802
7411
*
6803
7412
*****************************************************************************/
6804
7413
 
6805
 
NLM_EXTERN Uint2 LIBCALL SeqMgrIndexFeaturesEx (Uint2 entityID, Pointer ptr, Boolean flip)
 
7414
NLM_EXTERN Uint2 LIBCALL SeqMgrIndexFeaturesEx (Uint2 entityID, Pointer ptr, Boolean flip, Boolean dorevfeats)
6806
7415
 
6807
7416
{
6808
7417
  BioseqExtraPtr      bspextra;
6919
7528
 
6920
7529
  /* finish building array of sorted features on each indexed bioseq */
6921
7530
 
6922
 
  IndexRecordedFeatures (sep);
 
7531
  IndexRecordedFeatures (sep, dorevfeats);
6923
7532
 
6924
7533
  /* set best protein feature for segmented protein bioseqs and their parts */
6925
7534
 
6987
7596
NLM_EXTERN Uint2 LIBCALL SeqMgrIndexFeatures (Uint2 entityID, Pointer ptr)
6988
7597
 
6989
7598
{
6990
 
  return SeqMgrIndexFeaturesEx (entityID, ptr, FALSE);
 
7599
  return SeqMgrIndexFeaturesEx (entityID, ptr, FALSE, FALSE);
6991
7600
}
6992
7601
 
6993
7602
/*****************************************************************************
7129
7738
  return sfp;
7130
7739
}
7131
7740
 
 
7741
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetPROTgivenProduct (BioseqPtr bsp,
 
7742
                                                         SeqMgrFeatContext PNTR context)
 
7743
 
 
7744
{
 
7745
  BioseqExtraPtr  bspextra;
 
7746
  ObjMgrDataPtr   omdp;
 
7747
  SeqFeatPtr      sfp;
 
7748
 
 
7749
  if (context != NULL) {
 
7750
    MemSet ((Pointer) context, 0, sizeof (SeqMgrFeatContext));
 
7751
  }
 
7752
  omdp = SeqMgrGetOmdpForBioseq (bsp);
 
7753
  if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
 
7754
  bspextra = (BioseqExtraPtr) omdp->extradata;
 
7755
  if (bspextra == NULL) return NULL;
 
7756
  sfp = bspextra->cdsOrRnaFeat;
 
7757
  if (sfp == NULL || sfp->data.choice != SEQFEAT_PROT) return NULL;
 
7758
  SetContextForFeature (sfp, context, omdp);
 
7759
  return sfp;
 
7760
}
 
7761
 
7132
7762
NLM_EXTERN ValNodePtr LIBCALL SeqMgrGetSfpProductList (BioseqPtr bsp)
7133
7763
 
7134
7764
{
7190
7820
  if (grp == NULL) return FALSE;
7191
7821
  if (grp != NULL && HasNoText (grp->locus) && HasNoText (grp->allele) &&
7192
7822
      HasNoText (grp->desc) && HasNoText (grp->maploc) &&
7193
 
      grp->db == NULL && grp->syn == NULL) return TRUE;
 
7823
      HasNoText (grp->locus_tag) && grp->db == NULL &&
 
7824
      grp->syn == NULL) return TRUE;
 
7825
  return FALSE;
 
7826
}
 
7827
 
 
7828
static Boolean CheckInternalExonBoundaries (Int2 numivalsA, Int4Ptr ivalsA, Int2 numivalsB, Int4Ptr ivalsB)
 
7829
 
 
7830
{
 
7831
  Int2  i;
 
7832
  Int2  j;
 
7833
 
 
7834
  if (numivalsA > numivalsB) return FALSE;
 
7835
  if (ivalsA == NULL || ivalsB == NULL) return TRUE;
 
7836
 
 
7837
  /* scan first exon-intron boundary against candidate start positions */
 
7838
 
 
7839
  for (i = 0; i <= numivalsB - numivalsA; i++) {
 
7840
    if (ivalsA [1] == ivalsB [2 * i + 1]) break;
 
7841
  }
 
7842
  if (i > numivalsB - numivalsA) return FALSE;
 
7843
 
 
7844
  /* scan subsequent exon-intron and intron-exon boundaries */
 
7845
 
 
7846
  for (j = 2; j <= 2 * numivalsA - 2; j++) {
 
7847
    if (ivalsA [j] != ivalsB [2 * i + j]) return FALSE;
 
7848
  }
 
7849
 
 
7850
  return TRUE;
 
7851
}
 
7852
 
 
7853
static Boolean StrandsMatch (Uint1 featstrand, Uint1 locstrand)
 
7854
 
 
7855
{
 
7856
  if (featstrand == locstrand) return TRUE;
 
7857
  if (locstrand == Seq_strand_unknown && featstrand != Seq_strand_minus) return TRUE;
 
7858
  if (featstrand == Seq_strand_unknown && locstrand != Seq_strand_minus) return TRUE;
 
7859
  if (featstrand == Seq_strand_both && locstrand != Seq_strand_minus) return TRUE;
 
7860
  if (locstrand == Seq_strand_both) return TRUE;
7194
7861
  return FALSE;
7195
7862
}
7196
7863
 
7197
7864
static Int4 TestForOverlap (SMFeatItemPtr feat, SeqLocPtr slp,
7198
 
                            Int4 left, Int4 right, Int2 overlapType)
 
7865
                            Int4 left, Int4 right, Int2 overlapType,
 
7866
                            Int2 numivals, Int4Ptr ivals)
7199
7867
 
7200
7868
{
7201
7869
  SeqLocPtr   a, b;
7204
7872
 
7205
7873
  if (overlapType == SIMPLE_OVERLAP) {
7206
7874
 
7207
 
    /* location must merely be overlapped by gene, etc. */
7208
 
 
 
7875
    /* location must merely be overlapped by gene, etc., or either one inside the other */
 
7876
 
 
7877
    if (feat->right >= left && feat->left <= right) {
 
7878
      diff = ABS (left - feat->left) + ABS (feat->right - right);
 
7879
      return diff;
 
7880
    }
 
7881
 
 
7882
    /*
7209
7883
    if ((feat->left <= left && feat->right > left) ||
7210
7884
        (feat->left < right && feat->right >= right)) {
7211
 
      diff = (left - feat->left) + (feat->right - right);
 
7885
      diff = ABS (left - feat->left) + ABS (feat->right - right);
7212
7886
      return diff;
7213
7887
    }
 
7888
    */
7214
7889
 
7215
7890
  } else if (overlapType == CONTAINED_WITHIN) {
7216
7891
 
7221
7896
      return diff;
7222
7897
    }
7223
7898
 
7224
 
  } else if (overlapType == CHECK_INTERVALS) {
 
7899
  } else if (overlapType == LOCATION_SUBSET || overlapType == CHECK_INTERVALS) {
7225
7900
 
7226
7901
    /* requires individual intervals to be completely contained within gene, etc. */
7227
7902
 
7230
7905
      if (sfp != NULL) {
7231
7906
        diff = SeqLocAinB (slp, sfp->location);
7232
7907
        if (diff >= 0) {
7233
 
          return diff;
 
7908
          if (overlapType == LOCATION_SUBSET || numivals == 1 ||
 
7909
              CheckInternalExonBoundaries (numivals, ivals, feat->numivals, feat->ivals)) {
 
7910
            return diff;
 
7911
          }
7234
7912
        }
7235
7913
      }
7236
7914
    }
7237
7915
 
7238
 
  } else if (overlapType == INTERVAL_OVERLAP) {
7239
 
 
7240
 
    /* requires overlap between at least one pair of intervals */
7241
 
 
7242
 
    if ((feat->left <= left && feat->right > left) ||
7243
 
        (feat->left < right && feat->right >= right)) {
 
7916
  } else if (overlapType == INTERVAL_OVERLAP || overlapType == COMMON_INTERVAL) {
 
7917
 
 
7918
    /* requires overlap between at least one pair of intervals (INTERVAL_OVERLAP) */
 
7919
    /* or one complete shared interval (COMMON_INTERVAL) */
 
7920
 
 
7921
    if (feat->right >= left && feat->left <= right) {
7244
7922
      sfp = feat->sfp;
7245
7923
      if (sfp != NULL) {
7246
7924
        a = SeqLocFindNext (slp, NULL);
7247
7925
        while (a != NULL) {
7248
7926
          b = SeqLocFindNext (sfp->location, NULL);
7249
7927
          while (b != NULL) {
7250
 
            if (SeqLocCompare (a, b) != SLC_NO_MATCH) {
7251
 
              diff = (left - feat->left) + (feat->right - right);
 
7928
            if ((overlapType == INTERVAL_OVERLAP
 
7929
                && SeqLocCompare (a, b) != SLC_NO_MATCH) 
 
7930
              || (overlapType == COMMON_INTERVAL
 
7931
                && SeqLocCompare (a, b) == SLC_A_EQ_B))
 
7932
            {
 
7933
              diff = ABS (left - feat->left) + ABS (feat->right - right);
7252
7934
              return diff;
7253
7935
            }
7254
7936
            b = SeqLocFindNext (sfp->location, b);
7258
7940
      }
7259
7941
    }
7260
7942
  }
 
7943
  else if (overlapType == RANGE_MATCH)
 
7944
  {
 
7945
        /* left and right ends must match exactly */
 
7946
        if (feat->right == right && feat->left == left)
 
7947
        {
 
7948
          return 0;
 
7949
        }
 
7950
  }
7261
7951
 
7262
7952
  return -1;
7263
7953
}
7264
7954
 
 
7955
static void SeqMgrBestOverlapSetContext (
 
7956
  SMFeatItemPtr best,
 
7957
  ObjMgrDataPtr omdp,
 
7958
  Pointer userdata,
 
7959
  SeqMgrFeatContext PNTR context
 
7960
)
 
7961
 
 
7962
{
 
7963
  SeqFeatPtr  bst;
 
7964
 
 
7965
  if (best != NULL && omdp != NULL && context != NULL) {
 
7966
    bst = best->sfp;
 
7967
    context->entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
 
7968
    context->itemID = best->itemID;
 
7969
    context->sfp = best->sfp;
 
7970
    context->sap = best->sap;
 
7971
    context->bsp = best->bsp;
 
7972
    context->label = best->label;
 
7973
    context->left = best->left;
 
7974
    context->right = best->right;
 
7975
    context->dnaStop = best->dnaStop;
 
7976
    context->partialL = best->partialL;
 
7977
    context->partialR = best->partialR;
 
7978
    context->farloc = best->farloc;
 
7979
    context->strand = best->strand;
 
7980
    if (bst != NULL) {
 
7981
      context->seqfeattype = bst->data.choice;
 
7982
    } else {
 
7983
      context->seqfeattype = FindFeatFromFeatDefType (best->subtype);
 
7984
    }
 
7985
    context->featdeftype = best->subtype;
 
7986
    context->numivals = best->numivals;
 
7987
    context->ivals = best->ivals;
 
7988
    context->userdata = userdata;
 
7989
    context->omdp = (Pointer) omdp;
 
7990
    context->index = best->index + 1;
 
7991
  }
 
7992
}
 
7993
 
7265
7994
static SeqFeatPtr SeqMgrGetBestOverlappingFeat (SeqLocPtr slp, Uint2 subtype,
7266
7995
                                                SMFeatItemPtr PNTR array,
7267
7996
                                                Int4 num, Int4Ptr pos,
7268
7997
                                                Int2 overlapType,
7269
 
                                                SeqMgrFeatContext PNTR context)
 
7998
                                                SeqMgrFeatContext PNTR context,
 
7999
                                                Int2Ptr count,
 
8000
                                                Pointer userdata,
 
8001
                                                SeqMgrFeatExploreProc userfunc)
7270
8002
 
7271
8003
{
7272
8004
  SMFeatItemPtr   best = NULL;
7273
8005
  BioseqPtr       bsp;
7274
8006
  BioseqExtraPtr  bspextra;
7275
 
  SeqFeatPtr      bst;
7276
8007
  Int4            diff;
7277
8008
  Uint2           entityID;
7278
8009
  SMFeatItemPtr   feat;
 
8010
  Int4            from;
 
8011
  Boolean         goOn = TRUE;
7279
8012
  Int4            hier = -1;
7280
 
  Uint2           index = 0;
 
8013
  Int2            i;
 
8014
  Uint4           index = 0;
 
8015
  Int4Ptr         ivals = NULL;
7281
8016
  Int4            L;
7282
8017
  Int4            left;
7283
8018
  SeqLocPtr       loc;
7284
8019
  Int4            max = INT4_MAX;
7285
8020
  Int4            mid;
 
8021
  Int2            numivals = 0;
7286
8022
  SeqEntryPtr     oldscope;
7287
8023
  ObjMgrDataPtr   omdp;
7288
8024
  SMFeatItemPtr   prev;
7290
8026
  Int4            right;
7291
8027
  SeqEntryPtr     sep;
7292
8028
  Uint1           strand;
 
8029
  Int4            swap;
 
8030
  SeqLocPtr       tmp;
 
8031
  Int4            to;
7293
8032
 
7294
8033
  if (context != NULL) {
7295
8034
    MemSet ((Pointer) context, 0, sizeof (SeqMgrFeatContext));
7297
8036
  if (pos != NULL) {
7298
8037
    *pos = 0;
7299
8038
  }
 
8039
  if (count != NULL) {
 
8040
    *count = 0;
 
8041
  }
7300
8042
  if (slp == NULL) return NULL;
7301
8043
 
7302
8044
  bsp = FindAppropriateBioseq (slp, NULL);
7330
8072
      array = bspextra->orgsByPos;
7331
8073
      num = bspextra->numorgs;
7332
8074
      break;
 
8075
        case FEATDEF_operon :
 
8076
      array = bspextra->operonsByPos;
 
8077
      num = bspextra->numoperons;
7333
8078
    default :
7334
8079
      break;
7335
8080
  }
7369
8114
 
7370
8115
  feat = array [R];
7371
8116
 
7372
 
  if (feat != NULL && feat->left > right && R > 0) {
 
8117
  if (feat != NULL && feat->left > left && R > 0) {
7373
8118
 
7374
8119
    /* if hit is already past location, location was in between local hits */
7375
8120
 
7387
8132
    hier = feat->overlap;
7388
8133
  }
7389
8134
 
7390
 
  loc = SeqLocMergeEx (bsp, slp, NULL, FALSE, TRUE, FALSE, FALSE);
 
8135
  loc = SeqLocMergeExEx (bsp, slp, NULL, FALSE, /* TRUE */ FALSE, FALSE, FALSE, TRUE);
7391
8136
  strand = SeqLocStrand (loc);
 
8137
  if (overlapType == CHECK_INTERVALS) {
 
8138
    tmp = NULL;
 
8139
    while ((tmp = SeqLocFindNext (loc, tmp)) != NULL) {
 
8140
      numivals++;
 
8141
    }
 
8142
    if (numivals > 0) {
 
8143
      ivals = MemNew (sizeof (Int4) * (numivals * 2));
 
8144
      if (ivals != NULL) {
 
8145
        tmp = NULL;
 
8146
        i = 0;
 
8147
        while ((tmp = SeqLocFindNext (loc, tmp)) != NULL) {
 
8148
          from = SeqLocStart (tmp);
 
8149
          to = SeqLocStop (tmp);
 
8150
          if (strand == Seq_strand_minus) {
 
8151
            swap = from;
 
8152
            from = to;
 
8153
            to = swap;
 
8154
          }
 
8155
          ivals [i] = from;
 
8156
          i++;
 
8157
          ivals [i] = to;
 
8158
          i++;
 
8159
        }
 
8160
      }
 
8161
    }
 
8162
  }
7392
8163
  SeqLocFree (loc);
7393
8164
 
7394
8165
  /* linear scan to smallest covering gene, publication, biosource, etc. */
7397
8168
 
7398
8169
    /* requires feature to be contained within gene, etc. */
7399
8170
 
7400
 
    diff = TestForOverlap (feat, slp, left, right, overlapType);
 
8171
    diff = TestForOverlap (feat, slp, left, right, overlapType, numivals, ivals);
7401
8172
    if (diff >= 0) {
7402
8173
 
7403
 
      if (feat->strand == strand ||
7404
 
          (strand == Seq_strand_unknown && feat->strand != Seq_strand_minus) ||
7405
 
          (feat->strand == Seq_strand_unknown && strand != Seq_strand_minus) ||
7406
 
          strand == Seq_strand_both) {
 
8174
      if (StrandsMatch (feat->strand, strand)) {
 
8175
 
 
8176
        if (userfunc != NULL && context != NULL && goOn) {
 
8177
          SeqMgrBestOverlapSetContext (feat, omdp, userdata, context);
 
8178
          if (! userfunc (feat->sfp, context)) {
 
8179
            goOn = FALSE;
 
8180
          }
 
8181
          if (count != NULL) {
 
8182
            (*count)++;
 
8183
          }
 
8184
        }
 
8185
 
7407
8186
        /* diff = (left - feat->left) + (feat->right - right); */
7408
8187
        if (diff < max) {
7409
8188
          best = feat;
7423
8202
    feat = array [hier];
7424
8203
    if (feat != NULL) {
7425
8204
 
7426
 
      diff = TestForOverlap (feat, slp, left, right, overlapType);
 
8205
      diff = TestForOverlap (feat, slp, left, right, overlapType, numivals, ivals);
7427
8206
      if (diff >= 0) {
7428
8207
 
7429
 
        if (feat->strand == strand ||
7430
 
            (strand == Seq_strand_unknown && feat->strand != Seq_strand_minus) ||
7431
 
            (feat->strand == Seq_strand_unknown && strand != Seq_strand_minus)) {
 
8208
        if (StrandsMatch (feat->strand, strand)) {
 
8209
 
 
8210
          if (userfunc != NULL && context != NULL && goOn) {
 
8211
            SeqMgrBestOverlapSetContext (feat, omdp, userdata, context);
 
8212
            if (! userfunc (feat->sfp, context)) {
 
8213
              goOn = FALSE;
 
8214
            }
 
8215
            if (count != NULL) {
 
8216
              (*count)++;
 
8217
            }
 
8218
          }
 
8219
 
7432
8220
          /* diff = (left - feat->left) + (feat->right - right); */
7433
8221
          if (diff < max) {
7434
8222
            best = feat;
7443
8231
    }
7444
8232
  }
7445
8233
 
 
8234
  if (ivals != NULL) {
 
8235
    ivals = MemFree (ivals);
 
8236
  }
7446
8237
 
7447
8238
  if (best != NULL) {
7448
8239
    if (pos != NULL) {
7449
8240
      *pos = index + 1;
7450
8241
    }
7451
8242
    if (context != NULL) {
7452
 
      bst = best->sfp;
7453
 
      context->entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
7454
 
      context->itemID = best->itemID;
7455
 
      context->sfp = best->sfp;
7456
 
      context->sap = best->sap;
7457
 
      context->bsp = best->bsp;
7458
 
      context->label = best->label;
7459
 
      context->left = best->left;
7460
 
      context->right = best->right;
7461
 
      context->dnaStop = best->dnaStop;
7462
 
      context->partialL = best->partialL;
7463
 
      context->partialR = best->partialR;
7464
 
      context->farloc = best->farloc;
7465
 
      context->strand = best->strand;
7466
 
      if (bst != NULL) {
7467
 
        context->seqfeattype = bst->data.choice;
7468
 
      } else {
7469
 
        context->seqfeattype = FindFeatFromFeatDefType (best->subtype);
7470
 
      }
7471
 
      context->featdeftype = best->subtype;
7472
 
      context->numivals = best->numivals;
7473
 
      context->ivals = best->ivals;
7474
 
      context->userdata = NULL;
7475
 
      context->omdp = (Pointer) omdp;
7476
 
      context->index = best->index + 1;
 
8243
      SeqMgrBestOverlapSetContext (best, omdp, userdata, context);
7477
8244
    }
7478
8245
    return best->sfp;
7479
8246
  }
7481
8248
  return NULL;
7482
8249
}
7483
8250
 
 
8251
NLM_EXTERN Int4 TestFeatOverlap (SeqFeatPtr sfpA, SeqFeatPtr sfpB, Int2 overlapType)
 
8252
 
 
8253
{
 
8254
  Int4           diff;
 
8255
  SMFeatItemPtr  sfipA, sfipB;
 
8256
 
 
8257
  if (sfpA == NULL || sfpB == NULL) return -1;
 
8258
  sfipA = SeqMgrFindSMFeatItemPtr (sfpA);
 
8259
  sfipB = SeqMgrFindSMFeatItemPtr (sfpB);
 
8260
  if (sfipA == NULL || sfipB == NULL) return -1;
 
8261
 
 
8262
  diff = TestForOverlap (sfipB, sfpA->location, sfipA->left, sfipA->right,
 
8263
                         overlapType, sfipA->numivals, sfipA->ivals);
 
8264
  if (diff < 0) return -1;
 
8265
 
 
8266
  if (StrandsMatch (sfipB->strand, sfipA->strand)) {
 
8267
    return diff;
 
8268
  }
 
8269
 
 
8270
  return -1;
 
8271
}
 
8272
 
7484
8273
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingGene (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
7485
8274
 
7486
8275
{
7487
 
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_GENE, NULL, 0, NULL, CONTAINED_WITHIN, context);
 
8276
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_GENE, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
7488
8277
}
7489
8278
 
7490
8279
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingmRNA (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
7491
8280
 
7492
8281
{
7493
 
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_mRNA, NULL, 0, NULL, CONTAINED_WITHIN, context);
 
8282
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_mRNA, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
 
8283
}
 
8284
 
 
8285
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetLocationSupersetmRNA (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
 
8286
 
 
8287
{
 
8288
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_mRNA, NULL, 0, NULL, LOCATION_SUBSET, context, NULL, NULL, NULL);
7494
8289
}
7495
8290
 
7496
8291
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingCDS (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
7497
8292
 
7498
8293
{
7499
 
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_CDS, NULL, 0, NULL, CONTAINED_WITHIN, context);
 
8294
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_CDS, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
7500
8295
}
7501
8296
 
7502
8297
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingPub (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
7503
8298
 
7504
8299
{
7505
 
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_PUB, NULL, 0, NULL, CONTAINED_WITHIN, context);
 
8300
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_PUB, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
7506
8301
}
7507
8302
 
7508
8303
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingSource (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
7509
8304
 
7510
8305
{
7511
 
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_BIOSRC, NULL, 0, NULL, CONTAINED_WITHIN, context);
 
8306
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_BIOSRC, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
 
8307
}
 
8308
 
 
8309
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetOverlappingOperon (SeqLocPtr slp, SeqMgrFeatContext PNTR context)
 
8310
 
 
8311
{
 
8312
  return SeqMgrGetBestOverlappingFeat (slp, FEATDEF_operon, NULL, 0, NULL, CONTAINED_WITHIN, context, NULL, NULL, NULL);
7512
8313
}
7513
8314
 
7514
8315
/*****************************************************************************
7715
8516
 
7716
8517
{
7717
8518
  return SeqMgrGetBestOverlappingFeat (slp, subtype, (SMFeatItemPtr PNTR) featarray,
7718
 
                                       numfeats, position, overlapType, context);
 
8519
                                       numfeats, position, overlapType, context, NULL, NULL, NULL);
 
8520
}
 
8521
 
 
8522
NLM_EXTERN Int2 LIBCALL SeqMgrGetAllOverlappingFeatures (SeqLocPtr slp, Uint2 subtype,
 
8523
                                                         VoidPtr featarray,
 
8524
                                                         Int4 numfeats,
 
8525
                                                         Int2 overlapType,
 
8526
                                                         Pointer userdata,
 
8527
                                                         SeqMgrFeatExploreProc userfunc)
 
8528
 
 
8529
{
 
8530
  SeqMgrFeatContext  context;
 
8531
  Int2               count;
 
8532
 
 
8533
  SeqMgrGetBestOverlappingFeat (slp, subtype, (SMFeatItemPtr PNTR) featarray,
 
8534
                                numfeats, NULL, overlapType, &context, &count,
 
8535
                                userdata, userfunc);
 
8536
 
 
8537
  return count;
7719
8538
}
7720
8539
 
7721
8540
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetFeatureInIndex (BioseqPtr bsp, VoidPtr featarray,
7722
 
                                                       Int4 numfeats, Uint2 index,
 
8541
                                                       Int4 numfeats, Uint4 index,
7723
8542
                                                       SeqMgrFeatContext PNTR context)
7724
8543
 
7725
8544
{
7889
8708
static SeqFeatPtr LIBCALL SeqMgrGetNextFeatureEx (BioseqPtr bsp, SeqFeatPtr curr,
7890
8709
                                                  Uint1 seqFeatChoice, Uint1 featDefChoice,
7891
8710
                                                  SeqMgrFeatContext PNTR context,
7892
 
                                                  Boolean byLabel)
 
8711
                                                  Boolean byLabel, Boolean byLocusTag)
7893
8712
 
7894
8713
{
7895
8714
  SMFeatItemPtr PNTR  array = NULL;
7896
8715
  BioseqExtraPtr      bspextra;
7897
8716
  Uint2               entityID;
7898
 
  Uint2               i;
 
8717
  Uint4               i;
7899
8718
  SMFeatItemPtr       item;
 
8719
  Int4                num = 0;
7900
8720
  ObjMgrDataPtr       omdp;
7901
8721
  Uint1               seqfeattype;
7902
8722
 
7918
8738
  if (omdp == NULL) return NULL;
7919
8739
  bspextra = (BioseqExtraPtr) omdp->extradata;
7920
8740
  if (bspextra == NULL) return NULL;
7921
 
  if (byLabel) {
 
8741
  if (byLocusTag) {
 
8742
    array = bspextra->genesByLocusTag;
 
8743
    num = bspextra->numgenes;
 
8744
  } else if (byLabel) {
7922
8745
    array = bspextra->featsByLabel;
 
8746
    num = bspextra->numfeats;
7923
8747
  } else {
7924
8748
    array = bspextra->featsByPos;
 
8749
    num = bspextra->numfeats;
7925
8750
  }
7926
 
  if (array == NULL || bspextra->numfeats < 1) return NULL;
 
8751
  if (array == NULL || num < 1) return NULL;
7927
8752
 
7928
8753
  entityID = ObjMgrGetEntityIDForPointer (omdp->dataptr);
7929
8754
 
7931
8756
 
7932
8757
  /* now look for next appropriate feature */
7933
8758
 
7934
 
  while (i < bspextra->numfeats) {
 
8759
  while (i < num) {
7935
8760
    item = array [i];
7936
8761
    if (item != NULL) {
7937
8762
      curr = item->sfp;
7960
8785
          context->ivals = item->ivals;
7961
8786
          context->userdata = NULL;
7962
8787
          context->omdp = (Pointer) omdp;
7963
 
          if (byLabel) {
 
8788
          if (byLocusTag) {
 
8789
            context->index = i;
 
8790
          } else if (byLabel) {
7964
8791
            context->index = i;
7965
8792
          } else {
7966
8793
            context->index = item->index + 1;
7979
8806
                                                    SeqMgrFeatContext PNTR context)
7980
8807
 
7981
8808
{
7982
 
  return SeqMgrGetNextFeatureEx (bsp, curr, seqFeatChoice, featDefChoice, context, FALSE);
 
8809
  return SeqMgrGetNextFeatureEx (bsp, curr, seqFeatChoice, featDefChoice, context, FALSE, FALSE);
7983
8810
}
7984
8811
 
7985
8812
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetNextFeatureByLabel (BioseqPtr bsp, SeqFeatPtr curr,
7987
8814
                                                           SeqMgrFeatContext PNTR context)
7988
8815
 
7989
8816
{
7990
 
  return SeqMgrGetNextFeatureEx (bsp, curr, seqFeatChoice, featDefChoice, context, TRUE);
 
8817
  return SeqMgrGetNextFeatureEx (bsp, curr, seqFeatChoice, featDefChoice, context, TRUE, FALSE);
 
8818
}
 
8819
 
 
8820
NLM_EXTERN SeqFeatPtr LIBCALL SeqMgrGetNextGeneByLocusTag (BioseqPtr bsp, SeqFeatPtr curr,
 
8821
                                                           SeqMgrFeatContext PNTR context
 
8822
)
 
8823
 
 
8824
{
 
8825
  return SeqMgrGetNextFeatureEx (bsp, curr, SEQFEAT_GENE, 0, context, FALSE, TRUE);
7991
8826
}
7992
8827
 
7993
8828
/*****************************************************************************
8001
8836
                                   SeqMgrBioseqContextPtr context,
8002
8837
                                   SeqMgrBioseqExploreProc userfunc,
8003
8838
                                   Boolean nucs, Boolean prots, Boolean parts,
8004
 
                                   Int2Ptr count)
 
8839
                                   Int4Ptr count)
8005
8840
 
8006
8841
{
8007
8842
  BioseqPtr       bsp;
8066
8901
  return TRUE;
8067
8902
}
8068
8903
 
8069
 
NLM_EXTERN Int2 LIBCALL SeqMgrExploreBioseqs (Uint2 entityID, Pointer ptr, Pointer userdata,
 
8904
NLM_EXTERN Int4 LIBCALL SeqMgrExploreBioseqs (Uint2 entityID, Pointer ptr, Pointer userdata,
8070
8905
                                              SeqMgrBioseqExploreProc userfunc,
8071
8906
                                              Boolean nucs, Boolean prots, Boolean parts)
8072
8907
 
8073
8908
{
8074
8909
  SeqMgrBioseqContext  context;
8075
 
  Int2                 count = 0;
 
8910
  Int4                 count = 0;
8076
8911
  SeqEntryPtr          sep;
8077
8912
 
8078
8913
  if (entityID == 0) {
8094
8929
  return count;
8095
8930
}
8096
8931
 
8097
 
NLM_EXTERN Int2 LIBCALL SeqMgrExploreSegments (BioseqPtr bsp, Pointer userdata,
 
8932
NLM_EXTERN Int4 LIBCALL SeqMgrExploreSegments (BioseqPtr bsp, Pointer userdata,
8098
8933
                                               SeqMgrSegmentExploreProc userfunc)
8099
8934
 
8100
8935
{
8101
8936
  BioseqExtraPtr        bspextra;
8102
8937
  SeqMgrSegmentContext  context;
8103
 
  Int2                  count = 0;
 
8938
  Int4                  count = 0;
8104
8939
  Uint2                 entityID;
8105
 
  Uint2                 i;
 
8940
  Uint4                 i;
8106
8941
  ObjMgrDataPtr         omdp;
8107
8942
  SMSeqIdxPtr PNTR      partsByLoc;
8108
8943
  SMSeqIdxPtr           segpartptr;
8145
8980
  return count;
8146
8981
}
8147
8982
 
8148
 
NLM_EXTERN Int2 LIBCALL SeqMgrExploreDescriptors (BioseqPtr bsp, Pointer userdata,
 
8983
NLM_EXTERN Int4 LIBCALL SeqMgrExploreDescriptors (BioseqPtr bsp, Pointer userdata,
8149
8984
                                                  SeqMgrDescExploreProc userfunc,
8150
8985
                                                  BoolPtr seqDescFilter)
8151
8986
 
8152
8987
{
8153
8988
  BioseqSetPtr       bssp;
8154
8989
  SeqMgrDescContext  context;
8155
 
  Int2               count = 0;
 
8990
  Int4               count = 0;
8156
8991
  Uint2              entityID;
8157
 
  Uint2              itemID;
 
8992
  Uint4              itemID;
8158
8993
  ObjMgrDataPtr      omdp;
8159
8994
  ValNodePtr         sdp;
8160
8995
  SeqEntryPtr        sep;
8213
9048
  return count;
8214
9049
}
8215
9050
 
8216
 
NLM_EXTERN Int2 LIBCALL SeqMgrExploreFeatures (BioseqPtr bsp, Pointer userdata,
8217
 
                                               SeqMgrFeatExploreProc userfunc,
8218
 
                                               SeqLocPtr locationFilter,
8219
 
                                               BoolPtr seqFeatFilter, BoolPtr featDefFilter)
 
9051
static Int4 LIBCALL SeqMgrExploreFeaturesInt (BioseqPtr bsp, Pointer userdata,
 
9052
                                              SeqMgrFeatExploreProc userfunc,
 
9053
                                              SeqLocPtr locationFilter,
 
9054
                                              BoolPtr seqFeatFilter,
 
9055
                                              BoolPtr featDefFilter,
 
9056
                                              Boolean doreverse)
8220
9057
 
8221
9058
{
8222
9059
  BioseqExtraPtr      bspextra;
8223
9060
  SeqMgrFeatContext   context;
8224
 
  Int2                count = 0;
 
9061
  Int4                count = 0;
8225
9062
  Uint2               entityID;
 
9063
  SMFeatItemPtr PNTR  featsByID;
8226
9064
  SMFeatItemPtr PNTR  featsByPos;
8227
 
  Uint2               i;
 
9065
  SMFeatItemPtr PNTR  featsByRev;
 
9066
  Uint4               i;
8228
9067
  SMFeatItemPtr       item;
8229
9068
  Int4                left = INT4_MIN;
8230
9069
  ObjMgrDataPtr       omdp;
8231
9070
  Int4                right = INT4_MAX;
8232
9071
  Uint1               seqfeattype;
8233
9072
  SeqFeatPtr          sfp;
8234
 
  Uint2               start = 0;
 
9073
  Uint4               start = 0;
8235
9074
  Int4                tmp;
8236
9075
 
8237
9076
  omdp = SeqMgrGetOmdpForBioseq (bsp);
8241
9080
 
8242
9081
  bspextra = (BioseqExtraPtr) omdp->extradata;
8243
9082
  if (bspextra == NULL) return 0;
8244
 
  featsByPos = bspextra->featsByPos;
 
9083
 
 
9084
  if (doreverse) {
 
9085
    if (bspextra->featsByRev == NULL) {
 
9086
 
 
9087
      /* index by reverse position if not already done */
 
9088
 
 
9089
      featsByRev = (SMFeatItemPtr PNTR) MemNew (sizeof (SMFeatItemPtr) * (bspextra->numfeats + 1));
 
9090
      bspextra->featsByRev = featsByRev;
 
9091
 
 
9092
      if (featsByRev != NULL) {
 
9093
        featsByID = bspextra->featsByID;
 
9094
        for (i = 0; i < bspextra->numfeats; i++) {
 
9095
          featsByRev [i] = featsByID [i];
 
9096
        }
 
9097
 
 
9098
        /* sort all features by feature reverse location on bioseq */
 
9099
 
 
9100
        HeapSort ((VoidPtr) featsByRev, (size_t) bspextra->numfeats, sizeof (SMFeatItemPtr), SortFeatItemListByRev);
 
9101
      }
 
9102
    }
 
9103
 
 
9104
    featsByPos = bspextra->featsByRev;
 
9105
  } else {
 
9106
    featsByPos = bspextra->featsByPos;
 
9107
  }
8245
9108
  if (featsByPos == NULL || bspextra->numfeats < 1) return 0;
8246
9109
 
8247
9110
  if (locationFilter != NULL) {
8291
9154
 
8292
9155
      /* can exit once past rightmost limit */
8293
9156
 
8294
 
      if (locationFilter != NULL && item->left > right) return count;
 
9157
      if (locationFilter != NULL && (! doreverse) && item->left > right) return count;
 
9158
      if (locationFilter != NULL && (doreverse) && item->right < left) return count;
8295
9159
 
8296
9160
      sfp = item->sfp;
8297
9161
      if (sfp != NULL) {
8333
9197
  return count;
8334
9198
}
8335
9199
 
 
9200
NLM_EXTERN Int4 LIBCALL SeqMgrExploreFeatures (BioseqPtr bsp, Pointer userdata,
 
9201
                                               SeqMgrFeatExploreProc userfunc,
 
9202
                                               SeqLocPtr locationFilter,
 
9203
                                               BoolPtr seqFeatFilter,
 
9204
                                               BoolPtr featDefFilter)
 
9205
 
 
9206
{
 
9207
  return SeqMgrExploreFeaturesInt (bsp, userdata, userfunc, locationFilter, seqFeatFilter, featDefFilter, FALSE);
 
9208
}
 
9209
 
 
9210
NLM_EXTERN Int4 LIBCALL SeqMgrExploreFeaturesRev (BioseqPtr bsp, Pointer userdata,
 
9211
                                                  SeqMgrFeatExploreProc userfunc,
 
9212
                                                  SeqLocPtr locationFilter,
 
9213
                                                  BoolPtr seqFeatFilter,
 
9214
                                                  BoolPtr featDefFilter)
 
9215
 
 
9216
{
 
9217
  return SeqMgrExploreFeaturesInt (bsp, userdata, userfunc, locationFilter, seqFeatFilter, featDefFilter, TRUE);
 
9218
}
 
9219
 
8336
9220
static Int2 VisitDescriptorsPerSeqEntry (Uint2 entityID, SeqEntryPtr sep,
8337
9221
                                         Pointer userdata, SeqMgrDescExploreProc userfunc,
8338
9222
                                         BoolPtr seqDescFilter)
8675
9559
  return -1;
8676
9560
}
8677
9561
 
 
9562
/*****************************************************************************
 
9563
*
 
9564
*   TrimLocInSegment takes a location on an indexed far segmented part and trims
 
9565
*     trims it to the region referred to by the parent segmented or delta bioseq.
 
9566
*
 
9567
*     Only implemented for seqloc_int components, not seqloc_point
 
9568
*
 
9569
*****************************************************************************/
 
9570
 
 
9571
NLM_EXTERN SeqLocPtr TrimLocInSegment (
 
9572
  BioseqPtr master,
 
9573
  SeqLocPtr location,
 
9574
  BoolPtr p5ptr,
 
9575
  BoolPtr p3ptr
 
9576
)
 
9577
 
 
9578
{
 
9579
  BioseqPtr         bsp;
 
9580
  BioseqExtraPtr    bspextra;
 
9581
  Char              buf [80];
 
9582
  Int2              compare;
 
9583
  ObjMgrDataPtr     omdp;
 
9584
  Boolean           partial5;
 
9585
  Boolean           partial3;
 
9586
  SMSeqIdxPtr PNTR  partsBySeqId;
 
9587
  SeqLocPtr         rsult = NULL;
 
9588
  SMSeqIdxPtr       segpartptr;
 
9589
  CharPtr           seqIdOfPart;
 
9590
  SeqIdPtr          sip;
 
9591
  SeqIntPtr         sint;
 
9592
  SeqLocPtr         slp;
 
9593
  Uint1             strand;
 
9594
  Int2              L, R, mid;
 
9595
  Int4              start, stop, swap;
 
9596
 
 
9597
  if (master == NULL || location == NULL) return NULL;
 
9598
 
 
9599
  omdp = SeqMgrGetOmdpForBioseq (master);
 
9600
  if (omdp == NULL || omdp->datatype != OBJ_BIOSEQ) return NULL;
 
9601
  bspextra = (BioseqExtraPtr) omdp->extradata;
 
9602
  if (bspextra == NULL) return NULL;
 
9603
 
 
9604
  partsBySeqId = bspextra->partsBySeqId;
 
9605
  if (partsBySeqId == NULL || bspextra->numsegs < 1) return NULL;
 
9606
 
 
9607
  partial5 = FALSE;
 
9608
  partial3 = FALSE;
 
9609
 
 
9610
  if (p5ptr != NULL) {
 
9611
    partial5 = *p5ptr;
 
9612
  }
 
9613
  if (p3ptr != NULL) {
 
9614
    partial3 = *p3ptr;
 
9615
  }
 
9616
 
 
9617
  for (slp = SeqLocFindNext (location, NULL);
 
9618
       slp != NULL;
 
9619
       slp = SeqLocFindNext (location, slp)) {
 
9620
    if (slp->choice != SEQLOC_INT) continue;
 
9621
    sint = (SeqIntPtr) slp->data.ptrvalue;
 
9622
    if (sint == NULL) continue;
 
9623
    strand = sint->strand;
 
9624
 
 
9625
    bsp = BioseqFind (sint->id);
 
9626
    if (bsp == NULL) continue;
 
9627
 
 
9628
    for (sip = bsp->id; sip != NULL; sip = sip->next) {
 
9629
      if (! MakeReversedSeqIdString (sip, buf, sizeof (buf) - 1)) continue;
 
9630
 
 
9631
      L = 0;
 
9632
      R = bspextra->numsegs - 1;
 
9633
      while (L < R) {
 
9634
        mid = (L + R) / 2;
 
9635
        segpartptr = partsBySeqId [mid];
 
9636
        compare = StringCmp (segpartptr->seqIdOfPart, buf);
 
9637
        if (compare < 0) {
 
9638
          L = mid + 1;
 
9639
        } else {
 
9640
          R = mid;
 
9641
        }
 
9642
      }
 
9643
 
 
9644
      segpartptr = partsBySeqId [R];
 
9645
      seqIdOfPart = segpartptr->seqIdOfPart;
 
9646
 
 
9647
      while (R < bspextra->numsegs && StringCmp (seqIdOfPart, buf) == 0) {
 
9648
 
 
9649
        start = sint->from;
 
9650
        stop = sint->to;
 
9651
 
 
9652
        if ((sint->from <= segpartptr->from && sint->to > segpartptr->from) ||
 
9653
            (sint->from < segpartptr->to && sint->to >= segpartptr->to)) {
 
9654
 
 
9655
          if (sint->from < segpartptr->from) {
 
9656
            start = segpartptr->from;
 
9657
            if (strand == Seq_strand_minus || strand == Seq_strand_both_rev) {
 
9658
              partial3 = TRUE;
 
9659
            } else {
 
9660
              partial5 = TRUE;
 
9661
            }
 
9662
          }
 
9663
          if (sint->to > segpartptr->to) {
 
9664
            stop = segpartptr->to;
 
9665
            if (strand == Seq_strand_minus || strand == Seq_strand_both_rev) {
 
9666
              partial5 = TRUE;
 
9667
            } else {
 
9668
              partial3 = TRUE;
 
9669
            }
 
9670
          }
 
9671
 
 
9672
          if (strand == Seq_strand_minus || strand == Seq_strand_both_rev) {
 
9673
            swap = start;
 
9674
            start = stop;
 
9675
            stop = swap;
 
9676
          }
 
9677
 
 
9678
          rsult = AddIntervalToLocation (rsult, sint->id, start, stop, FALSE, FALSE);
 
9679
        }
 
9680
 
 
9681
        R++;
 
9682
        if (R < bspextra->numsegs) {
 
9683
          segpartptr = partsBySeqId [R];
 
9684
          seqIdOfPart = segpartptr->seqIdOfPart;
 
9685
        } else {
 
9686
          seqIdOfPart = NULL;
 
9687
        }
 
9688
      }
 
9689
    }
 
9690
  }
 
9691
 
 
9692
  if (p5ptr != NULL) {
 
9693
    *p5ptr = partial5;
 
9694
  }
 
9695
  if (p3ptr != NULL) {
 
9696
    *p3ptr = partial3;
 
9697
  }
 
9698
 
 
9699
  return rsult;
 
9700
}
 
9701
 
 
9702
static void LockAllBioseqs (BioseqPtr bsp, Pointer userdata);
 
9703
 
8678
9704
static void LockAllSegments (SeqLocPtr slp, ValNodePtr PNTR vnpp)
8679
9705
 
8680
9706
{
8708
9734
 
8709
9735
  bsp = BioseqLockById (sip);
8710
9736
  ValNodeAddPointer (vnpp, 0, (Pointer) bsp);
 
9737
 
 
9738
  /* now recurse if component is also far delta or seg */
 
9739
 
 
9740
  if (bsp != NULL) {
 
9741
    if (bsp->repr == Seq_repr_seg || bsp->repr == Seq_repr_delta) {
 
9742
      LockAllBioseqs (bsp, (Pointer) vnpp);
 
9743
    }
 
9744
  }
8711
9745
}
8712
9746
 
8713
9747
static void LockAllBioseqs (BioseqPtr bsp, Pointer userdata)
8778
9812
  }
8779
9813
}
8780
9814
 
8781
 
NLM_EXTERN ValNodePtr LockFarComponentsEx (SeqEntryPtr sep, Boolean components, Boolean locations, Boolean products)
 
9815
static void LockAllSublocs (SeqLocPtr loc, Pointer userdata)
 
9816
 
 
9817
{
 
9818
  SeqLocPtr        slp = NULL;
 
9819
  ValNodePtr PNTR  vnpp;
 
9820
 
 
9821
  if (loc == NULL) return;
 
9822
  vnpp = (ValNodePtr PNTR) userdata;
 
9823
  if (vnpp == NULL) return;
 
9824
 
 
9825
  while ((slp = SeqLocFindNext (loc, slp)) != NULL) {
 
9826
    if (slp != NULL && slp->choice != SEQLOC_NULL) {
 
9827
      LockAllSegments (slp, vnpp);
 
9828
    }
 
9829
  }
 
9830
}
 
9831
 
 
9832
NLM_EXTERN ValNodePtr LockFarComponentsEx (SeqEntryPtr sep, Boolean components, Boolean locations, Boolean products, SeqLocPtr loc)
8782
9833
 
8783
9834
{
8784
9835
  ValNodePtr   bsplist = NULL;
8795
9846
  if (products) {
8796
9847
    VisitFeaturesInSep (sep, (Pointer) &bsplist, LockAllProducts);
8797
9848
  }
 
9849
  if (loc != NULL) {
 
9850
    LockAllSublocs (sep, (Pointer) &bsplist);
 
9851
  }
8798
9852
  SeqEntrySetScope (oldsep);
8799
9853
  return bsplist;
8800
9854
}
8802
9856
NLM_EXTERN ValNodePtr LockFarComponents (SeqEntryPtr sep)
8803
9857
 
8804
9858
{
8805
 
  return LockFarComponentsEx (sep, TRUE, FALSE, FALSE);
 
9859
  return LockFarComponentsEx (sep, TRUE, FALSE, FALSE, NULL);
8806
9860
}
8807
9861
 
8808
9862
NLM_EXTERN ValNodePtr UnlockFarComponents (ValNodePtr bsplist)
8821
9875
  return ValNodeFree (bsplist);
8822
9876
}
8823
9877
 
 
9878
/*****************************************************************************
 
9879
*
 
9880
*   SeqMgrSetPreCache
 
9881
*       registers the GiToSeqID precache function
 
9882
*   LookupFarSeqIDs
 
9883
*       calls any registered function to preload the cache
 
9884
*
 
9885
*****************************************************************************/
 
9886
 
 
9887
NLM_EXTERN void LIBCALL SeqMgrSetPreCache (SIDPreCacheFunc func)
 
9888
 
 
9889
{
 
9890
  SeqMgrPtr  smp;
 
9891
 
 
9892
  smp = SeqMgrWriteLock ();
 
9893
  if (smp == NULL) return;
 
9894
  smp->seq_id_precache_func = func;
 
9895
  SeqMgrUnlock ();
 
9896
}
 
9897
 
 
9898
NLM_EXTERN Int4 LookupFarSeqIDs (
 
9899
  SeqEntryPtr sep,
 
9900
  Boolean components,
 
9901
  Boolean locations,
 
9902
  Boolean products,
 
9903
  Boolean alignments,
 
9904
  Boolean history
 
9905
)
 
9906
 
 
9907
{
 
9908
  SIDPreCacheFunc  func;
 
9909
  SeqMgrPtr        smp;
 
9910
 
 
9911
  smp = SeqMgrReadLock ();
 
9912
  if (smp == NULL) return 0;
 
9913
  func = smp->seq_id_precache_func;
 
9914
  SeqMgrUnlock ();
 
9915
  if (func == NULL) return 0;
 
9916
  return (*func) (sep, components, locations, products, alignments, history);
 
9917
}
 
9918
 
 
9919
/*****************************************************************************
 
9920
*
 
9921
*   SeqMgrSetSeqIdSetFunc
 
9922
*       registers the GiToSeqIdSet lookup function
 
9923
*   GetSeqIdSetForGI
 
9924
*       calls any registered function to lookup the set of SeqIds
 
9925
*
 
9926
*****************************************************************************/
 
9927
 
 
9928
NLM_EXTERN void LIBCALL SeqMgrSetSeqIdSetFunc (SeqIdSetLookupFunc func)
 
9929
 
 
9930
{
 
9931
  SeqMgrPtr  smp;
 
9932
 
 
9933
  smp = SeqMgrWriteLock ();
 
9934
  if (smp == NULL) return;
 
9935
  smp->seq_id_set_lookup_func = func;
 
9936
  SeqMgrUnlock ();
 
9937
}
 
9938
 
 
9939
NLM_EXTERN SeqIdPtr LIBCALL GetSeqIdSetForGI (Int4 gi)
 
9940
 
 
9941
{
 
9942
  SeqIdSetLookupFunc  func;
 
9943
  SeqMgrPtr           smp;
 
9944
 
 
9945
  smp = SeqMgrReadLock ();
 
9946
  if (smp == NULL) return 0;
 
9947
  func = smp->seq_id_set_lookup_func;
 
9948
  SeqMgrUnlock ();
 
9949
  if (func == NULL) return 0;
 
9950
  return (*func) (gi);
 
9951
}
 
9952
 
 
9953
/*****************************************************************************
 
9954
*
 
9955
*   SeqMgrSetLenFunc
 
9956
*       registers the GiToSeqLen lookup function
 
9957
*   SeqMgrSetAccnVerFunc
 
9958
*       registers the GiToAccnVer lookup function
 
9959
*
 
9960
*****************************************************************************/
 
9961
 
 
9962
NLM_EXTERN void LIBCALL SeqMgrSetLenFunc (SeqLenLookupFunc func)
 
9963
 
 
9964
{
 
9965
  SeqMgrPtr  smp;
 
9966
 
 
9967
  smp = SeqMgrWriteLock ();
 
9968
  if (smp == NULL) return;
 
9969
  smp->seq_len_lookup_func = func;
 
9970
  SeqMgrUnlock ();
 
9971
}
 
9972
 
 
9973
NLM_EXTERN void LIBCALL SeqMgrSetAccnVerFunc (AccnVerLookupFunc func)
 
9974
 
 
9975
{
 
9976
  SeqMgrPtr  smp;
 
9977
 
 
9978
  smp = SeqMgrWriteLock ();
 
9979
  if (smp == NULL) return;
 
9980
  smp->accn_ver_lookup_func = func;
 
9981
  SeqMgrUnlock ();
 
9982
}
 
9983
 
8824
9984
/*******************************************************************
8825
9985
*
8826
9986
*   SeqEntryAsnOut()