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

« back to all changes in this revision

Viewing changes to demo/asn2fsa.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*   asn2fsa.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:  asn2fsa.c
 
27
*
 
28
* Author:  Jonathan Kans
 
29
*
 
30
* Version Creation Date:   3/4/04
 
31
*
 
32
* $Revision: 1.23 $
 
33
*
 
34
* File Description:
 
35
*
 
36
* Modifications:  
 
37
* --------------------------------------------------------------------------
 
38
* Date     Name        Description of modification
 
39
* -------  ----------  -----------------------------------------------------
 
40
*
 
41
*
 
42
* ==========================================================================
 
43
*/
 
44
 
 
45
#include <ncbi.h>
 
46
#include <objall.h>
 
47
#include <objsset.h>
 
48
#include <objsub.h>
 
49
#include <objfdef.h>
 
50
#include <seqport.h>
 
51
#include <sequtil.h>
 
52
#include <sqnutils.h>
 
53
#include <subutil.h>
 
54
#include <tofasta.h>
 
55
#include <gather.h>
 
56
#include <explore.h>
 
57
#include <lsqfetch.h>
 
58
#include <readdb.h>
 
59
#include <pmfapi.h>
 
60
#ifdef INTERNAL_NCBI_ASN2FSA
 
61
#include <accpubseq.h>
 
62
#endif
 
63
 
 
64
#define ASN2FSA_APP_VER "1.2"
 
65
 
 
66
CharPtr ASN2FSA_APPLICATION = ASN2FSA_APP_VER;
 
67
 
 
68
static ValNodePtr  requested_uid_list = NULL;
 
69
static TNlmMutex   requested_uid_mutex = NULL;
 
70
 
 
71
static ValNodePtr  locked_bsp_list = NULL;
 
72
static TNlmMutex   locked_bsp_mutex = NULL;
 
73
 
 
74
static void AddUidToQueue (
 
75
  SeqIdPtr sip
 
76
)
 
77
 
 
78
{
 
79
  ValNodePtr  last = NULL, vnp;
 
80
  Int4        ret;
 
81
  Int4        uid;
 
82
 
 
83
  if (sip == NULL || sip->choice != SEQID_GI) return;
 
84
  uid = (Int4) sip->data.intvalue;
 
85
  if (uid < 1) return;
 
86
 
 
87
  ret = NlmMutexLockEx (&requested_uid_mutex);
 
88
  if (ret) {
 
89
    ErrPostEx (SEV_FATAL, 0, 0, "AddUidToQueue mutex failed [%ld]", (long) ret);
 
90
    return;
 
91
  }
 
92
 
 
93
  /* check against uids already in queue */
 
94
 
 
95
  last = NULL;
 
96
  for (vnp = requested_uid_list; vnp != NULL; vnp = vnp->next) {
 
97
    last = vnp;
 
98
    if ((Int4) vnp->data.intvalue == uid) break;
 
99
  }
 
100
 
 
101
  /* add uid to queue */
 
102
 
 
103
  if (vnp == NULL) {
 
104
    if (last != NULL) {
 
105
      vnp = ValNodeAddInt (&last, 0, uid);
 
106
      last = vnp;
 
107
    } else {
 
108
      requested_uid_list = ValNodeAddInt (NULL, 0, uid);
 
109
      last = requested_uid_list;
 
110
    }
 
111
  }
 
112
 
 
113
  NlmMutexUnlock (requested_uid_mutex);
 
114
}
 
115
 
 
116
static Int4 RemoveUidFromQueue (
 
117
  void
 
118
)
 
119
 
 
120
{
 
121
  Int4        ret, uid = 0;
 
122
  ValNodePtr  vnp;
 
123
 
 
124
  ret = NlmMutexLockEx (&requested_uid_mutex);
 
125
  if (ret) {
 
126
    ErrPostEx (SEV_FATAL, 0, 0, "RemoveUidFromQueue mutex failed [%ld]", (long) ret);
 
127
    return 0;
 
128
  }
 
129
 
 
130
  /* extract next requested uid from queue */
 
131
 
 
132
  if (requested_uid_list != NULL) {
 
133
    vnp = requested_uid_list;
 
134
    requested_uid_list = vnp->next;
 
135
    vnp->next = NULL;
 
136
    uid = (Int4) vnp->data.intvalue;
 
137
    ValNodeFree (vnp);
 
138
  }
 
139
 
 
140
  NlmMutexUnlock (requested_uid_mutex);
 
141
 
 
142
  return uid;
 
143
}
 
144
 
 
145
static void QueueFarSegments (SeqLocPtr slp)
 
146
 
 
147
{
 
148
  BioseqPtr   bsp;
 
149
  SeqLocPtr   loc;
 
150
  SeqIdPtr    sip;
 
151
  ValNodePtr  vnp;
 
152
 
 
153
  if (slp == NULL) return;
 
154
 
 
155
  sip = SeqLocId (slp);
 
156
  if (sip == NULL) {
 
157
    loc = SeqLocFindNext (slp, NULL);
 
158
    if (loc != NULL) {
 
159
      sip = SeqLocId (loc);
 
160
    }
 
161
  }
 
162
  if (sip == NULL) return;
 
163
 
 
164
  /* if packaged in record, no need to fetch it */
 
165
 
 
166
  if (BioseqFindCore (sip) != NULL) return;
 
167
 
 
168
  /* check against currently locked records */
 
169
 
 
170
  for (vnp = locked_bsp_list; vnp != NULL; vnp = vnp->next) {
 
171
    bsp = (BioseqPtr) vnp->data.ptrvalue;
 
172
    if (bsp == NULL) continue;
 
173
    if (SeqIdIn (sip, bsp->id)) return;
 
174
  }
 
175
 
 
176
  AddUidToQueue (sip);
 
177
}
 
178
 
 
179
static void QueueFarBioseqs (BioseqPtr bsp, Pointer userdata)
 
180
 
 
181
{
 
182
  DeltaSeqPtr  dsp;
 
183
  SeqLocPtr    slp = NULL;
 
184
  ValNode      vn;
 
185
 
 
186
  if (bsp == NULL) return;
 
187
 
 
188
  if (bsp->repr == Seq_repr_seg) {
 
189
    vn.choice = SEQLOC_MIX;
 
190
    vn.extended = 0;
 
191
    vn.data.ptrvalue = bsp->seq_ext;
 
192
    vn.next = NULL;
 
193
    while ((slp = SeqLocFindNext (&vn, slp)) != NULL) {
 
194
      if (slp != NULL && slp->choice != SEQLOC_NULL) {
 
195
        QueueFarSegments (slp);
 
196
      }
 
197
    }
 
198
  } else if (bsp->repr == Seq_repr_delta) {
 
199
    for (dsp = (DeltaSeqPtr) (bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
 
200
      if (dsp->choice == 1) {
 
201
        slp = (SeqLocPtr) dsp->data.ptrvalue;
 
202
        if (slp != NULL && slp->choice != SEQLOC_NULL) {
 
203
          QueueFarSegments (slp);
 
204
        }
 
205
      }
 
206
    }
 
207
  }
 
208
}
 
209
 
 
210
static void AddBspToList (
 
211
  BioseqPtr bsp
 
212
)
 
213
 
 
214
{
 
215
  Int4        ret;
 
216
  ValNodePtr  vnp;
 
217
 
 
218
  if (bsp == NULL) return;
 
219
 
 
220
  ret = NlmMutexLockEx (&locked_bsp_mutex);
 
221
  if (ret) {
 
222
    ErrPostEx (SEV_FATAL, 0, 0, "AddBspToList mutex failed [%ld]", (long) ret);
 
223
    return;
 
224
  }
 
225
 
 
226
  vnp = ValNodeAddPointer (&locked_bsp_list, 0, (Pointer) bsp);
 
227
 
 
228
  NlmMutexUnlock (locked_bsp_mutex);
 
229
}
 
230
 
 
231
static ValNodePtr ExtractBspList (
 
232
  void
 
233
)
 
234
 
 
235
{
 
236
  Int4        ret;
 
237
  ValNodePtr  vnp;
 
238
 
 
239
  ret = NlmMutexLockEx (&locked_bsp_mutex);
 
240
  if (ret) {
 
241
    ErrPostEx (SEV_FATAL, 0, 0, "ExtractBspList mutex failed [%ld]", (long) ret);
 
242
    return NULL;
 
243
  }
 
244
 
 
245
  vnp = locked_bsp_list;
 
246
  locked_bsp_list = NULL;
 
247
 
 
248
  NlmMutexUnlock (locked_bsp_mutex);
 
249
 
 
250
  return vnp;
 
251
}
 
252
 
 
253
typedef struct fastaflags {
 
254
  Boolean  master_style;
 
255
  Boolean  expand_gaps;
 
256
  Boolean  far_genomic_qual;
 
257
  Boolean  qual_gap_is_zero;
 
258
  Boolean  batch;
 
259
  Boolean  binary;
 
260
  Boolean  compressed;
 
261
  Boolean  lock;
 
262
  Boolean  useThreads;
 
263
  Boolean  usePUBSEQ;
 
264
  Boolean  useBLAST;
 
265
  CharPtr  blastdbname;
 
266
  Int2     type;
 
267
  Int2     linelen;
 
268
  Boolean  failed;
 
269
  FILE     *nt;
 
270
  FILE     *aa;
 
271
  FILE     *ql;
 
272
  FILE     *fr;
 
273
  FILE     *logfp;
 
274
} FastaFlagData, PNTR FastaFlagPtr;
 
275
 
 
276
static VoidPtr DoAsyncLookup (
 
277
  VoidPtr arg
 
278
)
 
279
 
 
280
{
 
281
  BioseqPtr     bsp;
 
282
  FastaFlagPtr  ffp;
 
283
  Int4          uid;
 
284
  ValNode       vn;
 
285
 
 
286
  ffp = (FastaFlagPtr) arg;
 
287
  if (ffp == NULL) return;
 
288
 
 
289
#ifdef INTERNAL_NCBI_ASN2FSA
 
290
  if (ffp->usePUBSEQ) {
 
291
    PUBSEQInit ();
 
292
  }
 
293
#endif
 
294
  if (ffp->useBLAST) {
 
295
    ReadDBBioseqFetchEnable ("asn2fsa", ffp->blastdbname, TRUE, FALSE);
 
296
  }
 
297
 
 
298
  MemSet ((Pointer) &vn, 0, sizeof (ValNode));
 
299
 
 
300
  uid = RemoveUidFromQueue ();
 
301
  while (uid > 0) {
 
302
 
 
303
    vn.choice = SEQID_GI;
 
304
    vn.data.intvalue = uid;
 
305
    vn.next = NULL;
 
306
 
 
307
    bsp = BioseqLockById (&vn);
 
308
    if (bsp != NULL) {
 
309
      AddBspToList (bsp);
 
310
    }
 
311
 
 
312
    uid = RemoveUidFromQueue ();
 
313
  }
 
314
 
 
315
  if (ffp->useBLAST) {
 
316
    ReadDBBioseqFetchDisable ();
 
317
  }
 
318
#ifdef INTERNAL_NCBI_ASN2FSA
 
319
  if (ffp->usePUBSEQ) {
 
320
    PUBSEQFini ();
 
321
  }
 
322
#endif
 
323
}
 
324
 
 
325
#define NUM_ASYNC_LOOKUP_THREADS 5
 
326
 
 
327
static void ProcessAsyncLookups (
 
328
  FastaFlagPtr ffp
 
329
)
 
330
 
 
331
{
 
332
  Int2        i;
 
333
  VoidPtr     status;
 
334
  TNlmThread  thds [NUM_ASYNC_LOOKUP_THREADS];
 
335
 
 
336
  /* spawn several threads for individual BioseqLockById requests */
 
337
 
 
338
  for (i = 0; i < NUM_ASYNC_LOOKUP_THREADS; i++) {
 
339
    thds [i] = NlmThreadCreate (DoAsyncLookup, (Pointer) ffp);
 
340
  }
 
341
 
 
342
  /* wait for all fetching threads to complete */
 
343
 
 
344
  for (i = 0; i < NUM_ASYNC_LOOKUP_THREADS; i++) {
 
345
    NlmThreadJoin (thds [i], &status);
 
346
  }
 
347
}
 
348
 
 
349
static ValNodePtr AsyncLockFarComponents (
 
350
  SeqEntryPtr sep,
 
351
  FastaFlagPtr ffp
 
352
)
 
353
 
 
354
{
 
355
  BioseqPtr    bsp;
 
356
  ValNodePtr   bsplist = NULL, sublist, vnp;
 
357
  SeqEntryPtr  oldsep;
 
358
 
 
359
  if (sep == NULL || ffp == NULL) return NULL;
 
360
  oldsep = SeqEntrySetScope (sep);
 
361
 
 
362
  /* add far uids to queue */
 
363
 
 
364
  VisitBioseqsInSep (sep, NULL, QueueFarBioseqs);
 
365
 
 
366
  /* fetching from uid list using several threads */
 
367
 
 
368
  ProcessAsyncLookups (ffp);
 
369
 
 
370
  sublist = ExtractBspList ();
 
371
 
 
372
  /* take list, look for seg or delta, recurse */
 
373
 
 
374
  while (sublist != NULL) {
 
375
    for (vnp = sublist; vnp != NULL; vnp = vnp->next) {
 
376
      bsp = (BioseqPtr) vnp->data.ptrvalue;
 
377
      if (bsp == NULL) continue;
 
378
      QueueFarBioseqs (bsp, NULL);
 
379
    }
 
380
 
 
381
    ValNodeLink (&bsplist, sublist);
 
382
    sublist = NULL;
 
383
 
 
384
    ProcessAsyncLookups (ffp);
 
385
 
 
386
    sublist = ExtractBspList ();
 
387
  }
 
388
 
 
389
  SeqEntrySetScope (oldsep);
 
390
  return bsplist;
 
391
}
 
392
 
 
393
static ValNodePtr DoLockFarComponents (
 
394
  SeqEntryPtr sep,
 
395
  FastaFlagPtr ffp
 
396
)
 
397
 
 
398
{
 
399
  ValNodePtr  rsult;
 
400
  time_t      start_time, stop_time;
 
401
 
 
402
  /*
 
403
  if (NlmThreadsAvailable () && ffp->useThreads) {
 
404
    return AsyncLockFarComponents (sep);
 
405
  }
 
406
 
 
407
  return LockFarComponents (sep);
 
408
  */
 
409
 
 
410
  start_time = GetSecs ();
 
411
 
 
412
  if (NlmThreadsAvailable () && ffp->useThreads) {
 
413
    rsult = AsyncLockFarComponents (sep, ffp);
 
414
  } else if (ffp->useThreads) {
 
415
    Message (MSG_POST, "Threads not available in this executable");
 
416
    rsult = LockFarComponents (sep);
 
417
  } else {
 
418
    rsult = LockFarComponents (sep);
 
419
  }
 
420
 
 
421
  stop_time = GetSecs ();
 
422
 
 
423
  return rsult;
 
424
}
 
425
 
 
426
static Boolean DeltaLitOnly (
 
427
  BioseqPtr bsp
 
428
)
 
429
 
 
430
{
 
431
  ValNodePtr  vnp;
 
432
 
 
433
  if (bsp == NULL || bsp->repr != Seq_repr_delta) return FALSE;
 
434
  for (vnp = (ValNodePtr)(bsp->seq_ext); vnp != NULL; vnp = vnp->next) {
 
435
    if (vnp->choice == 1) return FALSE;
 
436
  }
 
437
  return TRUE;
 
438
}
 
439
 
 
440
static Boolean SegHasParts (
 
441
  BioseqPtr bsp
 
442
)
 
443
 
 
444
{
 
445
  BioseqSetPtr  bssp;
 
446
  SeqEntryPtr   sep;
 
447
 
 
448
  if (bsp == NULL || bsp->repr != Seq_repr_seg) return FALSE;
 
449
  sep = bsp->seqentry;
 
450
  if (sep == NULL) return FALSE;
 
451
  sep = sep->next;
 
452
  if (sep == NULL || (! IS_Bioseq_set (sep))) return FALSE;
 
453
  bssp = (BioseqSetPtr) sep->data.ptrvalue;
 
454
  if (bssp != NULL && bssp->_class == BioseqseqSet_class_parts) return TRUE;
 
455
  return FALSE;
 
456
}
 
457
 
 
458
static void CacheFarComponents (
 
459
  FastaFlagPtr ffp,
 
460
  ValNodePtr bsplist
 
461
)
 
462
 
 
463
{
 
464
  BioseqPtr   bsp;
 
465
  Uint2       entityID;
 
466
  ValNodePtr  vnp;
 
467
 
 
468
  if (ffp == NULL || ffp->fr == NULL || bsplist == NULL) return;
 
469
 
 
470
  for (vnp = bsplist; vnp != NULL; vnp = vnp->next) {
 
471
    bsp = (BioseqPtr) vnp->data.ptrvalue;
 
472
    if (bsp == NULL) continue;
 
473
 
 
474
    /* cache raw and constructed, near segmented, and delta literal */
 
475
 
 
476
    switch (bsp->repr) {
 
477
        case Seq_repr_raw :
 
478
        case Seq_repr_const :
 
479
          if (BioseqFastaStream (bsp, ffp->fr, 0, ffp->linelen, 0, 0, TRUE) < 0) {
 
480
            ffp->failed = TRUE;
 
481
          }
 
482
          break;
 
483
        case Seq_repr_seg :
 
484
          entityID = ObjMgrGetEntityIDForPointer (bsp);
 
485
          AssignIDsInEntity (entityID, 0, NULL);
 
486
          if (SegHasParts (bsp)) {
 
487
            if (BioseqFastaStream (bsp, ffp->fr, 0, ffp->linelen, 0, 0, TRUE) < 0) {
 
488
              ffp->failed = TRUE;
 
489
            }
 
490
          }
 
491
          break;
 
492
        case Seq_repr_delta :
 
493
          if (DeltaLitOnly (bsp)) {
 
494
            if (BioseqFastaStream (bsp, ffp->fr, 0, ffp->linelen, 0, 0, TRUE) < 0) {
 
495
              ffp->failed = TRUE;
 
496
            }
 
497
          }
 
498
          break;
 
499
        default :
 
500
          break;
 
501
    }
 
502
  }
 
503
}
 
504
 
 
505
static void PrintQualProc (
 
506
  CharPtr buf,
 
507
  Uint4 buflen,
 
508
  Pointer userdata
 
509
)
 
510
 
 
511
{
 
512
  FILE  *fp;
 
513
 
 
514
  fp = (FILE*) userdata;
 
515
  fprintf (fp, "%s", buf);
 
516
}
 
517
 
 
518
static void PrintQualScores (
 
519
  BioseqPtr bsp,
 
520
  Pointer userdata
 
521
)
 
522
 
 
523
{
 
524
  FastaFlagPtr  ffp;
 
525
 
 
526
  ffp = (FastaFlagPtr) userdata;
 
527
  if (bsp == NULL || ffp == NULL) return;
 
528
  if (! ISA_na (bsp->mol)) return;
 
529
 
 
530
  if (ffp->far_genomic_qual) {
 
531
    PrintQualityScoresForContig (bsp, ffp->qual_gap_is_zero, ffp->ql);
 
532
  } else {
 
533
    PrintQualityScoresToBuffer (bsp, ffp->qual_gap_is_zero, ffp->ql, PrintQualProc);
 
534
  }
 
535
}
 
536
 
 
537
static void ProcessSingleRecord (
 
538
  CharPtr directory,
 
539
  CharPtr base,
 
540
  CharPtr suffix,
 
541
  FastaFlagPtr ffp
 
542
)
 
543
 
 
544
{
 
545
  AsnIoPtr       aip;
 
546
  BioseqPtr      bsp;
 
547
  ValNodePtr     bsplist;
 
548
  BioseqSetPtr   bssp;
 
549
  Pointer        dataptr = NULL;
 
550
  Uint2          datatype, entityID = 0;
 
551
  Char           file [FILENAME_MAX], path [PATH_MAX];
 
552
  StreamFlgType  flags = 0;
 
553
  FILE           *fp, *ofp = NULL;
 
554
  SeqEntryPtr    sep;
 
555
 
 
556
  if (ffp == NULL) return;
 
557
 
 
558
  if (base == NULL) {
 
559
    base = "";
 
560
  }
 
561
  if (suffix == NULL) {
 
562
    suffix = "";
 
563
  }
 
564
  StringNCpy_0 (path, directory, sizeof (path));
 
565
  sprintf (file, "%s%s", base, suffix);
 
566
  FileBuildPath (path, NULL, file);
 
567
 
 
568
  if (StringHasNoText (path)) return;
 
569
 
 
570
  if (ffp->type == 1) {
 
571
    fp = FileOpen (path, "r");
 
572
    if (fp == NULL) {
 
573
      Message (MSG_POSTERR, "Failed to open '%s'", path);
 
574
      return;
 
575
    }
 
576
 
 
577
    dataptr = ReadAsnFastaOrFlatFile (fp, &datatype, NULL, FALSE, FALSE, FALSE, FALSE);
 
578
 
 
579
    FileClose (fp);
 
580
 
 
581
    entityID = ObjMgrRegister (datatype, dataptr);
 
582
 
 
583
  } else if (ffp->type >= 2 && ffp->type <= 5) {
 
584
    aip = AsnIoOpen (path, ffp->binary? "rb" : "r");
 
585
    if (aip == NULL) {
 
586
      Message (MSG_POSTERR, "AsnIoOpen failed for input file '%s'", path);
 
587
      return;
 
588
    }
 
589
 
 
590
    switch (ffp->type) {
 
591
      case 2 :
 
592
        dataptr = (Pointer) SeqEntryAsnRead (aip, NULL);
 
593
        datatype = OBJ_SEQENTRY;
 
594
        break;
 
595
      case 3 :
 
596
        dataptr = (Pointer) BioseqAsnRead (aip, NULL);
 
597
        datatype = OBJ_BIOSEQ;
 
598
        break;
 
599
      case 4 :
 
600
        dataptr = (Pointer) BioseqSetAsnRead (aip, NULL);
 
601
        datatype = OBJ_BIOSEQSET;
 
602
        break;
 
603
      case 5 :
 
604
        dataptr = (Pointer) SeqSubmitAsnRead (aip, NULL);
 
605
        datatype = OBJ_SEQSUB;
 
606
        break;
 
607
      default :
 
608
        break;
 
609
    }
 
610
 
 
611
    AsnIoClose (aip);
 
612
 
 
613
    entityID = ObjMgrRegister (datatype, dataptr);
 
614
 
 
615
  } else {
 
616
    Message (MSG_POSTERR, "Input format type '%d' unrecognized", (int) ffp->type);
 
617
    return;
 
618
  }
 
619
 
 
620
  if (entityID < 1 || dataptr == NULL) {
 
621
    Message (MSG_POSTERR, "Data read failed for input file '%s'", path);
 
622
    return;
 
623
  }
 
624
 
 
625
  if (datatype == OBJ_SEQSUB || datatype == OBJ_SEQENTRY ||
 
626
        datatype == OBJ_BIOSEQ || datatype == OBJ_BIOSEQSET) {
 
627
 
 
628
    sep = GetTopSeqEntryForEntityID (entityID);
 
629
 
 
630
    if (sep == NULL) {
 
631
      sep = SeqEntryNew ();
 
632
      if (sep != NULL) {
 
633
        if (datatype == OBJ_BIOSEQ) {
 
634
          bsp = (BioseqPtr) dataptr;
 
635
          sep->choice = 1;
 
636
          sep->data.ptrvalue = bsp;
 
637
          SeqMgrSeqEntry (SM_BIOSEQ, (Pointer) bsp, sep);
 
638
        } else if (datatype == OBJ_BIOSEQSET) {
 
639
          bssp = (BioseqSetPtr) dataptr;
 
640
          sep->choice = 2;
 
641
          sep->data.ptrvalue = bssp;
 
642
          SeqMgrSeqEntry (SM_BIOSEQSET, (Pointer) bssp, sep);
 
643
        } else {
 
644
          sep = SeqEntryFree (sep);
 
645
        }
 
646
      }
 
647
      sep = GetTopSeqEntryForEntityID (entityID);
 
648
    }
 
649
 
 
650
    if (sep != NULL) {
 
651
      if (ffp->expand_gaps) {
 
652
        flags = STREAM_EXPAND_GAPS;
 
653
      }
 
654
 
 
655
      bsplist = NULL;
 
656
      if (ffp->lock) {
 
657
        bsplist = DoLockFarComponents (sep, ffp);
 
658
        if (bsplist != NULL && ffp->fr != NULL) {
 
659
          CacheFarComponents (ffp, bsplist);
 
660
        }
 
661
      }
 
662
 
 
663
      if (ffp->nt != NULL) {
 
664
        if (SeqEntryFastaStream (sep, ffp->nt, flags, ffp->linelen, 0, 0,
 
665
                                 TRUE, FALSE, ffp->master_style) < 0) {
 
666
          ffp->failed = TRUE;
 
667
        }
 
668
      }
 
669
      if (ffp->aa != NULL) {
 
670
        if (SeqEntryFastaStream (sep, ffp->aa, flags, ffp->linelen, 0, 0,
 
671
                                 FALSE, TRUE, ffp->master_style) < 0) {
 
672
          ffp->failed = TRUE;
 
673
        }
 
674
      }
 
675
      if (ffp->ql != NULL) {
 
676
        VisitBioseqsInSep (sep, (Pointer) ffp, PrintQualScores);
 
677
      }
 
678
 
 
679
      bsplist = UnlockFarComponents (bsplist);
 
680
 
 
681
    }
 
682
  } else {
 
683
    Message (MSG_POSTERR, "Datatype %d not recognized", (int) datatype);
 
684
  }
 
685
 
 
686
  ObjMgrFree (datatype, dataptr);
 
687
}
 
688
 
 
689
static void ProcessMultipleRecord (
 
690
  CharPtr directory,
 
691
  CharPtr base,
 
692
  CharPtr suffix,
 
693
  FastaFlagPtr ffp
 
694
)
 
695
 
 
696
{
 
697
  AsnIoPtr       aip;
 
698
  AsnModulePtr   amp;
 
699
  AsnTypePtr     atp, atp_bss, atp_desc, atp_se;
 
700
  BioseqPtr      bsp;
 
701
  ValNodePtr     bsplist;
 
702
  Char           buf [64], cmmd [256], file [FILENAME_MAX], path [PATH_MAX], longest [64];
 
703
  Char           path1 [PATH_MAX], path2 [PATH_MAX], path3 [PATH_MAX];
 
704
  StreamFlgType  flags = 0;
 
705
  FILE           *fp, *tfp;
 
706
  Int4           numrecords = 0;
 
707
  SeqEntryPtr    fsep, sep;
 
708
  ObjMgrPtr      omp;
 
709
  time_t         starttime, stoptime, worsttime;
 
710
#ifdef OS_UNIX
 
711
  CharPtr        gzcatprog;
 
712
  int            ret;
 
713
  Boolean        usedPopen = FALSE;
 
714
#endif
 
715
 
 
716
  if (ffp == NULL) return;
 
717
 
 
718
  if (base == NULL) {
 
719
    base = "";
 
720
  }
 
721
  if (suffix == NULL) {
 
722
    suffix = "";
 
723
  }
 
724
  StringNCpy_0 (path, directory, sizeof (path));
 
725
  sprintf (file, "%s%s", base, suffix);
 
726
  FileBuildPath (path, NULL, file);
 
727
 
 
728
  if (StringHasNoText (path)) return;
 
729
 
 
730
#ifndef OS_UNIX
 
731
  if (ffp->compressed) {
 
732
    Message (MSG_POSTERR, "Can only decompress on-the-fly on UNIX machines");
 
733
    return;
 
734
  }
 
735
#endif
 
736
 
 
737
  amp = AsnAllModPtr ();
 
738
  if (amp == NULL) {
 
739
    Message (MSG_POSTERR, "Unable to load AsnAllModPtr");
 
740
    return;
 
741
  }
 
742
 
 
743
  atp_bss = AsnFind ("Bioseq-set");
 
744
  if (atp_bss == NULL) {
 
745
    Message (MSG_POSTERR, "Unable to find ASN.1 type Bioseq-set");
 
746
    return;
 
747
  }
 
748
 
 
749
  atp_desc = AsnFind ("Bioseq-set.descr");
 
750
  if (atp_desc == NULL) {
 
751
    Message (MSG_POSTERR, "Unable to find ASN.1 type Bioseq-set.descr");
 
752
    return;
 
753
  }
 
754
 
 
755
  atp_se = AsnFind ("Bioseq-set.seq-set.E");
 
756
  if (atp_se == NULL) {
 
757
    Message (MSG_POSTERR, "Unable to find ASN.1 type Bioseq-set.seq-set.E");
 
758
    return;
 
759
  }
 
760
 
 
761
#ifdef OS_UNIX
 
762
  if (ffp->compressed) {
 
763
    gzcatprog = getenv ("NCBI_UNCOMPRESS-BINARY");
 
764
    if (gzcatprog != NULL) {
 
765
      sprintf (cmmd, "%s %s", gzcatprog, path);
 
766
    } else {
 
767
      ret = system ("gzcat -h >/dev/null 2>&1");
 
768
      if (ret == 0) {
 
769
        sprintf (cmmd, "gzcat %s", path);
 
770
      } else if (ret == -1) {
 
771
        Message (MSG_POSTERR, "Unable to fork or exec gzcat in ScanBioseqSetRelease");
 
772
        return;
 
773
      } else {
 
774
        ret = system ("zcat -h >/dev/null 2>&1");
 
775
        if (ret == 0) {
 
776
          sprintf (cmmd, "zcat %s", path);
 
777
        } else if (ret == -1) {
 
778
          Message (MSG_POSTERR, "Unable to fork or exec zcat in ScanBioseqSetRelease");
 
779
          return;
 
780
        } else {
 
781
          Message (MSG_POSTERR, "Unable to find zcat or gzcat in ScanBioseqSetRelease - please edit your PATH environment variable");
 
782
          return;
 
783
        }
 
784
      }
 
785
    }
 
786
    fp = popen (cmmd, /* ffp->binary? "rb" : */ "r");
 
787
    usedPopen = TRUE;
 
788
  } else {
 
789
    fp = FileOpen (path, ffp->binary? "rb" : "r");
 
790
  }
 
791
#else
 
792
  fp = FileOpen (path, ffp->binary? "rb" : "r");
 
793
#endif
 
794
  if (fp == NULL) {
 
795
    Message (MSG_POSTERR, "FileOpen failed for input file '%s'", path);
 
796
    return;
 
797
  }
 
798
 
 
799
  aip = AsnIoNew (ffp->binary? ASNIO_BIN_IN : ASNIO_TEXT_IN, fp, NULL, NULL, NULL);
 
800
  if (aip == NULL) {
 
801
    Message (MSG_ERROR, "AsnIoNew failed for input file '%s'", path);
 
802
    return;
 
803
  }
 
804
 
 
805
  TmpNam (path1);
 
806
  tfp = FileOpen (path1, "w");
 
807
  fprintf (tfp, "\n");
 
808
  FileClose (tfp);
 
809
 
 
810
  TmpNam (path2);
 
811
  tfp = FileOpen (path2, "w");
 
812
  fprintf (tfp, "\n");
 
813
  FileClose (tfp);
 
814
 
 
815
  TmpNam (path3);
 
816
  tfp = FileOpen (path3, "w");
 
817
  fprintf (tfp, "\n");
 
818
  FileClose (tfp);
 
819
 
 
820
  atp = atp_bss;
 
821
 
 
822
  if (ffp->expand_gaps) {
 
823
    flags = STREAM_EXPAND_GAPS;
 
824
  }
 
825
 
 
826
  longest [0] = '\0';
 
827
  worsttime = 0;
 
828
 
 
829
  while ((atp = AsnReadId (aip, amp, atp)) != NULL) {
 
830
    if (atp == atp_se) {
 
831
      sep = SeqEntryAsnRead (aip, atp);
 
832
 
 
833
      starttime = GetSecs ();
 
834
      buf [0] = '\0';
 
835
 
 
836
      if (ffp->logfp != NULL) {
 
837
        fsep = FindNthBioseq (sep, 1);
 
838
        if (fsep != NULL && fsep->choice == 1) {
 
839
          bsp = (BioseqPtr) fsep->data.ptrvalue;
 
840
          if (bsp != NULL) {
 
841
            SeqIdWrite (bsp->id, buf, PRINTID_FASTA_LONG, sizeof (buf));
 
842
            fprintf (ffp->logfp, "%s\n", buf);
 
843
            fflush (ffp->logfp);
 
844
          }
 
845
        }
 
846
      }
 
847
 
 
848
      bsplist = NULL;
 
849
      if (ffp->lock) {
 
850
        bsplist = DoLockFarComponents (sep, ffp);
 
851
        if (bsplist != NULL && ffp->fr != NULL) {
 
852
          CacheFarComponents (ffp, bsplist);
 
853
        }
 
854
      }
 
855
 
 
856
      if (ffp->nt != NULL) {
 
857
        SeqEntryFastaStream (sep, ffp->nt, flags, ffp->linelen, 0, 0, TRUE, FALSE, ffp->master_style);
 
858
      }
 
859
      if (ffp->aa != NULL) {
 
860
        SeqEntryFastaStream (sep, ffp->aa, flags, ffp->linelen, 0, 0, FALSE, TRUE, ffp->master_style);
 
861
      }
 
862
      if (ffp->ql != NULL) {
 
863
        VisitBioseqsInSep (sep, (Pointer) ffp, PrintQualScores);
 
864
      }
 
865
 
 
866
      bsplist = UnlockFarComponents (bsplist);
 
867
 
 
868
      stoptime = GetSecs ();
 
869
      if (stoptime - starttime > worsttime && StringDoesHaveText (buf)) {
 
870
        worsttime = stoptime - starttime;
 
871
        StringCpy (longest, buf);
 
872
      }
 
873
      numrecords++;
 
874
 
 
875
      SeqEntryFree (sep);
 
876
      omp = ObjMgrGet ();
 
877
      ObjMgrReapOne (omp);
 
878
      ObjMgrFreeCache (0);
 
879
    } else {
 
880
      AsnReadVal (aip, atp, NULL);
 
881
    }
 
882
  }
 
883
 
 
884
  AsnIoFree (aip, FALSE);
 
885
 
 
886
#ifdef OS_UNIX
 
887
  if (usedPopen) {
 
888
    pclose (fp);
 
889
  } else {
 
890
    FileClose (fp);
 
891
  }
 
892
#else
 
893
  FileClose (fp);
 
894
#endif
 
895
 
 
896
  if (ffp->logfp != NULL && (! StringHasNoText (longest))) {
 
897
    fprintf (ffp->logfp, "Longest processing time %ld seconds on %s\n",
 
898
             (long) worsttime, longest);
 
899
    fprintf (ffp->logfp, "Total number of records %ld\n", (long) numrecords);
 
900
    fflush (ffp->logfp);
 
901
  }
 
902
 
 
903
  sprintf (cmmd, "rm %s; rm %s; rm %s", path1, path2, path3);
 
904
  system (cmmd);
 
905
}
 
906
 
 
907
static void ProcessOneRecord (
 
908
  CharPtr directory,
 
909
  CharPtr base,
 
910
  CharPtr suffix,
 
911
  FastaFlagPtr ffp
 
912
)
 
913
 
 
914
{
 
915
  if (ffp == NULL) return;
 
916
 
 
917
  if (ffp->batch) {
 
918
    ProcessMultipleRecord (directory, base, suffix, ffp);
 
919
  } else {
 
920
    ProcessSingleRecord (directory, base, suffix, ffp);
 
921
  }
 
922
}
 
923
 
 
924
static void ProcessOneSeqEntry (
 
925
  SeqEntryPtr sep,
 
926
  FastaFlagPtr ffp
 
927
)
 
928
 
 
929
 
 
930
{
 
931
  ValNodePtr     bsplist;
 
932
  StreamFlgType  flags = 0;
 
933
 
 
934
  if (sep == NULL || ffp == NULL) return;
 
935
 
 
936
  if (ffp->expand_gaps) {
 
937
    flags = STREAM_EXPAND_GAPS;
 
938
  }
 
939
 
 
940
  bsplist = NULL;
 
941
  if (ffp->lock) {
 
942
    bsplist = DoLockFarComponents (sep, ffp);
 
943
    if (bsplist != NULL && ffp->fr != NULL) {
 
944
      CacheFarComponents (ffp, bsplist);
 
945
    }
 
946
  }
 
947
 
 
948
  if (ffp->nt != NULL) {
 
949
    if (SeqEntryFastaStream (sep, ffp->nt, flags, ffp->linelen, 0, 0,
 
950
                             TRUE, FALSE, ffp->master_style) < 0) {
 
951
      ffp->failed = TRUE;
 
952
    }
 
953
  }
 
954
  if (ffp->aa != NULL) {
 
955
    if (SeqEntryFastaStream (sep, ffp->aa, flags, ffp->linelen, 0, 0,
 
956
                             FALSE, TRUE, ffp->master_style) < 0) {
 
957
      ffp->failed = TRUE;
 
958
    }
 
959
  }
 
960
  if (ffp->ql != NULL) {
 
961
    VisitBioseqsInSep (sep, (Pointer) ffp, PrintQualScores);
 
962
  }
 
963
 
 
964
  bsplist = UnlockFarComponents (bsplist);
 
965
}
 
966
 
 
967
static void FileRecurse (
 
968
  CharPtr directory,
 
969
  CharPtr subdir,
 
970
  CharPtr suffix,
 
971
  Boolean dorecurse,
 
972
  FastaFlagPtr ffp
 
973
)
 
974
 
 
975
{
 
976
  Char        path [PATH_MAX];
 
977
  CharPtr     ptr, str;
 
978
  ValNodePtr  head, vnp;
 
979
 
 
980
  /* get list of all files in source directory */
 
981
 
 
982
  head = DirCatalog (directory);
 
983
 
 
984
  for (vnp = head; vnp != NULL; vnp = vnp->next) {
 
985
    if (vnp->choice == 0) {
 
986
      if (StringHasNoText (subdir) || StringStr (directory, subdir) != NULL) {
 
987
        str = (CharPtr) vnp->data.ptrvalue;
 
988
        if (! StringHasNoText (str)) {
 
989
 
 
990
          /* does filename have desired substring? */
 
991
 
 
992
          ptr = StringStr (str, suffix);
 
993
          if (ptr != NULL) {
 
994
            *ptr = '\0';
 
995
 
 
996
            /* process file that has desired suffix (usually .ent) */
 
997
 
 
998
            ProcessOneRecord (directory, str, suffix, ffp);
 
999
          }
 
1000
        }
 
1001
      }
 
1002
    } else if (vnp->choice == 1 && dorecurse) {
 
1003
 
 
1004
      /* recurse into subdirectory */
 
1005
 
 
1006
      StringNCpy_0 (path, directory, sizeof (path));
 
1007
      str = (CharPtr) vnp->data.ptrvalue;
 
1008
      FileBuildPath (path, str, NULL);
 
1009
 
 
1010
      FileRecurse (path, str, suffix, dorecurse, ffp);
 
1011
    }
 
1012
  }
 
1013
 
 
1014
  /* clean up file list */
 
1015
 
 
1016
  ValNodeFreeData (head);
 
1017
}
 
1018
 
 
1019
static SeqEntryPtr SeqEntryFromAccnOrGi (
 
1020
  CharPtr accn
 
1021
)
 
1022
 
 
1023
{
 
1024
  Boolean      alldigits;
 
1025
  Char         ch;
 
1026
  CharPtr      ptr;
 
1027
  SeqEntryPtr  sep = NULL;
 
1028
  SeqIdPtr     sip;
 
1029
  Int4         uid = 0;
 
1030
  long int     val;
 
1031
 
 
1032
  if (StringHasNoText (accn)) return NULL;
 
1033
 
 
1034
  TrimSpacesAroundString (accn);
 
1035
 
 
1036
  alldigits = TRUE;
 
1037
  ptr = accn;
 
1038
  ch = *ptr;
 
1039
  while (ch != '\0') {
 
1040
    if (! IS_DIGIT (ch)) {
 
1041
      alldigits = FALSE;
 
1042
    }
 
1043
    ptr++;
 
1044
    ch = *ptr;
 
1045
  }
 
1046
 
 
1047
  if (alldigits) {
 
1048
    if (sscanf (accn, "%ld", &val) == 1) {
 
1049
      uid = (Int4) val;
 
1050
    }
 
1051
  } else {
 
1052
    sip = SeqIdFromAccessionDotVersion (accn);
 
1053
    if (sip != NULL) {
 
1054
      uid = GetGIForSeqId (sip);
 
1055
      SeqIdFree (sip);
 
1056
    }
 
1057
  }
 
1058
 
 
1059
  if (uid > 0) {
 
1060
    sep = PubSeqSynchronousQuery (uid, 0, -1);
 
1061
  }
 
1062
 
 
1063
  return sep;
 
1064
}
 
1065
 
 
1066
/* Args structure contains command-line arguments */
 
1067
 
 
1068
#define p_argInputPath     0
 
1069
#define i_argInputFile     1
 
1070
#define o_argNtOutFile     2
 
1071
#define v_argAaOutFile     3
 
1072
#define q_argQlOutFile     4
 
1073
#define x_argSuffix        5
 
1074
#define u_argRecurse       6
 
1075
#define m_argMaster        7
 
1076
#define g_argExpandGaps    8
 
1077
#define s_argGenomicQual   9
 
1078
#define z_argZeroQualGap  10
 
1079
#define a_argType         11
 
1080
#define b_argBinary       12
 
1081
#define c_argCompressed   13
 
1082
#define r_argRemote       14
 
1083
#define f_argFastaIdx     15
 
1084
#define d_argBlastDB      16
 
1085
#define k_argLocalFetch   17
 
1086
#define l_argLockFar      18
 
1087
#define h_argFarOutFile   19
 
1088
#define e_argLineLength   20
 
1089
#define T_argThreads      21
 
1090
#define L_argLogFile      22
 
1091
#define A_argAccession    23
 
1092
 
 
1093
Args myargs [] = {
 
1094
  {"Path to ASN.1 Files", NULL, NULL, NULL,
 
1095
    TRUE, 'p', ARG_STRING, 0.0, 0, NULL},
 
1096
  {"Single Input File", "stdin", NULL, NULL,
 
1097
    TRUE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
 
1098
  {"Nucleotide Output File Name", NULL, NULL, NULL,
 
1099
    TRUE, 'o', ARG_FILE_OUT, 0.0, 0, NULL},
 
1100
  {"Protein Output File Name", NULL, NULL, NULL,
 
1101
    TRUE, 'v', ARG_FILE_OUT, 0.0, 0, NULL},
 
1102
  {"Quality Score Output File Name", NULL, NULL, NULL,
 
1103
    TRUE, 'q', ARG_FILE_OUT, 0.0, 0, NULL},
 
1104
  {"File Selection Substring", ".ent", NULL, NULL,
 
1105
    TRUE, 'x', ARG_STRING, 0.0, 0, NULL},
 
1106
  {"Recurse", "F", NULL, NULL,
 
1107
    TRUE, 'u', ARG_BOOLEAN, 0.0, 0, NULL},
 
1108
  {"Master Style for Near Segmented Sequences", "F", NULL, NULL,
 
1109
    TRUE, 'm', ARG_BOOLEAN, 0.0, 0, NULL},
 
1110
  {"Expand Delta Gaps into Ns", "F", NULL, NULL,
 
1111
    TRUE, 'g', ARG_BOOLEAN, 0.0, 0, NULL},
 
1112
  {"Far Genomic Contig for Quality Scores", "F", NULL, NULL,
 
1113
    TRUE, 's', ARG_BOOLEAN, 0.0, 0, NULL},
 
1114
  {"Print Quality Score Gap as -1", "F", NULL, NULL,
 
1115
    TRUE, 'z', ARG_BOOLEAN, 0.0, 0, NULL},
 
1116
  {"ASN.1 Type (a Any, e Seq-entry, b Bioseq, s Bioseq-set, m Seq-submit, t Batch Processing)", "a", NULL, NULL,
 
1117
    TRUE, 'a', ARG_STRING, 0.0, 0, NULL},
 
1118
  {"Bioseq-set is Binary", "F", NULL, NULL,
 
1119
    TRUE, 'b', ARG_BOOLEAN, 0.0, 0, NULL},
 
1120
  {"Bioseq-set is Compressed", "F", NULL, NULL,
 
1121
    TRUE, 'c', ARG_BOOLEAN, 0.0, 0, NULL},
 
1122
  {"Remote Fetching from ID", "F", NULL, NULL,
 
1123
    TRUE, 'r', ARG_BOOLEAN, 0.0, 0, NULL},
 
1124
  {"Path to Indexed FASTA Data", NULL, NULL, NULL,
 
1125
    TRUE, 'f', ARG_STRING, 0.0, 0, NULL},
 
1126
  {"Path to ReadDB Database", NULL, NULL, NULL,
 
1127
    TRUE, 'd', ARG_STRING, 0.0, 0, NULL},
 
1128
  {"Local Fetching", "F", NULL, NULL,
 
1129
    TRUE, 'k', ARG_BOOLEAN, 0.0, 0, NULL},
 
1130
  {"Lock Components in Advance", "F", NULL, NULL,
 
1131
    TRUE, 'l', ARG_BOOLEAN, 0.0, 0, NULL},
 
1132
  {"Far Component Cache Output File Name", NULL, NULL, NULL,
 
1133
    TRUE, 'h', ARG_FILE_OUT, 0.0, 0, NULL},
 
1134
  {"Line Length", "70", "10", "120",
 
1135
    TRUE, 'e', ARG_INT, 0.0, 0, NULL},
 
1136
  {"Use Threads", "F", NULL, NULL,
 
1137
    TRUE, 'T', ARG_BOOLEAN, 0.0, 0, NULL},
 
1138
  {"Log File", NULL, NULL, NULL,
 
1139
    TRUE, 'L', ARG_FILE_OUT, 0.0, 0, NULL},
 
1140
  {"Accession to Fetch", NULL, NULL, NULL,
 
1141
    TRUE, 'A', ARG_STRING, 0.0, 0, NULL},
 
1142
};
 
1143
 
 
1144
Int2 Main (void)
 
1145
 
 
1146
{
 
1147
  Char           app [64], sfx [32];
 
1148
  CharPtr        accn, base, blastdb, directory, fastaidx, ntout,
 
1149
                 aaout, qlout, frout, logfile, ptr, str, suffix;
 
1150
  Boolean        batch, binary, blast, compressed, dorecurse,
 
1151
                 expandgaps, fargenomicqual, fasta, local, lock,
 
1152
                 masterstyle, qualgapzero, remote, usethreads;
 
1153
  FastaFlagData  ffd;
 
1154
  Int2           linelen, type = 0;
 
1155
  time_t         run_time, start_time, stop_time;
 
1156
  SeqEntryPtr    sep;
 
1157
 
 
1158
  /* standard setup */
 
1159
 
 
1160
  ErrSetFatalLevel (SEV_MAX);
 
1161
  ErrClearOptFlags (EO_SHOW_USERSTR);
 
1162
  ErrSetLogfile ("stderr", ELOG_APPEND);
 
1163
  UseLocalAsnloadDataAndErrMsg ();
 
1164
  ErrPathReset ();
 
1165
 
 
1166
  if (! AllObjLoad ()) {
 
1167
    Message (MSG_FATAL, "AllObjLoad failed");
 
1168
    return 1;
 
1169
  }
 
1170
  if (! SubmitAsnLoad ()) {
 
1171
    Message (MSG_FATAL, "SubmitAsnLoad failed");
 
1172
    return 1;
 
1173
  }
 
1174
  if (! FeatDefSetLoad ()) {
 
1175
    Message (MSG_FATAL, "FeatDefSetLoad failed");
 
1176
    return 1;
 
1177
  }
 
1178
  if (! SeqCodeSetLoad ()) {
 
1179
    Message (MSG_FATAL, "SeqCodeSetLoad failed");
 
1180
    return 1;
 
1181
  }
 
1182
  if (! GeneticCodeTableLoad ()) {
 
1183
    Message (MSG_FATAL, "GeneticCodeTableLoad failed");
 
1184
    return 1;
 
1185
  }
 
1186
 
 
1187
  /* process command line arguments */
 
1188
 
 
1189
  sprintf (app, "asn2fsa %s", ASN2FSA_APPLICATION);
 
1190
  if (! GetArgs (app, sizeof (myargs) / sizeof (Args), myargs)) {
 
1191
    return 0;
 
1192
  }
 
1193
 
 
1194
  /* additional setup modifications */
 
1195
 
 
1196
  MemSet ((Pointer) &ffd, 0, sizeof (FastaFlagData));
 
1197
 
 
1198
  directory = (CharPtr) myargs [p_argInputPath].strvalue;
 
1199
  suffix = (CharPtr) myargs [x_argSuffix].strvalue;
 
1200
  base = (CharPtr) myargs [i_argInputFile].strvalue;
 
1201
  accn = (CharPtr) myargs [A_argAccession].strvalue;
 
1202
  dorecurse = (Boolean) myargs [u_argRecurse].intvalue;
 
1203
  remote = (Boolean ) myargs [r_argRemote].intvalue;
 
1204
  fastaidx = (CharPtr) myargs [f_argFastaIdx].strvalue;
 
1205
  fasta = (Boolean) StringDoesHaveText (fastaidx);
 
1206
  blastdb = (CharPtr) myargs [d_argBlastDB].strvalue;
 
1207
  blast = (Boolean) StringDoesHaveText (blastdb);
 
1208
  local = (Boolean) myargs [k_argLocalFetch].intvalue;
 
1209
  lock = (Boolean) myargs [l_argLockFar].intvalue;
 
1210
  linelen = (Int2) myargs [e_argLineLength].intvalue;
 
1211
  usethreads = (Boolean) myargs [T_argThreads].intvalue;
 
1212
 
 
1213
  expandgaps = (Boolean) myargs [g_argExpandGaps].intvalue;
 
1214
  masterstyle = (Boolean) myargs [m_argMaster].intvalue;
 
1215
  fargenomicqual = (Boolean) myargs [s_argGenomicQual].intvalue;
 
1216
  qualgapzero = (Boolean) myargs [z_argZeroQualGap].intvalue;
 
1217
  batch = FALSE;
 
1218
  binary = (Boolean) myargs [b_argBinary].intvalue;
 
1219
  compressed = (Boolean) myargs [c_argCompressed].intvalue;
 
1220
 
 
1221
  str = myargs [a_argType].strvalue;
 
1222
  if (StringICmp (str, "a") == 0) {
 
1223
    type = 1;
 
1224
  } else if (StringICmp (str, "e") == 0) {
 
1225
    type = 2;
 
1226
  } else if (StringICmp (str, "b") == 0) {
 
1227
    type = 3;
 
1228
  } else if (StringICmp (str, "s") == 0) {
 
1229
    type = 4;
 
1230
  } else if (StringICmp (str, "m") == 0) {
 
1231
    type = 5;
 
1232
  } else if (StringICmp (str, "t") == 0) {
 
1233
    type = 1;
 
1234
    batch = TRUE;
 
1235
  } else {
 
1236
    type = 1;
 
1237
  }
 
1238
 
 
1239
  if ((binary || compressed) && (! batch)) {
 
1240
    if (type == 1) {
 
1241
      Message (MSG_FATAL, "-b or -c cannot be used without -t or -a");
 
1242
      return 1;
 
1243
    }
 
1244
  }
 
1245
 
 
1246
  if (StringHasNoText (directory) && StringHasNoText (base)) {
 
1247
    Message (MSG_FATAL, "Input path or input file must be specified");
 
1248
    return 1;
 
1249
  }
 
1250
 
 
1251
  ntout = (CharPtr) myargs [o_argNtOutFile].strvalue;
 
1252
  aaout = (CharPtr) myargs [v_argAaOutFile].strvalue;
 
1253
  qlout = (CharPtr) myargs [q_argQlOutFile].strvalue;
 
1254
  frout = (CharPtr) myargs [h_argFarOutFile].strvalue;
 
1255
 
 
1256
  logfile = (CharPtr) myargs [L_argLogFile].strvalue;
 
1257
 
 
1258
  /* default to stdout for nucleotide output if nothing specified */
 
1259
 
 
1260
  if (StringHasNoText (ntout) &&
 
1261
      StringHasNoText (aaout) &&
 
1262
      StringHasNoText (qlout)) {
 
1263
    ntout = "stdout";
 
1264
  }
 
1265
 
 
1266
  start_time = GetSecs ();
 
1267
 
 
1268
  /* populate parameter structure */
 
1269
 
 
1270
  ffd.expand_gaps = expandgaps;
 
1271
  ffd.master_style = masterstyle;
 
1272
  ffd.far_genomic_qual = fargenomicqual;
 
1273
  ffd.qual_gap_is_zero = (Boolean) (! qualgapzero);
 
1274
  ffd.batch = batch;
 
1275
  ffd.binary = binary;
 
1276
  ffd.compressed = compressed;
 
1277
  ffd.lock = lock;
 
1278
  ffd.useThreads = usethreads;
 
1279
  ffd.type = type;
 
1280
  ffd.linelen = linelen;
 
1281
  ffd.failed = FALSE;
 
1282
  ffd.nt = NULL;
 
1283
  ffd.aa = NULL;
 
1284
  ffd.ql = NULL;
 
1285
  ffd.fr = NULL;
 
1286
  ffd.logfp = NULL;
 
1287
 
 
1288
  if (! StringHasNoText (ntout)) {
 
1289
    ffd.nt = FileOpen (ntout, "w");
 
1290
    if (ffd.nt == NULL) {
 
1291
      Message (MSG_FATAL, "Unable to open nucleotide output file");
 
1292
      return 1;
 
1293
    }
 
1294
  }
 
1295
 
 
1296
  if (! StringHasNoText (aaout)) {
 
1297
    ffd.aa = FileOpen (aaout, "w");
 
1298
    if (ffd.aa == NULL) {
 
1299
      Message (MSG_FATAL, "Unable to open protein output file");
 
1300
      return 1;
 
1301
    }
 
1302
  }
 
1303
 
 
1304
  if (! StringHasNoText (qlout)) {
 
1305
    ffd.ql = FileOpen (qlout, "w");
 
1306
    if (ffd.ql == NULL) {
 
1307
      Message (MSG_FATAL, "Unable to open quality score output file");
 
1308
      return 1;
 
1309
    }
 
1310
  }
 
1311
 
 
1312
  if (! StringHasNoText (frout)) {
 
1313
    ffd.fr = FileOpen (frout, "w");
 
1314
    if (ffd.fr == NULL) {
 
1315
      Message (MSG_FATAL, "Unable to open far component cache output file");
 
1316
      return 1;
 
1317
    }
 
1318
    ffd.lock = TRUE;
 
1319
  }
 
1320
 
 
1321
  if (! StringHasNoText (logfile)) {
 
1322
    ffd.logfp = FileOpen (logfile, "w");
 
1323
    if (ffd.logfp == NULL) {
 
1324
      Message (MSG_FATAL, "Unable to open log file");
 
1325
      return 1;
 
1326
    }
 
1327
  }
 
1328
 
 
1329
  /* register fetch functions */
 
1330
 
 
1331
  if (remote) {
 
1332
#ifdef INTERNAL_NCBI_ASN2FSA
 
1333
    if (! PUBSEQBioseqFetchEnable ("asn2fsa", FALSE)) {
 
1334
      Message (MSG_POSTERR, "PUBSEQBioseqFetchEnable failed");
 
1335
      return 1;
 
1336
    }
 
1337
    ffd.usePUBSEQ = TRUE;
 
1338
    ffd.useThreads = FALSE;
 
1339
#else
 
1340
    PubSeqFetchEnable ();
 
1341
#endif
 
1342
  }
 
1343
 
 
1344
  if (blast) {
 
1345
    ptr = StringRChr (blastdb, DIRDELIMCHR);
 
1346
    if (ptr != NULL) {
 
1347
      *ptr = '\0';
 
1348
      ptr++;
 
1349
      TransientSetAppParam ("NCBI", "BLAST", "BLASTDB", blastdb);
 
1350
      if (StringDoesHaveText (ptr)) {
 
1351
        ReadDBBioseqFetchEnable ("asn2fsa", ptr, TRUE, FALSE);
 
1352
        ffd.blastdbname = ptr;
 
1353
        ffd.useBLAST = TRUE;
 
1354
      } else {
 
1355
        ReadDBBioseqFetchEnable ("asn2fsa", "nr", TRUE, FALSE);
 
1356
        ffd.blastdbname = "nr";
 
1357
        ffd.useBLAST = TRUE;
 
1358
      }
 
1359
    } else {
 
1360
      ReadDBBioseqFetchEnable ("asn2fsa", blastdb, TRUE, FALSE);
 
1361
      ffd.blastdbname = blastdb;
 
1362
      ffd.useBLAST = TRUE;
 
1363
    }
 
1364
  }
 
1365
 
 
1366
  if (fasta) {
 
1367
    AltIndexedFastaLibFetchEnable (fastaidx);
 
1368
  }
 
1369
 
 
1370
  if (local) {
 
1371
    LocalSeqFetchInit (FALSE);
 
1372
  }
 
1373
 
 
1374
  /* recurse through all files within source directory or subdirectories */
 
1375
 
 
1376
  if (StringDoesHaveText (accn)) {
 
1377
 
 
1378
    if (remote) {
 
1379
      sep = SeqEntryFromAccnOrGi (accn);
 
1380
      if (sep != NULL) {
 
1381
        ProcessOneSeqEntry (sep, &ffd);
 
1382
        SeqEntryFree (sep);
 
1383
      }
 
1384
    }
 
1385
 
 
1386
  } else if (StringDoesHaveText (directory)) {
 
1387
 
 
1388
    FileRecurse (directory, NULL, suffix, dorecurse, &ffd);
 
1389
 
 
1390
  } else if (StringDoesHaveText (base)) {
 
1391
 
 
1392
    ptr = StringRChr (base, '.');
 
1393
    if (ptr != NULL) {
 
1394
      StringNCpy_0 (sfx, ptr, sizeof (sfx));
 
1395
      *ptr = '\0';
 
1396
    }
 
1397
    ProcessOneRecord (directory, base, sfx, &ffd);
 
1398
  }
 
1399
 
 
1400
  if (ffd.nt != NULL) {
 
1401
    FileClose (ffd.nt);
 
1402
  }
 
1403
  if (ffd.aa != NULL) {
 
1404
    FileClose (ffd.aa);
 
1405
  }
 
1406
  if (ffd.ql != NULL) {
 
1407
    FileClose (ffd.ql);
 
1408
  }
 
1409
  if (ffd.fr != NULL) {
 
1410
    FileClose (ffd.fr);
 
1411
    CreateFastaIndex (frout);
 
1412
  }
 
1413
 
 
1414
  stop_time = GetSecs ();
 
1415
  run_time = stop_time - start_time;
 
1416
 
 
1417
  if (ffd.logfp != NULL) {
 
1418
    fprintf (ffd.logfp, "Finished in %ld seconds\n", (long) run_time);
 
1419
    FileClose (ffd.logfp);
 
1420
  }
 
1421
 
 
1422
  /* close fetch functions */
 
1423
 
 
1424
  if (local) {
 
1425
    LocalSeqFetchDisable ();
 
1426
  }
 
1427
 
 
1428
  if (fasta) {
 
1429
    AltIndexedFastaLibFetchDisable ();
 
1430
  }
 
1431
 
 
1432
  if (blast) {
 
1433
    ReadDBBioseqFetchDisable ();
 
1434
  }
 
1435
 
 
1436
  if (remote) {
 
1437
#ifdef INTERNAL_NCBI_ASN2FSA
 
1438
    PUBSEQBioseqFetchDisable ();
 
1439
#else
 
1440
    PubSeqFetchDisable ();
 
1441
#endif
 
1442
  }
 
1443
 
 
1444
  if (ffd.failed) {
 
1445
    return 1;
 
1446
  }
 
1447
 
 
1448
  return 0;
 
1449
}
 
1450