|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/api/asn2gnb3.c |
source navigation diff markup identifier search freetext search file search |
1 /* asn2gnb3.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: asn2gnb3.c
27 *
28 * Author: Karl Sirotkin, Tom Madden, Tatiana Tatusov, Jonathan Kans,
29 * Mati Shomrat
30 *
31 * Version Creation Date: 10/21/98
32 *
33 * $Revision: 1.120 $
34 *
35 * File Description: New GenBank flatfile generator - work in progress
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * ==========================================================================
40 */
41
42 #include <ncbi.h>
43 #include <objall.h>
44 #include <objsset.h>
45 #include <objsub.h>
46 #include <objfdef.h>
47 #include <objpubme.h>
48 #include <seqport.h>
49 #include <sequtil.h>
50 #include <sqnutils.h>
51 #include <subutil.h>
52 #include <tofasta.h>
53 #include <explore.h>
54 #include <gbfeat.h>
55 #include <gbftdef.h>
56 #include <edutil.h>
57 #include <alignmgr2.h>
58 #include <asn2gnbi.h>
59
60 #ifdef WIN_MAC
61 #if __profile__
62 #include <Profiler.h>
63 #endif
64 #endif
65
66 static CharPtr ref_link = "http://www.ncbi.nlm.nih.gov/RefSeq/";
67
68 static CharPtr doc_link = "http://www.ncbi.nlm.nih.gov/genome/guide/build.shtml";
69
70 static CharPtr ev_link = "http://www.ncbi.nlm.nih.gov/sutils/evv.cgi?";
71
72 static CharPtr link_encode = "http://www.nhgri.nih.gov/10005107";
73
74 static CharPtr link_seqn = "http://www.ncbi.nlm.nih.gov/nuccore/";
75 static CharPtr link_seqp = "http://www.ncbi.nlm.nih.gov/protein/";
76
77 static CharPtr link_gold_stamp_id = "http://genomesonline.org/GOLD_CARDS/";
78
79
80 /* ********************************************************************** */
81
82 static void AddHistCommentString (
83 IntAsn2gbJobPtr ajp,
84 StringItemPtr ffstring,
85 CharPtr prefix,
86 CharPtr suffix,
87 DatePtr dp,
88 SeqIdPtr ids,
89 Boolean is_na
90 )
91
92 {
93 Int2 count = 0;
94 Char buf [256];
95 Boolean first;
96 Int4 gi = 0;
97 SeqIdPtr sip;
98 CharPtr strd;
99
100 if (dp == NULL || ids == NULL || prefix == NULL || suffix == NULL || ffstring == NULL) return;
101
102 strd = asn2gb_PrintDate (dp);
103 if (strd == NULL) {
104 strd = StringSave ("?");
105 }
106
107 for (sip = ids; sip != NULL; sip = sip->next) {
108 if (sip->choice == SEQID_GI) {
109 gi = (long) sip->data.intvalue;
110 count++;
111 }
112 }
113
114 if (count > 1) {
115 sprintf (buf, "%s or before %s %s", prefix, strd, suffix);
116 } else {
117 sprintf (buf, "%s %s %s", prefix, strd, suffix);
118 }
119 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
120
121 MemFree (strd);
122
123 if (gi == 0) {
124 FFAddOneString (ffstring, " gi:?", FALSE, FALSE, TILDE_EXPAND);
125 return;
126 }
127
128 first = TRUE;
129 for (sip = ids; sip != NULL; sip = sip->next) {
130 if (sip->choice == SEQID_GI) {
131 gi = (long) sip->data.intvalue;
132 if (! first) {
133 FFAddOneString (ffstring, ",", FALSE, FALSE, TILDE_IGNORE);
134 }
135 first = FALSE;
136 if ( GetWWW(ajp) ) {
137 FFAddOneString (ffstring, " gi:", FALSE, FALSE, TILDE_IGNORE);
138 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
139 if (is_na) {
140 FF_Add_NCBI_Base_URL (ffstring, link_seqn);
141 } else {
142 FF_Add_NCBI_Base_URL (ffstring, link_seqp);
143 }
144 sprintf (buf, "%ld", (long) gi);
145 FFAddTextToString (ffstring, /* "val=" */ NULL, buf, "\">", FALSE, FALSE, TILDE_IGNORE);
146 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
147 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
148 } else {
149 sprintf (buf, " gi:%ld", (long) gi);
150 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
151 }
152 }
153 }
154
155 FFAddOneString (ffstring, ".", FALSE, FALSE, TILDE_EXPAND);
156 }
157
158 static void AddHTGSCommentString (
159 StringItemPtr ffstring,
160 BioseqPtr bsp,
161 MolInfoPtr mip
162 )
163
164 {
165 CharPtr buf = NULL;
166 Char buffer [256];
167 Int4 buflen = 0;
168 DeltaSeqPtr dsp;
169 ValNodePtr head = NULL;
170 Int4 num_s = 0;
171 Int4 num_g = 0;
172 CharPtr str = NULL;
173
174 if (bsp == NULL || mip == NULL || mip->tech < 2) return;
175
176 if (bsp->repr == Seq_repr_delta) {
177 for (dsp = (DeltaSeqPtr) bsp->seq_ext, buflen = 0; dsp != NULL; dsp = dsp->next) {
178 buflen += 80;
179 }
180 if (buflen > 0) {
181 buf = MemNew ((size_t) (buflen + 1));
182 if (buf == NULL) return;
183 CountGapsInDeltaSeq (bsp, &num_s, &num_g, NULL, NULL, buf, buflen);
184 }
185 }
186
187 if (mip->tech == MI_TECH_htgs_0) {
188
189 if (num_s > 0) {
190 sprintf (buffer, "* NOTE: This record contains %ld individual~", (long) (num_g + 1));
191 ValNodeCopyStr (&head, 0, buffer);
192 ValNodeCopyStr (&head, 0, "* sequencing reads that have not been assembled into~");
193 ValNodeCopyStr (&head, 0, "* contigs. Runs of N are used to separate the reads~");
194 ValNodeCopyStr (&head, 0, "* and the order in which they appear is completely~");
195 ValNodeCopyStr (&head, 0, "* arbitrary. Low-pass sequence sampling is useful for~");
196 ValNodeCopyStr (&head, 0, "* identifying clones that may be gene-rich and allows~");
197 ValNodeCopyStr (&head, 0, "* overlap relationships among clones to be deduced.~");
198 ValNodeCopyStr (&head, 0, "* However, it should not be assumed that this clone~");
199 ValNodeCopyStr (&head, 0, "* will be sequenced to completion. In the event that~");
200 ValNodeCopyStr (&head, 0, "* the record is updated, the accession number will~");
201 ValNodeCopyStr (&head, 0, "* be preserved.");
202 }
203 ValNodeCopyStr (&head, 0, "~");
204 ValNodeCopyStr (&head, 0, buf);
205
206 } else if (mip->tech == MI_TECH_htgs_1) {
207
208 ValNodeCopyStr (&head, 0, "* NOTE: This is a \"working draft\" sequence.");
209 if (num_s > 0) {
210 sprintf (buffer, " It currently~* consists of %ld contigs. The true order of the pieces~", (long) (num_g + 1));
211 ValNodeCopyStr (&head, 0, buffer);
212 ValNodeCopyStr (&head, 0, "* is not known and their order in this sequence record is~");
213 ValNodeCopyStr (&head, 0, "* arbitrary. Gaps between the contigs are represented as~");
214 ValNodeCopyStr (&head, 0, "* runs of N, but the exact sizes of the gaps are unknown.");
215 }
216 ValNodeCopyStr (&head, 0, "~* This record will be updated with the finished sequence~");
217 ValNodeCopyStr (&head, 0, "* as soon as it is available and the accession number will~");
218 ValNodeCopyStr (&head, 0, "* be preserved.");
219 ValNodeCopyStr (&head, 0, "~");
220 ValNodeCopyStr (&head, 0, buf);
221
222 } else if (mip->tech == MI_TECH_htgs_2) {
223
224 ValNodeCopyStr (&head, 0, "* NOTE: This is a \"working draft\" sequence.");
225 if (num_s > 0) {
226 sprintf (buffer, " It currently~* consists of %ld contigs. Gaps between the contigs~", (long) (num_g + 1));
227 ValNodeCopyStr (&head, 0, buffer);
228 ValNodeCopyStr (&head, 0, "* are represented as runs of N. The order of the pieces~");
229 ValNodeCopyStr (&head, 0, "* is believed to be correct as given, however the sizes~");
230 ValNodeCopyStr (&head, 0, "* of the gaps between them are based on estimates that have~");
231 ValNodeCopyStr (&head, 0, "* provided by the submittor.");
232 }
233 ValNodeCopyStr (&head, 0, "~* This sequence will be replaced~");
234 ValNodeCopyStr (&head, 0, "* by the finished sequence as soon as it is available and~");
235 ValNodeCopyStr (&head, 0, "* the accession number will be preserved.");
236 ValNodeCopyStr (&head, 0, "~");
237 ValNodeCopyStr (&head, 0, buf);
238
239 } else if ((str = StringForSeqTech (mip->tech)) != NULL) {
240
241 sprintf (buffer, "Method: %s.", str);
242 ValNodeCopyStr (&head, 0, buffer);
243 }
244
245 MemFree (buf);
246
247 str = MergeFFValNodeStrs (head);
248
249 FFAddOneString (ffstring, str, TRUE, TRUE, TILDE_EXPAND);
250
251 MemFree (str);
252 ValNodeFreeData (head);
253 }
254
255 static void AddWGSMasterCommentString (
256 StringItemPtr ffstring,
257 BioseqPtr bsp,
258 CharPtr wgsaccn,
259 CharPtr wgsname
260 )
261
262 {
263 size_t acclen;
264 BioSourcePtr biop;
265 Char buf [256];
266 SeqMgrDescContext dcontext;
267 CharPtr first = NULL;
268 CharPtr last = NULL;
269 ObjectIdPtr oip;
270 OrgRefPtr orp;
271 SeqDescrPtr sdp;
272 CharPtr taxname = NULL;
273 UserFieldPtr ufp;
274 UserObjectPtr uop;
275 Char ver [16];
276
277 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
278 if (sdp != NULL) {
279 biop = (BioSourcePtr) sdp->data.ptrvalue;
280 if (biop != NULL) {
281 orp = biop->org;
282 if (orp != NULL) {
283 taxname = orp->taxname;
284 }
285 }
286 }
287
288 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
289 while (sdp != NULL) {
290 uop = (UserObjectPtr) sdp->data.ptrvalue;
291 if (uop != NULL) {
292 oip = uop->type;
293 if (oip != NULL && StringICmp (oip->str, "WGSProjects") == 0) {
294 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
295 oip = ufp->label;
296 if (oip == NULL || oip->str == NULL || ufp->choice != 1) continue;
297 if (StringICmp (oip->str, "WGS_accession_first") == 0) {
298 first = (CharPtr) ufp->data.ptrvalue;
299 } else if (StringICmp (oip->str, "WGS_accession_last") == 0) {
300 last = (CharPtr) ufp->data.ptrvalue;
301 }
302 }
303 }
304 }
305 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
306 }
307
308 if (StringHasNoText (taxname)) {
309 taxname = "?";
310 }
311 ver [0] = '\0';
312 acclen = StringLen (wgsname);
313 if (acclen == 12) {
314 StringCpy (ver, wgsname + 4);
315 ver [2] = '\0';
316 } else if (acclen == 13) {
317 StringCpy (ver, wgsname + 4);
318 ver [2] = '\0';
319 } else if (acclen == 15) {
320 StringCpy (ver, wgsname + 7);
321 ver [2] = '\0';
322 }
323
324 sprintf (buf, "The %s whole genome shotgun (WGS) project has the project accession %s.", taxname, wgsaccn);
325 FFAddOneString(ffstring, buf, TRUE, FALSE, TILDE_EXPAND);
326
327 sprintf (buf, " This version of the project (%s) has the accession number %s", ver, wgsname);
328 FFAddOneString(ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
329
330 if (first == NULL && last == NULL) {
331 sprintf (buf, ".");
332 FFAddOneString(ffstring, buf, TRUE, FALSE, TILDE_EXPAND);
333 } else {
334 if (first != NULL && last == NULL) {
335 last = first;
336 } else if (first == NULL && last != NULL) {
337 first = last;
338 }
339 if (StringDoesHaveText (first) && StringDoesHaveText (last)) {
340 if (StringCmp (first, last) != 0) {
341 sprintf (buf, ", and consists of sequences %s-%s.", first, last);
342 FFAddOneString(ffstring, buf, TRUE, FALSE, TILDE_EXPAND);
343 } else {
344 sprintf (buf, ", and consists of sequence %s.", first);
345 FFAddOneString(ffstring, buf, TRUE, FALSE, TILDE_EXPAND);
346 }
347 } else {
348 sprintf (buf, ".");
349 FFAddOneString(ffstring, buf, TRUE, FALSE, TILDE_EXPAND);
350 }
351 }
352 }
353
354
355 static CharPtr GetMolInfoCommentString (
356 BioseqPtr bsp,
357 MolInfoPtr mip
358 )
359
360 {
361 Boolean is_aa;
362 CharPtr str = NULL;
363
364 if (bsp == NULL || mip == NULL) return NULL;
365
366 is_aa = ISA_aa (bsp->mol);
367 switch (mip->completeness) {
368 case 1 :
369 str = "COMPLETENESS: full length";
370 break;
371 case 2 :
372 str = "COMPLETENESS: not full length";
373 break;
374 case 3 :
375 if (is_aa) {
376 str = "COMPLETENESS: incomplete on the amino end";
377 } else {
378 str = "COMPLETENESS: incomplete on the 5' end";
379 }
380 break;
381 case 4 :
382 if (is_aa) {
383 str = "COMPLETENESS: incomplete on the carboxy end";
384 } else {
385 str = "COMPLETENESS: incomplete on the 3' end";
386 }
387 break;
388 case 5 :
389 str = "COMPLETENESS: incomplete on both ends";
390 break;
391 case 6 :
392 if (is_aa) {
393 str = "COMPLETENESS: complete on the amino end";
394 } else {
395 str = "COMPLETENESS: complete on the 5' end";
396 }
397 break;
398 case 7 :
399 if (is_aa) {
400 str = "COMPLETENESS: complete on the carboxy end";
401 } else {
402 str = "COMPLETENESS: complete on the 3' end";
403 }
404 break;
405 default :
406 str = "COMPLETENESS: unknown";
407 break;
408 }
409
410 return str;
411 }
412
413 static CharPtr GetStrForBankit (
414 UserObjectPtr uop
415 )
416
417 {
418 CharPtr bic = NULL, uvc = NULL, ptr;
419 ObjectIdPtr oip;
420 UserFieldPtr ufp;
421
422 if (uop == NULL) return NULL;
423 if ((oip = uop->type) == NULL) return NULL;
424 if (StringCmp (oip->str, "Submission") != 0) return NULL;
425
426 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
427 oip = ufp->label;
428 if (StringCmp(oip->str, "UniVecComment") == 0) {
429 uvc = ufp->data.ptrvalue;
430 } else if (StringCmp(oip->str, "AdditionalComment") == 0) {
431 bic = ufp->data.ptrvalue;
432 }
433 }
434
435 if (uvc == NULL && bic == NULL) return NULL;
436
437 ptr = (CharPtr) MemNew (StringLen (uvc) + StringLen (bic) + 45);
438 if (uvc != NULL && bic != NULL) {
439 sprintf (ptr, "Vector Explanation: %s~Bankit Comment: %s", uvc, bic);
440 } else if (uvc != NULL) {
441 sprintf (ptr, "Vector Explanation: %s", uvc);
442 } else if (bic != NULL) {
443 sprintf (ptr, "Bankit Comment: %s", bic);
444 }
445
446 return ptr;
447 }
448
449 static CharPtr reftxt0 = " The reference sequence was derived from ";
450 static CharPtr reftxtg = " The reference sequence was generated based on analysis of ";
451 static CharPtr reftxti = " The reference sequence is identical to ";
452 static CharPtr reftxt1 = " This record is predicted by genome sequence analysis and is not yet supported by experimental evidence.";
453 static CharPtr reftxt2 = " This record has not yet been subject to final NCBI review.";
454 static CharPtr reftxt3 = " This record has not been reviewed and the function is unknown.";
455 static CharPtr reftxt4 = " This record has undergone validation or preliminary review.";
456 static CharPtr reftxt5 = " This record has been curated by ";
457 static CharPtr reftxt6 = " This record is predicted by automated computational analysis.";
458 static CharPtr reftxt7 = " This record is provided to represent a collection of whole genome shotgun sequences.";
459 static CharPtr reftxt9 = " This record is derived from an annotated genomic sequence (";
460 static CharPtr reftxt21 = "NCBI contigs are derived from assembled genomic sequence data.";
461 static CharPtr reftxt22 = " Features on this sequence have been produced for build ";
462 static CharPtr reftxt23 = " of the NCBI's genome annotation";
463 static CharPtr reftxt41 = " This record is based on preliminary annotation provided by ";
464
465 static CharPtr GetStatusForRefTrack (
466 UserObjectPtr uop
467 )
468
469 {
470 CharPtr st;
471 ObjectIdPtr oip;
472 UserFieldPtr ufp, urf = NULL;
473
474 if (uop == NULL) return NULL;
475 if ((oip = uop->type) == NULL) return NULL;
476 if (StringCmp (oip->str, "RefGeneTracking") != 0) return NULL;
477 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
478 oip = ufp->label;
479 if (StringCmp(oip->str, "Assembly") == 0) {
480 urf = ufp;
481 }
482 }
483 /* if (urf == NULL || urf->choice != 11) return NULL; */
484 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
485 oip = ufp->label;
486 if (StringCmp (oip->str, "Status") == 0) {
487 st = (CharPtr) ufp->data.ptrvalue;
488 if (StringICmp (st, "Inferred") == 0) {
489 return "INFERRED ";
490 } else if (StringICmp (st, "Provisional") == 0) {
491 return "PROVISIONAL ";
492 } else if (StringICmp (st, "Predicted") == 0) {
493 return "PREDICTED ";
494 } else if (StringICmp (st, "Validated") == 0) {
495 return "VALIDATED ";
496 } else if (StringICmp (st, "Reviewed") == 0) {
497 return "REVIEWED ";
498 } else if (StringICmp (st, "Model") == 0) {
499 return "MODEL ";
500 } else if (StringICmp (st, "WGS") == 0) {
501 return "WGS ";
502 } else if (StringICmp (st, "Pipeline") == 0) {
503 return "Pipeline ";
504 }
505 }
506 }
507 return NULL;
508 }
509
510
511 static Boolean URLHasSuspiciousHtml (
512 IntAsn2gbJobPtr ajp,
513 CharPtr searchString
514 )
515
516 {
517 Char ch;
518 CharPtr ptr;
519 Int4 state;
520 ValNodePtr matches;
521
522 if (StringHasNoText (searchString)) return FALSE;
523
524 state = 0;
525 ptr = searchString;
526 ch = *ptr;
527
528 while (ch != '\0') {
529 matches = NULL;
530 ch = TO_LOWER (ch);
531 state = TextFsaNext (ajp->bad_html_fsa, state, ch, &matches);
532 if (matches != NULL) {
533 return TRUE;
534 }
535 ptr++;
536 ch = *ptr;
537 }
538
539 return FALSE;
540 }
541
542 static Boolean GetGiFromAccnDotVer (CharPtr source, Int4Ptr gip)
543
544 {
545 Int4 gi = 0;
546 SeqIdPtr sip;
547
548 if (StringHasNoText (source) || gip == NULL) return FALSE;
549 *gip = 0;
550
551 sip = SeqIdFromAccessionDotVersion (source);
552 if (sip == NULL) return FALSE;
553 gi = GetGIForSeqId (sip);
554 SeqIdFree (sip);
555 if (gi == 0) return FALSE;
556
557 *gip = gi;
558 return TRUE;
559 }
560
561 static void AddStrForRefTrack (
562 IntAsn2gbJobPtr ajp,
563 StringItemPtr ffstring,
564 UserObjectPtr uop,
565 Boolean is_na,
566 CharPtr genomeBuildNumber,
567 CharPtr genomeVersionNumber
568 )
569
570 {
571 CharPtr accn, curator = NULL, name, source = NULL, st, url = NULL;
572 Char buf [64];
573 ObjectIdPtr oip;
574 UserFieldPtr ufp, tmp, u, urf = NULL;
575 Int4 from, to, gi;
576 Int2 i = 0;
577 Int2 review = 0;
578 Boolean generated = FALSE, identical = FALSE;
579
580 if ( uop == NULL || ffstring == NULL ) return;
581 if ((oip = uop->type) == NULL) return;
582 if (StringCmp (oip->str, "RefGeneTracking") != 0) return;
583
584 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
585 oip = ufp->label;
586 if (StringCmp(oip->str, "Assembly") == 0) {
587 urf = ufp;
588 } else if (StringCmp(oip->str, "IdenticalTo") == 0) {
589 urf = ufp;
590 identical = TRUE;
591 }
592 if (StringCmp (oip->str, "Status") == 0) {
593 st = (CharPtr) ufp->data.ptrvalue;
594 if (StringICmp (st, "Inferred") == 0) {
595 review = 1;
596 } else if (StringICmp (st, "Provisional") == 0) {
597 review = 2;
598 } else if (StringICmp (st, "Predicted") == 0) {
599 review = 3;
600 } else if (StringICmp (st, "Validated") == 0) {
601 review = 4;
602 } else if (StringICmp (st, "Reviewed") == 0) {
603 review = 5;
604 } else if (StringICmp (st, "Model") == 0) {
605 review = 6;
606 } else if (StringICmp (st, "WGS") == 0) {
607 review = 7;
608 } else if (StringICmp (st, "Pipeline") == 0) {
609 review = 8;
610 }
611 } else if (StringCmp (oip->str, "Generated") == 0) {
612 generated = ufp->data.boolvalue;
613 } else if (StringCmp (oip->str, "Collaborator") == 0) {
614 st = (CharPtr) ufp->data.ptrvalue;
615 if (! StringHasNoText (st)) {
616 curator = st;
617 }
618 } else if (StringCmp (oip->str, "CollaboratorURL") == 0) {
619 st = (CharPtr) ufp->data.ptrvalue;
620 if (! StringHasNoText (st)) {
621 url = st;
622 }
623 } else if (StringCmp (oip->str, "GenomicSource") == 0) {
624 st = (CharPtr) ufp->data.ptrvalue;
625 if (! StringHasNoText (st)) {
626 source = st;
627 }
628 }
629 }
630 if (urf != NULL && urf->choice == 11) {
631 for (tmp = urf->data.ptrvalue; tmp != NULL; tmp = tmp->next) {
632 for (u = tmp->data.ptrvalue; u != NULL; u = u->next) {
633 oip = u->label;
634 if (StringCmp (oip->str, "accession") == 0 ||
635 StringCmp (oip->str, "name") == 0) {
636 i++;
637 }
638 }
639 }
640 }
641 if ( GetWWW(ajp) ) {
642 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
643 FF_Add_NCBI_Base_URL (ffstring, ref_link);
644 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
645 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
646 if (review == 8) {
647 FFAddOneString (ffstring, " INFORMATION", FALSE, FALSE, TILDE_IGNORE);
648 }
649 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
650 } else {
651 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
652 if (review == 8) {
653 FFAddOneString (ffstring, " INFORMATION", FALSE, FALSE, TILDE_IGNORE);
654 }
655 }
656 FFAddOneString (ffstring, ":", FALSE, FALSE, TILDE_IGNORE);
657 if (review == 1) {
658 FFAddOneString (ffstring, reftxt1, FALSE, FALSE, TILDE_IGNORE);
659 } else if (review == 2) {
660 if (curator == NULL) {
661 FFAddOneString (ffstring, reftxt2, FALSE, FALSE, TILDE_IGNORE);
662 }
663 } else if (review == 3) {
664 FFAddOneString (ffstring, reftxt3, FALSE, FALSE, TILDE_IGNORE);
665 } else if (review == 4) {
666 FFAddOneString (ffstring, reftxt4, FALSE, FALSE, TILDE_IGNORE);
667 } else if (review == 5) {
668 if (curator == NULL) {
669 curator = "NCBI staff";
670 }
671 } else if (review == 6) {
672 FFAddOneString (ffstring, reftxt6, FALSE, FALSE, TILDE_IGNORE);
673 } else if (review == 7) {
674 FFAddOneString (ffstring, reftxt7, FALSE, FALSE, TILDE_IGNORE);
675 } else if (review == 8) {
676 }
677 if (curator != NULL) {
678 if (review == 2) {
679 FFAddOneString (ffstring, reftxt41, FALSE, FALSE, TILDE_IGNORE);
680 } else {
681 FFAddOneString (ffstring, reftxt5, FALSE, FALSE, TILDE_IGNORE);
682 }
683 if (GetWWW (ajp) && url != NULL && (! URLHasSuspiciousHtml (ajp, url))) {
684 if (StringNCmp (url, "http://", 7) == 0 || StringNCmp (url, "https://", 8) == 0) {
685 FFAddTextToString(ffstring, "<a href=\"", url, "\">", FALSE, FALSE, TILDE_IGNORE);
686 FFAddOneString (ffstring, curator, FALSE, FALSE, TILDE_IGNORE);
687 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
688 } else if (StringNCmp (url, "www.", 4) == 0) {
689 FFAddTextToString(ffstring, "<a href=http://\"", url, "\">", FALSE, FALSE, TILDE_IGNORE);
690 FFAddOneString (ffstring, curator, FALSE, FALSE, TILDE_IGNORE);
691 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
692 } else {
693 FFAddOneString (ffstring, curator, FALSE, FALSE, TILDE_IGNORE);
694 }
695 } else {
696 FFAddOneString (ffstring, curator, FALSE, FALSE, TILDE_IGNORE);
697 }
698 FFAddOneString (ffstring, ".", FALSE, FALSE, TILDE_IGNORE);
699 }
700 if (source != NULL) {
701 FFAddOneString (ffstring, reftxt9, FALSE, FALSE, TILDE_IGNORE);
702 gi = 0;
703 if (GetWWW (ajp) && ValidateAccnDotVer (source) == 0 && GetGiFromAccnDotVer (source, &gi)) {
704 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
705 if (is_na) {
706 FF_Add_NCBI_Base_URL (ffstring, link_seqn);
707 } else {
708 FF_Add_NCBI_Base_URL (ffstring, link_seqp);
709 }
710 if (gi > 0) {
711 sprintf (buf, "%ld", (long) gi);
712 FFAddTextToString(ffstring, /* "val=" */ NULL, buf, "\">", FALSE, FALSE, TILDE_IGNORE);
713 } else {
714 FFAddTextToString(ffstring, /* "val=" */ NULL, source, "\">", FALSE, FALSE, TILDE_IGNORE);
715 }
716 FFAddOneString (ffstring, source, FALSE, FALSE, TILDE_IGNORE);
717 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
718 } else {
719 FFAddOneString (ffstring, source, FALSE, FALSE, TILDE_IGNORE);
720 }
721 FFAddOneString (ffstring, ").", FALSE, FALSE, TILDE_IGNORE);
722 }
723 if (i > 0) {
724 if (review == 8 && (genomeBuildNumber != NULL || genomeVersionNumber != NULL)) {
725 FFAddOneString (ffstring, reftxt22, FALSE, FALSE, TILDE_EXPAND);
726 FFAddOneString (ffstring, genomeBuildNumber, FALSE, FALSE, TILDE_EXPAND);
727 if (StringHasNoText (genomeVersionNumber)) {
728 genomeVersionNumber = "1";
729 }
730 FFAddOneString (ffstring, " version ", FALSE, FALSE, TILDE_EXPAND);
731 FFAddOneString (ffstring, genomeVersionNumber, FALSE, FALSE, TILDE_EXPAND);
732 FFAddOneString (ffstring, reftxt23, FALSE, FALSE, TILDE_EXPAND);
733
734 FFAddOneString (ffstring, " [see ", FALSE, FALSE, TILDE_EXPAND);
735
736 if ( GetWWW(ajp) ) {
737 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
738 FF_Add_NCBI_Base_URL (ffstring, doc_link);
739 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
740 }
741 FFAddOneString (ffstring, "documentation", FALSE, FALSE, TILDE_IGNORE);
742 if ( GetWWW(ajp) ) {
743 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
744 }
745
746 FFAddOneString (ffstring, "]. ", FALSE, FALSE, TILDE_EXPAND);
747 }
748 if (generated) {
749 FFAddOneString (ffstring, reftxtg, FALSE, FALSE, TILDE_IGNORE);
750 } else if (identical) {
751 FFAddOneString (ffstring, reftxti, FALSE, FALSE, TILDE_IGNORE);
752 } else {
753 FFAddOneString (ffstring, reftxt0, FALSE, FALSE, TILDE_IGNORE);
754 }
755
756 for (tmp = urf->data.ptrvalue; tmp != NULL; tmp = tmp->next) {
757 accn = NULL;
758 from = 0;
759 to = 0;
760 name = NULL;
761 gi = 0;
762 for (u = tmp->data.ptrvalue; u != NULL; u = u->next) {
763 oip = u->label;
764 if (oip != NULL && oip->str != NULL) {
765 if (StringICmp (oip->str, "accession") == 0 && u->choice == 1) {
766 accn = (CharPtr) u->data.ptrvalue;
767 } else if (StringICmp (oip->str, "from") == 0 && u->choice == 2) {
768 from = u->data.intvalue;
769 } else if (StringICmp (oip->str, "to") == 0 && u->choice == 2) {
770 to = u->data.intvalue;
771 } else if (StringICmp (oip->str, "name") == 0 && u->choice == 1) {
772 name = (CharPtr) u->data.ptrvalue;
773 } else if (StringICmp (oip->str, "gi") == 0 && u->choice == 2) {
774 gi = u->data.intvalue;
775 }
776 }
777 }
778 if (StringDoesHaveText (accn)) {
779 if (GetWWW (ajp) && ValidateAccnDotVer (accn) == 0 && GetGiFromAccnDotVer (accn, &gi)) {
780 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
781 if (is_na) {
782 FF_Add_NCBI_Base_URL (ffstring, link_seqn);
783 } else {
784 FF_Add_NCBI_Base_URL (ffstring, link_seqp);
785 }
786 if (gi > 0) {
787 sprintf (buf, "%ld", (long) gi);
788 FFAddTextToString(ffstring, /* "val=" */ NULL, buf, "\">", FALSE, FALSE, TILDE_IGNORE);
789 } else {
790 FFAddTextToString(ffstring, /* "val=" */ NULL, accn, "\">", FALSE, FALSE, TILDE_IGNORE);
791 }
792 FFAddOneString (ffstring, accn, FALSE, FALSE, TILDE_IGNORE);
793 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
794 } else if (GetWWW (ajp) && ValidateAccn (accn) == 0) {
795 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
796 if (is_na) {
797 FF_Add_NCBI_Base_URL (ffstring, link_seqn);
798 } else {
799 FF_Add_NCBI_Base_URL (ffstring, link_seqp);
800 }
801 FFAddTextToString(ffstring, /* "val=" */ NULL, accn, "\">", FALSE, FALSE, TILDE_IGNORE);
802 FFAddOneString (ffstring, accn, FALSE, FALSE, TILDE_IGNORE);
803 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
804 } else {
805 FFAddOneString (ffstring, accn, FALSE, FALSE, TILDE_IGNORE);
806 }
807 if (from > 0 && to > 0) {
808 sprintf (buf, " (range: %ld-%ld)", (long) from, (long) to);
809 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_IGNORE);
810 }
811 } else if (StringDoesHaveText (name)) {
812 FFAddOneString (ffstring, name, FALSE, FALSE, TILDE_IGNORE);
813 } else continue;
814 if (tmp->next != NULL) {
815 ufp = tmp->next;
816 if (ufp->next != NULL) {
817 FFAddOneString (ffstring, ", ", FALSE, FALSE, TILDE_IGNORE);
818 } else {
819 FFAddOneString (ffstring, " and ", FALSE, FALSE, TILDE_IGNORE);
820 }
821 }
822 }
823 FFAddOneString (ffstring, ".", FALSE, FALSE, TILDE_EXPAND);
824 }
825 }
826
827 static CharPtr GetGenomeBuildNumber (
828 UserObjectPtr uop
829 )
830
831 {
832 ObjectIdPtr oip;
833 CharPtr str;
834 UserFieldPtr ufp;
835
836 if (uop == NULL) return NULL;
837 if ((oip = uop->type) == NULL) return NULL;
838 if (StringCmp (oip->str, "GenomeBuild") != 0) return NULL;
839 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
840 oip = ufp->label;
841 if (StringCmp(oip->str, "NcbiAnnotation") == 0) {
842 if (ufp->choice == 1) { /* string */
843 str = ufp->data.ptrvalue;
844 if (! StringHasNoText (str)) return str;
845 }
846 } else if (StringCmp (oip->str, "Annotation") == 0) {
847 if (ufp->choice == 1) { /* string */
848 str = ufp->data.ptrvalue;
849 if (! StringHasNoText (str)) {
850 if (StringNICmp (str, "NCBI build ", 11) == 0) {
851 if (! StringHasNoText (str + 11)) {
852 return (str + 11);
853 }
854 }
855 }
856 }
857 }
858 }
859 return NULL;
860 }
861
862 static CharPtr GetGenomeVersionNumber (
863 UserObjectPtr uop
864 )
865
866 {
867 ObjectIdPtr oip;
868 CharPtr str;
869 UserFieldPtr ufp;
870
871 if (uop == NULL) return NULL;
872 if ((oip = uop->type) == NULL) return NULL;
873 if (StringCmp (oip->str, "GenomeBuild") != 0) return NULL;
874 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
875 oip = ufp->label;
876 if (StringCmp(oip->str, "NcbiVersion") == 0) {
877 if (ufp->choice == 1) { /* string */
878 str = ufp->data.ptrvalue;
879 if (! StringHasNoText (str)) return str;
880 }
881 }
882 }
883 return NULL;
884 }
885
886
887 static CharPtr reftxt11 = "This record is predicted by automated computational analysis. This record is derived from a genomic sequence";
888 static CharPtr reftxt12 = "annotated using gene prediction method:";
889
890 static void FindModelEvidenceUop (
891 UserObjectPtr uop,
892 Pointer userdata
893 )
894
895 {
896 ObjectIdPtr oip;
897 UserObjectPtr PNTR uopp;
898
899 if (uop == NULL || userdata == NULL) return;
900 uopp = (UserObjectPtr PNTR) userdata;
901 oip = uop->type;
902 if (oip == NULL) return;
903 if (StringCmp (oip->str, "ModelEvidence") == 0) {
904 *uopp = uop;
905 }
906 }
907
908 static Boolean DoGetAnnotationComment (
909 BioseqPtr bsp,
910 CharPtr PNTR namep,
911 CharPtr PNTR methodp,
912 BoolPtr mrnaEv,
913 BoolPtr estEv
914 )
915
916 {
917 Int2 ce = 0, cm = 0;
918 SeqMgrDescContext dcontext;
919 CharPtr method = NULL;
920 UserObjectPtr moduop;
921 CharPtr name = NULL;
922 ObjectIdPtr oip;
923 SeqDescrPtr sdp;
924 UserFieldPtr u;
925 UserFieldPtr ufp;
926 UserObjectPtr uop;
927
928 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
929 while (sdp != NULL) {
930 uop = (UserObjectPtr) sdp->data.ptrvalue;
931 if (uop != NULL) {
932 moduop = NULL;
933 VisitUserObjectsInUop (uop, (Pointer) &moduop, FindModelEvidenceUop);
934 if (moduop != NULL) {
935 oip = moduop->type;
936 if (oip != NULL && StringCmp(oip->str, "ModelEvidence") == 0) {
937 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
938 oip = ufp->label;
939 if (oip == NULL) continue;
940 if (StringCmp (oip->str, "Contig Name") == 0) {
941 name = (CharPtr) ufp->data.ptrvalue;
942 } else if (StringCmp (oip->str, "Method") == 0) {
943 method = (CharPtr) ufp->data.ptrvalue;
944 } else if (StringCmp (oip->str, "mRNA") == 0) {
945 *mrnaEv = TRUE;
946 } else if (StringCmp (oip->str, "EST") == 0) {
947 *estEv = TRUE;
948 } else if (StringCmp (oip->str, "Counts") == 0) {
949 for (u = (UserFieldPtr) ufp->data.ptrvalue; u != NULL; u = u->next) {
950 if (u->data.ptrvalue == NULL) continue;
951 if (u->choice != 2) continue;
952 oip = u->label;
953 if (oip == NULL) continue;
954 if (StringCmp (oip->str, "mRNA") == 0) {
955 cm = (Int2) u->data.intvalue;
956 if (cm > 0) {
957 *mrnaEv = TRUE;
958 }
959 } else if (StringCmp (oip->str, "EST") == 0) {
960 ce = (Int2) u->data.intvalue;
961 if (ce > 0) {
962 *estEv = TRUE;
963 }
964 }
965 }
966 }
967 }
968 }
969 }
970 }
971 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
972 }
973 if (StringHasNoText (name)) return FALSE;
974 *namep = name;
975 if (! StringHasNoText (method)) {
976 *methodp = method;
977 }
978 return TRUE;
979 }
980
981 static Boolean GetAnnotationComment (
982 BioseqPtr bsp,
983 CharPtr PNTR namep,
984 CharPtr PNTR methodp,
985 BoolPtr mrnaEv,
986 BoolPtr estEv
987 )
988
989 {
990 SeqFeatPtr cds;
991
992 if (DoGetAnnotationComment (bsp, namep, methodp, mrnaEv, estEv)) return TRUE;
993 if (ISA_aa (bsp->mol)) {
994 cds = SeqMgrGetCDSgivenProduct (bsp, NULL);
995 if (cds != NULL) {
996 bsp = BioseqFindFromSeqLoc (cds->location);
997 if (bsp != NULL) {
998 return DoGetAnnotationComment (bsp, namep, methodp, mrnaEv, estEv);
999 }
1000 }
1001 }
1002 return FALSE;
1003 }
1004
1005 static void FindGeneFeat (
1006 SeqFeatPtr sfp,
1007 Pointer userdata
1008 )
1009
1010 {
1011 SeqFeatPtr PNTR sfpp;
1012
1013 if (sfp->data.choice != SEQFEAT_GENE) return;
1014 sfpp = (SeqFeatPtr PNTR) userdata;
1015 *sfpp = sfp;
1016 }
1017
1018 static void FindLocusId (
1019 ValNodePtr dbxref,
1020 CharPtr locusIDp
1021 )
1022
1023 {
1024 DbtagPtr dbt;
1025 ObjectIdPtr oip;
1026 ValNodePtr vnp;
1027
1028 for (vnp = dbxref; vnp != NULL; vnp = vnp->next) {
1029 dbt = (DbtagPtr) vnp->data.ptrvalue;
1030 if (dbt == NULL) continue;
1031 if (StringICmp (dbt->db, "LocusID") != 0 && StringICmp (dbt->db, "InterimID") != 0) continue;
1032 oip = dbt->tag;
1033 if (oip == NULL) continue;
1034 if (oip->str != NULL) {
1035 StringCpy (locusIDp, oip->str);
1036 } else if (oip->id > 0) {
1037 sprintf (locusIDp, "%ld", (long) oip->id);
1038 }
1039 }
1040 }
1041
1042 static Boolean GetGeneAndLocus (
1043 BioseqPtr bsp,
1044 CharPtr PNTR genep,
1045 CharPtr locusIDp,
1046 CharPtr taxIDp
1047 )
1048
1049 {
1050 BioSourcePtr biop;
1051 DbtagPtr dbt;
1052 SeqMgrDescContext dcontext;
1053 SeqFeatPtr gene = NULL;
1054 GeneRefPtr grp;
1055 ObjectIdPtr oip;
1056 OrgRefPtr orp;
1057 SeqDescrPtr sdp;
1058 SeqEntryPtr sep;
1059 CharPtr str;
1060 ValNodePtr syn;
1061 ValNodePtr vnp;
1062
1063 sep = GetTopSeqEntryForEntityID (bsp->idx.entityID);
1064 if (sep == NULL) return FALSE;
1065 VisitFeaturesInSep (sep, (Pointer) &gene, FindGeneFeat);
1066 if (gene == NULL) return FALSE;
1067
1068 grp = (GeneRefPtr) gene->data.value.ptrvalue;
1069 if (grp == NULL) return FALSE;
1070 if (! StringHasNoText (grp->locus)) {
1071 *genep = grp->locus;
1072 } else {
1073 syn = grp->syn;
1074 if (syn != NULL) {
1075 str = (CharPtr) syn->data.ptrvalue;
1076 if (! StringHasNoText (str)) {
1077 *genep = str;
1078 }
1079 }
1080 }
1081 FindLocusId (gene->dbxref, locusIDp);
1082 FindLocusId (grp->db, locusIDp);
1083
1084 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
1085 if (sdp != NULL) {
1086 biop = (BioSourcePtr) sdp->data.ptrvalue;
1087 if (biop != NULL) {
1088 orp = biop->org;
1089 if (orp != NULL) {
1090 for (vnp = orp->db; vnp != NULL; vnp = vnp->next) {
1091 dbt = (DbtagPtr) vnp->data.ptrvalue;
1092 if (dbt == NULL) continue;
1093 if (StringCmp (dbt->db, "taxon") == 0) {
1094 oip = dbt->tag;
1095 if (oip == NULL) continue;
1096 if (oip->str != NULL) {
1097 StringCpy (taxIDp, oip->str);
1098 } else if (oip->id > 0) {
1099 sprintf (taxIDp, "%ld", (long) oip->id);
1100 }
1101 }
1102 }
1103 }
1104 }
1105 }
1106
1107 if (genep == NULL || StringHasNoText (locusIDp)) return FALSE;
1108
1109 return TRUE;
1110 }
1111
1112 static CharPtr nsAreGapsString = "The strings of n's in this record represent gaps between contigs, and the length of each string corresponds to the length of the gap.";
1113 static CharPtr nsWGSGapsString = "The strings of n's in this record represent gaps between contigs or uncallable bases.";
1114
1115 static Boolean IsTpa (
1116 BioseqPtr bsp,
1117 Boolean has_tpa_assembly,
1118 BoolPtr isRefSeqP,
1119 BoolPtr isTsaP
1120 )
1121
1122 {
1123 SeqMgrDescContext dcontext;
1124 DbtagPtr dbt;
1125 Boolean has_bankit = FALSE;
1126 Boolean has_genbank = FALSE;
1127 Boolean has_gi = FALSE;
1128 Boolean has_local = FALSE;
1129 Boolean has_refseq = FALSE;
1130 Boolean has_smart = FALSE;
1131 Boolean has_tpa = FALSE;
1132 Boolean is_tsa = FALSE;
1133 MolInfoPtr mip;
1134 SeqDescrPtr sdp;
1135 SeqIdPtr sip;
1136
1137 if (bsp == NULL || bsp->id == NULL) return FALSE;
1138 for (sip = bsp->id; sip != NULL; sip = sip->next) {
1139 switch (sip->choice) {
1140 case SEQID_LOCAL :
1141 has_local = TRUE;
1142 break;
1143 case SEQID_GENBANK :
1144 case SEQID_EMBL :
1145 case SEQID_DDBJ :
1146 has_genbank = TRUE;
1147 break;
1148 case SEQID_OTHER :
1149 has_refseq = TRUE;
1150 if (isRefSeqP != NULL) {
1151 *isRefSeqP = TRUE;
1152 }
1153 break;
1154 case SEQID_GI :
1155 has_gi = TRUE;
1156 break;
1157 case SEQID_TPG :
1158 case SEQID_TPE :
1159 case SEQID_TPD :
1160 has_tpa = TRUE;
1161 break;
1162 case SEQID_GENERAL :
1163 dbt = (DbtagPtr) sip->data.ptrvalue;
1164 if (dbt != NULL) {
1165 if (StringICmp (dbt->db, "BankIt") == 0) {
1166 has_bankit = TRUE;
1167 }
1168 if (StringICmp (dbt->db, "TMSMART") == 0) {
1169 has_smart = TRUE;
1170 }
1171 }
1172 break;
1173 default :
1174 break;
1175 }
1176 }
1177
1178 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
1179 if (sdp != NULL && sdp->choice == Seq_descr_molinfo) {
1180 mip = (MolInfoPtr) sdp->data.ptrvalue;
1181 if (mip != NULL) {
1182 if (mip->tech == MI_TECH_tsa) {
1183 is_tsa = TRUE;
1184 if (isTsaP != NULL) {
1185 *isTsaP = TRUE;
1186 }
1187 }
1188 }
1189 }
1190
1191 if (is_tsa) return TRUE;
1192 if (has_genbank) return FALSE;
1193 if (has_tpa) return TRUE;
1194 if (has_refseq) return TRUE;
1195 if (has_bankit && has_tpa_assembly) return TRUE;
1196 if (has_smart && has_tpa_assembly) return TRUE;
1197 if (has_gi) return FALSE;
1198 if (has_local && has_tpa_assembly) return TRUE;
1199
1200 return FALSE;
1201 }
1202
1203 static CharPtr GetPrimaryStrForDelta (
1204 BioseqPtr bsp
1205 )
1206
1207 {
1208 Boolean accn;
1209 Char buf [64], tmp [80];
1210 Int4 curr_start = 0, len, start0, start1;
1211 DbtagPtr dbt;
1212 DeltaSeqPtr deltasp;
1213 Int4 gi;
1214 ValNodePtr head = NULL;
1215 SeqIdPtr id, sip;
1216 SeqIntPtr intp;
1217 SeqLitPtr litp;
1218 SeqLocPtr slp;
1219 CharPtr str;
1220 Uint1 strand;
1221
1222 if (bsp == NULL || bsp->repr != Seq_repr_delta || bsp->seq_ext_type != 4) return NULL;
1223
1224 for (deltasp = (DeltaSeqPtr) bsp->seq_ext; deltasp != NULL; deltasp = deltasp->next) {
1225 if (deltasp->choice == 1) {
1226 slp = (SeqLocPtr) deltasp->data.ptrvalue;
1227 if (slp != NULL && slp->choice == SEQLOC_INT) {
1228 intp = (SeqIntPtr) slp->data.ptrvalue;
1229 start0 = curr_start;
1230 start1 = intp->from;
1231 len = intp->to - intp->from + 1;
1232 curr_start += len;
1233 strand = intp->strand;
1234 sip = intp->id;
1235 if (sip == NULL) continue;
1236 id = NULL;
1237 accn = FALSE;
1238 if (sip->choice == SEQID_GI) {
1239 gi = (Int4) sip->data.intvalue;
1240 if (GetAccnVerFromServer (gi, buf)) {
1241 accn = TRUE;
1242 } else {
1243 id = GetSeqIdForGI (gi);
1244 }
1245 if (id == NULL) {
1246 sprintf (buf, "%ld", (long) gi);
1247 accn = TRUE;
1248 }
1249 } else {
1250 id = SeqIdDup (sip);
1251 }
1252 if (id != NULL || accn) {
1253 if (head == NULL) {
1254 ValNodeCopyStr (&head, 0, "CONTIG_SPAN PRIMARY_IDENTIFIER PRIMARY_SPAN COMP");
1255 }
1256 if (id != NULL) {
1257 SeqIdWrite (id, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
1258 if (id->choice == SEQID_GENERAL) {
1259 dbt = (DbtagPtr) id->data.ptrvalue;
1260 if (dbt != NULL && StringICmp (dbt->db, "ti") == 0) {
1261 StringCpy (buf, "TI");
1262 SeqIdWrite (id, buf + 2, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 3);
1263 }
1264 }
1265 }
1266 sprintf (tmp, "~%ld-%ld ",
1267 (long) (start0 + 1), (long) (start0 + len));
1268 tmp [21] = '\0';
1269 StringCat (buf, " ");
1270 buf [18] = '\0';
1271 StringCat (tmp, buf);
1272 sprintf (buf, " %ld-%ld ",
1273 (long) (start1 + 1), (long) (start1 + len));
1274 buf [21] = '\0';
1275 StringCat (tmp, buf);
1276 if (strand == Seq_strand_minus) {
1277 StringCat (tmp, "c");
1278 }
1279 ValNodeCopyStr (&head, 0, tmp);
1280 }
1281 SeqIdFree (id);
1282 }
1283 } else if (deltasp->choice == 2) {
1284 litp = (SeqLitPtr) deltasp->data.ptrvalue;
1285 if (litp != NULL) {
1286 curr_start += litp->length;
1287 }
1288 }
1289 }
1290
1291 if (head == NULL) return NULL;
1292
1293 str = MergeFFValNodeStrs (head);
1294 ValNodeFreeData (head);
1295
1296 return str;
1297 }
1298
1299 static CharPtr GetStrForTpaOrRefSeqHist (
1300 BioseqPtr bsp,
1301 Boolean isRefSeq,
1302 Boolean isTsa
1303 )
1304
1305 {
1306 Boolean accn;
1307 Char bfr [100];
1308 Char buf [100];
1309 DbtagPtr dbt;
1310 Int4 gi;
1311 ValNodePtr head = NULL;
1312 SeqHistPtr hist;
1313 SeqIdPtr id;
1314 Int2 j;
1315 int k;
1316 Int2 max;
1317 Boolean minus1;
1318 Boolean minus2;
1319 Int4 oldstop = -1;
1320 Uint1 residue;
1321 SeqAlignPtr salp;
1322 SeqAlignPtr salptmp;
1323 StreamCache sc;
1324 SeqIdPtr sip;
1325 Int4 start;
1326 Int4 stop;
1327 CharPtr str;
1328 Char tmp [120];
1329
1330 if (bsp == NULL) return NULL;
1331 hist = bsp->hist;
1332 if (hist != NULL && hist->assembly != NULL) {
1333 salp = SeqAlignListDup (hist->assembly);
1334 AlnMgr2IndexLite (salp);
1335 AlnMgr2SortAlnSetByNthRowPos (salp, 1);
1336 salptmp = (SeqAlignPtr) (salp->segs);
1337 while (salptmp != NULL) {
1338 AlnMgr2GetNthSeqRangeInSA (salptmp, 1, &start, &stop);
1339 sip = AlnMgr2GetNthSeqIdPtr (salptmp, 2);
1340 if (sip != NULL) {
1341 id = NULL;
1342 accn = FALSE;
1343 buf [0] = '\0';
1344 if (sip->choice == SEQID_GI) {
1345 gi = (Int4) sip->data.intvalue;
1346 if (GetAccnVerFromServer (gi, buf)) {
1347 accn = TRUE;
1348 } else {
1349 id = GetSeqIdForGI (gi);
1350 }
1351 } else {
1352 id = SeqIdDup (sip);
1353 }
1354 if (id != NULL || accn) {
1355 if (head == NULL) {
1356 if (isRefSeq) {
1357 ValNodeCopyStr (&head, 0, "REFSEQ_SPAN PRIMARY_IDENTIFIER PRIMARY_SPAN COMP");
1358 } else if (isTsa) {
1359 ValNodeCopyStr (&head, 0, "TSA_SPAN PRIMARY_IDENTIFIER PRIMARY_SPAN COMP");
1360 } else {
1361 ValNodeCopyStr (&head, 0, "TPA_SPAN PRIMARY_IDENTIFIER PRIMARY_SPAN COMP");
1362 }
1363 }
1364 if (isRefSeq && oldstop > -1 && oldstop < start) {
1365 sprintf (tmp, "~%ld-%ld ",
1366 (long) (oldstop + 1), (long) (start));
1367 tmp [21] = '\0';
1368 StringCpy (bfr, " ");
1369 k = 0;
1370 if (StreamCacheSetup (bsp, NULL, 0, &sc)) {
1371 if (start - oldstop < 15) {
1372 StreamCacheSetPosition (&sc, oldstop);
1373 bfr [k] = '"';
1374 k++;
1375 max = start - oldstop;
1376 for (j = 0; j < max; j++) {
1377 residue = StreamCacheGetResidue (&sc);
1378 bfr [k] = (Char) residue;
1379 k++;
1380 }
1381 bfr [k] = '"';
1382 k++;
1383 } else {
1384 StreamCacheSetPosition (&sc, oldstop);
1385 bfr [k] = '"';
1386 k++;
1387 for (j = 0; j < 4; j++) {
1388 residue = StreamCacheGetResidue (&sc);
1389 bfr [k] = (Char) residue;
1390 k++;
1391 }
1392 bfr [k] = '.';
1393 k++;
1394 bfr [k] = '.';
1395 k++;
1396 bfr [k] = '.';
1397 k++;
1398 StreamCacheSetPosition (&sc, start - 4);
1399 for (j = 0; j < 4; j++) {
1400 residue = StreamCacheGetResidue (&sc);
1401 bfr [k] = (Char) residue;
1402 k++;
1403 }
1404 bfr [k] = '"';
1405 k++;
1406 }
1407 } else {
1408 /*
1409 StringCpy (bfr, "inserted base(s)");
1410 */
1411 }
1412 bfr [k] = '\0';
1413 StringCat (bfr, " ");
1414 bfr [18] = '\0';
1415 StringCat (tmp, bfr);
1416 sprintf (bfr, " %ld-%ld ",
1417 (long) 1, (long) (start - oldstop));
1418 bfr [21] = '\0';
1419 StringCat (tmp, bfr);
1420 ValNodeCopyStr (&head, 0, tmp);
1421 }
1422 oldstop = stop + 1;
1423 if (id != NULL) {
1424 SeqIdWrite (id, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
1425 if (id->choice == SEQID_GENERAL) {
1426 dbt = (DbtagPtr) id->data.ptrvalue;
1427 if (dbt != NULL && StringICmp (dbt->db, "ti") == 0) {
1428 StringCpy (buf, "TI");
1429 SeqIdWrite (id, buf + 2, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 3);
1430 }
1431 }
1432 }
1433 sprintf (tmp, "~%ld-%ld ",
1434 (long) (start + 1), (long) (stop + 1));
1435 /*
1436 i = 39 - StringLen (buf);
1437 if (i > 0) {
1438 tmp [i] = '\0';
1439 } else {
1440 tmp [21] = '\0';
1441 }
1442 */
1443 tmp [21] = '\0';
1444 StringCat (buf, " ");
1445 buf [18] = '\0';
1446 StringCat (tmp, buf);
1447 AlnMgr2GetNthSeqRangeInSA (salptmp, 2, &start, &stop);
1448 sprintf (buf, " %ld-%ld ",
1449 (long) (start + 1), (long) (stop + 1));
1450 buf [21] = '\0';
1451 StringCat (tmp, buf);
1452 minus1 = (Boolean) (AlnMgr2GetNthStrand (salptmp, 1) == Seq_strand_minus);
1453 minus2 = (Boolean) (AlnMgr2GetNthStrand (salptmp, 2) == Seq_strand_minus);
1454 if (minus1 || minus2) {
1455 if (! (minus1 && minus2)) {
1456 StringCat (tmp, "c");
1457 }
1458 }
1459 ValNodeCopyStr (&head, 0, tmp);
1460 }
1461 SeqIdFree (id);
1462 }
1463 SeqIdFree (sip);
1464 salptmp = salptmp->next;
1465 }
1466 SeqAlignFree (salp);
1467 }
1468
1469 if (head == NULL) return NULL;
1470
1471 str = MergeFFValNodeStrs (head);
1472 ValNodeFreeData (head);
1473
1474 return str;
1475 }
1476
1477 static CharPtr tpaString = "THIRD PARTY ANNOTATION DATABASE: This TPA record uses data from DDBJ/EMBL/GenBank ";
1478
1479 static CharPtr GetStrForTPA (
1480 UserObjectPtr uop,
1481 BioseqPtr bsp
1482 )
1483
1484 {
1485 Char ch;
1486 UserFieldPtr curr;
1487 SeqHistPtr hist;
1488 Int2 i;
1489 Char id [41];
1490 Boolean isRefSeq = FALSE;
1491 Boolean isTsa = FALSE;
1492 Int2 j;
1493 size_t len;
1494 ObjectIdPtr oip;
1495 CharPtr ptr;
1496 CharPtr str;
1497 CharPtr tmp;
1498 UserFieldPtr ufp;
1499
1500 if (uop == NULL) return NULL;
1501 if ((oip = uop->type) == NULL) return NULL;
1502 if (StringCmp (oip->str, "TpaAssembly") != 0) return NULL;
1503 if (bsp == NULL) return NULL;
1504 hist = bsp->hist;
1505 if (hist != NULL && hist->assembly != NULL) return NULL;
1506 if (! IsTpa (bsp, TRUE, &isRefSeq, &isTsa)) return NULL;
1507 if (isRefSeq) return NULL;
1508
1509 len = StringLen (tpaString) + StringLen ("entries ") + StringLen ("and ") + 5;
1510 i = 0;
1511 for (curr = uop->data; curr != NULL; curr = curr->next) {
1512 if (curr->choice != 11) continue;
1513 for (ufp = curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
1514 if (ufp->choice != 1) continue;
1515 oip = ufp->label;
1516 if (oip == NULL || StringICmp (oip->str, "accession") != 0) continue;
1517 str = (CharPtr) ufp->data.ptrvalue;
1518 if (StringHasNoText (str)) continue;
1519 len += StringLen (str) + 2;
1520 i++;
1521 }
1522 }
1523 if (i == 0) return NULL;
1524
1525 ptr = (CharPtr) MemNew (len);
1526 if (ptr == NULL) return NULL;
1527 StringCpy (ptr, tpaString);
1528 if (i > 1) {
1529 StringCat (ptr, "entries ");
1530 } else {
1531 StringCat (ptr, "entry ");
1532 }
1533
1534 j = 0;
1535 for (curr = uop->data; curr != NULL; curr = curr->next) {
1536 if (curr->choice != 11) continue;
1537 for (ufp = curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
1538 if (ufp->choice != 1) continue;
1539 oip = ufp->label;
1540 if (oip == NULL || StringICmp (oip->str, "accession") != 0) continue;
1541 str = (CharPtr) ufp->data.ptrvalue;
1542 if (StringHasNoText (str)) continue;
1543 StringNCpy_0 (id, str, sizeof (id));
1544 tmp = id;
1545 ch = *tmp;
1546 while (ch != '\0') {
1547 if (IS_LOWER (ch)) {
1548 *tmp = TO_UPPER (ch);
1549 }
1550 tmp++;
1551 ch = *tmp;
1552 }
1553 if (j == i - 1 && i > 1) {
1554 StringCat (ptr, " and ");
1555 } else if (j > 0) {
1556 StringCat (ptr, ", ");
1557 }
1558 StringCat (ptr, id);
1559 j++;
1560 }
1561 }
1562
1563 return ptr;
1564 }
1565
1566 static CharPtr GetStrForGenome (
1567 UserObjectPtr uop,
1568 BioseqPtr bsp
1569 )
1570
1571 {
1572 ObjectIdPtr oip;
1573
1574 if (uop == NULL) return NULL;
1575 if ((oip = uop->type) == NULL) return NULL;
1576 if (StringCmp (oip->str, "GenomeInfo") != 0) return NULL;
1577
1578 /* !!! need to implement !!! */
1579
1580 return NULL;
1581 }
1582
1583 static CharPtr StrucCommentFFEndPrint (
1584 IntAsn2gbJobPtr ajp,
1585 StringItemPtr ffstring,
1586 FmtType format,
1587 Int2 gb_init_indent,
1588 Int2 gb_cont_indent,
1589 Int2 eb_init_indent,
1590 Int2 eb_cont_indent,
1591 CharPtr eb_line_prefix
1592 )
1593 {
1594 StringItemPtr temp = FFGetString(ajp);
1595 CharPtr result;
1596
1597 if ( (ffstring == NULL) || (ajp == NULL) ) return NULL;
1598
1599 if (format == GENBANK_FMT || format == GENPEPT_FMT) {
1600 FFLineWrap (temp, ffstring, gb_init_indent, gb_cont_indent, ASN2FF_GB_MAX - 12, NULL);
1601 } else {
1602 FFLineWrap (temp, ffstring, eb_init_indent, eb_cont_indent, ASN2FF_EMBL_MAX - 5, eb_line_prefix);
1603 }
1604 result = FFToCharPtr (temp);
1605 FFRecycleString (ajp, temp);
1606 return result;
1607 }
1608
1609 static size_t ThresholdForStructuredCommentColumnarDisplay (
1610 FmtType format
1611 )
1612 {
1613 // We are trying to make those structured comments look pretty. However, if the first column gets
1614 // too big, the printout starts to look ugly. This function attempts to define the first column
1615 // extent at which pretty turns into ugly.
1616
1617 const size_t MAX_COLUMN_WIDTH = 45;
1618 switch ( format ) {
1619
1620 case GENBANK_FMT:
1621 case GENPEPT_FMT:
1622 return MIN( MAX_COLUMN_WIDTH, ASN2FF_GB_MAX - 12 );
1623
1624 default:
1625 return MIN( MAX_COLUMN_WIDTH, ASN2FF_EMBL_MAX - 5 );
1626 }
1627 }
1628
1629 static CharPtr GetStrForStructuredComment (
1630 Asn2gbWorkPtr awp,
1631 IntAsn2gbJobPtr ajp,
1632 UserObjectPtr uop,
1633 BioseqPtr bsp
1634 )
1635
1636 {
1637 UserFieldPtr curr;
1638 StringItemPtr ffstring;
1639 CharPtr field;
1640 ValNodePtr head = NULL;
1641 size_t len;
1642 size_t max = 0;
1643 ObjectIdPtr oip;
1644 CharPtr prefix = NULL;
1645 CharPtr str;
1646 CharPtr suffix = NULL;
1647 CharPtr tmp;
1648
1649 if (awp == NULL || ajp == NULL || uop == NULL) return NULL;
1650 if ((oip = uop->type) == NULL) return NULL;
1651 if (StringCmp (oip->str, "StructuredComment") != 0) return NULL;
1652
1653 ffstring = FFGetString (ajp);
1654 if (ffstring == NULL) return NULL;
1655
1656 for (curr = uop->data; curr != NULL; curr = curr->next) {
1657 if (curr->choice != 1) continue;
1658 oip = curr->label;
1659 if (oip == NULL) continue;
1660 field = oip->str;
1661 if (StringHasNoText (field)) continue;
1662 if (StringCmp (field, "StructuredCommentPrefix") == 0) {
1663 str = (CharPtr) curr->data.ptrvalue;
1664 if (StringDoesHaveText (str)) {
1665 prefix = str;
1666 }
1667 continue;
1668 }
1669 if (StringCmp (field, "StructuredCommentSuffix") == 0) {
1670 str = (CharPtr) curr->data.ptrvalue;
1671 if (StringDoesHaveText (str)) {
1672 suffix = str;
1673 }
1674 continue;
1675 }
1676 len = StringLen (field);
1677 if (len > max) {
1678 max = len;
1679 }
1680 }
1681
1682 if (StringHasNoText (prefix)) {
1683 prefix = "##Metadata-START##";
1684 }
1685 if (StringHasNoText (suffix)) {
1686 suffix = "##Metadata-END##";
1687 }
1688
1689 if (StringDoesHaveText (prefix)) {
1690 tmp = (CharPtr) MemNew (StringLen (prefix) + 4);
1691 if (tmp != NULL) {
1692 sprintf (tmp, "%s\n", prefix);
1693 ValNodeAddStr (&head, 0, tmp);
1694 }
1695 }
1696 if (max > ThresholdForStructuredCommentColumnarDisplay (awp->format)) {
1697 for (curr = uop->data; curr != NULL; curr = curr->next) {
1698 if (curr->choice != 1) continue;
1699 oip = curr->label;
1700 if (oip == NULL) continue;
1701 field = oip->str;
1702 if (StringHasNoText (field)) continue;
1703 if (StringCmp (field, "StructuredCommentPrefix") == 0) continue;
1704 if (StringCmp (field, "StructuredCommentSuffix") == 0) continue;
1705 str = (CharPtr) curr->data.ptrvalue;
1706 if (StringHasNoText (str)) continue;
1707 ValNodeCopyStr (&head, 0, field);
1708 ValNodeCopyStr (&head, 0, " ");
1709 ValNodeCopyStr (&head, 0, str);
1710 ValNodeCopyStr (&head, 0, "\n");
1711 }
1712 } else {
1713 for (curr = uop->data; curr != NULL; curr = curr->next) {
1714 if (curr->choice != 1) continue;
1715 oip = curr->label;
1716 if (oip == NULL) continue;
1717 field = oip->str;
1718 if (StringHasNoText (field)) continue;
1719 if (StringCmp (field, "StructuredCommentPrefix") == 0) continue;
1720 if (StringCmp (field, "StructuredCommentSuffix") == 0) continue;
1721 str = (CharPtr) curr->data.ptrvalue;
1722 if (StringHasNoText (str)) continue;
1723 len = max + StringLen (str) + 4;
1724 FFStartPrint (ffstring, GENBANK_FMT, 0, max + 1, field, max + 1, 0, max + 1, field, TRUE);
1725 if (GetWWW (ajp) && StringCmp (field, "GOLD Stamp ID") == 0 && StringNCmp (str, "Gi", 2) == 0) {
1726 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
1727 FF_Add_NCBI_Base_URL (ffstring, link_gold_stamp_id);
1728 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
1729 FFAddOneString (ffstring, ".html", FALSE, FALSE, TILDE_EXPAND);
1730 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
1731 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
1732 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
1733 } else {
1734 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
1735 }
1736 /*
1737 FFAddOneString (ffstring, "\n", FALSE, FALSE, TILDE_EXPAND);
1738 */
1739 tmp = StrucCommentFFEndPrint (ajp, ffstring, awp->format, max + 1, max + 1, 0, max + 1, NULL);
1740 ValNodeCopyStr (&head, 0, tmp);
1741 MemFree (tmp);
1742 FFRecycleString (ajp, ffstring);
1743 ffstring = FFGetString (ajp);
1744 /*
1745 tmp = (CharPtr) MemNew (len);
1746 if (tmp == NULL) continue;
1747 StringCpy (tmp, field);
1748 len = StringLen (tmp);
1749 while (len < max) {
1750 tmp [len] = ' ';
1751 len++;
1752 }
1753 tmp [len] = '\0';
1754 StringCat (tmp, " ");
1755 StringCat (tmp, str);
1756 StringCat (tmp, "\n");
1757 ValNodeCopyStr (&head, 0, tmp);
1758 MemFree (tmp);
1759 */
1760 }
1761 }
1762 if (StringDoesHaveText (suffix)) {
1763 tmp = (CharPtr) MemNew (StringLen (suffix) + 4);
1764 if (tmp != NULL) {
1765 sprintf (tmp, "%s\n", suffix);
1766 ValNodeAddStr (&head, 0, tmp);
1767 }
1768 }
1769
1770 if (head == NULL) return NULL;
1771
1772 str = MergeFFValNodeStrs (head);
1773 ValNodeFreeData (head);
1774
1775 FFRecycleString (ajp, ffstring);
1776
1777 return str;
1778 }
1779
1780 static void AddAltPrimaryBlock (
1781 Asn2gbWorkPtr awp
1782 )
1783
1784 {
1785 IntAsn2gbJobPtr ajp;
1786 Asn2gbSectPtr asp;
1787 BaseBlockPtr bbp = NULL;
1788 BioseqPtr bsp;
1789 GBSeqPtr gbseq;
1790 CharPtr str;
1791 StringItemPtr ffstring;
1792
1793 if (awp == NULL) return;
1794 ajp = awp->ajp;
1795 if (ajp == NULL) return;
1796 bsp = awp->bsp;
1797 if (bsp == NULL) return;
1798 asp = awp->asp;
1799 if (asp == NULL) return;
1800
1801 ffstring = FFGetString(ajp);
1802 if ( ffstring == NULL ) return;
1803
1804 str = GetPrimaryStrForDelta (bsp);
1805 if (str != NULL) {
1806
1807 bbp = (BaseBlockPtr) Asn2gbAddBlock (awp, PRIMARY_BLOCK, sizeof (BaseBlock));
1808 if (bbp != NULL) {
1809
1810 FFStartPrint (ffstring, awp->format, 0, 12, "PRIMARY", 12, 5, 5, "PR", TRUE);
1811
1812 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
1813
1814 bbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "PR");
1815
1816 /* optionally populate gbseq for XML-ized GenBank format */
1817
1818 if (ajp->gbseq) {
1819 gbseq = &asp->gbseq;
1820 } else {
1821 gbseq = NULL;
1822 }
1823
1824 if (gbseq != NULL) {
1825 gbseq->primary = StringSave (str);
1826 }
1827
1828 if (awp->afp != NULL) {
1829 DoImmediateFormat (awp->afp, (BaseBlockPtr) bbp);
1830 }
1831 }
1832 MemFree (str);
1833 }
1834
1835 FFRecycleString(ajp, ffstring);
1836 }
1837
1838 static CharPtr GeStrForTSA (
1839 UserObjectPtr uop
1840 )
1841
1842 {
1843 Int4 asf, ast, prf, prt;
1844 Char buf [80], tmp [80];
1845 UserFieldPtr curr;
1846 Boolean has_asf, has_ast, has_prf, has_prt;
1847 ValNodePtr head = NULL;
1848 ObjectIdPtr oip;
1849 CharPtr pid;
1850 CharPtr str;
1851 UserFieldPtr ufp;
1852
1853 if (uop == NULL) return NULL;
1854 if ((oip = uop->type) == NULL) return NULL;
1855 if (StringCmp (oip->str, "TSA") != 0) return NULL;
1856
1857 for (curr = uop->data; curr != NULL; curr = curr->next) {
1858 if (curr->choice != 11) continue;
1859 asf = 0;
1860 ast = 0;
1861 prf = 0;
1862 prt = 0;
1863 pid = NULL;
1864 has_asf = FALSE;
1865 has_ast = FALSE;
1866 has_prf = FALSE;
1867 has_prt = FALSE;
1868 for (ufp = curr->data.ptrvalue; ufp != NULL; ufp = ufp->next) {
1869 oip = ufp->label;
1870 if (oip == NULL) continue;
1871 if (StringICmp (oip->str, "assembly from") == 0 && ufp->choice == 2) {
1872 asf = (Int4) ufp->data.intvalue;
1873 has_asf = TRUE;
1874 } else if (StringICmp (oip->str, "assembly to") == 0 && ufp->choice == 2) {
1875 ast = (Int4) ufp->data.intvalue;
1876 has_ast = TRUE;
1877 } else if (StringICmp (oip->str, "primary from") == 0 && ufp->choice == 2) {
1878 prf = (Int4) ufp->data.intvalue;
1879 has_prf = TRUE;
1880 } else if (StringICmp (oip->str, "primary to") == 0 && ufp->choice == 2) {
1881 prt = (Int4) ufp->data.intvalue;
1882 has_prt = TRUE;
1883 } else if (StringICmp (oip->str, "primary ID") == 0 && ufp->choice == 1) {
1884 pid = (CharPtr) ufp->data.ptrvalue;
1885 }
1886 }
1887 if (has_asf && has_ast && has_prf && has_prt && pid != NULL) {
1888 if (head == NULL) {
1889 ValNodeCopyStr (&head, 0, "TSA_SPAN PRIMARY_IDENTIFIER PRIMARY_SPAN COMP");
1890 }
1891 StringCpy (buf, pid);
1892 if (StringNCmp (pid, "gnl|ti|", 7) == 0) {
1893 StringCpy (buf, "TI");
1894 StringCat (buf, pid + 7);
1895 }
1896 sprintf (tmp, "~%ld-%ld ",
1897 (long) (asf + 1), (long) (ast + 1));
1898 tmp [21] = '\0';
1899 StringCat (buf, " ");
1900 buf [18] = '\0';
1901 StringCat (tmp, buf);
1902 sprintf (buf, " %ld-%ld ",
1903 (long) (prf + 1), (long) (prt + 1));
1904 buf [21] = '\0';
1905 StringCat (tmp, buf);
1906 if (prf > prt) {
1907 StringCat (tmp, "c");
1908 }
1909 ValNodeCopyStr (&head, 0, tmp);
1910 }
1911 }
1912
1913 if (head == NULL) return NULL;
1914
1915 str = MergeFFValNodeStrs (head);
1916 ValNodeFreeData (head);
1917
1918 return str;
1919 }
1920
1921 static void AddTsaBlock (
1922 Asn2gbWorkPtr awp,
1923 UserObjectPtr uop
1924 )
1925
1926 {
1927 IntAsn2gbJobPtr ajp;
1928 Asn2gbSectPtr asp;
1929 BaseBlockPtr bbp = NULL;
1930 BioseqPtr bsp;
1931 GBSeqPtr gbseq;
1932 CharPtr str;
1933 StringItemPtr ffstring;
1934
1935 if (awp == NULL) return;
1936 ajp = awp->ajp;
1937 if (ajp == NULL) return;
1938 bsp = awp->bsp;
1939 if (bsp == NULL) return;
1940 asp = awp->asp;
1941 if (asp == NULL) return;
1942
1943 ffstring = FFGetString(ajp);
1944 if ( ffstring == NULL ) return;
1945
1946 str = GeStrForTSA (uop);
1947 if (str != NULL) {
1948
1949 bbp = (BaseBlockPtr) Asn2gbAddBlock (awp, PRIMARY_BLOCK, sizeof (BaseBlock));
1950 if (bbp != NULL) {
1951
1952 FFStartPrint (ffstring, awp->format, 0, 12, "PRIMARY", 12, 5, 5, "PR", TRUE);
1953
1954 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
1955
1956 bbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "PR");
1957
1958 /* optionally populate gbseq for XML-ized GenBank format */
1959
1960 if (ajp->gbseq) {
1961 gbseq = &asp->gbseq;
1962 } else {
1963 gbseq = NULL;
1964 }
1965
1966 if (gbseq != NULL) {
1967 gbseq->primary = StringSave (str);
1968 }
1969
1970 if (awp->afp != NULL) {
1971 DoImmediateFormat (awp->afp, (BaseBlockPtr) bbp);
1972 }
1973 }
1974 MemFree (str);
1975 }
1976
1977 FFRecycleString(ajp, ffstring);
1978 }
1979
1980 NLM_EXTERN void AddPrimaryBlock (
1981 Asn2gbWorkPtr awp
1982 )
1983
1984 {
1985 IntAsn2gbJobPtr ajp;
1986 Asn2gbSectPtr asp;
1987 BaseBlockPtr bbp = NULL;
1988 BioseqPtr bsp;
1989 SeqMgrDescContext dcontext;
1990 GBSeqPtr gbseq;
1991 Boolean has_tpa_assembly = FALSE;
1992 Boolean has_tsa = FALSE;
1993 SeqHistPtr hist;
1994 Boolean isRefSeq = FALSE;
1995 Boolean isTsa = FALSE;
1996 ObjectIdPtr oip;
1997 SeqDescrPtr sdp;
1998 CharPtr str;
1999 UserObjectPtr uop;
2000 StringItemPtr ffstring;
2001
2002 if (awp == NULL) return;
2003 ajp = awp->ajp;
2004 if (ajp == NULL) return;
2005 bsp = awp->bsp;
2006 if (bsp == NULL) return;
2007 asp = awp->asp;
2008 if (asp == NULL) return;
2009
2010 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
2011 while (sdp != NULL) {
2012 uop = (UserObjectPtr) sdp->data.ptrvalue;
2013 if (uop != NULL) {
2014 oip = uop->type;
2015 if (oip != NULL) {
2016 if (StringCmp (oip->str, "TpaAssembly") == 0) {
2017 has_tpa_assembly = TRUE;
2018 } else if (StringCmp (oip->str, "TSA") == 0) {
2019 has_tsa = TRUE;
2020 }
2021 }
2022 }
2023 if (has_tpa_assembly || has_tsa) {
2024 sdp = NULL;
2025 } else {
2026 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
2027 }
2028 }
2029
2030 if (has_tsa) {
2031 AddTsaBlock (awp, uop);
2032 return;
2033 }
2034
2035 hist = bsp->hist;
2036 if ((! IsTpa (bsp, has_tpa_assembly, &isRefSeq, &isTsa)) ||
2037 hist == NULL || hist->assembly == NULL) {
2038 if (awp->forcePrimaryBlock) {
2039 AddAltPrimaryBlock (awp);
2040 }
2041 return;
2042 }
2043
2044 ffstring = FFGetString(ajp);
2045 if ( ffstring == NULL ) return;
2046
2047 str = GetStrForTpaOrRefSeqHist (bsp, isRefSeq, isTsa);
2048 if (str != NULL) {
2049
2050 bbp = (BaseBlockPtr) Asn2gbAddBlock (awp, PRIMARY_BLOCK, sizeof (BaseBlock));
2051 if (bbp != NULL) {
2052
2053 if (has_tpa_assembly) {
2054 bbp->entityID = dcontext.entityID;
2055 bbp->itemID = dcontext.itemID;
2056 bbp->itemtype = OBJ_SEQDESC;
2057 }
2058
2059 FFStartPrint (ffstring, awp->format, 0, 12, "PRIMARY", 12, 5, 5, "PR", TRUE);
2060
2061 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2062
2063 bbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "PR");
2064
2065 /* optionally populate gbseq for XML-ized GenBank format */
2066
2067 if (ajp->gbseq) {
2068 gbseq = &asp->gbseq;
2069 } else {
2070 gbseq = NULL;
2071 }
2072
2073 if (gbseq != NULL) {
2074 gbseq->primary = StringSave (str);
2075 }
2076
2077 if (awp->afp != NULL) {
2078 DoImmediateFormat (awp->afp, (BaseBlockPtr) bbp);
2079 }
2080 }
2081 MemFree (str);
2082 }
2083
2084 FFRecycleString(ajp, ffstring);
2085 }
2086
2087 static CharPtr reftxt32 = "It is defined by coordinates on the sequence of chromosome";
2088 static CharPtr reftxt33 = "from the";
2089 static CharPtr reftxt34 = "assembly of the human genome (NCBI build";
2090 static CharPtr reftxt35 = ").";
2091
2092 /*
2093 static CharPtr GetDBLinkString (
2094 UserObjectPtr uop
2095 )
2096
2097 {
2098 Char buf [128];
2099 Int4Ptr ip;
2100 ObjectIdPtr oip;
2101 UserFieldPtr ufp;
2102 Int4 val;
2103
2104 if (uop == NULL) return NULL;
2105
2106 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
2107 oip = ufp->label;
2108 if (oip == NULL || oip->str == NULL || ufp->choice != 8) continue;
2109 if (StringICmp (oip->str, "Trace Assembly Archive") == 0) {
2110 ip = (Int4Ptr) ufp->data.ptrvalue;
2111 if (ufp->num > 0 && ip != NULL) {
2112 val = ip [0];
2113 if (val > 0) {
2114 sprintf (buf, "Trace Assembly Archive:%ld", (long) val);
2115 return StringSave (buf);
2116 }
2117 }
2118 }
2119 }
2120
2121 return NULL;
2122 }
2123 */
2124
2125 static CharPtr GetEncodeString (
2126 UserObjectPtr uop,
2127 BioseqPtr bsp
2128 )
2129
2130 {
2131 CharPtr assembly_date = NULL;
2132 BioSourcePtr biop;
2133 CharPtr chromosome = NULL;
2134 SeqMgrDescContext dcontext;
2135 size_t len;
2136 CharPtr ncbi_annotation = NULL;
2137 ObjectIdPtr oip;
2138 SeqDescrPtr sdp;
2139 SubSourcePtr ssp;
2140 CharPtr str;
2141 UserFieldPtr ufp;
2142
2143 if (uop == NULL || bsp == NULL) return NULL;
2144
2145 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
2146 oip = ufp->label;
2147 if (oip == NULL || oip->str == NULL || ufp->choice != 1) continue;
2148 if (StringICmp (oip->str, "AssemblyDate") == 0) {
2149 assembly_date = (CharPtr) ufp->data.ptrvalue;
2150 } else if (StringICmp (oip->str, "NcbiAnnotation") == 0) {
2151 ncbi_annotation = (CharPtr) ufp->data.ptrvalue;
2152 }
2153 }
2154
2155 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
2156 if (sdp != NULL) {
2157 biop = (BioSourcePtr) sdp->data.ptrvalue;
2158 if (biop != NULL) {
2159 for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) {
2160 if (ssp->subtype == SUBSRC_chromosome) {
2161 chromosome = ssp->name;
2162 }
2163 }
2164 }
2165 }
2166
2167 if (chromosome == NULL || assembly_date == NULL || ncbi_annotation == NULL) return NULL;
2168
2169 if (StringHasNoText (chromosome)) {
2170 chromosome = "?";
2171 }
2172 if (StringHasNoText (assembly_date)) {
2173 assembly_date = "?";
2174 }
2175 if (StringHasNoText (ncbi_annotation)) {
2176 ncbi_annotation = "?";
2177 }
2178
2179 len = StringLen (reftxt32) + StringLen (reftxt33) +
2180 StringLen (reftxt34) + StringLen (reftxt35) +
2181 StringLen (chromosome) +
2182 StringLen (assembly_date) +
2183 StringLen (ncbi_annotation);
2184
2185 str = (CharPtr) MemNew (sizeof (Char) * (len + 10));
2186 if (str == NULL) return NULL;
2187
2188 sprintf (str, "%s %s %s %s %s %s%s", reftxt32, chromosome, reftxt33,
2189 assembly_date, reftxt34, ncbi_annotation, reftxt35);
2190
2191 return str;
2192 }
2193
2194 NLM_EXTERN void AddCommentBlock (
2195 Asn2gbWorkPtr awp
2196 )
2197
2198 {
2199 size_t acclen;
2200 SeqMgrAndContext acontext;
2201 AnnotDescPtr adp;
2202 Boolean annotDescCommentToComment;
2203 IntAsn2gbJobPtr ajp;
2204 BioseqPtr bsp;
2205 Char buf [1024];
2206 CommentBlockPtr cbp;
2207 Char ch;
2208 Boolean didGenome = FALSE;
2209 Boolean didRefTrack = FALSE;
2210 Boolean didTPA = FALSE;
2211 DbtagPtr dbt;
2212 SeqMgrDescContext dcontext;
2213 /*
2214 UserObjectPtr dblinkUop = NULL;
2215 */
2216 DeltaSeqPtr dsp;
2217 UserObjectPtr encodeUop = NULL;
2218 Boolean estEv = FALSE;
2219 /*
2220 SeqMgrFeatContext fcontext;
2221 */
2222 Boolean first = TRUE;
2223 GBBlockPtr gbp;
2224 CharPtr geneName = NULL;
2225 CharPtr genomeBuildNumber = NULL;
2226 CharPtr genomeVersionNumber = NULL;
2227 Int4 gi = 0;
2228 Int4 gsdbid = 0;
2229 Boolean has_gaps = FALSE;
2230 Boolean hasRefTrackStatus = FALSE;
2231 SeqHistPtr hist;
2232 Boolean is_collab = FALSE;
2233 Boolean is_encode = FALSE;
2234 Boolean is_other = FALSE;
2235 Boolean is_tpa = FALSE;
2236 Boolean is_wgs = FALSE;
2237 SeqLitPtr litp;
2238 ObjectIdPtr localID = NULL;
2239 Char locusID [32];
2240 CharPtr method = NULL;
2241 MolInfoPtr mip;
2242 Boolean mrnaEv = FALSE;
2243 CharPtr name = NULL;
2244 ObjectIdPtr ncbifileID = NULL;
2245 ObjectIdPtr oip;
2246 Boolean okay;
2247 BioseqPtr parent;
2248 SeqDescrPtr sdp;
2249 /*
2250 SeqFeatPtr sfp;
2251 */
2252 Boolean showGBBSource = FALSE;
2253 SeqIdPtr sip;
2254 CharPtr str;
2255 Char taxID [32];
2256 Char tmp [32];
2257 TextSeqIdPtr tsip;
2258 UserFieldPtr ufp;
2259 UserObjectPtr uop = NULL;
2260 CharPtr wgsaccn = NULL;
2261 CharPtr wgsname = NULL;
2262 StringItemPtr ffstring = NULL;
2263
2264 if (awp == NULL) return;
2265 ajp = awp->ajp;
2266 if (ajp == NULL) return;
2267 bsp = awp->bsp;
2268 if (bsp == NULL) return;
2269
2270 if (GetWWW (ajp) && awp->mode == ENTREZ_MODE && awp->afp != NULL &&
2271 (awp->format == GENBANK_FMT || awp->format == GENPEPT_FMT)) {
2272 sprintf (buf, "<a name=\"comment_%ld\"></a>", (long) awp->currGi);
2273 DoQuickLinkFormat (awp->afp, buf);
2274 }
2275
2276 ffstring = FFGetString(ajp);
2277 if ( ffstring == NULL ) return;
2278
2279 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
2280 while (sdp != NULL) {
2281 uop = (UserObjectPtr) sdp->data.ptrvalue;
2282 if (uop != NULL) {
2283 str = GetStatusForRefTrack (uop);
2284 if (str != NULL) {
2285 hasRefTrackStatus = TRUE;
2286 }
2287 if (genomeBuildNumber == NULL) {
2288 genomeBuildNumber = GetGenomeBuildNumber (uop);
2289 }
2290 if (genomeVersionNumber == NULL) {
2291 genomeVersionNumber = GetGenomeVersionNumber (uop);
2292 }
2293 oip = uop->type;
2294 if (oip != NULL) {
2295 if (StringICmp (oip->str, "ENCODE") == 0) {
2296 is_encode = TRUE;
2297 encodeUop = uop;
2298 }
2299 /*
2300 if (StringICmp (oip->str, "DBLink") == 0) {
2301 dblinkUop = uop;
2302 }
2303 */
2304 }
2305 }
2306 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
2307 }
2308
2309 /*
2310 if (dblinkUop != NULL) {
2311 str = GetDBLinkString (dblinkUop);
2312 if (StringDoesHaveText (str)) {
2313 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2314 if (cbp != NULL) {
2315
2316 cbp->entityID = awp->entityID;
2317 cbp->first = first;
2318 first = FALSE;
2319
2320 if (cbp->first) {
2321 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2322 } else {
2323 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2324 }
2325
2326 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2327
2328 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2329 FFRecycleString(ajp, ffstring);
2330 ffstring = FFGetString(ajp);
2331
2332 if (awp->afp != NULL) {
2333 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2334 }
2335 }
2336 }
2337 }
2338 */
2339
2340 for (sip = bsp->id; sip != NULL; sip = sip->next) {
2341 if (sip->choice == SEQID_OTHER) {
2342 tsip = (TextSeqIdPtr) sip->data.ptrvalue;
2343
2344 if (tsip != NULL) {
2345 is_other = TRUE;
2346 if (StringNCmp (tsip->accession, "NC_", 3) == 0) {
2347 if (hasRefTrackStatus) {
2348 /* will print elsewhere */
2349 } else if (! StringHasNoText (genomeBuildNumber)) {
2350 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2351 if (cbp != NULL) {
2352
2353 cbp->entityID = awp->entityID;
2354 cbp->first = first;
2355 first = FALSE;
2356
2357 if (cbp->first) {
2358 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2359 } else {
2360 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2361 }
2362
2363 FFAddOneString (ffstring, "GENOME ANNOTATION ", FALSE, FALSE, TILDE_IGNORE);
2364
2365 if ( GetWWW(ajp) ) {
2366 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2367 FF_Add_NCBI_Base_URL (ffstring, ref_link);
2368 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2369 }
2370 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
2371 if ( GetWWW(ajp) ) {
2372 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2373 }
2374 FFAddOneString (ffstring, ": ", FALSE, FALSE, TILDE_IGNORE);
2375
2376 FFAddOneString (ffstring, reftxt22, FALSE, FALSE, TILDE_EXPAND);
2377 FFAddOneString (ffstring, genomeBuildNumber, FALSE, FALSE, TILDE_EXPAND);
2378 if (StringHasNoText (genomeVersionNumber)) {
2379 genomeVersionNumber = "1";
2380 }
2381 FFAddOneString (ffstring, " version ", FALSE, FALSE, TILDE_EXPAND);
2382 FFAddOneString (ffstring, genomeVersionNumber, FALSE, FALSE, TILDE_EXPAND);
2383 FFAddOneString (ffstring, reftxt23, FALSE, FALSE, TILDE_EXPAND);
2384
2385 FFAddOneString (ffstring, " [see ", FALSE, FALSE, TILDE_EXPAND);
2386
2387 if ( GetWWW(ajp) ) {
2388 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2389 FF_Add_NCBI_Base_URL (ffstring, doc_link);
2390 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2391 }
2392 FFAddOneString (ffstring, "documentation", FALSE, FALSE, TILDE_IGNORE);
2393 if ( GetWWW(ajp) ) {
2394 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2395 }
2396
2397 FFAddOneString (ffstring, "].", FALSE, FALSE, TILDE_EXPAND);
2398
2399 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2400 FFRecycleString(ajp, ffstring);
2401 ffstring = FFGetString(ajp);
2402
2403 if (awp->afp != NULL) {
2404 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2405 }
2406 }
2407 }
2408
2409 } else if (StringNCmp(tsip->accession, "NT_", 3) == 0 || StringNCmp(tsip->accession, "NW_", 3) == 0) {
2410
2411 if (is_encode) {
2412 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2413 if (cbp != NULL) {
2414
2415 cbp->entityID = awp->entityID;
2416 cbp->first = first;
2417 first = FALSE;
2418
2419 if (cbp->first) {
2420 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2421 } else {
2422 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2423 }
2424
2425 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
2426 FFAddOneString (ffstring, ": ", FALSE, FALSE, TILDE_IGNORE);
2427
2428 FFAddOneString (ffstring, "This record was provided by the ", FALSE, FALSE, TILDE_EXPAND);
2429 if ( GetWWW(ajp) ) {
2430 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2431 FF_Add_NCBI_Base_URL (ffstring, link_encode);
2432 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2433 }
2434 FFAddOneString (ffstring, "ENCODE", FALSE, FALSE, TILDE_EXPAND);
2435 if ( GetWWW(ajp) ) {
2436 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2437 }
2438 FFAddOneString (ffstring, " project.", FALSE, FALSE, TILDE_EXPAND);
2439
2440 str = GetEncodeString (encodeUop, bsp);
2441 if (str != NULL) {
2442 FFAddOneString (ffstring, " ", FALSE, FALSE, TILDE_EXPAND);
2443 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2444 }
2445 MemFree (str);
2446
2447 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2448 FFRecycleString(ajp, ffstring);
2449 ffstring = FFGetString(ajp);
2450
2451 if (awp->afp != NULL) {
2452 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2453 }
2454 }
2455
2456 } else if (! hasRefTrackStatus) {
2457
2458 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2459 if (cbp != NULL) {
2460
2461 cbp->entityID = awp->entityID;
2462 cbp->first = first;
2463 first = FALSE;
2464
2465 if (cbp->first) {
2466 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2467 } else {
2468 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2469 }
2470
2471 FFAddOneString (ffstring, "GENOME ANNOTATION ", FALSE, FALSE, TILDE_IGNORE);
2472
2473 if ( GetWWW(ajp) ) {
2474 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2475 FF_Add_NCBI_Base_URL (ffstring, ref_link);
2476 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2477 }
2478 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
2479 if ( GetWWW(ajp) ) {
2480 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2481 }
2482 FFAddOneString (ffstring, ": ", FALSE, FALSE, TILDE_IGNORE);
2483
2484 if (! StringHasNoText (genomeBuildNumber)) {
2485 FFAddOneString (ffstring, reftxt22, FALSE, FALSE, TILDE_EXPAND);
2486 FFAddOneString (ffstring, genomeBuildNumber, FALSE, FALSE, TILDE_EXPAND);
2487 if (StringHasNoText (genomeVersionNumber)) {
2488 genomeVersionNumber = "1";
2489 }
2490 FFAddOneString (ffstring, " version ", FALSE, FALSE, TILDE_EXPAND);
2491 FFAddOneString (ffstring, genomeVersionNumber, FALSE, FALSE, TILDE_EXPAND);
2492 FFAddOneString (ffstring, reftxt23, FALSE, FALSE, TILDE_EXPAND);
2493
2494 FFAddOneString (ffstring, " [see ", FALSE, FALSE, TILDE_EXPAND);
2495
2496 if ( GetWWW(ajp) ) {
2497 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2498 FF_Add_NCBI_Base_URL (ffstring, doc_link);
2499 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2500 }
2501 FFAddOneString (ffstring, "documentation", FALSE, FALSE, TILDE_IGNORE);
2502 if ( GetWWW(ajp) ) {
2503 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2504 }
2505
2506 FFAddOneString (ffstring, "].", FALSE, FALSE, TILDE_EXPAND);
2507 } else {
2508
2509 FFAddOneString (ffstring, reftxt21, TRUE, FALSE, TILDE_EXPAND);
2510
2511 FFAddOneString (ffstring, "~Also see:~ ", FALSE, FALSE, TILDE_EXPAND);
2512
2513 if ( GetWWW(ajp) ) {
2514 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2515 FF_Add_NCBI_Base_URL (ffstring, doc_link);
2516 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2517 }
2518 FFAddOneString (ffstring, "Documentation", FALSE, FALSE, TILDE_IGNORE);
2519 if ( GetWWW(ajp) ) {
2520 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2521 }
2522
2523 FFAddOneString (ffstring, " of NCBI's Annotation Process~ ", FALSE, FALSE, TILDE_EXPAND);
2524 }
2525
2526 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2527 FFRecycleString(ajp, ffstring);
2528 ffstring = FFGetString(ajp);
2529
2530 if (awp->afp != NULL) {
2531 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2532 }
2533 }
2534 }
2535
2536 } else if (StringNCmp(tsip->accession, "XP_", 3) == 0 ||
2537 StringNCmp(tsip->accession, "XM_", 3) == 0 ||
2538 StringNCmp(tsip->accession, "XR_", 3) == 0 ||
2539 StringNCmp(tsip->accession, "ZP_", 3) == 0) {
2540
2541 name = NULL;
2542 method = NULL;
2543 mrnaEv = FALSE;
2544 estEv = FALSE;
2545 if (GetAnnotationComment (bsp, &name, &method, &mrnaEv, &estEv)) {
2546
2547 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2548 if (cbp != NULL) {
2549
2550 cbp->entityID = awp->entityID;
2551 cbp->first = first;
2552 first = FALSE;
2553
2554 if (cbp->first) {
2555 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2556 } else {
2557 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2558 }
2559
2560 FFAddOneString (ffstring, "MODEL ", FALSE, FALSE, TILDE_IGNORE);
2561
2562 if ( GetWWW(ajp) ) {
2563 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2564 FF_Add_NCBI_Base_URL (ffstring, ref_link);
2565 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2566 }
2567 FFAddOneString (ffstring, "REFSEQ", FALSE, FALSE, TILDE_IGNORE);
2568 if ( GetWWW(ajp) ) {
2569 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2570 }
2571 FFAddOneString (ffstring, ": ", FALSE, FALSE, TILDE_IGNORE);
2572
2573 FFAddTextToString (ffstring, NULL, reftxt11, " (", FALSE, FALSE, TILDE_IGNORE);
2574
2575 if ( GetWWW(ajp) ) {
2576 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2577 if (IS_ntdb_accession (name)) {
2578 FF_Add_NCBI_Base_URL (ffstring, link_seqn);
2579 } else {
2580 FF_Add_NCBI_Base_URL (ffstring, link_seqp);
2581 }
2582 gi = 0;
2583 if (ValidateAccnDotVer (name) == 0 && GetGiFromAccnDotVer (name, &gi)) {
2584 sprintf (tmp, "%ld", (long) gi);
2585 FFAddOneString (ffstring, tmp, FALSE, FALSE, TILDE_IGNORE);
2586 } else {
2587 FFAddOneString (ffstring, name, FALSE, FALSE, TILDE_IGNORE);
2588 }
2589 gi = 0;
2590 FFAddOneString (ffstring, "?report=graph", FALSE, FALSE, TILDE_IGNORE);
2591 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2592 FFAddOneString (ffstring, name, FALSE, FALSE, TILDE_IGNORE);
2593 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2594 } else {
2595 FFAddOneString (ffstring, name, FALSE, FALSE, TILDE_IGNORE);
2596 }
2597
2598 FFAddOneString (ffstring, ")", FALSE, FALSE, TILDE_IGNORE);
2599
2600 if (method != NULL) {
2601 FFAddOneString (ffstring, " ", FALSE, FALSE, TILDE_IGNORE);
2602 FFAddOneString (ffstring, reftxt12, FALSE, FALSE, TILDE_IGNORE);
2603 FFAddOneString (ffstring, " ", FALSE, FALSE, TILDE_IGNORE);
2604 FFAddOneString (ffstring, method, FALSE, FALSE, TILDE_IGNORE);
2605 }
2606
2607 if (mrnaEv || estEv) {
2608 FFAddOneString (ffstring, ", supported by ", FALSE, FALSE, TILDE_IGNORE);
2609 if (mrnaEv && estEv) {
2610 FFAddOneString (ffstring, "mRNA and EST ", FALSE, FALSE, TILDE_IGNORE);
2611 } else if (mrnaEv) {
2612 FFAddOneString (ffstring, "mRNA ", FALSE, FALSE, TILDE_IGNORE);
2613 } else {
2614 FFAddOneString (ffstring, "EST ", FALSE, FALSE, TILDE_IGNORE);
2615 }
2616 geneName = NULL;
2617 locusID [0] = '\0';
2618 taxID [0] = '\0';
2619 if ( GetWWW(ajp) && GetGeneAndLocus (bsp, &geneName, locusID, taxID)) {
2620 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2621 FF_Add_NCBI_Base_URL (ffstring, ev_link);
2622 FFAddTextToString (ffstring, "contig=", name, NULL, FALSE, FALSE, TILDE_IGNORE);
2623 FFAddTextToString (ffstring, "&gene=", geneName, NULL, FALSE, FALSE, TILDE_IGNORE);
2624 FFAddTextToString (ffstring, "&lid=", locusID, NULL, FALSE, FALSE, TILDE_IGNORE);
2625 if (! StringHasNoText (taxID)) {
2626 FFAddTextToString (ffstring, "&taxid=", taxID, NULL, FALSE, FALSE, TILDE_IGNORE);
2627 }
2628 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2629 FFAddOneString (ffstring, "evidence", FALSE, FALSE, TILDE_IGNORE);
2630 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2631 } else {
2632 FFAddOneString (ffstring, "evidence", FALSE, FALSE, TILDE_IGNORE);
2633 }
2634 }
2635
2636 FFAddOneString (ffstring, ".", FALSE, FALSE, TILDE_IGNORE);
2637
2638 FFAddOneString (ffstring, "~Also see:~ ", FALSE, FALSE, TILDE_EXPAND);
2639
2640 if ( GetWWW(ajp) ) {
2641 FFAddOneString (ffstring, "<a href=\"", FALSE, FALSE, TILDE_IGNORE);
2642 FF_Add_NCBI_Base_URL (ffstring, doc_link);
2643 FFAddOneString (ffstring, "\">", FALSE, FALSE, TILDE_IGNORE);
2644 }
2645 FFAddOneString (ffstring, "Documentation", FALSE, FALSE, TILDE_IGNORE);
2646 if ( GetWWW(ajp) ) {
2647 FFAddOneString (ffstring, "</a>", FALSE, FALSE, TILDE_IGNORE);
2648 }
2649
2650 FFAddOneString (ffstring, " of NCBI's Annotation Process~ ", FALSE, FALSE, TILDE_EXPAND);
2651
2652 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2653 FFRecycleString(ajp, ffstring);
2654 ffstring = FFGetString(ajp);
2655
2656 if (awp->afp != NULL) {
2657 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2658 }
2659 }
2660 }
2661 } else {
2662 if (StringLen (tsip->accession) == 15) {
2663 is_wgs = TRUE;
2664 if (StringCmp (tsip->accession + 9, "000000") == 0) {
2665 wgsaccn = tsip->accession;
2666 wgsname = tsip->name; /* master accession has 8 zeroes, name has project version plus 6 zeroes */
2667 }
2668 }
2669 }
2670 }
2671
2672 } else if (sip->choice == SEQID_TPG || sip->choice == SEQID_TPE || sip->choice == SEQID_TPD) {
2673
2674 is_tpa = TRUE;
2675
2676 tsip = (TextSeqIdPtr) sip->data.ptrvalue;
2677 if (tsip != NULL && tsip->accession != NULL) {
2678 acclen = StringLen (tsip->accession);
2679 if (acclen == 12) {
2680 is_wgs = TRUE;
2681 if (StringCmp (tsip->accession + 6, "000000") == 0) {
2682 wgsaccn = tsip->accession;
2683 wgsname = tsip->name; /* master accession has 8 zeroes, name has project version plus 6 zeroes */
2684 }
2685 } else if (acclen == 13) {
2686 is_wgs = TRUE;
2687 if (StringCmp (tsip->accession + 6, "0000000") == 0) {
2688 wgsaccn = tsip->accession;
2689 wgsname = tsip->name; /* master accession has 9 zeroes, name has project version plus 7 zeroes */
2690 }
2691 } else if (ajp->newSourceOrg && StringLen (tsip->accession) == 6) {
2692 ch = tsip->accession [0];
2693 if (ch == 'J' || ch == 'K' || ch == 'L' || ch == 'M') {
2694 showGBBSource = TRUE;
2695 }
2696 }
2697 }
2698
2699 } else if (sip->choice == SEQID_GENBANK || sip->choice == SEQID_EMBL || sip->choice == SEQID_DDBJ) {
2700
2701 is_collab = TRUE;
2702
2703 tsip = (TextSeqIdPtr) sip->data.ptrvalue;
2704 if (tsip != NULL && tsip->accession != NULL) {
2705 acclen = StringLen (tsip->accession);
2706 if (acclen == 12) {
2707 is_wgs = TRUE;
2708 if (StringCmp (tsip->accession + 6, "000000") == 0) {
2709 wgsaccn = tsip->accession;
2710 wgsname = tsip->name; /* master accession has 8 zeroes, name has project version plus 6 zeroes */
2711 }
2712 } else if (acclen == 13) {
2713 is_wgs = TRUE;
2714 if (StringCmp (tsip->accession + 6, "0000000") == 0) {
2715 wgsaccn = tsip->accession;
2716 wgsname = tsip->name; /* master accession has 9 zeroes, name has project version plus 7 zeroes */
2717 }
2718 } else if (ajp->newSourceOrg && StringLen (tsip->accession) == 6) {
2719 ch = tsip->accession [0];
2720 if (ch == 'J' || ch == 'K' || ch == 'L' || ch == 'M') {
2721 showGBBSource = TRUE;
2722 }
2723 }
2724 }
2725
2726 } else if (sip->choice == SEQID_GENERAL) {
2727 dbt = (DbtagPtr) sip->data.ptrvalue;
2728
2729 /* show GSDB sequence identifier */
2730
2731 if (dbt != NULL && StringCmp (dbt->db, "GSDB") == 0 && dbt->tag != NULL) {
2732 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2733 if (cbp != NULL) {
2734
2735 cbp->entityID = awp->entityID;
2736 cbp->first = first;
2737 first = FALSE;
2738
2739 /* string will be created after we know if there are additional comments */
2740
2741 gsdbid = dbt->tag->id;
2742 sprintf (buf, "GSDB:S:%ld.", (long) gsdbid);
2743
2744 if (cbp->first) {
2745 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2746 } else {
2747 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2748 }
2749
2750 /* CheckEndPunctuation, ConvertDoubleQuotes, and ExpandTildes already taken into account */
2751
2752 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_IGNORE);
2753
2754 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2755 FFRecycleString(ajp, ffstring);
2756 ffstring = FFGetString(ajp);
2757
2758 if (awp->afp != NULL) {
2759 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2760 }
2761 }
2762 } else if (dbt != NULL && StringCmp (dbt->db, "NCBIFILE") == 0 && dbt->tag != NULL) {
2763 ncbifileID = dbt->tag;
2764 }
2765
2766 } else if (sip->choice == SEQID_GI) {
2767 gi = (Int4) sip->data.intvalue;
2768
2769 } else if (sip->choice == SEQID_LOCAL) {
2770 localID = (ObjectIdPtr) sip->data.ptrvalue;
2771 }
2772 }
2773
2774 if (localID != NULL) {
2775 if (is_tpa || is_collab) {
2776 if (awp->mode == SEQUIN_MODE || awp->mode == DUMP_MODE) {
2777 buf [0] = '\0';
2778 if (! StringHasNoText (localID->str)) {
2779 if (StringLen (localID->str) < 1000) {
2780 sprintf (buf, "LocalID: %s", localID->str);
2781 } else {
2782 sprintf (buf, "LocalID string too large");
2783 }
2784 } else {
2785 sprintf (buf, "LocalID: %ld", (long) localID->id);
2786 }
2787
2788 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2789 if (cbp != NULL) {
2790
2791 cbp->entityID = awp->entityID;
2792 cbp->first = first;
2793 first = FALSE;
2794
2795 if (cbp->first) {
2796 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2797 } else {
2798 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2799 }
2800
2801 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
2802
2803 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12,5, 5, "CC");
2804 FFRecycleString(ajp, ffstring);
2805 ffstring = FFGetString(ajp);
2806
2807 if (awp->afp != NULL) {
2808 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2809 }
2810 }
2811 }
2812 }
2813 }
2814
2815 if (ncbifileID != NULL) {
2816 if (is_tpa || is_collab) {
2817 if (awp->mode == SEQUIN_MODE || awp->mode == DUMP_MODE) {
2818 buf [0] = '\0';
2819 if (! StringHasNoText (ncbifileID->str)) {
2820 if (StringLen (ncbifileID->str) < 1000) {
2821 sprintf (buf, "FileID: %s", ncbifileID->str);
2822 } else {
2823 sprintf (buf, "FileID string too large");
2824 }
2825 } else {
2826 sprintf (buf, "FileID: %ld", (long) ncbifileID->id);
2827 }
2828
2829 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2830 if (cbp != NULL) {
2831
2832 cbp->entityID = awp->entityID;
2833 cbp->first = first;
2834 first = FALSE;
2835
2836 if (cbp->first) {
2837 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2838 } else {
2839 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2840 }
2841
2842 FFAddOneString (ffstring, buf, FALSE, FALSE, TILDE_EXPAND);
2843
2844 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12,5, 5, "CC");
2845 FFRecycleString(ajp, ffstring);
2846 ffstring = FFGetString(ajp);
2847
2848 if (awp->afp != NULL) {
2849 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2850 }
2851 }
2852 }
2853 }
2854 }
2855
2856 /* RefSeq results in allocated comment string */
2857
2858 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
2859 while (sdp != NULL) {
2860
2861 uop = (UserObjectPtr) sdp->data.ptrvalue;
2862 if (uop != NULL) {
2863
2864 if (! didTPA) {
2865 str = GetStrForTPA (uop, bsp);
2866 if (str != NULL) {
2867
2868 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2869 if (cbp != NULL) {
2870
2871 cbp->entityID = dcontext.entityID;
2872 cbp->itemID = dcontext.itemID;
2873 cbp->itemtype = OBJ_SEQDESC;
2874 cbp->first = first;
2875 first = FALSE;
2876
2877 if (cbp->first) {
2878 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2879 } else {
2880 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2881 }
2882
2883 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2884
2885 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12,5, 5, "CC");
2886 FFRecycleString(ajp, ffstring);
2887 ffstring = FFGetString(ajp);
2888
2889 if (awp->afp != NULL) {
2890 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2891 }
2892 }
2893 MemFree (str);
2894 didTPA = TRUE;
2895 }
2896 }
2897
2898 if (! ajp->flags.hideBankItComment) {
2899 str = GetStrForBankit (uop);
2900 if (str != NULL) {
2901
2902 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2903 if (cbp != NULL) {
2904
2905 cbp->entityID = dcontext.entityID;
2906 cbp->itemID = dcontext.itemID;
2907 cbp->itemtype = OBJ_SEQDESC;
2908 cbp->first = first;
2909 first = FALSE;
2910
2911 if (cbp->first) {
2912 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2913 } else {
2914 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2915 }
2916
2917 FFAddOneString (ffstring, str, TRUE, FALSE, TILDE_EXPAND);
2918
2919 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12,5, 5, "CC");
2920 FFRecycleString(ajp, ffstring);
2921 ffstring = FFGetString(ajp);
2922
2923 if (awp->afp != NULL) {
2924 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2925 }
2926 }
2927 MemFree (str);
2928 }
2929 }
2930
2931 if (! didRefTrack) {
2932 str = GetStatusForRefTrack (uop);
2933 if (str != NULL) {
2934
2935 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2936 if (cbp != NULL) {
2937
2938 cbp->entityID = dcontext.entityID;
2939 cbp->itemID = dcontext.itemID;
2940 cbp->itemtype = OBJ_SEQDESC;
2941 cbp->first = first;
2942 first = FALSE;
2943
2944 if (cbp->first) {
2945 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2946 } else {
2947 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2948 }
2949
2950 if (StringICmp (str, "Pipeline ") != 0) {
2951 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2952 }
2953
2954 AddStrForRefTrack (ajp, ffstring, uop, ISA_na (bsp->mol), genomeBuildNumber, genomeVersionNumber);
2955
2956 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12,5, 5, "CC");
2957 FFRecycleString(ajp, ffstring);
2958 ffstring = FFGetString(ajp);
2959
2960 if (awp->afp != NULL) {
2961 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2962 }
2963 }
2964 /* do not free static str from GetStatusForRefTrack */
2965 didRefTrack = TRUE;
2966 }
2967 }
2968
2969 if (! didGenome) {
2970 str = GetStrForGenome (uop, bsp);
2971 if (str != NULL) {
2972
2973 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
2974 if (cbp != NULL) {
2975
2976 cbp->entityID = dcontext.entityID;
2977 cbp->itemID = dcontext.itemID;
2978 cbp->itemtype = OBJ_SEQDESC;
2979 cbp->first = first;
2980 first = FALSE;
2981
2982 if (cbp->first) {
2983 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
2984 } else {
2985 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
2986 }
2987
2988 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
2989
2990 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
2991 FFRecycleString(ajp, ffstring);
2992 ffstring = FFGetString(ajp);
2993
2994 if (awp->afp != NULL) {
2995 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
2996 }
2997 }
2998 MemFree (str);
2999 didGenome = TRUE;
3000 }
3001 }
3002 }
3003 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
3004 }
3005
3006 if (bsp->repr == Seq_repr_delta && bsp->seq_ext_type == 4 && is_wgs) {
3007 has_gaps = FALSE;
3008 for (dsp = (DeltaSeqPtr) bsp->seq_ext; dsp; dsp=dsp->next) {
3009 if (dsp->choice == 2) {
3010 litp = (SeqLitPtr) dsp->data.ptrvalue;
3011 if (litp != NULL) {
3012 if ((litp->seq_data == NULL || litp->seq_data_type == Seq_code_gap) &&
3013 litp->length > 0) {
3014 has_gaps = TRUE;
3015 }
3016 }
3017 }
3018 }
3019 if (has_gaps) {
3020 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3021 if (cbp != NULL) {
3022
3023 cbp->entityID = awp->entityID;
3024 cbp->first = first;
3025 first = FALSE;
3026
3027 if (cbp->first) {
3028 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3029 } else {
3030 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3031 }
3032
3033 if (is_wgs) {
3034 FFAddOneString (ffstring, nsWGSGapsString, TRUE, FALSE, TILDE_EXPAND);
3035 } else {
3036 FFAddOneString (ffstring, nsAreGapsString, TRUE, FALSE, TILDE_EXPAND);
3037 }
3038
3039 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3040 FFRecycleString(ajp, ffstring);
3041 ffstring = FFGetString(ajp);
3042
3043 if (awp->afp != NULL) {
3044 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3045 }
3046 }
3047 }
3048 }
3049
3050 /* Seq-hist results in allocated comment string */
3051
3052 hist = bsp->hist;
3053 if (hist != NULL) {
3054
3055 if (hist->replaced_by_ids != NULL && hist->replaced_by_date != NULL) {
3056
3057 okay = TRUE;
3058 for (sip = hist->replaced_by_ids; sip != NULL; sip = sip->next) {
3059 if (sip->choice == SEQID_GI) {
3060 if (gi == (Int4) sip->data.intvalue) {
3061 okay = FALSE;
3062 }
3063 }
3064 }
3065
3066 if (okay) {
3067 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3068 if (cbp != NULL) {
3069
3070 cbp->entityID = awp->entityID;
3071 cbp->first = first;
3072 first = FALSE;
3073
3074 if (cbp->first) {
3075 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3076 } else {
3077 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3078 }
3079
3080 AddHistCommentString (ajp, ffstring, "[WARNING] On", "this sequence was replaced by",
3081 hist->replaced_by_date, hist->replaced_by_ids, ISA_na (bsp->mol));
3082
3083 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3084 FFRecycleString(ajp, ffstring);
3085 ffstring = FFGetString(ajp);
3086
3087 if (awp->afp != NULL) {
3088 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3089 }
3090 }
3091 }
3092 }
3093
3094 if (hist->replace_ids != NULL && hist->replace_date != NULL && awp->mode != SEQUIN_MODE) {
3095
3096 okay = TRUE;
3097 for (sip = hist->replace_ids; sip != NULL; sip = sip->next) {
3098 if (sip->choice == SEQID_GI) {
3099 if (gi == (Int4) sip->data.intvalue) {
3100 okay = FALSE;
3101 }
3102 }
3103 }
3104
3105 if (okay) {
3106 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3107 if (cbp != NULL) {
3108
3109 cbp->entityID = awp->entityID;
3110 cbp->first = first;
3111 first = FALSE;
3112
3113 if (cbp->first) {
3114 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3115 } else {
3116 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3117 }
3118
3119 AddHistCommentString (ajp, ffstring, "On", "this sequence version replaced",
3120 hist->replace_date, hist->replace_ids, ISA_na (bsp->mol));
3121
3122 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3123 FFRecycleString(ajp, ffstring);
3124 ffstring = FFGetString(ajp);
3125
3126 if (awp->afp != NULL) {
3127 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3128 }
3129 }
3130 }
3131 }
3132
3133 }
3134
3135 /* just save IDs for comment, maploc, and region descriptors */
3136
3137 /*
3138 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_comment, &dcontext);
3139 while (sdp != NULL) {
3140 if (sdp->data.ptrvalue != NULL) {
3141 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3142 if (cbp != NULL) {
3143 cbp->entityID = dcontext.entityID;
3144 cbp->itemID = dcontext.itemID;
3145 cbp->itemtype = OBJ_SEQDESC;
3146 cbp->first = first;
3147 first = FALSE;
3148
3149 if (awp->afp != NULL) {
3150 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3151 }
3152 }
3153 }
3154 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_comment, &dcontext);
3155 }
3156 */
3157
3158 /* WGS master comment goes before comment descriptors */
3159
3160 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
3161 if (sdp != NULL) {
3162
3163 mip = (MolInfoPtr) sdp->data.ptrvalue;
3164 if (mip != NULL) {
3165 if (mip->tech == MI_TECH_wgs) {
3166
3167 if (wgsname != NULL) {
3168
3169 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3170 if (cbp != NULL) {
3171
3172 /*
3173 cbp->entityID = dcontext.entityID;
3174 cbp->itemID = dcontext.itemID;
3175 cbp->itemtype = OBJ_SEQDESC;
3176 */
3177 cbp->entityID = awp->entityID;
3178 cbp->first = first;
3179 first = FALSE;
3180
3181 if (cbp->first) {
3182 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3183 } else {
3184 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3185 }
3186
3187 AddWGSMasterCommentString (ffstring, bsp, wgsaccn, wgsname);
3188
3189 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3190 FFRecycleString(ajp, ffstring);
3191 ffstring = FFGetString(ajp);
3192
3193 cbp->itemID = dcontext.itemID;
3194 cbp->itemtype = OBJ_SEQDESC;
3195 if (awp->afp != NULL) {
3196 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3197 }
3198 cbp->itemID = 0;
3199 cbp->itemtype = 0;
3200 }
3201 }
3202 }
3203 }
3204 }
3205
3206 if (showGBBSource) {
3207 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_genbank, &dcontext);
3208 if (sdp != NULL) {
3209 gbp = (GBBlockPtr) sdp->data.ptrvalue;
3210 if (gbp != NULL && (! StringHasNoText (gbp->source))) {
3211 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3212 if (cbp != NULL) {
3213
3214 cbp->entityID = dcontext.entityID;
3215 cbp->itemID = dcontext.itemID;
3216 cbp->itemtype = OBJ_SEQDESC;
3217 cbp->first = first;
3218 first = FALSE;
3219
3220 if (cbp->first) {
3221 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3222 } else {
3223 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3224 }
3225
3226 FFAddOneString (ffstring, "Original source text: ", FALSE, FALSE, TILDE_EXPAND);
3227 FFAddOneString (ffstring, gbp->source, TRUE, TRUE, TILDE_EXPAND);
3228
3229 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3230 FFRecycleString(ajp, ffstring);
3231 ffstring = FFGetString(ajp);
3232
3233 if (awp->afp != NULL) {
3234 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3235 }
3236 }
3237 }
3238 }
3239 }
3240
3241 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_comment, &dcontext);
3242 while (sdp != NULL) {
3243 if (StringDoesHaveText ((CharPtr)sdp->data.ptrvalue)) {
3244 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3245 if (cbp != NULL) {
3246
3247 cbp->entityID = dcontext.entityID;
3248 cbp->itemID = dcontext.itemID;
3249 cbp->itemtype = OBJ_SEQDESC;
3250 cbp->first = first;
3251 first = FALSE;
3252
3253 if (awp->afp != NULL) {
3254 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3255 }
3256 }
3257 }
3258 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_comment, &dcontext);
3259 }
3260
3261 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_maploc, &dcontext);
3262 while (sdp != NULL) {
3263 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3264 if (cbp != NULL) {
3265
3266 cbp->entityID = dcontext.entityID;
3267 cbp->itemID = dcontext.itemID;
3268 cbp->itemtype = OBJ_SEQDESC;
3269 cbp->first = first;
3270 first = FALSE;
3271
3272 if (awp->afp != NULL) {
3273 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3274 }
3275 }
3276 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_maploc, &dcontext);
3277 }
3278
3279 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_region, &dcontext);
3280 while (sdp != NULL) {
3281 if (sdp->data.ptrvalue != NULL) {
3282 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3283 if (cbp != NULL) {
3284
3285 cbp->entityID = dcontext.entityID;
3286 cbp->itemID = dcontext.itemID;
3287 cbp->itemtype = OBJ_SEQDESC;
3288 cbp->first = first;
3289 first = FALSE;
3290
3291 if (awp->afp != NULL) {
3292 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3293 }
3294 }
3295 }
3296 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_region, &dcontext);
3297 }
3298
3299 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_name, &dcontext);
3300 while (sdp != NULL) {
3301 if (sdp->data.ptrvalue != NULL) {
3302 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3303 if (cbp != NULL) {
3304
3305 cbp->entityID = dcontext.entityID;
3306 cbp->itemID = dcontext.itemID;
3307 cbp->itemtype = OBJ_SEQDESC;
3308 cbp->first = first;
3309 first = FALSE;
3310
3311 if (awp->afp != NULL) {
3312 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3313 }
3314 }
3315 }
3316 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_name, &dcontext);
3317 }
3318
3319 /* StructuredComment user object */
3320
3321 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_user, &dcontext);
3322 while (sdp != NULL) {
3323
3324 uop = (UserObjectPtr) sdp->data.ptrvalue;
3325 if (uop != NULL) {
3326
3327 str = GetStrForStructuredComment (awp, ajp, uop, bsp);
3328 if (str != NULL) {
3329
3330 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3331 if (cbp != NULL) {
3332
3333 cbp->entityID = dcontext.entityID;
3334 cbp->itemID = dcontext.itemID;
3335 cbp->itemtype = OBJ_SEQDESC;
3336 cbp->first = first;
3337 first = FALSE;
3338
3339 if (cbp->first) {
3340 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3341 } else {
3342 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3343 FFAddOneString (ffstring, "\n", FALSE, FALSE, TILDE_EXPAND);
3344 }
3345
3346 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_EXPAND);
3347
3348 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3349 FFRecycleString(ajp, ffstring);
3350 ffstring = FFGetString(ajp);
3351
3352 if (awp->afp != NULL) {
3353 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3354 }
3355 }
3356 MemFree (str);
3357 }
3358 }
3359 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_user, &dcontext);
3360 }
3361
3362 /* HTGS results in allocated comment string */
3363
3364 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
3365 if (sdp != NULL) {
3366
3367 mip = (MolInfoPtr) sdp->data.ptrvalue;
3368 if (mip != NULL) {
3369 if (mip->completeness != 0 && is_other) {
3370
3371 str = GetMolInfoCommentString (bsp, mip);
3372
3373 if (str != NULL) {
3374 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3375 if (cbp != NULL) {
3376
3377 cbp->entityID = dcontext.entityID;
3378 cbp->itemID = dcontext.itemID;
3379 cbp->itemtype = OBJ_SEQDESC;
3380 cbp->first = first;
3381 first = FALSE;
3382
3383 if (cbp->first) {
3384 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3385 } else {
3386 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3387 }
3388
3389 FFAddOneString (ffstring, str, TRUE, FALSE, TILDE_EXPAND);
3390
3391 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3392 FFRecycleString(ajp, ffstring);
3393 ffstring = FFGetString(ajp);
3394
3395 if (awp->afp != NULL) {
3396 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3397 }
3398 }
3399 }
3400
3401 }
3402 if (mip->tech == MI_TECH_htgs_0 ||
3403 mip->tech == MI_TECH_htgs_1 ||
3404 mip->tech == MI_TECH_htgs_2) {
3405
3406 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3407 if (cbp != NULL) {
3408
3409 /*
3410 cbp->entityID = dcontext.entityID;
3411 cbp->itemID = dcontext.itemID;
3412 cbp->itemtype = OBJ_SEQDESC;
3413 */
3414 cbp->entityID = awp->entityID;
3415 cbp->first = first;
3416 first = FALSE;
3417
3418 if (cbp->first) {
3419 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3420 } else {
3421 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3422 }
3423
3424 AddHTGSCommentString (ffstring, bsp, mip);
3425
3426 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3427 FFRecycleString(ajp, ffstring);
3428 ffstring = FFGetString(ajp);
3429
3430 if (awp->afp != NULL) {
3431 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3432 }
3433 }
3434
3435 } else {
3436 str = StringForSeqTech (mip->tech);
3437 if (! StringHasNoText (str)) {
3438
3439 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3440 if (cbp != NULL) {
3441
3442 /*
3443 cbp->entityID = dcontext.entityID;
3444 cbp->itemID = dcontext.itemID;
3445 cbp->itemtype = OBJ_SEQDESC;
3446 */
3447 cbp->entityID = awp->entityID;
3448 cbp->first = first;
3449 first = FALSE;
3450
3451 if (cbp->first) {
3452 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3453 } else {
3454 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3455 }
3456
3457 FFAddTextToString (ffstring, "Method: ", str, NULL, TRUE, FALSE, TILDE_EXPAND);
3458
3459 cbp->string = FFEndPrint(ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3460 FFRecycleString(ajp, ffstring);
3461 ffstring = FFGetString(ajp);
3462
3463 if (awp->afp != NULL) {
3464 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3465 }
3466 }
3467 }
3468 }
3469 }
3470 }
3471
3472 parent = awp->parent;
3473 if (parent == NULL) return;
3474
3475 /* no longer adding comment features that are full length on appropriate segment */
3476
3477 /*
3478 sfp = SeqMgrGetNextFeature (parent, NULL, SEQFEAT_COMMENT, 0, &fcontext);
3479 while (sfp != NULL) {
3480 if (fcontext.left == awp->from && fcontext.right == awp->to) {
3481 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3482 if (cbp != NULL) {
3483
3484 cbp->entityID = fcontext.entityID;
3485 cbp->itemID = fcontext.itemID;
3486 cbp->itemtype = OBJ_SEQFEAT;
3487 cbp->first = first;
3488 first = FALSE;
3489
3490 if (awp->afp != NULL) {
3491 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3492 }
3493 }
3494 }
3495 sfp = SeqMgrGetNextFeature (parent, sfp, SEQFEAT_COMMENT, 0, &fcontext);
3496 }
3497 */
3498
3499 /* look for Seq-annot.desc.comment on annots packaged on current bioseq */
3500
3501 annotDescCommentToComment = FALSE;
3502 adp = SeqMgrGetNextAnnotDesc (bsp, NULL, Annot_descr_user, &acontext);
3503 while (adp != NULL) {
3504 uop = (UserObjectPtr) adp->data.ptrvalue;
3505 if (uop != NULL) {
3506 oip = uop->type;
3507 if (oip != NULL) {
3508 if (StringCmp (oip->str, "AnnotDescCommentPolicy") == 0) {
3509 for (ufp = uop->data; ufp != NULL; ufp = ufp->next) {
3510 oip = ufp->label;
3511 if (oip == NULL || ufp->data.ptrvalue == NULL) continue;
3512 if (StringCmp (oip->str, "Policy") == 0) {
3513 if (StringICmp ((CharPtr) ufp->data.ptrvalue, "ShowInComment") == 0) {
3514 annotDescCommentToComment = TRUE;
3515 }
3516 }
3517 }
3518 }
3519 }
3520 }
3521 adp = SeqMgrGetNextAnnotDesc (bsp, adp, Annot_descr_user, &acontext);
3522 }
3523
3524 if (annotDescCommentToComment) {
3525 adp = SeqMgrGetNextAnnotDesc (bsp, NULL, Annot_descr_comment, &acontext);
3526 while (adp != NULL) {
3527 str = (CharPtr) adp->data.ptrvalue;
3528 if (StringDoesHaveText (str)) {
3529 cbp = (CommentBlockPtr) Asn2gbAddBlock (awp, COMMENT_BLOCK, sizeof (CommentBlock));
3530 if (cbp != NULL) {
3531
3532 cbp->entityID = awp->entityID;
3533 cbp->first = first;
3534 first = FALSE;
3535
3536 if (cbp->first) {
3537 FFStartPrint (ffstring, awp->format, 0, 12, "COMMENT", 12, 5, 5, "CC", TRUE);
3538 } else {
3539 FFStartPrint (ffstring, awp->format, 0, 12, NULL, 12, 5, 5, "CC", FALSE);
3540 }
3541
3542 FFAddOneString (ffstring, str, TRUE, FALSE, TILDE_EXPAND);
3543
3544 cbp->string = FFEndPrint (ajp, ffstring, awp->format, 12, 12, 5, 5, "CC");
3545 FFRecycleString (ajp, ffstring);
3546 ffstring = FFGetString (ajp);
3547
3548 if (awp->afp != NULL) {
3549 DoImmediateFormat (awp->afp, (BaseBlockPtr) cbp);
3550 }
3551 }
3552 }
3553 adp = SeqMgrGetNextAnnotDesc (bsp, adp, Annot_descr_comment, &acontext);
3554 }
3555 }
3556
3557 FFRecycleString(ajp, ffstring);
3558 }
3559
3560 NLM_EXTERN void AddFeatHeaderBlock (
3561 Asn2gbWorkPtr awp
3562 )
3563
3564 {
3565 IntAsn2gbJobPtr ajp;
3566 BaseBlockPtr bbp;
3567 Char buf [128];
3568 StringItemPtr ffstring;
3569 CharPtr suffix = NULL;
3570
3571 if (awp == NULL) return;
3572 ajp = awp->ajp;
3573 if (ajp == NULL) return;
3574
3575 bbp = Asn2gbAddBlock (awp, FEATHEADER_BLOCK, sizeof (BaseBlock));
3576 if (bbp == NULL) return;
3577
3578 bbp->entityID = awp->entityID;
3579
3580 if (GetWWW (ajp) && awp->mode == ENTREZ_MODE && awp->afp != NULL &&
3581 (awp->format == GENBANK_FMT || awp->format == GENPEPT_FMT)) {
3582 sprintf (buf, "<a name=\"feature_%ld\"></a>", (long) awp->currGi);
3583 DoQuickLinkFormat (awp->afp, buf);
3584 }
3585
3586 if (awp->format != FTABLE_FMT) {
3587 ffstring = FFGetString(ajp);
3588 if ( ffstring == NULL ) return;
3589
3590 FFStartPrint (ffstring, awp->format, 0, 12, "FEATURES", 21, 5, 0, "FH", TRUE);
3591
3592 if (awp->format == EMBL_FMT || awp->format == EMBLPEPT_FMT) {
3593 FFAddOneString (ffstring, "Key", FALSE, FALSE, TILDE_IGNORE);
3594 FFAddNChar(ffstring, ' ', 13 , FALSE);
3595 }
3596
3597 FFAddOneString (ffstring, "Location/Qualifiers", FALSE, FALSE, TILDE_TO_SPACES);
3598
3599 if (awp->format == EMBL_FMT || awp->format == EMBLPEPT_FMT) {
3600 FFAddNewLine(ffstring);
3601 FFAddNewLine(ffstring);
3602 }
3603
3604 suffix = FFEndPrint(ajp, ffstring, awp->format, 12, 21, 5, 0, "FH");
3605 FFRecycleString(ajp, ffstring);
3606 }
3607
3608 bbp->string = suffix;
3609
3610 if (awp->afp != NULL) {
3611 DoImmediateFormat (awp->afp, bbp);
3612 }
3613 }
3614
3615 static Uint2 ComputeSourceHash (
3616 CharPtr key,
3617 Uint2 start
3618 )
3619
3620 {
3621 Uint4 h;
3622 Uint2 M;
3623 Uint2 S;
3624
3625 if (key == NULL) return start;
3626
3627 M = 101; /* prime key */
3628 S = 256; /* size of alphabet */
3629
3630 for (h = start; *key != '\0'; key++) {
3631 h = (S * h + *key) % M;
3632 }
3633
3634 return (Uint2) h;
3635 }
3636
3637 static BaseBlockPtr AddSource (
3638 Asn2gbWorkPtr awp,
3639 ValNodePtr PNTR head,
3640 BioSourcePtr biop,
3641 CharPtr comment
3642 )
3643
3644 {
3645 BaseBlockPtr bbp;
3646 DbtagPtr dbt;
3647 Uint2 hash;
3648 SourceType idx;
3649 IntSrcBlockPtr isp;
3650 ObjectIdPtr oip;
3651 OrgModPtr omp;
3652 OrgNamePtr onp;
3653 OrgRefPtr orp;
3654 SubSourcePtr ssp;
3655 CharPtr str;
3656 Uint1 subtype;
3657 Char tmp [16];
3658 ValNodePtr vnp;
3659
3660 if (awp == NULL || head == NULL || biop == NULL) return NULL;
3661
3662 bbp = (BaseBlockPtr) MemNew (sizeof (IntSrcBlock));
3663 if (bbp == NULL) return NULL;
3664 bbp->blocktype = SOURCEFEAT_BLOCK;
3665 bbp->section = awp->currsection;
3666
3667 ValNodeAddPointer (head, 0, bbp);
3668
3669 isp = (IntSrcBlockPtr) bbp;
3670 isp->biop = biop;
3671 isp->is_focus = biop->is_focus;
3672 if (biop->origin == 5) {
3673 isp->is_synthetic = TRUE;
3674 }
3675
3676 orp = biop->org;
3677 if (orp == NULL) return bbp;
3678
3679 if (StringICmp (orp->taxname, "synthetic construct") == 0) {
3680 isp->is_synthetic = TRUE;
3681 }
3682
3683 isp->orghash = ComputeSourceHash (orp->taxname, 0);
3684 isp->taxname = orp->taxname;
3685
3686 hash = 0;
3687 onp = orp->orgname;
3688 if (onp != NULL) {
3689 if (StringICmp (onp->div, "SYN") == 0) {
3690 isp->is_synthetic = TRUE;
3691 }
3692 isp->omp = onp->mod;
3693 for (omp = onp->mod; omp != NULL; omp = omp->next) {
3694 subtype = omp->subtype;
3695 if (subtype == 253) {
3696 subtype = 35;
3697 } else if (subtype == 254) {
3698 subtype = 36;
3699 } else if (subtype == 255) {
3700 subtype = 37;
3701 }
3702 if (subtype < 38) {
3703 idx = orgModToSourceIdx [subtype];
3704 if (idx > 0 && idx < ASN2GNBK_TOTAL_SOURCE) {
3705 str = asn2gnbk_source_quals [idx].name;
3706 hash = ComputeSourceHash (str, hash);
3707 hash = ComputeSourceHash (omp->subname, hash);
3708 }
3709 }
3710 }
3711 }
3712 if (comment != NULL) {
3713 hash = ComputeSourceHash ("note", hash);
3714 hash = ComputeSourceHash (comment, hash);
3715 }
3716 isp->modhash = hash;
3717
3718 hash = 0;
3719 for (ssp = biop->subtype; ssp != NULL; ssp = ssp->next) {
3720 subtype = ssp->subtype;
3721 if (subtype == 255) {
3722 subtype = 38;
3723 }
3724 if (subtype < 39) {
3725 idx = subSourceToSourceIdx [subtype];
3726 if (idx > 0 && idx < ASN2GNBK_TOTAL_SOURCE) {
3727 str = asn2gnbk_source_quals [idx].name;
3728 hash = ComputeSourceHash (str, hash);
3729 hash = ComputeSourceHash (ssp->name, hash);
3730 }
3731 }
3732 }
3733 isp->subhash = hash;
3734 isp->ssp = biop->subtype;
3735
3736 hash = 0;
3737 for (vnp = orp->db; vnp != NULL; vnp = vnp->next) {
3738 dbt = (DbtagPtr) vnp->data.ptrvalue;
3739 if (dbt != NULL) {
3740 hash = ComputeSourceHash (dbt->db, hash);
3741 oip = dbt->tag;
3742 if (oip != NULL) {
3743 if (oip->str != NULL) {
3744 hash = ComputeSourceHash (oip->str, hash);
3745 } else {
3746 sprintf (tmp, "%ld", (long) oip->id);
3747 hash = ComputeSourceHash (tmp, hash);
3748 }
3749 }
3750 }
3751 }
3752 isp->xrfhash = hash;
3753 isp->vnp = orp->db;
3754
3755 return bbp;
3756 }
3757
3758 static int LIBCALLBACK SortSourcesByHash (
3759 VoidPtr ptr1,
3760 VoidPtr ptr2
3761 )
3762
3763 {
3764 Int4 diff;
3765 IntSrcBlockPtr isp1;
3766 IntSrcBlockPtr isp2;
3767 ValNodePtr vnp1;
3768 ValNodePtr vnp2;
3769
3770 if (ptr1 == NULL || ptr2 == NULL) return 0;
3771 vnp1 = *((ValNodePtr PNTR) ptr1);
3772 vnp2 = *((ValNodePtr PNTR) ptr2);
3773 if (vnp1 == NULL || vnp2 == NULL) return 0;
3774 isp1 = (IntSrcBlockPtr) vnp1->data.ptrvalue;
3775 isp2 = (IntSrcBlockPtr) vnp2->data.ptrvalue;
3776 if (isp1 == NULL || isp2 == NULL) return 0;
3777
3778 if (isp1->is_focus && (! isp2->is_focus)) return -1;
3779 if (isp2->is_focus && (! isp1->is_focus)) return 1;
3780
3781 diff = isp1->orghash - isp2->orghash;
3782 if (diff > 0) return -1;
3783 if (diff < 0) return 1;
3784
3785 diff = isp1->xrfhash - isp2->xrfhash;
3786 if (diff > 0) return -1;
3787 if (diff < 0) return 1;
3788
3789 /* sort so that sources with modifiers come first */
3790
3791 diff = isp1->modhash - isp2->modhash;
3792 if (diff > 0) return -1;
3793 if (diff < 0) return 1;
3794
3795 diff = isp1->subhash - isp2->subhash;
3796 if (diff > 0) return -1;
3797 if (diff < 0) return 1;
3798
3799 /* if all hashes are equal, descriptor comes first */
3800
3801 if (isp1->is_descriptor && (! isp2->is_descriptor)) {
3802 return -1;
3803 } else if (isp2->is_descriptor && (! isp1->is_descriptor)) {
3804 return 1;
3805 }
3806
3807 /* now sort identical sources by position, to only fuse abutting ones */
3808 /* feature with smallest left extreme is first */
3809
3810 if (isp1->left > isp2->left) {
3811 return 1;
3812 } else if (isp1->left < isp2->left) {
3813 return -1;
3814 }
3815
3816 /* if same left extreme, shortest source feature is first just for flatfile */
3817
3818 if (isp1->right > isp2->right) {
3819 return 1;
3820 } else if (isp1->right < isp2->right) {
3821 return -1;
3822 }
3823
3824 return 0;
3825 }
3826
3827 static int LIBCALLBACK SortSourcesByPos (
3828 VoidPtr ptr1,
3829 VoidPtr ptr2
3830 )
3831
3832 {
3833 IntSrcBlockPtr isp1;
3834 IntSrcBlockPtr isp2;
3835 ValNodePtr vnp1;
3836 ValNodePtr vnp2;
3837
3838 if (ptr1 == NULL || ptr2 == NULL) return 0;
3839 vnp1 = *((ValNodePtr PNTR) ptr1);
3840 vnp2 = *((ValNodePtr PNTR) ptr2);
3841 if (vnp1 == NULL || vnp2 == NULL) return 0;
3842 isp1 = (IntSrcBlockPtr) vnp1->data.ptrvalue;
3843 isp2 = (IntSrcBlockPtr) vnp2->data.ptrvalue;
3844 if (isp1 == NULL || isp2 == NULL) return 0;
3845
3846 /* descriptor always goes first */
3847
3848 if (isp1->is_descriptor && (! isp2->is_descriptor)) {
3849 return -1;
3850 } else if (isp2->is_descriptor && (! isp1->is_descriptor)) {
3851 return 1;
3852 }
3853
3854 /* feature with smallest left extreme is first */
3855
3856 if (isp1->left > isp2->left) {
3857 return 1;
3858 } else if (isp1->left < isp2->left) {
3859 return -1;
3860 }
3861
3862 /* if same left extreme, shortest source feature is first just for flatfile */
3863
3864 if (isp1->right > isp2->right) {
3865 return 1;
3866 } else if (isp1->right < isp2->right) {
3867 return -1;
3868 }
3869
3870 return 0;
3871 }
3872
3873 /* */
3874 /* s_isFuzzyLoc () -- Determines is a location has fuzzy coordinates */
3875 /* */
3876
3877 static Boolean s_isFuzzyLoc ( SeqLocPtr pLocation )
3878 {
3879 SeqIntPtr pIntLocation;
3880
3881 if (pLocation == NULL)
3882 return FALSE;
3883
3884 if (pLocation->choice != SEQLOC_INT)
3885 return FALSE;
3886
3887 if (pLocation->data.ptrvalue == NULL)
3888 return FALSE;
3889
3890 pIntLocation = (SeqIntPtr) pLocation->data.ptrvalue;
3891
3892 if ((pIntLocation->if_from != NULL) && (pIntLocation->if_from->choice == 2))
3893 return TRUE;
3894
3895 if ((pIntLocation->if_to != NULL) && (pIntLocation->if_to->choice == 2))
3896 return TRUE;
3897
3898 return FALSE;
3899 }
3900
3901 static void GetSourcesOnBioseq (
3902 Asn2gbWorkPtr awp,
3903 BioseqPtr target,
3904 BioseqPtr bsp,
3905 Int4 from,
3906 Int4 to
3907 )
3908
3909 {
3910 IntAsn2gbJobPtr ajp;
3911 BaseBlockPtr bbp;
3912 BioSourcePtr biop;
3913 SeqMgrDescContext dcontext;
3914 SeqMgrFeatContext fcontext;
3915 Boolean hasNulls;
3916 Int4 left;
3917 Boolean loop = FALSE;
3918 Int2 idx;
3919 IntSrcBlockPtr isp;
3920 Int4Ptr ivals;
3921 SeqLocPtr newloc;
3922 Boolean noLeft;
3923 Boolean noRight;
3924 Int2 numivals;
3925 Boolean okay;
3926 Int4 right;
3927 SeqDescrPtr sdp;
3928 SeqFeatPtr sfp;
3929 SeqInt sint;
3930 SeqIdPtr sip;
3931 Boolean split;
3932 Int4 start;
3933 Int4 stop;
3934 Uint1 strand;
3935 ValNode vn;
3936 ValNodePtr vnp;
3937
3938 if (awp == NULL || target == NULL || bsp == NULL) return;
3939 ajp = awp->ajp;
3940 if (ajp == NULL) return;
3941
3942 if (awp->format != FTABLE_FMT || awp->mode == DUMP_MODE) {
3943
3944 /* full length loc for descriptors */
3945
3946 sint.from = 0;
3947 if (ajp->ajp.slp != NULL) {
3948 sint.to = SeqLocLen (ajp->ajp.slp) - 1;
3949 } else {
3950 sint.to = bsp->length - 1;
3951 }
3952 sint.strand = Seq_strand_plus;
3953 sint.id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
3954 sint.if_from = NULL;
3955 sint.if_to = NULL;
3956
3957 vn.choice = SEQLOC_INT;
3958 vn.data.ptrvalue = (Pointer) &sint;
3959 vn.next = NULL;
3960
3961 /* if SWISS-PROT, may have multiple source descriptors */
3962
3963 if (ISA_aa (bsp->mol)) {
3964 for (sip = bsp->id; sip != NULL; sip = sip->next) {
3965 if (sip->choice == SEQID_SWISSPROT) {
3966 loop = TRUE;
3967 }
3968 }
3969 }
3970
3971 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_source, &dcontext);
3972 while (sdp != NULL) {
3973
3974 /* check if descriptor on part already added on segmented bioseq */
3975
3976 okay = TRUE;
3977 for (vnp = awp->srchead; vnp != NULL && okay; vnp = vnp->next) {
3978 bbp = (BaseBlockPtr) vnp->data.ptrvalue;
3979 if (bbp != NULL) {
3980 if (bbp->entityID == dcontext.entityID &&
3981 bbp->itemID == dcontext.itemID &&
3982 bbp->itemtype == OBJ_SEQDESC) {
3983 okay = FALSE;
3984 }
3985 }
3986 }
3987
3988 if (okay) {
3989 biop = (BioSourcePtr) sdp->data.ptrvalue;
3990 bbp = AddSource (awp, &(awp->srchead), biop, NULL);
3991 if (bbp != NULL) {
3992
3993 bbp->entityID = dcontext.entityID;
3994 bbp->itemID = dcontext.itemID;
3995 bbp->itemtype = OBJ_SEQDESC;
3996
3997 isp = (IntSrcBlockPtr) bbp;
3998 isp->loc = SeqLocMerge (target, &vn, NULL, FALSE, TRUE, FALSE);
3999 isp->left = 0;
4000 isp->right = bsp->length - 1;
4001 isp->is_descriptor = TRUE;
4002 }
4003 }
4004
4005 /* if SWISS-PROT, loop through multiple source descriptors */
4006
4007 if (loop) {
4008 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_source, &dcontext);
4009 } else {
4010 sdp = NULL;
4011 }
4012 }
4013
4014 SeqIdFree (sint.id);
4015 }
4016
4017 if ((! awp->contig) || awp->showconsource) {
4018
4019 /* features are indexed on parent if segmented */
4020
4021 bsp = awp->parent;
4022
4023 sfp = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_BIOSRC, 0, &fcontext);
4024 while (sfp != NULL) {
4025 ivals = fcontext.ivals;
4026 numivals = fcontext.numivals;
4027 if (ivals != NULL && numivals > 0) {
4028
4029 idx = (numivals - 1) * 2;
4030 start = ivals [idx];
4031 stop = ivals [idx + 1];
4032 if (stop >= from && stop <= to && (ajp->ajp.slp == NULL || SeqLocCompare (sfp->location, ajp->ajp.slp) > 0)) {
4033
4034 biop = (BioSourcePtr) sfp->data.value.ptrvalue;
4035 bbp = AddSource (awp, &(awp->srchead), biop, sfp->comment);
4036 if (bbp != NULL) {
4037
4038 bbp->entityID = fcontext.entityID;
4039 bbp->itemID = fcontext.itemID;
4040 bbp->itemtype = OBJ_SEQFEAT;
4041
4042 isp = (IntSrcBlockPtr) bbp;
4043 if (sfp->location != NULL && sfp->location->choice == SEQLOC_PNT) {
4044 isp->loc = AsnIoMemCopy ((Pointer) sfp->location,
4045 (AsnReadFunc) SeqLocAsnRead,
4046 (AsnWriteFunc) SeqLocAsnWrite);
4047 } else if (s_isFuzzyLoc (sfp->location)) {
4048 isp->loc = AsnIoMemCopy ((Pointer) sfp->location,
4049 (AsnReadFunc) SeqLocAsnRead,
4050 (AsnWriteFunc) SeqLocAsnWrite);
4051 } else if (SeqLocId(sfp->location) == NULL) {
4052 isp->loc = AsnIoMemCopy ((Pointer) sfp->location,
4053 (AsnReadFunc) SeqLocAsnRead,
4054 (AsnWriteFunc) SeqLocAsnWrite);
4055 } else {
4056 CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
4057 hasNulls = LocationHasNullsBetween (sfp->location);
4058 isp->loc = SeqLocMerge (target, sfp->location, NULL, FALSE, TRUE, hasNulls);
4059 SetSeqLocPartial (isp->loc, noLeft, noRight);
4060 }
4061 isp->left = fcontext.left;
4062 isp->right = fcontext.right;
4063 isp->comment = sfp->comment;
4064 if (ajp->ajp.slp != NULL) {
4065 sip = SeqIdParse ("lcl|dummy");
4066 left = GetOffsetInBioseq (ajp->ajp.slp, bsp, SEQLOC_LEFT_END);
4067 right = GetOffsetInBioseq (ajp->ajp.slp, bsp, SEQLOC_RIGHT_END);
4068 strand = SeqLocStrand (ajp->ajp.slp);
4069 split = FALSE;
4070 newloc = SeqLocReMapEx (sip, ajp->ajp.slp, isp->loc, 0, FALSE, ajp->masterStyle);
4071 /*
4072 newloc = SeqLocCopyRegion (sip, isp->loc, bsp, left, right, strand, &split);
4073 */
4074 SeqIdFree (sip);
4075 if (newloc != NULL) {
4076 A2GBSeqLocReplaceID (newloc, ajp->ajp.slp);
4077 isp->loc = SeqLocFree (isp->loc);
4078 isp->loc = newloc;
4079 isp->left = left;
4080 isp->right = right;
4081 }
4082 }
4083 }
4084 }
4085 }
4086
4087 sfp = SeqMgrGetNextFeature (bsp, sfp, SEQFEAT_BIOSRC, 0, &fcontext);
4088 }
4089 }
4090 }
4091
4092 static Boolean LIBCALLBACK GetSourcesOnSeg (
4093 SeqLocPtr slp,
4094 SeqMgrSegmentContextPtr context
4095 )
4096
4097 {
4098 Asn2gbWorkPtr awp;
4099 BioseqPtr bsp;
4100 Int4 from;
4101 SeqLocPtr loc;
4102 SeqEntryPtr oldscope;
4103 SeqEntryPtr sep;
4104 SeqIdPtr sip;
4105 Int4 to;
4106
4107 if (slp == NULL || context == NULL) return FALSE;
4108 awp = (Asn2gbWorkPtr) context->userdata;
4109
4110 from = context->cumOffset;
4111 to = from + context->to - context->from;
4112
4113 sip = SeqLocId (slp);
4114 if (sip == NULL) {
4115 loc = SeqLocFindNext (slp, NULL);
4116 if (loc != NULL) {
4117 sip = SeqLocId (loc);
4118 }
4119 }
4120 if (sip == NULL) return TRUE;
4121
4122 /* biosource descriptors only on parts within entity */
4123
4124 sep = GetTopSeqEntryForEntityID (awp->entityID);
4125 oldscope = SeqEntrySetScope (sep);
4126 bsp = BioseqFind (sip);
4127 SeqEntrySetScope (oldscope);
4128
4129 if (bsp != NULL) {
4130 GetSourcesOnBioseq (awp, awp->target, bsp, from, to);
4131 return TRUE;
4132 }
4133
4134 /* if we ever want to fetch remote sources, code goes here */
4135
4136 #if 0
4137 Uint2 entityID;
4138
4139 /* may remote fetch genome component if not already in memory */
4140
4141 bsp = BioseqLockById (sip);
4142
4143 if (bsp == NULL) return TRUE;
4144
4145 entityID = ObjMgrGetEntityIDForPointer (bsp);
4146
4147 if (entityID != awp->entityID) {
4148
4149 /* if segment not packaged in record, may need to feature index it */
4150
4151 if (SeqMgrFeaturesAreIndexed (entityID) == 0) {
4152 SeqMgrIndexFeatures (entityID, NULL);
4153 }
4154
4155 /* collect features indexed on the remote bioseq */
4156
4157 from = 0;
4158 to = bsp->length - 1;
4159 }
4160
4161 GetSourcesOnBioseq (awp, awp->target, bsp, from, to);
4162
4163 BioseqUnlock (bsp);
4164 #endif
4165
4166 return TRUE;
4167 }
4168
4169 /* isIdenticalSource() -- Checks to see if two sources are identical */
4170 /* by comparing the actual values in the */
4171 /* fields. This only gets called if the two */
4172 /* sources hashed the same -- it's a double- */
4173 /* check since two non-identical things will */
4174 /* occassionally hash to the same value. */
4175 /* Now checks for adjacent or overlapping. */
4176
4177 static Boolean isIdenticalSource (IntSrcBlockPtr isp1, IntSrcBlockPtr isp2)
4178 {
4179 OrgModPtr omp1;
4180 OrgModPtr omp2;
4181 SubSourcePtr ssp1;
4182 SubSourcePtr ssp2;
4183 ValNodePtr vnp1;
4184 ValNodePtr vnp2;
4185 ObjectIdPtr oip1;
4186 ObjectIdPtr oip2;
4187 DbtagPtr dbt1;
4188 DbtagPtr dbt2;
4189
4190 if (isp1->is_focus != isp2->is_focus)
4191 return FALSE;
4192
4193 /* Compare the taxonomy names */
4194
4195 if (StringICmp(isp1->taxname,isp2->taxname) != 0)
4196 return FALSE;
4197
4198 /* Compare the comment */
4199
4200 if (StringICmp(isp1->comment,isp2->comment) != 0)
4201 return FALSE;
4202
4203 /* Compare the org mods */
4204
4205 omp1 = isp1->omp;
4206 omp2 = isp2->omp;
4207 while (omp1 != NULL && omp2 != NULL)
4208 {
4209 if (omp1->subtype != omp2->subtype)
4210 return FALSE;
4211 if (StringICmp (omp1->subname, omp2->subname) != 0)
4212 return FALSE;
4213 omp1 = omp1->next;
4214 omp2 = omp2->next;
4215 }
4216
4217 if (omp1 != NULL || omp2 != NULL)
4218 return FALSE;
4219
4220 /* Compare the subtypes */
4221
4222 ssp1 = isp1->ssp;
4223 ssp2 = isp2->ssp;
4224
4225 while (ssp1 != NULL && ssp2 != NULL)
4226 {
4227 if (ssp1->subtype != ssp2->subtype)
4228 return FALSE;
4229 if (StringICmp(ssp1->name, ssp2->name) != 0)
4230 return FALSE;
4231 ssp1 = ssp1->next;
4232 ssp2 = ssp2->next;
4233 }
4234
4235 if (ssp1 != NULL || ssp2 != NULL)
4236 return FALSE;
4237
4238 /* Compare the DB tags */
4239
4240 vnp1 = isp1->vnp;
4241 vnp2 = isp2->vnp;
4242
4243 while (vnp1 != NULL && vnp2 != NULL)
4244 {
4245 dbt1 = (DbtagPtr) vnp1->data.ptrvalue;
4246 dbt2 = (DbtagPtr) vnp2->data.ptrvalue;
4247
4248 if ((dbt1 != NULL) && (dbt2 != NULL)) {
4249 if (StringCmp (dbt1->db, dbt2->db) != 0)
4250 return FALSE;
4251
4252 oip1 = dbt1->tag;
4253 oip2 = dbt2->tag;
4254 if ((oip1 != NULL) && (oip2 != NULL)) {
4255 if (oip1->str != NULL) {
4256 if (StringICmp(oip1->str, oip2->str) != 0)
4257 return FALSE;
4258 } else {
4259 if (oip1->id != oip2->id)
4260 return FALSE;
4261 }
4262 }
4263 else if (oip1 != NULL)
4264 return FALSE;
4265 else if (oip2 != NULL)
4266 return FALSE;
4267 }
4268 else if (dbt1 != NULL)
4269 return FALSE;
4270 else if (dbt2 != NULL)
4271 return FALSE;
4272
4273 vnp1 = vnp1->next;
4274 vnp2 = vnp2->next;
4275 }
4276
4277 if (vnp1 != NULL || vnp2 != NULL)
4278 return FALSE;
4279
4280 /* now check for not adjacent or overlapping */
4281
4282 if (isp2->right + 1 < isp1->left) return FALSE;
4283
4284 /* If it passed all checks, then they */
4285 /* are the same, so return true. */
4286
4287 return TRUE;
4288 }
4289
4290 static void CleanupPackedSeqInt (SeqLocPtr location)
4291
4292 {
4293 SeqLocPtr head = NULL;
4294 SeqIntPtr loc;
4295 SeqIntPtr sintp;
4296 SeqLocPtr slp;
4297
4298 if (location == NULL || location->choice != SEQLOC_PACKED_INT || location->data.ptrvalue == NULL) return;
4299
4300 slp = SeqLocFindNext (location, NULL);
4301 while (slp != NULL) {
4302 if (slp->choice == SEQLOC_INT) {
4303 sintp = (SeqIntPtr) slp->data.ptrvalue;
4304 if (sintp != NULL) {
4305 loc = AsnIoMemCopy (sintp, (AsnReadFunc) SeqIntAsnRead,
4306 (AsnWriteFunc) SeqIntAsnWrite);
4307 ValNodeAddPointer (&head, SEQLOC_INT, loc);
4308 }
4309 }
4310 slp = SeqLocFindNext (location, slp);
4311 }
4312 if (head == NULL) return;
4313
4314 location->data.ptrvalue = SeqLocFree (location->data.ptrvalue);
4315 location->data.ptrvalue = head;
4316
4317 slp = location->data.ptrvalue;
4318 if (slp == NULL || slp->next != NULL) return;
4319 /* here seqloc_packed_int points to a single location element, so no need for seqloc_packed_int parent */
4320 location->choice = slp->choice;
4321 location->data.ptrvalue = (Pointer) slp->data.ptrvalue;
4322 MemFree (slp);
4323 }
4324
4325 NLM_EXTERN void AddSourceFeatBlock (
4326 Asn2gbWorkPtr awp
4327 )
4328
4329 {
4330 IntAsn2gbJobPtr ajp;
4331 Asn2gbSectPtr asp;
4332 BaseBlockPtr bbp;
4333 BioseqPtr bsp;
4334 SeqFeatPtr cds;
4335 SeqMgrFeatContext context;
4336 BioseqPtr dna;
4337 SeqLocPtr duploc;
4338 Boolean excise;
4339 GBFeaturePtr gbfeat = NULL;
4340 GBSeqPtr gbseq;
4341 ValNodePtr head = NULL;
4342 IntSrcBlockPtr isp;
4343 IntSrcBlockPtr lastisp;
4344 IntSrcBlockPtr descrIsp;
4345 ValNodePtr next;
4346 ValNodePtr PNTR prev;
4347 SeqInt sint;
4348 SeqLocPtr slp;
4349 CharPtr str;
4350 BioseqPtr target;
4351 ValNode vn;
4352 ValNodePtr vnp;
4353 Boolean descHasFocus = FALSE;
4354 StringItemPtr ffstring;
4355
4356 if (awp == NULL) return;
4357 ajp = awp->ajp;
4358 if (ajp == NULL) return;
4359 asp = awp->asp;
4360 if (asp == NULL) return;
4361 bsp = awp->bsp;
4362 if (bsp == NULL) return;
4363
4364 ffstring = FFGetString(ajp);
4365 if ( ffstring == NULL ) return;
4366
4367
4368 /* collect biosources on bioseq */
4369
4370 awp->srchead = NULL;
4371 GetSourcesOnBioseq (awp, bsp, bsp, awp->from, awp->to);
4372 target = bsp;
4373
4374 if (bsp->repr == Seq_repr_seg) {
4375
4376 /* collect biosource descriptors on local parts */
4377
4378 SeqMgrExploreSegments (bsp, (Pointer) awp, GetSourcesOnSeg);
4379 target = awp->target;
4380 }
4381
4382 if (awp->srchead == NULL && ISA_aa (bsp->mol)) {
4383
4384 /* if protein with no sources, get sources applicable to DNA location of CDS */
4385
4386 cds = SeqMgrGetCDSgivenProduct (bsp, &context);
4387 if (cds != NULL) {
4388 dna = BioseqFindFromSeqLoc (cds->location);
4389 if (dna != NULL) {
4390 GetSourcesOnBioseq (awp, dna, dna, context.left, context.right);
4391 target = dna;
4392 }
4393 }
4394 }
4395
4396 head = awp->srchead;
4397 awp->srchead = NULL;
4398
4399 if (head == NULL && (awp->format != FTABLE_FMT || awp->mode == DUMP_MODE)) {
4400
4401 if (ajp->gbseq) {
4402 gbseq = &asp->gbseq;
4403 } else {
4404 gbseq = NULL;
4405 }
4406
4407 sint.from = 0;
4408 sint.to = bsp->length - 1;
4409 sint.strand = Seq_strand_plus;
4410 sint.id = SeqIdStripLocus (SeqIdDup (SeqIdFindBest (bsp->id, 0)));
4411 sint.if_from = NULL;
4412 sint.if_to = NULL;
4413
4414 vn.choice = SEQLOC_INT;
4415 vn.data.ptrvalue = (Pointer) &sint;
4416 vn.next = NULL;
4417
4418 FFStartPrint (ffstring, awp->format, 5, 21, NULL, 0, 5, 21, "FT", FALSE);
4419 FFAddOneString(ffstring, "source", FALSE, FALSE, TILDE_IGNORE);
4420 FFAddNChar(ffstring, ' ', 21 - 5 - StringLen("source"), FALSE);
4421
4422 if (gbseq != NULL) {
4423 gbfeat = GBFeatureNew ();
4424 if (gbfeat != NULL) {
4425 gbfeat->key = StringSave ("source");
4426 }
4427 }
4428
4429 str = FFFlatLoc (ajp, bsp, &vn, (Boolean) (awp->style == MASTER_STYLE));
4430 if ( GetWWW(ajp) ) {
4431 FF_www_featloc (ffstring, str);
4432 } else {
4433 FFAddOneString (ffstring, str, FALSE, FALSE, TILDE_IGNORE);
4434 }
4435
4436 if (gbseq != NULL) {
4437 if (gbfeat != NULL) {
4438 if (! StringHasNoText (str)) {
4439 gbfeat->location = StringSave (str);
4440 } else {
4441 gbfeat->location = StringSave ("");
4442 }
4443 }
4444 }
4445
4446 MemFree (str);
4447
4448 if (ajp->flags.needOrganismQual) {
4449 FFAddNewLine(ffstring);
4450 FFAddTextToString (ffstring, "/organism=\"", "unknown", "\"", FALSE, TRUE, TILDE_TO_SPACES);
4451 #ifdef ASN2GNBK_PRINT_UNKNOWN_ORG
4452 } else {
4453 FFAddNewLine(ffstring);
4454 FFAddTextToString (ffstring, "/organism=\"", "unknown", "\"", FALSE, TRUE, TILDE_TO_SPACES);
4455 #endif
4456 }
4457
4458 str = GetMolTypeQual (bsp);
4459 if (StringICmp (str, "ncRNA") == 0) {
4460 str = "other RNA";
4461 }
4462 if (str == NULL) {
4463 switch (bsp->mol) {
4464 case Seq_mol_dna :
4465 str = "unassigned DNA";
4466 break;
4467 case Seq_mol_rna :
4468 str = "unassigned RNA";
4469 break;
4470 case Seq_mol_aa :
4471 break;
4472 default :
4473 str = "unassigned DNA";
4474 break;
4475 }
4476 }
4477 if (str != NULL) {
4478 FFAddNewLine(ffstring);
4479 FFAddTextToString (ffstring, "/mol_type=\"", str, "\"", FALSE, TRUE, TILDE_TO_SPACES);
4480 }
4481
4482 str = FFEndPrint(ajp, ffstring, awp->format, 5, 21, 5, 21, "FT");
4483
4484 bbp = (BaseBlockPtr) Asn2gbAddBlock (awp, SOURCEFEAT_BLOCK, sizeof (IntSrcBlock));
4485 if (bbp != NULL) {
4486 bbp->section = awp->currsection;
4487 bbp->string = str;
4488 } else {
4489 MemFree(str);
4490 }
4491 FFRecycleString(ajp, ffstring);
4492
4493 if (awp->afp != NULL) {
4494 DoImmediateFormat (awp->afp, (BaseBlockPtr) bbp);
4495 }
4496
4497 /* optionally populate gbseq for XML-ized GenBank format */
4498
4499 if (gbseq != NULL) {
4500 if (gbfeat != NULL) {
4501 AddFeatureToGbseq (gbseq, gbfeat, str, NULL);
4502 }
4503 }
4504 }
4505
4506 if (head == NULL) return;
4507
4508 /* sort by hash values */
4509
4510 head = SortValNode (head, SortSourcesByHash);
4511
4512 /* unique sources, excise duplicates from list */
4513
4514 prev = &(head);
4515 vnp = head;
4516 lastisp = NULL;
4517 while (vnp != NULL) {
4518 excise = FALSE;
4519 next = vnp->next;
4520 isp = (IntSrcBlockPtr) vnp->data.ptrvalue;
4521 if (isp->is_descriptor && isp->is_focus)
4522 descHasFocus = TRUE;
4523 if (lastisp != NULL) {
4524 if (isp != NULL) {
4525 if (lastisp->is_focus == isp->is_focus &&
4526 lastisp->orghash == isp->orghash &&
4527 lastisp->xrfhash == isp->xrfhash) {
4528
4529 /* check for identical modifiers */
4530
4531 if (lastisp->modhash == isp->modhash &&
4532 lastisp->subhash == isp->subhash) {
4533
4534 excise = isIdenticalSource (isp, lastisp);
4535
4536 /* or modifiers only in lastisp (e.g., on part bioseq) */
4537
4538 } else if (isp->modhash == 0 && isp->subhash == 0) {
4539 excise = isIdenticalSource (isp, lastisp);
4540 }
4541 }
4542 }
4543 }
4544 if (awp->mode == DUMP_MODE) {
4545 excise = FALSE;
4546 }
4547 /* does not fuse equivalent source features for local, general, refseq, and 2+6 genbank ids */
4548 if (excise && awp->sourcePubFuse) {
4549 *prev = vnp->next;
4550 vnp->next = NULL;
4551
4552 /* combine locations of duplicate sources */
4553
4554 if (lastisp != NULL) {
4555 slp = SeqLocMerge (target, lastisp->loc, isp->loc, FALSE, TRUE, FALSE);
4556 lastisp->loc = SeqLocFree (lastisp->loc);
4557 lastisp->loc = slp;
4558 lastisp->left = MIN (lastisp->left,isp->left);
4559 lastisp->right = MAX (lastisp->right, isp->right);
4560 }
4561
4562 /* and remove duplicate source */
4563
4564 SeqLocFree (isp->loc);
4565 MemFree (isp);
4566 ValNodeFree (vnp);
4567
4568 } else {
4569
4570 prev = &(vnp->next);
4571 lastisp = isp;
4572 }
4573 vnp = next;
4574 }
4575
4576 /* Sort again, by location this time */
4577
4578 head = SortValNode (head, SortSourcesByPos);
4579
4580 /* If the descriptor has a focus, then subtract */
4581 /* out all the other source locations. */
4582
4583 descrIsp = (IntSrcBlockPtr) head->data.ptrvalue; /* Sorted 1st by now */
4584
4585 if ((descHasFocus) && (! descrIsp->is_synthetic)) {
4586
4587 vnp = head;
4588 duploc = AsnIoMemCopy ((Pointer) descrIsp->loc,
4589 (AsnReadFunc) SeqLocAsnRead,
4590 (AsnWriteFunc) SeqLocAsnWrite);
4591 vnp = vnp->next;
4592 while (vnp != NULL) {
4593 isp = (IntSrcBlockPtr) vnp->data.ptrvalue;
4594 if (SeqLocAinB (descrIsp->loc, isp->loc) >= 0) {
4595 vnp = NULL; /* break the chain */
4596 descrIsp->loc = SeqLocFree (descrIsp->loc);
4597 descrIsp->loc = duploc;
4598 duploc = NULL;
4599 } else {
4600 descrIsp->loc = SeqLocSubtract (descrIsp->loc, isp->loc);
4601 vnp = vnp->next;
4602 }
4603 }
4604 CleanupPackedSeqInt (descrIsp->loc);
4605 descrIsp->left = SeqLocStart (descrIsp->loc);
4606 descrIsp->right = SeqLocStop (descrIsp->loc);
4607 SeqLocFree (duploc);
4608 }
4609
4610 /* if features completely subtracted descriptor
4611 intervals, suppress in release, entrez modes */
4612
4613 if (descrIsp->loc == NULL && ajp->flags.hideEmptySource && head->next != NULL) {
4614 vnp = head->next;
4615 head->next = NULL;
4616 ValNodeFreeData (head);
4617 head = vnp;
4618 }
4619
4620 /* finally link into blocks for current section */
4621
4622 ValNodeLink (&(awp->lastblock), head);
4623 vnp = awp->lastblock;
4624 if (vnp == NULL) return;
4625 while (vnp->next != NULL) {
4626 vnp = vnp->next;
4627 }
4628
4629 awp->lastblock = vnp;
4630 if (awp->blockList == NULL) {
4631 awp->blockList = vnp;
4632 }
4633 FFRecycleString(ajp, ffstring);
4634
4635 if (awp->afp != NULL) {
4636 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4637 isp = (IntSrcBlockPtr) vnp->data.ptrvalue;
4638 if (isp == NULL) continue;
4639 DoImmediateFormat (awp->afp, (BaseBlockPtr) isp);
4640 }
4641 }
4642
4643 }
4644
4645 static Boolean IsCDD (
4646 SeqFeatPtr sfp
4647 )
4648
4649 {
4650 DbtagPtr dbt;
4651 ValNodePtr vnp;
4652
4653 for (vnp = sfp->dbxref; vnp != NULL; vnp = vnp->next) {
4654 dbt = (DbtagPtr) vnp->data.ptrvalue;
4655 if (dbt != NULL && StringCmp (dbt->db, "CDD") == 0) return TRUE;
4656 }
4657
4658 return FALSE;
4659 }
4660
4661 static void GetFeatsOnCdsProduct (
4662 SeqFeatPtr cds,
4663 BioseqPtr nbsp,
4664 BioseqPtr pbsp,
4665 IntAsn2gbJobPtr ajp,
4666 Asn2gbWorkPtr awp
4667 )
4668
4669 {
4670 FeatBlockPtr fbp;
4671 IntFeatBlockPtr ifp;
4672 Boolean isRefSeq;
4673 Int4 lastleft;
4674 Int4 lastright;
4675 SeqAnnotPtr lastsap;
4676 SeqFeatPtr lastsfp;
4677 SeqLocPtr location;
4678 SeqLocPtr newloc;
4679 SeqMgrFeatContext pcontext;
4680 SeqFeatPtr prt;
4681 SeqIdPtr sip;
4682 SeqLocPtr slp;
4683 Boolean suppress;
4684
4685 if (cds == NULL || ajp == NULL || awp == NULL) return;
4686 if (nbsp == NULL || pbsp == NULL || (! ISA_aa (pbsp->mol))) return;
4687
4688 if (awp->hideCdsProdFeats) return;
4689
4690 isRefSeq = FALSE;
4691 for (sip = nbsp->id; sip != NULL; sip = sip->next) {
4692 if (sip->choice == SEQID_OTHER) {
4693 isRefSeq = TRUE;
4694 }
4695 }
4696
4697 /* explore mat_peptides, sites, etc. */
4698
4699 lastsfp = NULL;
4700 lastsap = NULL;
4701 lastleft = 0;
4702 lastright = 0;
4703
4704 prt = SeqMgrGetNextFeature (pbsp, NULL, 0, 0, &pcontext);
4705 while (prt != NULL) {
4706
4707 if (pcontext.featdeftype == FEATDEF_REGION ||
4708 pcontext.featdeftype == FEATDEF_SITE ||
4709 pcontext.featdeftype == FEATDEF_BOND ||
4710 pcontext.featdeftype == FEATDEF_mat_peptide_aa ||
4711 pcontext.featdeftype == FEATDEF_sig_peptide_aa ||
4712 pcontext.featdeftype == FEATDEF_transit_peptide_aa ||
4713 (pcontext.featdeftype == FEATDEF_preprotein /* && isRefSeq */)) {
4714
4715 if (awp->hideSitesBondsRegions && (pcontext.featdeftype == FEATDEF_REGION ||
4716 pcontext.featdeftype == FEATDEF_SITE ||
4717 pcontext.featdeftype == FEATDEF_BOND)) {
4718
4719 /* hide site, bond, and region features */
4720
4721 } else if (awp->hideCddFeats && pcontext.featdeftype == FEATDEF_REGION && IsCDD (prt)) {
4722
4723 /* passing this test prevents mapping of COG CDD region features */
4724
4725 } else if (pcontext.dnaStop >= awp->from && pcontext.dnaStop <= awp->to) {
4726
4727 /* suppress duplicate features (on protein) */
4728
4729 suppress = FALSE;
4730 if (lastsfp != NULL && lastsap != NULL) {
4731 if (lastsfp->idx.subtype == prt->idx.subtype &&
4732 lastleft == pcontext.left &&
4733 lastright == pcontext.right) {
4734 if (lastsap == pcontext.sap ||
4735 (lastsap->desc == NULL && pcontext.sap->desc == NULL)) {
4736 if (AsnIoMemComp (lastsfp, prt, (AsnWriteFunc) SeqFeatAsnWrite)) {
4737 suppress = TRUE;
4738 }
4739 }
4740 }
4741 }
4742
4743 /* make sure feature maps within nucleotide sublocation */
4744
4745 if (! suppress) {
4746 if (ajp->ajp.slp != NULL) {
4747 location = aaFeatLoc_to_dnaFeatLoc (cds, prt->location);
4748 slp = SeqLocMerge (nbsp, location, NULL, FALSE, TRUE, FALSE);
4749 if (slp != NULL) {
4750 sip = SeqIdParse ("lcl|dummy");
4751 newloc = SeqLocReMapEx (sip, ajp->ajp.slp, slp, 0, FALSE, ajp->masterStyle);
4752 SeqIdFree (sip);
4753 SeqLocFree (slp);
4754 if (newloc == NULL) {
4755 suppress = TRUE;
4756 }
4757 SeqLocFree (newloc);
4758 } else {
4759 suppress = TRUE;
4760 }
4761 SeqLocFree (location);
4762 }
4763 }
4764
4765 if (! suppress) {
4766
4767 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntFeatBlock));
4768 if (fbp != NULL) {
4769
4770 fbp->entityID = pcontext.entityID;
4771 fbp->itemID = pcontext.itemID;
4772 fbp->itemtype = OBJ_SEQFEAT;
4773 fbp->featdeftype = pcontext.featdeftype;
4774 ifp = (IntFeatBlockPtr) fbp;
4775 ifp->mapToNuc = TRUE;
4776 ifp->mapToProt = FALSE;
4777 ifp->mapToGen = FALSE;
4778 ifp->mapToMrna = FALSE;
4779 ifp->mapToPep = FALSE;
4780 ifp->firstfeat = awp->firstfeat;
4781 awp->firstfeat = FALSE;
4782
4783 if (awp->afp != NULL) {
4784 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
4785 }
4786 }
4787 }
4788
4789 lastsfp = prt;
4790 lastsap = pcontext.sap;
4791 lastleft = pcontext.left;
4792 lastright = pcontext.right;
4793
4794 }
4795 }
4796 prt = SeqMgrGetNextFeature (pbsp, prt, 0, 0, &pcontext);
4797 }
4798 }
4799
4800 static void GetRemoteFeatsOnCdsProduct (
4801 SeqFeatPtr cds,
4802 BioseqPtr nbsp,
4803 BioseqPtr pbsp,
4804 IntAsn2gbJobPtr ajp,
4805 Asn2gbWorkPtr awp
4806 )
4807
4808 {
4809 BioseqPtr bsp;
4810 FeatBlockPtr fbp;
4811 ValNodePtr head = NULL;
4812 IntFeatBlockPtr ifp;
4813 Boolean isRefSeq;
4814 Int4 lastleft;
4815 Int4 lastright;
4816 SeqAnnotPtr lastsap;
4817 SeqFeatPtr lastsfp;
4818 SeqLocPtr location;
4819 SeqLocPtr newloc;
4820 SeqFeatPtr prt;
4821 ValNodePtr publist;
4822 Asn2gbFreeFunc remotefree;
4823 Asn2gbLockFunc remotelock;
4824 ValNodePtr remotevnp;
4825 SeqAnnotPtr sap;
4826 SeqFeatPtr sfp;
4827 SeqIdPtr sip;
4828 SeqLocPtr slp;
4829 Boolean suppress;
4830 ValNodePtr vnp;
4831
4832 if (cds == NULL || ajp == NULL || awp == NULL) return;
4833 if (nbsp == NULL || pbsp == NULL || (! ISA_aa (pbsp->mol))) return;
4834
4835 if (awp->hideCdsProdFeats) return;
4836
4837 if (ajp->remotelock == NULL) return;
4838
4839 remotelock = ajp->remotelock;
4840 remotefree = ajp->remotefree;
4841
4842 sip = SeqIdFindBest (pbsp->id, SEQID_GI);
4843 if (sip == NULL) return;
4844
4845 remotevnp = remotelock (sip, ajp->remotedata);
4846 if (remotevnp == NULL) return;
4847
4848 /* do cleanup of remotely fetched feature tables */
4849
4850 for (vnp = remotevnp; vnp != NULL; vnp = vnp->next) {
4851 bsp = (BioseqPtr) vnp->data.ptrvalue;
4852 if (bsp == NULL) continue;
4853 for (sap = bsp->annot; sap != NULL; sap = sap->next) {
4854 if (sap->type != 1) continue;
4855 for (sfp = (SeqFeatPtr) sap->data; sfp != NULL; sfp = sfp->next) {
4856 publist = NULL;
4857 CleanUpSeqFeat (sfp, FALSE, FALSE, TRUE, TRUE, &publist);
4858 sfp->idx.subtype = FindFeatDefType (sfp);
4859 ValNodeFreeData (publist);
4860 ValNodeAddPointer (&head, 0, (Pointer) sfp);
4861 }
4862 }
4863 }
4864
4865 if (head == NULL) return;
4866
4867 isRefSeq = FALSE;
4868 for (sip = nbsp->id; sip != NULL; sip = sip->next) {
4869 if (sip->choice == SEQID_OTHER) {
4870 isRefSeq = TRUE;
4871 }
4872 }
4873
4874 /* explore mat_peptides, sites, etc. */
4875
4876 lastsfp = NULL;
4877 lastsap = NULL;
4878 lastleft = 0;
4879 lastright = 0;
4880
4881 for (vnp = head; vnp != NULL; vnp = vnp->next) {
4882
4883 prt = (SeqFeatPtr) vnp->data.ptrvalue;
4884 if (prt == NULL) continue;
4885
4886 if (prt->idx.subtype == FEATDEF_REGION ||
4887 prt->idx.subtype == FEATDEF_SITE ||
4888 prt->idx.subtype == FEATDEF_BOND ||
4889 prt->idx.subtype == FEATDEF_mat_peptide_aa ||
4890 prt->idx.subtype == FEATDEF_sig_peptide_aa ||
4891 prt->idx.subtype == FEATDEF_transit_peptide_aa ||
4892 (prt->idx.subtype == FEATDEF_preprotein /* && isRefSeq */)) {
4893
4894 if (awp->hideSitesBondsRegions && (prt->idx.subtype == FEATDEF_REGION ||
4895 prt->idx.subtype == FEATDEF_SITE ||
4896 prt->idx.subtype == FEATDEF_BOND)) {
4897
4898 /* hide site, bond, and region features */
4899
4900 } else if (awp->hideCddFeats && prt->idx.subtype == FEATDEF_REGION && IsCDD (prt)) {
4901
4902 /* passing this test prevents mapping of COG CDD region features */
4903
4904 } else {
4905
4906 suppress = FALSE;
4907
4908 /* make sure feature maps within nucleotide sublocation */
4909
4910 if (! suppress) {
4911 if (ajp->ajp.slp != NULL) {
4912 location = aaFeatLoc_to_dnaFeatLoc (cds, prt->location);
4913 slp = SeqLocMerge (nbsp, location, NULL, FALSE, TRUE, FALSE);
4914 if (slp != NULL) {
4915 sip = SeqIdParse ("lcl|dummy");
4916 newloc = SeqLocReMapEx (sip, ajp->ajp.slp, slp, 0, FALSE, ajp->masterStyle);
4917 SeqIdFree (sip);
4918 SeqLocFree (slp);
4919 if (newloc == NULL) {
4920 suppress = TRUE;
4921 }
4922 SeqLocFree (newloc);
4923 } else {
4924 suppress = TRUE;
4925 }
4926 SeqLocFree (location);
4927 }
4928 }
4929
4930 if (! suppress) {
4931
4932 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntFeatBlock));
4933 if (fbp != NULL) {
4934
4935 fbp->entityID = 0;
4936 fbp->itemID = 0;
4937 fbp->itemtype = OBJ_SEQFEAT;
4938 fbp->featdeftype = prt->idx.subtype;
4939 ifp = (IntFeatBlockPtr) fbp;
4940 ifp->mapToNuc = TRUE;
4941 ifp->mapToProt = FALSE;
4942 ifp->mapToGen = FALSE;
4943 ifp->mapToMrna = FALSE;
4944 ifp->mapToPep = FALSE;
4945 ifp->firstfeat = awp->firstfeat;
4946 awp->firstfeat = FALSE;
4947
4948 if (awp->afp != NULL) {
4949 DoImmediateRemoteFeatureFormat (awp->afp, (BaseBlockPtr) fbp, prt);
4950 }
4951 }
4952 }
4953 }
4954 }
4955 }
4956
4957 ValNodeFree (head);
4958
4959 if (remotefree != NULL) {
4960 remotefree (remotevnp, ajp->remotedata);
4961 } else {
4962 /* otherwise free Bioseqs and ValNode chain ourselves */
4963 for (vnp = remotevnp; vnp != NULL; vnp = vnp->next) {
4964 bsp = (BioseqPtr) vnp->data.ptrvalue;
4965 if (bsp != NULL) {
4966 BioseqFree (bsp);
4967 }
4968 }
4969 ValNodeFree (remotevnp);
4970 }
4971 }
4972
4973 static Boolean NotEMBLorDDBJ (
4974 BioseqPtr bsp
4975 )
4976
4977 {
4978 SeqIdPtr sip;
4979
4980 if (bsp == NULL) return TRUE;
4981 for (sip = bsp->id; sip != NULL; sip = sip->next) {
4982 if (sip->choice == SEQID_EMBL || sip->choice == SEQID_TPE) return FALSE;
4983 if (sip->choice == SEQID_DDBJ || sip->choice == SEQID_TPD) return FALSE;
4984 }
4985 return TRUE;
4986 }
4987
4988 static Boolean LIBCALLBACK GetFeatsOnBioseq (
4989 SeqFeatPtr sfp,
4990 SeqMgrFeatContextPtr fcontext
4991 )
4992
4993 {
4994 IntAsn2gbJobPtr ajp;
4995 Asn2gbSectPtr asp;
4996 Asn2gbWorkPtr awp;
4997 BioseqPtr bsp;
4998 Char buf [41];
4999 SeqFeatPtr cds;
5000 SeqMgrFeatContext cdscontext;
5001 FeatBlockPtr fbp;
5002 SeqLocPtr firstslp;
5003 GBQualPtr gbq;
5004 SeqFeatPtr gene;
5005 Int4 gi;
5006 GeneRefPtr grp;
5007 Boolean juststop = FALSE;
5008 IntCdsBlockPtr icp;
5009 Int2 idx;
5010 IntFeatBlockPtr ifp;
5011 IntPrtBlockPtr ipp;
5012 Boolean is_whole;
5013 Int4Ptr ivals;
5014 Int2 j;
5015 SeqAnnotPtr lastsap;
5016 SeqFeatPtr lastsfp;
5017 SeqLocPtr lastslp;
5018 SeqLocPtr newloc;
5019 Int2 numivals;
5020 Boolean okay;
5021 SeqEntryPtr oldscope;
5022 BioseqPtr parent;
5023 Boolean partial5;
5024 Boolean partial3;
5025 ValNodePtr ppr;
5026 BioseqPtr prod;
5027 ProtRefPtr prp;
5028 Boolean pseudo = FALSE;
5029 RNAGenPtr rgp;
5030 RnaRefPtr rrp;
5031 SeqEntryPtr sep;
5032 SeqIntPtr sintp;
5033 SeqIdPtr sip;
5034 SeqLocPtr slp;
5035 Int4 start;
5036 Int4 stop;
5037 TextSeqIdPtr tsip;
5038 ValNodePtr vnp;
5039 /*
5040 SeqMgrDescContext dcontext;
5041 PubdescPtr pdp;
5042 SeqDescrPtr sdp;
5043 */
5044
5045 if (sfp == NULL || fcontext == NULL) return FALSE;
5046 awp = (Asn2gbWorkPtr) fcontext->userdata;
5047 if (awp == NULL) return FALSE;
5048 ajp = awp->ajp;
5049 if (ajp == NULL) return FALSE;
5050 asp = awp->asp;
5051 if (asp == NULL) return FALSE;
5052 bsp = asp->bsp;
5053 if (bsp == NULL) return FALSE;
5054
5055 if (fcontext->featdeftype == FEATDEF_PUB ||
5056 fcontext->featdeftype == FEATDEF_NON_STD_RESIDUE ||
5057 fcontext->featdeftype == FEATDEF_RSITE ||
5058 fcontext->featdeftype == FEATDEF_SEQ) return TRUE;
5059
5060 if (fcontext->featdeftype == FEATDEF_BIOSRC) return TRUE;
5061
5062 if (ajp->flags.validateFeats &&
5063 (fcontext->featdeftype == FEATDEF_BAD ||
5064 fcontext->featdeftype == FEATDEF_virion)) {
5065 return TRUE;
5066 }
5067
5068 if (ISA_na (bsp->mol) && fcontext->featdeftype == FEATDEF_HET) return TRUE;
5069
5070 /* check feature customization flags */
5071
5072 if (awp->hideImpFeats && sfp->data.choice == SEQFEAT_IMP && fcontext->featdeftype != FEATDEF_operon) return TRUE;
5073 if (awp->hideVariations && fcontext->featdeftype == FEATDEF_variation) return TRUE;
5074 if (awp->hideRepeatRegions && fcontext->featdeftype == FEATDEF_repeat_region) return TRUE;
5075 if (awp->hideGaps && fcontext->featdeftype == FEATDEF_gap) return TRUE;
5076 if (ISA_aa (bsp->mol) && fcontext->featdeftype == FEATDEF_REGION &&
5077 awp->hideCddFeats && IsCDD (sfp)) return TRUE;
5078 if (awp->hideSitesBondsRegions && (fcontext->featdeftype == FEATDEF_REGION ||
5079 fcontext->featdeftype == FEATDEF_SITE ||
5080 fcontext->featdeftype == FEATDEF_BOND)) return TRUE;
5081
5082 /* DDBJ does not want to show gene features */
5083
5084 if (fcontext->seqfeattype == SEQFEAT_GENE && awp->hideGeneFeats) return TRUE;
5085
5086 /* no longer suppressing comment features that are full length */
5087
5088 /*
5089 if (fcontext->seqfeattype == SEQFEAT_COMMENT &&
5090 fcontext->left == awp->from && fcontext->right == awp->to) return TRUE;
5091 */
5092
5093 ivals = fcontext->ivals;
5094 numivals = fcontext->numivals;
5095
5096 /* check to see if last interval is on this awp->from - awp->to range */
5097
5098 if (ivals != NULL && numivals > 0) {
5099 idx = (numivals - 1) * 2;
5100 start = ivals [idx];
5101 stop = ivals [idx + 1];
5102 if (stop < awp->from || stop > awp->to) {
5103
5104 /* may need to map sig_peptide on a different segment */
5105
5106 if (fcontext->seqfeattype == SEQFEAT_CDREGION) {
5107 sip = SeqLocIdForProduct (sfp->product);
5108 bsp = BioseqFind (sip);
5109 GetFeatsOnCdsProduct (sfp, asp->bsp, bsp, ajp, awp);
5110 }
5111
5112 if (! awp->showAllFeats) return TRUE;
5113
5114 /* if showing one segment, only show features covering this segment */
5115
5116 if (fcontext->right < awp->from || fcontext->left > awp->to) return TRUE;
5117
5118 } else if (fcontext->farloc && NotEMBLorDDBJ (awp->bsp)) {
5119
5120 /* last interval may not have been mapped to bioseq if far */
5121
5122 firstslp = NULL;
5123 lastslp = NULL;
5124
5125 slp = SeqLocFindNext (sfp->location, NULL);
5126 while (slp != NULL) {
5127 if (slp->choice != SEQLOC_NULL) {
5128 lastslp = slp;
5129 if (firstslp == NULL) {
5130 firstslp = slp;
5131 }
5132 }
5133 slp = SeqLocFindNext (sfp->location, slp);
5134 }
5135
5136 /* !!! EMBL may have different desired behavior on where to map !!! */
5137
5138 if (firstslp != NULL && SeqLocStrand (firstslp) == Seq_strand_minus) {
5139 slp = firstslp;
5140 } else {
5141 slp = lastslp;
5142 }
5143
5144 if (slp != NULL) {
5145 sip = SeqLocId (slp);
5146 if (sip != NULL) {
5147 bsp = BioseqFindCore (sip);
5148 if (bsp == NULL || (bsp != awp->parent && bsp != awp->bsp)) {
5149
5150 return TRUE;
5151 }
5152 }
5153 }
5154 }
5155 }
5156
5157 /* make sure feature is within sublocation */
5158
5159 if (ajp->ajp.slp != NULL) {
5160 if (SeqLocCompare (sfp->location, ajp->ajp.slp) == SLC_NO_MATCH) {
5161 slp = SeqLocMerge (bsp, sfp->location, NULL, FALSE, TRUE, FALSE);
5162 if (slp == NULL) return TRUE;
5163 sip = SeqIdParse ("lcl|dummy");
5164 newloc = SeqLocReMapEx (sip, ajp->ajp.slp, slp, 0, FALSE, ajp->masterStyle);
5165 SeqIdFree (sip);
5166 SeqLocFree (slp);
5167 if (newloc == NULL) return TRUE;
5168 SeqLocFree (newloc);
5169 }
5170 }
5171
5172 /* suppress duplicate features (on nucleotide) */
5173
5174 lastsfp = awp->lastsfp;
5175 lastsap = awp->lastsap;
5176 if (lastsfp != NULL && lastsap != NULL) {
5177 if (lastsfp->idx.subtype == sfp->idx.subtype &&
5178 awp->lastleft == fcontext->left &&
5179 awp->lastright == fcontext->right) {
5180 if (lastsap == fcontext->sap ||
5181 (lastsap->desc == NULL && fcontext->sap->desc == NULL)) {
5182 if (AsnIoMemComp (lastsfp, sfp, (AsnWriteFunc) SeqFeatAsnWrite)) {
5183 return TRUE;
5184 }
5185 }
5186 }
5187 }
5188
5189 /* if RELEASE_MODE, verify that features have all mandatory qualifiers */
5190
5191 if (ajp->flags.needRequiredQuals) {
5192 okay = FALSE;
5193
5194 switch (fcontext->featdeftype) {
5195
5196 case FEATDEF_CDS:
5197 if (ajp->flags.checkCDSproductID) {
5198 /* non-pseudo CDS must have /product */
5199 if (sfp->pseudo) {
5200 pseudo = TRUE;
5201 }
5202 grp = SeqMgrGetGeneXref (sfp);
5203 if (grp == NULL) {
5204 sep = GetTopSeqEntryForEntityID (ajp->ajp.entityID);
5205 oldscope = SeqEntrySetScope (sep);
5206 gene = SeqMgrGetOverlappingGene (sfp->location, NULL);
5207 SeqEntrySetScope (oldscope);
5208 if (gene != NULL) {
5209 grp = (GeneRefPtr) gene->data.value.ptrvalue;
5210 if (gene->pseudo) {
5211 pseudo = TRUE;
5212 }
5213 }
5214 }
5215 if (grp != NULL && grp->pseudo) {
5216 pseudo = TRUE;
5217 }
5218 if (sfp->location != NULL) {
5219 if (CheckSeqLocForPartial (sfp->location, &partial5, &partial3)) {
5220 if (partial5 && (! partial3)) {
5221 if (SeqLocLen (sfp->location) <= 5) {
5222 juststop = TRUE;
5223 }
5224 }
5225 }
5226 }
5227 if (pseudo || juststop) {
5228 okay = TRUE;
5229 } else if (sfp->product != NULL) {
5230 sip = SeqLocIdForProduct (sfp->product);
5231 if (sip != NULL) {
5232 if ((sip->choice == SEQID_GI && sip->data.intvalue > 0) ||
5233 sip->choice == SEQID_LOCAL) {
5234 sep = GetTopSeqEntryForEntityID (ajp->ajp.entityID);
5235 oldscope = SeqEntrySetScope (sep);
5236 prod = BioseqFind (sip);
5237 SeqEntrySetScope (oldscope);
5238 if (prod != NULL) {
5239 for (sip = prod->id; sip != NULL; sip = sip->next) {
5240 if (sip->choice == SEQID_GENBANK ||
5241 sip->choice == SEQID_EMBL ||
5242 sip->choice == SEQID_DDBJ ||
5243 sip->choice == SEQID_OTHER ||
5244 sip->choice == SEQID_PATENT ||
5245 sip->choice == SEQID_TPG ||
5246 sip->choice == SEQID_TPE ||
5247 sip->choice == SEQID_TPD ||
5248 sip->choice == SEQID_GPIPE) {
5249 tsip = (TextSeqIdPtr) sip->data.ptrvalue;
5250 if (tsip != NULL && (StringDoesHaveText (tsip->accession))) {
5251 if (ValidateAccn (tsip->accession) == 0)
5252 okay = TRUE;
5253 }
5254 }
5255 }
5256 } else if (sip->choice == SEQID_GI && sip->data.intvalue > 0) {
5257 /* RELEASE_MODE requires that /protein_id is an accession */
5258 gi = sip->data.intvalue;
5259 if (GetAccnVerFromServer (gi, buf)) {
5260 okay = TRUE;
5261 } else {
5262 sip = GetSeqIdForGI (gi);
5263 if (sip != NULL) {
5264 okay = TRUE;
5265 }
5266 }
5267 }
5268 } else if (sip->choice == SEQID_GENBANK ||
5269 sip->choice == SEQID_EMBL ||
5270 sip->choice == SEQID_DDBJ ||
5271 sip->choice == SEQID_OTHER ||
5272 sip->choice == SEQID_PATENT ||
5273 sip->choice == SEQID_TPG ||
5274 sip->choice == SEQID_TPE ||
5275 sip->choice == SEQID_TPD ||
5276 sip->choice == SEQID_GPIPE) {
5277 tsip = (TextSeqIdPtr) sip->data.ptrvalue;
5278 if (tsip != NULL && (StringDoesHaveText (tsip->accession))) {
5279 if (ValidateAccn (tsip->accession) == 0)
5280 okay = TRUE;
5281 }
5282 }
5283 }
5284 } else {
5285 if (sfp->excpt && (StringDoesHaveText (sfp->except_text))) {
5286 if (StringStr (sfp->except_text, "rearrangement required for product") != NULL) {
5287 okay = TRUE;
5288 }
5289 }
5290 }
5291 } else {
5292 okay = TRUE;
5293 }
5294 if (! okay) {
5295 ajp->relModeError = TRUE;
5296 }
5297 break;
5298
5299 case FEATDEF_conflict:
5300 if (sfp->cit == NULL) {
5301 /* RefSeq allows conflict with accession in comment instead of sfp->cit */
5302 for (sip = bsp->id; sip != NULL; sip = sip->next) {
5303 if (sip->choice == SEQID_OTHER) {
5304 if (StringDoesHaveText (sfp->comment)) {
5305 okay = TRUE;
5306 }
5307 }
5308 }
5309 }
5310 /* continue on to old_sequence */
5311 case FEATDEF_old_sequence:
5312 /* conflict and old_sequence require a publication printable on the segment */
5313 vnp = sfp->cit;
5314
5315 if (vnp != NULL && asp->referenceArray != NULL) {
5316 for (ppr = vnp->data.ptrvalue; ppr != NULL; ppr = ppr->next) {
5317 j = MatchRef (ppr, asp->referenceArray, asp->numReferences);
5318 if (j > 0) {
5319 okay = TRUE;
5320 break;
5321 }
5322 }
5323 }
5324 if (! okay) {
5325 /* compare qualifier can now substitute for citation qualifier */
5326 gbq = sfp->qual;
5327 while (gbq != NULL) {
5328 if (StringICmp (gbq->qual, "compare") == 0 && (StringDoesHaveText (gbq->val))) {
5329 okay = TRUE;
5330 break;
5331 }
5332 gbq = gbq->next;
5333 }
5334 }
5335 break;
5336
5337 case FEATDEF_GENE:
5338 /* gene requires /gene or /locus_tag, but desc or syn can be mapped to /gene */
5339 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
5340 if (grp != NULL) {
5341 if (StringDoesHaveText (grp->locus)) {
5342 okay = TRUE;
5343 } else if (StringDoesHaveText (grp->locus_tag)) {
5344 okay = TRUE;
5345 } else if (StringDoesHaveText (grp->desc)) {
5346 okay = TRUE;
5347 } else {
5348 vnp = grp->syn;
5349 if (vnp != NULL) {
5350 if (StringDoesHaveText (vnp->data.ptrvalue)) {
5351 okay = TRUE;
5352 }
5353 }
5354 }
5355 }
5356 break;
5357
5358 case FEATDEF_protein_bind:
5359 case FEATDEF_misc_binding:
5360 /* protein_bind or misc_binding require FTQUAL_bound_moiety */
5361 gbq = sfp->qual;
5362 while (gbq != NULL) {
5363 if (StringICmp (gbq->qual, "bound_moiety") == 0 && (StringDoesHaveText (gbq->val))) {
5364 okay = TRUE;
5365 break;
5366 }
5367 gbq = gbq->next;
5368 }
5369 break;
5370
5371 case FEATDEF_modified_base:
5372 /* modified_base requires FTQUAL_mod_base */
5373 gbq = sfp->qual;
5374 while (gbq != NULL) {
5375 if (StringICmp (gbq->qual, "mod_base") == 0 && (StringDoesHaveText (gbq->val))) {
5376 okay = TRUE;
5377 break;
5378 }
5379 gbq = gbq->next;
5380 }
5381 break;
5382
5383 case FEATDEF_gap:
5384 /* modified_base requires FTQUAL_estimated_length */
5385 gbq = sfp->qual;
5386 while (gbq != NULL) {
5387 if (StringICmp (gbq->qual, "estimated_length") == 0 && (StringDoesHaveText (gbq->val))) {
5388 okay = TRUE;
5389 break;
5390 }
5391 gbq = gbq->next;
5392 }
5393 break;
5394
5395 case FEATDEF_operon:
5396 /* operon requires FTQUAL_operon */
5397 gbq = sfp->qual;
5398 while (gbq != NULL) {
5399 if (StringICmp (gbq->qual, "operon") == 0 && (StringDoesHaveText (gbq->val))) {
5400 okay = TRUE;
5401 break;
5402 }
5403 gbq = gbq->next;
5404 }
5405 break;
5406
5407 case FEATDEF_ncRNA:
5408 /* ncRNA requires FTQUAL_ncRNA_class */
5409 gbq = sfp->qual;
5410 while (gbq != NULL) {
5411 if (StringICmp (gbq->qual, "ncRNA_class") == 0 && (StringDoesHaveText (gbq->val))) {
5412 okay = TRUE;
5413 break;
5414 }
5415 gbq = gbq->next;
5416 }
5417 rrp = (RnaRefPtr) sfp->data.value.ptrvalue;
5418 if (rrp != NULL && rrp->ext.choice == 3) {
5419 rgp = (RNAGenPtr) rrp->ext.value.ptrvalue;
5420 if (rgp != NULL) {
5421 if (StringDoesHaveText (rgp->_class)) {
5422 okay = TRUE;
5423 break;
5424 }
5425 }
5426 }
5427 break;
5428
5429 default:
5430 if (fcontext->featdeftype >= FEATDEF_GENE && fcontext->featdeftype < FEATDEF_MAX) {
5431 okay = TRUE;
5432 }
5433 break;
5434 }
5435
5436 if (okay == FALSE) return TRUE;
5437 }
5438
5439 /* if RELEASE_MODE, suppress features with location on near segmented Bioseq */
5440
5441 if (ajp->flags.suppressSegLoc) {
5442 bsp = awp->parent;
5443 if (bsp != NULL && bsp->repr == Seq_repr_seg && SegHasParts (bsp)) {
5444 slp = SeqLocFindNext (sfp->location, NULL);
5445 while (slp != NULL) {
5446 sip = SeqLocId (slp);
5447 if (sip != NULL) {
5448 if (SeqIdIn (sip, bsp->id)) return TRUE;
5449 }
5450 slp = SeqLocFindNext (sfp->location, slp);
5451 }
5452 }
5453 }
5454
5455 awp->lastsfp = sfp;
5456 awp->lastsap = fcontext->sap;
5457 awp->lastleft = fcontext->left;
5458 awp->lastright = fcontext->right;
5459
5460 if (fcontext->seqfeattype == SEQFEAT_CDREGION) {
5461 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
5462 } else if (fcontext->seqfeattype == SEQFEAT_PROT) {
5463 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntPrtBlock));
5464 } else {
5465 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntFeatBlock));
5466 }
5467 if (fbp == NULL) return TRUE;
5468
5469 fbp->entityID = fcontext->entityID;
5470 fbp->itemID = fcontext->itemID;
5471 fbp->itemtype = OBJ_SEQFEAT;
5472 fbp->featdeftype = fcontext->featdeftype;
5473 ifp = (IntFeatBlockPtr) fbp;
5474 ifp->mapToNuc = FALSE;
5475 ifp->mapToProt = FALSE;
5476 ifp->mapToGen = FALSE;
5477 ifp->mapToMrna = FALSE;
5478 ifp->mapToPep = FALSE;
5479 ifp->firstfeat = awp->firstfeat;
5480 awp->firstfeat = FALSE;
5481 /* this allows remote SNP, CDD, MGC, etc., not to be treated as local annotation */
5482 if (awp->entityID != fbp->entityID || fbp->itemID <= awp->localFeatCount) {
5483 awp->featseen = TRUE;
5484 }
5485 awp->featjustseen = TRUE;
5486
5487 if (fcontext->seqfeattype == SEQFEAT_PROT) {
5488
5489 /* set calculated molecular weight flags for proteins */
5490
5491 ifp->isPrt = TRUE;
5492 ipp = (IntPrtBlockPtr) fbp;
5493 prp = (ProtRefPtr) sfp->data.value.ptrvalue;
5494 if (prp != NULL) {
5495 if (prp->processed < 2) {
5496 is_whole = FALSE;
5497 slp = sfp->location;
5498 if (slp != NULL) {
5499 if (slp->choice == SEQLOC_WHOLE) {
5500 is_whole = TRUE;
5501 } else if (slp->choice == SEQLOC_INT) {
5502 sintp = (SeqIntPtr) slp->data.ptrvalue;
5503 if (sintp != NULL &&
5504 bsp != NULL &&
5505 sintp->from == 0 &&
5506 sintp->to == bsp->length - 1) {
5507 is_whole = TRUE;
5508 }
5509 }
5510 }
5511 if (is_whole) {
5512 ipp->is_whole_loc = TRUE;
5513 if (awp->has_sig_peptide) {
5514 if (awp->has_mat_peptide) {
5515 ipp->suppress_mol_wt = TRUE;
5516 } else if (awp->sig_pept_trim_len > 0) {
5517 ipp->sig_pept_trim_len = awp->sig_pept_trim_len;
5518 }
5519 } else {
5520 ipp->trim_initial_met = TRUE;
5521 }
5522 }
5523 }
5524 }
5525 }
5526
5527 if (awp->afp != NULL) {
5528 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
5529 }
5530
5531 /* optionally map CDS from cDNA onto genomic */
5532
5533 if (awp->isGPS && bsp != NULL && ISA_na (bsp->mol) && awp->copyGpsCdsUp &&
5534 fcontext->featdeftype == FEATDEF_mRNA) {
5535 sip = SeqLocIdForProduct (sfp->product);
5536 bsp = BioseqFind (sip);
5537 if (bsp != NULL && ISA_na (bsp->mol)) {
5538 cds = SeqMgrGetNextFeature (bsp, NULL, SEQFEAT_CDREGION, 0, &cdscontext);
5539 if (cds != NULL) {
5540 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
5541 if (fbp != NULL) {
5542
5543 fbp->entityID = cdscontext.entityID;
5544 fbp->itemID = cdscontext.itemID;
5545 fbp->itemtype = OBJ_SEQFEAT;
5546 fbp->featdeftype = cdscontext.featdeftype;
5547 ifp = (IntFeatBlockPtr) fbp;
5548 ifp->mapToNuc = FALSE;
5549 ifp->mapToProt = FALSE;
5550 ifp->mapToGen = TRUE;
5551 ifp->mapToMrna = FALSE;
5552 ifp->mapToPep = FALSE;
5553 ifp->firstfeat = awp->firstfeat;
5554 awp->firstfeat = FALSE;
5555
5556 if (awp->afp != NULL) {
5557 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
5558 }
5559 }
5560 }
5561 }
5562 }
5563
5564 if (fcontext->seqfeattype != SEQFEAT_CDREGION) return TRUE;
5565
5566 /* if feature table format, do not get features from protein product */
5567
5568 if (awp->format == FTABLE_FMT) return TRUE;
5569
5570 /* if CDS, collect more information from product protein bioseq - may be part */
5571
5572 sip = SeqLocIdForProduct (sfp->product);
5573 bsp = BioseqFind (sip);
5574 if (bsp == NULL || (! ISA_aa (bsp->mol))) return TRUE;
5575
5576 ifp->isCDS = TRUE;
5577 icp = (IntCdsBlockPtr) ifp;
5578
5579 /* first explore pubs to pick up figure and maploc - no longer shown */
5580
5581 /*
5582 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_pub, &dcontext);
5583 while (sdp != NULL) {
5584 pdp = (PubdescPtr) sdp->data.ptrvalue;
5585 if (pdp != NULL) {
5586 if (icp->fig == NULL) {
5587 icp->fig = StringSaveNoNull (pdp->fig);
5588 }
5589 if (icp->maploc == NULL) {
5590 icp->maploc = StringSaveNoNull (pdp->maploc);
5591 }
5592 }
5593 sdp = SeqMgrGetNextDescriptor (bsp, sdp, Seq_descr_pub, &dcontext);
5594 }
5595 */
5596
5597 /* product may be segmented part, and remaining features are indexed on parent */
5598
5599 parent = SeqMgrGetParentOfPart (bsp, NULL);
5600 if (parent != NULL) {
5601 bsp = parent;
5602 }
5603
5604 /* then explore mat_peptides, sites, etc. */
5605
5606 GetFeatsOnCdsProduct (sfp, asp->bsp, bsp, ajp, awp);
5607
5608 GetRemoteFeatsOnCdsProduct (sfp, asp->bsp, bsp, ajp, awp);
5609
5610 return TRUE;
5611 }
5612
5613 /*
5614 static Boolean TestGetAccnVerFromServer (Int4 gi, CharPtr buf)
5615
5616 {
5617 Char accn [64];
5618 SeqIdPtr sip;
5619
5620 if (buf == NULL) return FALSE;
5621 *buf = '\0';
5622 sip = GetSeqIdForGI (gi);
5623 if (sip == NULL) return FALSE;
5624 SeqIdWrite (sip, accn, PRINTID_TEXTID_ACC_VER, sizeof (accn) - 1);
5625 SeqIdFree (sip);
5626 if (StringLen (accn) < 40) {
5627 StringCpy (buf, accn);
5628 }
5629 return TRUE;
5630 }
5631 */
5632
5633 static WgsAccnPtr GetWgsNode (
5634 Asn2gbWorkPtr awp,
5635 CharPtr accn
5636 )
5637
5638 {
5639 ValNodePtr vnp;
5640 WgsAccnPtr wap = NULL;
5641
5642 if (awp == NULL || StringHasNoText (accn)) return NULL;
5643
5644 for (vnp = awp->wgsaccnlist; vnp != NULL; vnp = vnp->next) {
5645 wap = (WgsAccnPtr) vnp->data.ptrvalue;
5646 if (wap == NULL) continue;
5647 if (StringCmp (accn, wap->accn) == 0) return wap;
5648 }
5649 wap = (WgsAccnPtr) MemNew (sizeof (WgsAccn));
5650 if (wap == NULL) return NULL;
5651 StringCpy (wap->accn, accn);
5652 ValNodeAddPointer (&(awp->wgsaccnlist), 0, (Pointer) wap);
5653 return wap;
5654 }
5655
5656 static Boolean LIBCALLBACK GetFeatsOnSeg (
5657 SeqLocPtr slp,
5658 SeqMgrSegmentContextPtr context
5659 )
5660
5661 {
5662 Char accn [41];
5663 Uint4 accntype;
5664 IntAsn2gbJobPtr ajp;
5665 Asn2gbWorkPtr awp;
5666 BioseqPtr bsp;
5667 time_t currTime;
5668 Uint2 entityID;
5669 Int4 from;
5670 Int4 gi;
5671 Int4 left;
5672 SeqLocPtr loc;
5673 CharPtr ptr;
5674 Int4 right;
5675 SeqIdPtr sip;
5676 Int4 to;
5677 WgsAccnPtr wap = NULL;
5678
5679 if (slp == NULL || context == NULL) return FALSE;
5680 awp = (Asn2gbWorkPtr) context->userdata;
5681 if (awp == NULL) return FALSE;
5682 ajp = awp->ajp;
5683 if (ajp == NULL) return FALSE;
5684
5685 /* do not fetch outside of desired component */
5686
5687 if (ajp->ajp.slp != NULL) {
5688 left = GetOffsetInBioseq (ajp->ajp.slp, awp->parent, SEQLOC_LEFT_END);
5689 right = GetOffsetInBioseq (ajp->ajp.slp, awp->parent, SEQLOC_RIGHT_END);
5690
5691 from = context->cumOffset;
5692 to = from + context->to - context->from;
5693
5694 if (left > to) return TRUE;
5695 if (right < from) return TRUE;
5696 }
5697
5698 from = awp->from;
5699 to = awp->to;
5700
5701 sip = SeqLocId (slp);
5702 if (sip == NULL) {
5703 loc = SeqLocFindNext (slp, NULL);
5704 if (loc != NULL) {
5705 sip = SeqLocId (loc);
5706 }
5707 }
5708 if (sip == NULL) return TRUE;
5709
5710 /* if Web Entrez WGS */
5711
5712 if (awp->farFeatTimeLimit) {
5713 if (sip->choice == SEQID_GI) {
5714 gi = sip->data.intvalue;
5715 if (GetAccnVerFromServer (gi, accn)) {
5716 ptr = StringChr (accn, '.');
5717 if (ptr != NULL) {
5718 *ptr = '\0';
5719 }
5720 accntype = WHICH_db_accession (accn);
5721 if (ACCN_IS_WGS (accntype)) {
5722 accn [4] = '\0';
5723 wap = GetWgsNode (awp, accn);
5724 if (wap != NULL) {
5725 (wap->count)++;
5726 if (wap->count > 50) {
5727 if (! wap->hasfeats) return TRUE;
5728 }
5729 }
5730 }
5731 }
5732 }
5733 if (! awp->featseen) {
5734 currTime = GetSecs ();
5735 if (currTime - awp->farFeatStartTime > 25) return FALSE;
5736 }
5737 }
5738
5739 /* may want to remote fetch genome component if not already in memory */
5740
5741 bsp = BioseqLockById (sip);
5742
5743 if (bsp == NULL) return TRUE;
5744
5745 entityID = ObjMgrGetEntityIDForPointer (bsp);
5746
5747 if (entityID != awp->entityID) {
5748
5749 /* if segment not packaged in record, may need to feature index it */
5750
5751 if (SeqMgrFeaturesAreIndexed (entityID) == 0) {
5752 SeqMgrIndexFeatures (entityID, NULL);
5753 }
5754
5755 /* collect features indexed on the remote bioseq */
5756
5757 awp->from = 0;
5758 awp->to = bsp->length - 1;
5759 }
5760
5761 awp->lastsfp = NULL;
5762 awp->lastsap = NULL;
5763 awp->lastleft = 0;
5764 awp->lastright = 0;
5765
5766 awp->featjustseen = FALSE;
5767
5768 if (context->strand == Seq_strand_minus) {
5769 SeqMgrExploreFeaturesRev (bsp, (Pointer) awp, GetFeatsOnBioseq, /* awp->slp */ slp, NULL, NULL);
5770 } else {
5771 SeqMgrExploreFeatures (bsp, (Pointer) awp, GetFeatsOnBioseq, /* awp->slp */ slp, NULL, NULL);
5772 }
5773
5774 if (awp->featjustseen && wap != NULL) {
5775 wap->hasfeats = TRUE;
5776 }
5777
5778 /* restore original from and to */
5779
5780 awp->from = from;
5781 awp->to = to;
5782
5783 BioseqUnlock (bsp);
5784
5785 return TRUE;
5786 }
5787
5788 NLM_EXTERN void AddFeatureBlock (
5789 Asn2gbWorkPtr awp
5790 )
5791
5792 {
5793 IntAsn2gbJobPtr ajp;
5794 BioseqPtr bsp;
5795 SeqFeatPtr cds;
5796 SeqMgrDescContext dcontext;
5797 SeqMgrFeatContext fcontext;
5798 FeatBlockPtr fbp;
5799 SeqFeatPtr gene;
5800 IntFeatBlockPtr ifp;
5801 Boolean is_other;
5802 MolInfoPtr mip;
5803 SeqFeatPtr mrna;
5804 SeqFeatPtr prot;
5805 SeqDescrPtr sdp;
5806 SeqIdPtr sip;
5807 SeqLocPtr slp;
5808
5809 if (awp == NULL) return;
5810 ajp = awp->ajp;
5811 if (ajp == NULL) return;
5812 bsp = awp->parent;
5813 if (bsp == NULL) return;
5814
5815 awp->lastsfp = NULL;
5816 awp->lastsap = NULL;
5817 awp->lastleft = 0;
5818 awp->lastright = 0;
5819
5820 /* for protein molecular weight calculation, need sig_peptide, etc. */
5821
5822 awp->has_mat_peptide = FALSE;
5823 awp->has_sig_peptide = FALSE;
5824 awp->sig_pept_trim_len = 0;
5825
5826 if (awp->format == GENPEPT_FMT && ISA_aa (bsp->mol)) {
5827 prot = SeqMgrGetNextFeature (bsp, NULL, 0, 0, &fcontext);
5828 while (prot != NULL) {
5829 if (fcontext.featdeftype == FEATDEF_sig_peptide_aa ||
5830 fcontext.featdeftype == FEATDEF_transit_peptide_aa) {
5831 awp->has_sig_peptide = TRUE;
5832 if (fcontext.left == 0 && fcontext.right < bsp->length - 1) {
5833 awp->sig_pept_trim_len = fcontext.right + 1;
5834 }
5835 } else if (fcontext.featdeftype == FEATDEF_mat_peptide_aa) {
5836 awp->has_mat_peptide = TRUE;
5837 }
5838
5839 prot = SeqMgrGetNextFeature (bsp, prot, 0, 0, &fcontext);
5840 }
5841 }
5842
5843 /* optionally map gene from genomic onto cDNA */
5844
5845 if (awp->isGPS && ISA_na (bsp->mol) && awp->copyGpsGeneDown) {
5846 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
5847 if (sdp != NULL && sdp->choice == Seq_descr_molinfo) {
5848 mip = (MolInfoPtr) sdp->data.ptrvalue;
5849 if (mip != NULL) {
5850 if (mip->biomol == MOLECULE_TYPE_MRNA) {
5851 mrna = SeqMgrGetRNAgivenProduct (bsp, NULL);
5852 if (mrna != NULL) {
5853 gene = SeqMgrGetOverlappingGene (mrna->location, &fcontext);
5854 if (gene != NULL && gene->data.choice == SEQFEAT_GENE) {
5855
5856 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
5857 if (fbp != NULL) {
5858
5859 fbp->entityID = fcontext.entityID;
5860 fbp->itemID = fcontext.itemID;
5861 fbp->itemtype = OBJ_SEQFEAT;
5862 fbp->featdeftype = fcontext.featdeftype;
5863 ifp = (IntFeatBlockPtr) fbp;
5864 ifp->mapToNuc = FALSE;
5865 ifp->mapToProt = FALSE;
5866 ifp->mapToGen = FALSE;
5867 ifp->mapToMrna = TRUE;
5868 ifp->mapToPep = FALSE;
5869 ifp->isCDS = TRUE;
5870 ifp->firstfeat = awp->firstfeat;
5871 awp->firstfeat = FALSE;
5872
5873 if (awp->afp != NULL) {
5874 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
5875 }
5876 }
5877 }
5878 }
5879 }
5880 }
5881 }
5882 }
5883
5884 awp->farFeatTimeLimit = FALSE;
5885 if (bsp->repr == Seq_repr_seg || bsp->repr == Seq_repr_delta) {
5886 if (awp->mode == ENTREZ_MODE) {
5887 awp->farFeatTimeLimit = TRUE;
5888 }
5889 /*
5890 if (GetWWW (ajp) && awp->mode == ENTREZ_MODE) {
5891 sdp = SeqMgrGetNextDescriptor (bsp, NULL, Seq_descr_molinfo, &dcontext);
5892 if (sdp != NULL && sdp->choice == Seq_descr_molinfo && sdp->data.ptrvalue != NULL) {
5893 mip = (MolInfoPtr) sdp->data.ptrvalue;
5894 if (mip->tech == MI_TECH_wgs || mip->tech == MI_TECH_composite_wgs_htgs) {
5895 awp->farFeatTimeLimit = TRUE;
5896 }
5897 }
5898 }
5899 */
5900 }
5901
5902 if (! awp->onlyNearFeats) {
5903 if (awp->farFeatsSuppress) {
5904
5905 if (bsp->repr == Seq_repr_seg || bsp->repr == Seq_repr_delta) {
5906
5907 /* get start time for 25 second timeout in Web Entrez far WGS records */
5908
5909 if (awp->farFeatTimeLimit) {
5910 awp->farFeatStartTime = GetSecs ();
5911 }
5912
5913 /* if farFeatsSuppress first collect features on remote segments in MASTER_STYLE */
5914
5915 SeqMgrExploreSegments (bsp, (Pointer) awp, GetFeatsOnSeg);
5916
5917 awp->wgsaccnlist = ValNodeFreeData (awp->wgsaccnlist);
5918 }
5919 }
5920 }
5921
5922 if ((! awp->farFeatsSuppress) || (! awp->featseen)) {
5923
5924 /* reminder - features on near parts are indexed on segmented Bioseq */
5925
5926 slp = ajp->ajp.slp;
5927 if (slp != NULL && SeqLocStrand (slp) == Seq_strand_minus) {
5928 SeqMgrExploreFeaturesRev (bsp, (Pointer) awp, GetFeatsOnBioseq, awp->slp, NULL, NULL);
5929 } else {
5930 SeqMgrExploreFeatures (bsp, (Pointer) awp, GetFeatsOnBioseq, awp->slp, NULL, NULL);
5931 }
5932 }
5933
5934
5935 if (awp->format == GENPEPT_FMT && ISA_aa (bsp->mol)) {
5936 cds = SeqMgrGetCDSgivenProduct (bsp, &fcontext);
5937 if (cds != NULL && cds->data.choice == SEQFEAT_CDREGION) {
5938
5939 if (fcontext.entityID > 0 && fcontext.itemID > 0) {
5940
5941 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
5942 if (fbp != NULL) {
5943
5944 fbp->entityID = fcontext.entityID;
5945 fbp->itemID = fcontext.itemID;
5946 fbp->itemtype = OBJ_SEQFEAT;
5947 fbp->featdeftype = fcontext.featdeftype;
5948 ifp = (IntFeatBlockPtr) fbp;
5949 ifp->mapToNuc = FALSE;
5950 ifp->mapToProt = TRUE;
5951 ifp->mapToGen = FALSE;
5952 ifp->mapToMrna = FALSE;
5953 ifp->mapToPep = FALSE;
5954 ifp->isCDS = TRUE;
5955 ifp->firstfeat = awp->firstfeat;
5956 awp->firstfeat = FALSE;
5957
5958 if (awp->afp != NULL) {
5959 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
5960 }
5961 }
5962 } else if (cds->idx.entityID > 0 && cds->idx.itemID > 0) {
5963
5964 /* if protein bioseq and cds feature but no nucleotide, handle as special case */
5965
5966 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
5967 if (fbp != NULL) {
5968
5969 fbp->entityID = cds->idx.entityID;
5970 fbp->itemID = cds->idx.itemID;
5971 fbp->itemtype = OBJ_SEQFEAT;
5972 fbp->featdeftype = FEATDEF_CDS;
5973 ifp = (IntFeatBlockPtr) fbp;
5974 ifp->mapToNuc = FALSE;
5975 ifp->mapToProt = TRUE;
5976 ifp->mapToGen = FALSE;
5977 ifp->mapToMrna = FALSE;
5978 ifp->mapToPep = FALSE;
5979 ifp->isCDS = TRUE;
5980 ifp->firstfeat = awp->firstfeat;
5981 awp->firstfeat = FALSE;
5982
5983 if (awp->afp != NULL) {
5984 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
5985 }
5986 }
5987 }
5988 }
5989 prot = SeqMgrGetPROTgivenProduct (bsp, &fcontext);
5990 if (prot != NULL && prot->data.choice == SEQFEAT_PROT) {
5991
5992 is_other = FALSE;
5993 for (sip = bsp->id; sip != NULL; sip = sip->next) {
5994 if (sip->choice == SEQID_OTHER) {
5995 is_other = TRUE;
5996 }
5997 }
5998
5999 /* for RefSeq records or GenBank not release_mode */
6000 if (is_other || (! ajp->flags.forGbRelease)) {
6001
6002 fbp = (FeatBlockPtr) Asn2gbAddBlock (awp, FEATURE_BLOCK, sizeof (IntCdsBlock));
6003 if (fbp != NULL) {
6004
6005 fbp->entityID = fcontext.entityID;
6006 fbp->itemID = fcontext.itemID;
6007 fbp->itemtype = OBJ_SEQFEAT;
6008 fbp->featdeftype = fcontext.featdeftype;
6009 ifp = (IntFeatBlockPtr) fbp;
6010 ifp->mapToNuc = FALSE;
6011 ifp->mapToProt = FALSE;
6012 ifp->mapToGen = FALSE;
6013 ifp->mapToMrna = FALSE;
6014 ifp->mapToPep = TRUE;
6015 ifp->firstfeat = awp->firstfeat;
6016 awp->firstfeat = FALSE;
6017
6018 if (awp->afp != NULL) {
6019 DoImmediateFormat (awp->afp, (BaseBlockPtr) fbp);
6020 }
6021 }
6022 }
6023 }
6024 }
6025
6026 if (awp->onlyNearFeats) return;
6027
6028 if (awp->nearFeatsSuppress && awp->featseen) return;
6029
6030 if (! awp->farFeatsSuppress) {
6031
6032 if (bsp->repr == Seq_repr_seg || bsp->repr == Seq_repr_delta) {
6033
6034 /* get start time for 25 second timeout in Web Entrez far WGS records */
6035
6036 if (awp->farFeatTimeLimit) {
6037 awp->farFeatStartTime = GetSecs ();
6038 }
6039
6040 /* if not farFeatsSuppress now collect features on remote segments in MASTER_STYLE */
6041
6042 SeqMgrExploreSegments (bsp, (Pointer) awp, GetFeatsOnSeg);
6043
6044 awp->wgsaccnlist = ValNodeFreeData (awp->wgsaccnlist);
6045 }
6046 }
6047 }
6048
6049 NLM_EXTERN void AddFeatStatsBlock (
6050 Asn2gbWorkPtr awp
6051 )
6052
6053 {
6054 IntAsn2gbJobPtr ajp;
6055 BaseBlockPtr bbp;
6056 BioseqPtr bsp;
6057 StringItemPtr ffstring;
6058
6059 if (awp == NULL) return;
6060 ajp = awp->ajp;
6061 if ( ajp == NULL ) return;
6062 bsp = awp->bsp;
6063 if (bsp == NULL) return;
6064
6065 if (awp->format == EMBL_FMT || awp->format == EMBLPEPT_FMT) return;
6066
6067 bbp = Asn2gbAddBlock (awp, FEAT_STATS_BLOCK, sizeof (BaseBlock));
6068 if (bbp != NULL) {
6069 ffstring = FFGetString (ajp);
6070 if (ffstring != NULL) {
6071 FFStartPrint (ffstring, awp->format, 0, 12, "FEATSTATS", 12, 0, 0, NULL, FALSE);
6072
6073 FFAddOneString (ffstring, "placeholder", FALSE, FALSE, TILDE_TO_SPACES);
6074
6075 bbp->string = FFEndPrint (ajp, ffstring, awp->format, 12, 12, 0, 0, NULL);
6076 FFRecycleString(ajp, ffstring);
6077 }
6078
6079 if (awp->afp != NULL) {
6080 DoImmediateFormat (awp->afp, bbp);
6081 }
6082 }
6083 }
6084
6085 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |