~ubuntu-branches/ubuntu/feisty/ncbi-tools6/feisty

« back to all changes in this revision

Viewing changes to demo/blast_driver.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2004-11-01 20:07:56 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20041101200756-74jnpgwky59fev9v
Tags: 6.1.20041020-1
* New upstream release; debian/* resynched as necessary.
  - Fixes Vibrant invisible text bug!
* Take advantage of menu 2.1.8's support for multiple required packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: blast_driver.c,v 1.46 2004/06/08 17:47:43 dondosha Exp $
 
1
/* $Id: blast_driver.c,v 1.74 2004/10/06 19:12:24 dondosha Exp $
2
2
* ===========================================================================
3
3
*
4
4
*                            PUBLIC DOMAIN NOTICE
32
32
Contents: Main function for running BLAST
33
33
 
34
34
******************************************************************************
35
 
 * $Revision: 1.46 $
 
35
 * $Revision: 1.74 $
36
36
 * */
37
37
 
38
 
static char const rcsid[] = "$Id: blast_driver.c,v 1.46 2004/06/08 17:47:43 dondosha Exp $";
 
38
static char const rcsid[] = "$Id: blast_driver.c,v 1.74 2004/10/06 19:12:24 dondosha Exp $";
39
39
 
40
40
#include <ncbi.h>
41
41
#include <sqnutils.h>
52
52
#include <algo/blast/api/blast_input.h>
53
53
#include <algo/blast/api/blast_format.h>
54
54
#include <algo/blast/api/blast_seqalign.h>
55
 
#include <algo/blast/api/blast_format.h>
56
55
#include <algo/blast/api/seqsrc_readdb.h>
57
 
#include <algo/blast/api/multiseq_src.h>
 
56
#include <algo/blast/api/seqsrc_multiseq.h>
58
57
#include <algo/blast/api/blast_tabular.h>
 
58
#include <algo/blast/api/blast_mtlock.h>
 
59
#include <algo/blast/api/blast_prelim.h>
 
60
#include <algo/blast/api/blast_tback.h>
59
61
 
60
62
#define NUMARG (sizeof(myargs)/sizeof(myargs[0]))
61
63
 
63
65
   ARG_PROGRAM = 0,
64
66
   ARG_DB,
65
67
   ARG_QUERY,
 
68
   ARG_QUERY_LOC,
66
69
   ARG_SUBJECT,
 
70
   ARG_SUBJECT_LOC,
67
71
   ARG_STRAND,
68
72
   ARG_GENCODE,
69
73
   ARG_DBGENCODE,
101
105
   ARG_HTML,
102
106
   ARG_ASNOUT,
103
107
   ARG_OIDRANGE,
104
 
   ARG_TABULAR
 
108
   ARG_TABULAR,
 
109
   ARG_THREADS,
 
110
   ARG_SHOWGI,
 
111
   ARG_ACCESSION
105
112
} BlastArguments;
106
113
 
107
114
static Args myargs[] = {
111
118
     NULL, NULL, NULL, TRUE, 'd', ARG_STRING, 0.0, 0, NULL}, /* ARG_DB */
112
119
   { "Query File",               /* ARG_QUERY */
113
120
     "stdin", NULL, NULL, FALSE, 'i', ARG_FILE_IN, 0.0, 0, NULL},
114
 
   { "Subject File (for two sequences comparison", /* ARG_SUBJECT */
 
121
   { "Query location offsets; format: \"start stop\";\n"
 
122
     "Applies only if query file contains 1 sequence", /* ARG_QUERY_LOC */
 
123
     NULL, NULL, NULL, TRUE, 'I', ARG_STRING, 0.0, 0, NULL},
 
124
   { "Subject File (for sequence sets comparison)", /* ARG_SUBJECT */
115
125
     "stdin", NULL, NULL, FALSE, 'j', ARG_FILE_IN, 0.0, 0, NULL},
 
126
   { "Subject location offsets; format: \"start stop\";\n"/* ARG_SUBJECT_LOC */
 
127
     "Applies only if subject file (-j) contains 1 sequence",
 
128
     NULL, NULL, NULL, TRUE, 'J', ARG_STRING, 0.0, 0, NULL},
116
129
   { "Query strands to search against database: 0 or 3 is both, 1 is top, "
117
130
     "2 is bottom", /* ARG_STRAND */
118
131
     "0", NULL, NULL, FALSE, 'S', ARG_INT, 0.0, 0, NULL},
181
194
   {"Identity percentage cut-off",  /* ARG_PERC_IDENT */
182
195
    "0", NULL, NULL, FALSE, 'P', ARG_FLOAT, 0.0, 0, NULL},
183
196
   { "Longest intron length for uneven gap HSP linking (tblastn only)",
184
 
     "0", NULL, NULL, FALSE, 'I', ARG_INT, 0.0, 0, NULL}, /* ARG_INTRON */
 
197
     "0", NULL, NULL, FALSE, 'z', ARG_INT, 0.0, 0, NULL}, /* ARG_INTRON */
185
198
   { "Number of database sequences to show one-line descriptions for (V)",
186
199
     "500", NULL, NULL, FALSE, 'v', ARG_INT, 0.0, 0, NULL}, /* ARG_DESCRIPTIONS */
187
200
   { "Number of database sequence to show alignments for (B)", /* ARG_ALIGNMENTS */
204
217
     "Format: \"oid1 oid2\"; ',', ':' or ';' can also be used as delimiters\n" 
205
218
     "Full database is searched if range not provided.", /* ARG_OIDRANGE */
206
219
     NULL, NULL, NULL, TRUE, 'R', ARG_STRING, 0.0, 0, NULL},
207
 
   { "Produce on-the-fly tabular output",
208
 
     "0", NULL, NULL, FALSE, 'B', ARG_INT, 0.0, 0, NULL} /* ARG_TABULAR */
 
220
   { "Produce on-the-fly tabular output; 1 - just offsets and quality values;\n"
 
221
     "2 - add sequence data.",
 
222
     "0", NULL, NULL, FALSE, 'B', ARG_INT, 0.0, 0, NULL}, /* ARG_TABULAR */
 
223
   { "Number of threads to use in preliminary search stage",
 
224
     "1", NULL, NULL, FALSE, 'a', ARG_INT, 0.0, 0, NULL}, /* ARG_THREADS */
 
225
   { "Show gis in sequence ids",
 
226
     "F", NULL, NULL, FALSE, 'n', ARG_BOOLEAN, 0.0, 0, NULL}, /* ARG_SHOWGI */
 
227
   { "Show only accessions for sequence ids in tabular output",
 
228
     "F", NULL, NULL, FALSE, 'N', ARG_BOOLEAN, 0.0, 0, NULL}/* ARG_ACCESSION */
209
229
};
210
230
 
 
231
extern void PrintTabularOutputHeader PROTO((char* blast_database, 
 
232
               BioseqPtr query_bsp, SeqLocPtr query_slp, char* blast_program, 
 
233
               Int4 iteration, Boolean believe_query, FILE *outfp));
 
234
 
211
235
static Int2 BLAST_FillRPSInfo( RPSInfo **ppinfo, Nlm_MemMap **rps_mmap,
212
236
                               Nlm_MemMap **rps_pssm_mmap, CharPtr dbname )
213
237
{
319
343
   RPSInfo *rps_info)
320
344
{
321
345
   char* blast_program;
322
 
   Boolean ag_blast = TRUE, variable_wordsize = FALSE, mb_lookup = FALSE;
 
346
   Boolean ag_blast = FALSE, variable_wordsize = FALSE, mb_lookup = FALSE;
323
347
   Int4 greedy_extension = 0;
324
348
   Boolean greedy_with_ungapped = FALSE;
325
349
   Boolean is_gapped = FALSE;
326
 
   Uint1 program_number;
 
350
   EBlastProgramType program_number;
327
351
   Int2 status;
328
352
   Boolean use_pssm = FALSE;
329
353
 
331
355
   BlastProgram2Number(blast_program, &program_number);
332
356
 
333
357
   /* The following options are for blastn only */
334
 
   if (program_number == blast_type_blastn) {
 
358
   if (program_number == eBlastTypeBlastn) {
335
359
      if (myargs[ARG_TEMPL_LEN].intvalue == 0) {
336
360
         ag_blast = (Boolean) myargs[ARG_AG].intvalue;
337
361
         mb_lookup = (Boolean) myargs[ARG_LOOKUP].intvalue;
341
365
            variable_wordsize = (Boolean) myargs[ARG_VARIABLE_WORD].intvalue;
342
366
      } else {
343
367
         /* Discontiguous words */
344
 
         ag_blast = FALSE;
345
368
         mb_lookup = TRUE;
346
369
         variable_wordsize = FALSE;
347
370
      }
350
373
   }
351
374
 
352
375
   BLAST_FillLookupTableOptions(lookup_options, program_number, mb_lookup,
353
 
      myargs[ARG_THRESHOLD].intvalue, myargs[ARG_WORDSIZE].intvalue, 
 
376
      myargs[ARG_THRESHOLD].intvalue, (Int2)myargs[ARG_WORDSIZE].intvalue, 
354
377
      ag_blast, variable_wordsize, use_pssm);
355
378
   /* Fill the rest of the lookup table options */
356
379
   lookup_options->mb_template_length = 
364
387
   if (myargs[ARG_PHI].strvalue) {
365
388
      lookup_options->phi_pattern = strdup(myargs[ARG_PHI].strvalue);
366
389
      lookup_options->lut_type = 
367
 
          ((program_number == blast_type_blastn) ? 
 
390
          ((program_number == eBlastTypeBlastn) ? 
368
391
           PHI_NA_LOOKUP : PHI_AA_LOOKUP);
369
392
      hit_options->phi_align = TRUE;
370
393
   }
371
394
 
372
395
   BLAST_FillQuerySetUpOptions(query_setup_options, program_number, 
373
 
      myargs[ARG_FILTER].strvalue, myargs[ARG_STRAND].intvalue);
 
396
      myargs[ARG_FILTER].strvalue, (Uint1)myargs[ARG_STRAND].intvalue);
374
397
 
375
398
   if (myargs[ARG_GENCODE].intvalue &&
376
 
       (program_number == blast_type_blastx || 
377
 
        program_number == blast_type_tblastx))
 
399
       (program_number == eBlastTypeBlastx || 
 
400
        program_number == eBlastTypeTblastx))
378
401
      query_setup_options->genetic_code = myargs[ARG_GENCODE].intvalue;
379
402
 
380
403
   BLAST_FillInitialWordOptions(word_options, program_number, 
381
 
      (greedy_extension && !greedy_with_ungapped), 
 
404
      (Boolean)(greedy_extension && !greedy_with_ungapped), 
382
405
      myargs[ARG_WINDOW].intvalue, variable_wordsize, ag_blast, mb_lookup, 
383
406
      myargs[ARG_XDROP_UNGAPPED].intvalue);
384
407
 
385
408
   BLAST_FillExtensionOptions(ext_options, program_number, greedy_extension, 
386
409
      myargs[ARG_XDROP].intvalue, myargs[ARG_XDROP_FINAL].intvalue);
387
410
 
388
 
   if (program_number == blast_type_rpsblast ||
389
 
       program_number == blast_type_rpstblastn) {
 
411
   if (program_number == eBlastTypeRpsBlast ||
 
412
       program_number == eBlastTypeRpsTblastn) {
390
413
      BLAST_FillScoringOptions(score_options, program_number, FALSE,
391
414
                myargs[ARG_MISMATCH].intvalue, myargs[ARG_MATCH].intvalue,
392
 
                "BLOSUM62", rps_info->aux_info.gap_open_penalty,
 
415
                rps_info->aux_info.orig_score_matrix, 
 
416
                rps_info->aux_info.gap_open_penalty,
393
417
                rps_info->aux_info.gap_extend_penalty);
394
418
   } else {
395
419
      BLAST_FillScoringOptions(score_options, program_number, 
399
423
                myargs[ARG_GAPEXT].intvalue);
400
424
   }
401
425
 
402
 
   if (program_number != blast_type_tblastx)
 
426
   if (program_number != eBlastTypeTblastx)
403
427
      is_gapped = !myargs[ARG_UNGAPPED].intvalue;
404
428
 
405
429
   score_options->gapped_calculation = is_gapped;
420
444
      eff_len_options->searchsp_eff = (Int8) myargs[ARG_SEARCHSP].floatvalue; 
421
445
   }
422
446
 
423
 
   if (db_options && (program_number == blast_type_tblastn ||
424
 
                      program_number == blast_type_rpstblastn ||
425
 
                      program_number == blast_type_tblastx)) {
 
447
   if (db_options && (program_number == eBlastTypeTblastn ||
 
448
                      program_number == eBlastTypeRpsTblastn ||
 
449
                      program_number == eBlastTypeTblastx)) {
426
450
      if (myargs[ARG_DBGENCODE].intvalue)
427
451
         db_options->genetic_code = myargs[ARG_DBGENCODE].intvalue;
428
452
      if ((status = BLAST_GeneticCodeFind(db_options->genetic_code, 
433
457
   return 0;
434
458
}
435
459
 
 
460
static Int2 x_RestrictSeqLocToInterval(SeqLoc** slp_ptr, char* location)
 
461
{
 
462
   char* delimiters = " ,;";
 
463
   Int4 from, to;
 
464
   SeqLoc* slp, *new_slp = NULL;
 
465
   Uint4 full_length;
 
466
 
 
467
   if (!location || !slp_ptr || ValNodeLen(*slp_ptr) != 1)
 
468
      return 0;
 
469
 
 
470
   slp = *slp_ptr;
 
471
   full_length = SeqLocLen(slp);
 
472
   from = atoi(StringTokMT(location, delimiters, &location)) - 1;
 
473
   to = atoi(location) - 1;
 
474
   
 
475
   from = MAX(from, 0);
 
476
   if (to < 0) 
 
477
      to = full_length - 1;
 
478
   to = MIN(to, full_length - 1);
 
479
   if (from >= full_length) {
 
480
      SeqLocSetFree(slp);
 
481
      *slp_ptr = NULL;
 
482
      return -1;
 
483
   }
 
484
 
 
485
   new_slp = SeqLocIntNew(from, to, SeqLocStrand(slp),
 
486
                          SeqIdFindBestAccession(SeqLocId(slp)));
 
487
   SeqLocFree(slp);
 
488
   *slp_ptr = new_slp;
 
489
 
 
490
   return 0;
 
491
}        
 
492
 
 
493
 
436
494
Int2 Nlm_Main(void)
437
495
{
438
496
   BLAST_SequenceBlk *query = NULL;
442
500
   LookupTableOptions* lookup_options;
443
501
   char buf[256] = { '\0' };
444
502
   char* blast_program;
445
 
   Uint1 program_number;
 
503
   EBlastProgramType program_number;
446
504
   BlastInitialWordOptions* word_options;
447
505
   BlastScoringOptions* score_options;
448
506
   BlastExtensionOptions* ext_options;
452
510
   Int2 status = 0;
453
511
   QuerySetUpOptions* query_options=NULL;       
454
512
   BlastEffectiveLengthsOptions* eff_len_options=NULL;
 
513
   BlastMaskInformation maskInfo;
455
514
   BlastMaskLoc* lcase_mask = NULL;
456
515
   BlastMaskLoc* filter_loc=NULL;       /* All masking locations */
457
516
   SeqLoc* query_slp = NULL;
459
518
   FILE *infp, *outfp;
460
519
   BlastQueryInfo* query_info;
461
520
   BlastHSPResults* results = NULL;
 
521
   BlastHSPResults** results_ptr = NULL;
462
522
   Blast_Message* blast_message = NULL;
463
 
   SeqAlign* seqalign;
 
523
   SeqAlign* seqalign = NULL;
464
524
   BlastFormattingOptions* format_options;
465
 
   Boolean done;
466
525
   BlastDiagnostics* diagnostics;
467
 
   Int4 ctr = 0;
 
526
   Int2 ctr = 1;
468
527
   PSIBlastOptions* psi_options = NULL;
469
528
   BlastDatabaseOptions* db_options = NULL;
470
 
   ListNode* lookup_segments = NULL;
 
529
   BlastSeqLoc* lookup_segments = NULL;
471
530
   Boolean translated_query;
472
 
   Int4 num_queries;
 
531
   Int4 num_queries=0;
473
532
   BlastSeqSrc* seq_src = NULL;
474
533
   Boolean psi_blast = FALSE;
475
534
   Boolean rps_blast = FALSE;
478
537
   RPSInfo *rps_info = NULL;
479
538
   double scale_factor;
480
539
   BlastHSPStream* hsp_stream = NULL;
481
 
   Boolean tabular_output;
 
540
   int tabular_output;
482
541
   TNlmThread format_thread;
483
542
   BlastTabularFormatData* tf_data = NULL;
 
543
   int num_threads;
 
544
   Boolean believe_defline = FALSE;
484
545
 
485
546
   if (! GetArgs (buf, NUMARG, myargs))
486
547
      return (1);
492
553
   
493
554
   ErrSetMessageLevel(SEV_WARNING);
494
555
   
495
 
   if ((outfp = FileOpen(myargs[ARG_OUT].strvalue, "w")) == NULL) {
496
 
      ErrPostEx(SEV_FATAL, 1, 0, "blast: Unable to open output file %s\n", 
497
 
                myargs[ARG_OUT].strvalue);
498
 
     return (1);
499
 
   }
500
 
 
501
 
   tabular_output = (Boolean)myargs[ARG_TABULAR].intvalue;
 
556
   tabular_output = myargs[ARG_TABULAR].intvalue;
502
557
   
503
558
   blast_program = strdup(myargs[ARG_PROGRAM].strvalue);
504
559
   BlastProgram2Number(myargs[ARG_PROGRAM].strvalue, &program_number);
505
560
 
506
 
   db_is_na = (program_number == blast_type_blastn || 
507
 
               program_number == blast_type_tblastn || 
508
 
               program_number == blast_type_tblastx);
509
 
   query_is_na = (program_number == blast_type_blastn || 
510
 
                  program_number == blast_type_blastx || 
511
 
                  program_number == blast_type_rpstblastn || 
512
 
                  program_number == blast_type_tblastx);
513
 
 
514
 
   rps_blast = (program_number == blast_type_rpsblast ||
515
 
                program_number == blast_type_rpstblastn);
 
561
   db_is_na = (program_number == eBlastTypeBlastn || 
 
562
               program_number == eBlastTypeTblastn || 
 
563
               program_number == eBlastTypeTblastx);
 
564
   query_is_na = (program_number == eBlastTypeBlastn || 
 
565
                  program_number == eBlastTypeBlastx || 
 
566
                  program_number == eBlastTypeRpsTblastn || 
 
567
                  program_number == eBlastTypeTblastx);
 
568
 
 
569
   rps_blast = (program_number == eBlastTypeRpsBlast ||
 
570
                program_number == eBlastTypeRpsTblastn);
 
571
 
 
572
   num_threads = myargs[ARG_THREADS].intvalue;
516
573
 
517
574
   BLAST_InitDefaultOptions(program_number, &lookup_options,
518
575
      &query_options, &word_options, &ext_options, &hit_options,
520
577
      (psi_blast || rps_blast) ? &psi_options : NULL,
521
578
      &db_options);
522
579
 
523
 
   if (!myargs[ARG_DB].strvalue) {
 
580
   if ((dbname = myargs[ARG_DB].strvalue) == NULL) {
 
581
      Int4 letters_read;
524
582
      FILE *infp2;
525
583
      char *subject_file = strdup(myargs[ARG_SUBJECT].strvalue);
526
584
      if ((infp2 = FileOpen(subject_file, "r")) == NULL) {
531
589
      }
532
590
      sfree(subject_file);
533
591
 
534
 
      BLAST_GetQuerySeqLoc(infp2, db_is_na, 0, 0, 0, NULL, &subject_slp, 
535
 
                           0, NULL);
 
592
      letters_read = BLAST_GetQuerySeqLoc(infp2, db_is_na, 0, 0, 0, 0, NULL, &subject_slp, 
 
593
                           &ctr, NULL, FALSE);
 
594
      if (letters_read <= 0)
 
595
      {
 
596
           ErrPostEx(SEV_FATAL, 1, 0, "Bad return for BLAST_GetQuerySeqLoc\n");
 
597
           return -1;
 
598
      }
536
599
      FileClose(infp2);
537
600
      
 
601
      if ((status = x_RestrictSeqLocToInterval(&subject_slp, 
 
602
                          myargs[ARG_SUBJECT_LOC].strvalue)) != 0) {
 
603
         ErrPostEx(SEV_FATAL, 1, 0, 
 
604
                   "Subject location outside of the sequence range\n");
 
605
         return status;
 
606
      }
 
607
 
538
608
      seq_src = MultiSeqSrcInit(subject_slp, program_number);
539
 
 
540
 
      ctr = BLASTSeqSrcGetNumSeqs(seq_src);
541
609
   } else {
542
610
      int first_db_seq = 0;
543
611
      int final_db_seq = 0;
548
616
         final_db_seq = atoi(strtok(NULL, delimiters));
549
617
         sfree(range_str);
550
618
      }
551
 
      seq_src = ReaddbBlastSeqSrcInit(myargs[ARG_DB].strvalue, !db_is_na, 
552
 
                                   first_db_seq, final_db_seq, NULL);
 
619
      seq_src = ReaddbBlastSeqSrcInit(dbname, !db_is_na, 
 
620
                                      first_db_seq, final_db_seq, NULL);
553
621
   }
554
622
 
555
623
   if (rps_blast) {
565
633
   BLAST_FillOptions(lookup_options, query_options, word_options, 
566
634
      ext_options, hit_options, score_options, eff_len_options, 
567
635
      psi_options, db_options, seq_src, rps_info);
568
 
   if (!tabular_output) {
 
636
   if (tabular_output) {
 
637
      if ((outfp = FileOpen(myargs[ARG_OUT].strvalue, "w")) == NULL) {
 
638
         ErrPostEx(SEV_FATAL, 1, 0, "blast: Unable to open output file %s\n", 
 
639
                   myargs[ARG_OUT].strvalue);
 
640
        return (1);
 
641
      }
 
642
   } else {
569
643
      if ((status = BlastFormattingOptionsNew(program_number, 
570
644
                       myargs[ARG_OUT].strvalue, 
571
645
                       myargs[ARG_DESCRIPTIONS].intvalue, 
572
646
                       myargs[ARG_ALIGNMENTS].intvalue, 
573
647
                       myargs[ARG_FORMAT].intvalue, &format_options)) != 0)
574
648
         return status;
575
 
      format_options->html = (Boolean) myargs[ARG_HTML].intvalue;
576
 
 
577
 
      if (seq_src) {
578
 
         dbname = BLASTSeqSrcGetName(seq_src);
579
 
 
 
649
 
 
650
      if (myargs[ARG_HTML].intvalue) {
 
651
         format_options->html = TRUE;
 
652
         format_options->align_options += TXALIGN_HTML;
 
653
         format_options->print_options += TXALIGN_HTML;
 
654
      }
 
655
 
 
656
      if (myargs[ARG_SHOWGI].intvalue) {
 
657
         format_options->align_options += TXALIGN_SHOW_GI;
 
658
         format_options->print_options += TXALIGN_SHOW_GI;
 
659
      }
 
660
 
 
661
      if (dbname) {
580
662
         BLAST_PrintOutputHeader(format_options, 
581
 
            myargs[ARG_GREEDY].intvalue, dbname, !db_is_na);
 
663
            (Boolean)myargs[ARG_GREEDY].intvalue, blast_program, dbname, !db_is_na);
582
664
      }
 
665
 
 
666
     if (myargs[ARG_UNGAPPED].intvalue != 0) 
 
667
         format_options->print_options += TXALIGN_SHOW_NO_OF_SEGS;
 
668
 
583
669
   }
584
670
 
585
671
   if ((infp = FileOpen(myargs[ARG_QUERY].strvalue, "r")) == NULL) {
587
673
                myargs[ARG_QUERY].strvalue);
588
674
      return (1);
589
675
   }
590
 
   
591
 
   diagnostics = Blast_DiagnosticsInit();
592
 
 
593
 
   translated_query = (program_number == blast_type_blastx || 
594
 
                       program_number == blast_type_tblastx);
595
 
 
596
 
   done = FALSE;
 
676
 
 
677
   if (num_threads > 1) {
 
678
      diagnostics = Blast_DiagnosticsInitMT(Blast_MT_LOCKInit());
 
679
   } else {
 
680
      diagnostics = Blast_DiagnosticsInit();
 
681
   }
 
682
 
 
683
   translated_query = (program_number == eBlastTypeBlastx || 
 
684
                       program_number == eBlastTypeTblastx ||
 
685
                       program_number == eBlastTypeRpsTblastn);
 
686
 
 
687
   if (tabular_output)
 
688
      believe_defline = TRUE;
 
689
 
597
690
   /* Get the query (queries), loop if necessary. */
598
 
   while (!done) {
 
691
   while (1) {
 
692
      Int4 letters_read;
599
693
      if ((Boolean)myargs[ARG_LCASE].intvalue) {
600
 
         done = BLAST_GetQuerySeqLoc(infp, query_is_na, 
601
 
                   myargs[ARG_STRAND].intvalue, 0, 0,
602
 
                   &lcase_mask, &query_slp, ctr, 
603
 
                   &num_queries);
 
694
         letters_read = BLAST_GetQuerySeqLoc(infp, query_is_na, 
 
695
                   (Uint1)myargs[ARG_STRAND].intvalue, 0, 0, 0,
 
696
                   &lcase_mask, &query_slp, &ctr, 
 
697
                   &num_queries, believe_defline);
604
698
      } else {
605
 
         done = BLAST_GetQuerySeqLoc(infp, query_is_na,
606
 
                   myargs[ARG_STRAND].intvalue, 0, 0, NULL, &query_slp,
607
 
                   ctr, &num_queries);
608
 
      }
609
 
 
610
 
      if (translated_query) {
611
 
         BlastMaskLocDNAToProtein(&lcase_mask, query_slp);
 
699
         letters_read = BLAST_GetQuerySeqLoc(infp, query_is_na,
 
700
                   (Uint1)myargs[ARG_STRAND].intvalue, 0, 0, 0, NULL, &query_slp,
 
701
                   &ctr, &num_queries, believe_defline);
 
702
      }
 
703
 
 
704
      if (letters_read == 0)
 
705
         break;
 
706
 
 
707
      if (letters_read < 0)
 
708
      {
 
709
           ErrPostEx(SEV_FATAL, 1, 0, "BLAST_GetQuerySeqLoc returned an error\n");
 
710
           return -1;
 
711
      }
 
712
 
 
713
      if ((status = x_RestrictSeqLocToInterval(&query_slp, 
 
714
                          myargs[ARG_QUERY_LOC].strvalue)) != 0) {
 
715
         ErrPostEx(SEV_FATAL, 1, 0, 
 
716
                   "Query location outside of the sequence range\n");
 
717
         return status;
 
718
      }
 
719
 
 
720
      if (lcase_mask && translated_query) {
 
721
          BlastMaskLoc* blast_maskloc_tmp = BlastMaskLocNew(NUM_FRAMES);
 
722
          BlastMaskLocDNAToProtein(lcase_mask->seqloc_array[0], 
 
723
                                   blast_maskloc_tmp, 0, query_slp);
 
724
          lcase_mask = BlastMaskLocFree(lcase_mask);
 
725
          lcase_mask = blast_maskloc_tmp;
612
726
      }
613
727
 
614
728
      status = BLAST_SetUpQuery(program_number, query_slp, 
615
729
                  query_options, &query_info, &query);
616
730
 
 
731
      if (status) {
 
732
           ErrPostEx(SEV_FATAL, 1, 0, "BLAST_SetUpQuery returned non-zero status: %d\n", status);
 
733
           return status;
 
734
      }
 
735
 
617
736
      query->lcase_mask = lcase_mask;
 
737
      lcase_mask = NULL;
618
738
 
619
739
      if ((status = BLAST_ValidateOptions(program_number, ext_options, 
620
 
                       score_options, lookup_options, hit_options, 
621
 
                       &blast_message)) != 0) {
 
740
                       score_options, lookup_options, word_options,
 
741
                       hit_options, &blast_message)) != 0) {
622
742
         Blast_MessagePost(blast_message);
623
743
         return status;
624
744
      }
626
746
      status = 
627
747
         BLAST_MainSetUp(program_number, query_options, score_options, 
628
748
            hit_options, query, query_info, scale_factor, &lookup_segments, 
629
 
            &filter_loc, &sbp, &blast_message);
 
749
            &maskInfo, &sbp, &blast_message);
 
750
 
 
751
      if (maskInfo.mask_at_hash)
 
752
          maskInfo.filter_slp = BlastMaskLocFree(maskInfo.filter_slp);
 
753
      else
 
754
          filter_loc = maskInfo.filter_slp;
630
755
 
631
756
      if (translated_query) {
632
757
         /* Filter locations were returned in protein coordinates; convert them
645
770
                          lookup_segments, sbp, &lookup_wrap, rps_info);
646
771
    
647
772
      if (!tabular_output) {
648
 
         Int4 num_results = (rps_blast ? BLASTSeqSrcGetNumSeqs(seq_src) : 
649
 
                             query_info->num_queries);
 
773
         Int4 num_results = 
 
774
            (rps_blast ? BLASTSeqSrcGetNumSeqs(seq_src) : num_queries);
650
775
         /* Results in the collector stream should be sorted only for a
651
776
            database search. The latter is true if and only if the sequence
652
777
            source has non-zero database length. */
653
778
         Boolean sort_on_read = (BLASTSeqSrcGetTotLen(seq_src) != 0);
 
779
         MT_LOCK lock = NULL;
 
780
         if (num_threads > 1) {
 
781
            lock = Blast_MT_LOCKInit();
 
782
         }
654
783
         hsp_stream = 
655
 
            Blast_HSPListCollectorInit(program_number, hit_options, 
656
 
                                       num_results, sort_on_read);
 
784
            Blast_HSPListCollectorInitMT(program_number, hit_options, 
 
785
                                         num_results, sort_on_read, lock);
 
786
         results_ptr = &results;
657
787
      } else {
 
788
         /* Print the header of tabular output. */
 
789
         PrintTabularOutputHeader(myargs[ARG_DB].strvalue, NULL, query_slp, 
 
790
                                  blast_program, 0, FALSE, outfp);
 
791
         
658
792
         hsp_stream = Blast_HSPListQueueInit();
659
793
         tf_data = Blast_TabularFormatDataInit(program_number, hsp_stream, 
660
794
                      seq_src, query, query_info, score_options, sbp, 
661
795
                      eff_len_options, ext_options, hit_options, db_options, 
662
796
                      query_slp, outfp);
 
797
 
 
798
         if (tabular_output == 2) {
 
799
            if (program_number == eBlastTypeBlastn) {
 
800
               tf_data->format_options = eBlastTabularAddSequences;
 
801
            } else {
 
802
               fprintf(stderr, 
 
803
                       "WARNING: Sequences printout in tabular output"
 
804
                       " allowed only for blastn\n");
 
805
            }
 
806
         } 
 
807
 
 
808
         tf_data->show_gi = (Boolean) myargs[ARG_SHOWGI].intvalue;
 
809
         tf_data->show_accession = (Boolean) myargs[ARG_ACCESSION].intvalue;
 
810
 
663
811
         /* Start the formatting thread */
664
 
         if((format_thread = 
 
812
         if(NlmThreadsAvailable() && 
 
813
            (format_thread = 
665
814
             NlmThreadCreate(Blast_TabularFormatThread, (void*) tf_data))
666
815
            == NULL_thread) {
667
816
            fprintf(stderr, 
668
817
                    "Cannot create thread for formatting tabular output\n");
669
818
            return 1;
670
819
         }
 
820
         results_ptr = NULL;
671
821
      }
672
822
 
673
 
      if (rps_blast) {
674
 
         BLAST_RPSSearchEngine(program_number, query, query_info, 
 
823
      if (!NlmThreadsAvailable() || num_threads == 1) {
 
824
         if ((status=BLAST_SearchEngine(program_number, query, query_info, 
675
825
            seq_src, sbp, score_options, lookup_wrap, 
676
826
            word_options, ext_options, hit_options, eff_len_options, 
677
827
            psi_options, db_options, hsp_stream, diagnostics, 
678
 
            (tabular_output ? NULL : &results));
 
828
            results_ptr)) != 0)
 
829
         {
 
830
 
 
831
            ErrPostEx(SEV_FATAL, 1, 0, "BLAST_SearchEngine failed\n");
 
832
            return 1;
 
833
         }
679
834
      } else {
680
 
         BLAST_SearchEngine(program_number, query, query_info, 
681
 
            seq_src, sbp, score_options, lookup_wrap, 
682
 
            word_options, ext_options, hit_options, eff_len_options, 
683
 
            psi_options, db_options, hsp_stream, diagnostics, 
684
 
            (tabular_output ? NULL : &results));
 
835
         TNlmThread* thread_array =
 
836
            (TNlmThread*) calloc(num_threads, sizeof(TNlmThread));
 
837
         BlastPrelimSearchThreadData* search_data = NULL;
 
838
         void* join_status = NULL;
 
839
         int index;
 
840
         
 
841
         for (index = 0; index < num_threads; index++) {
 
842
            search_data = 
 
843
               BlastPrelimSearchThreadDataInit(program_number, query, 
 
844
                  query_info, seq_src, lookup_wrap, score_options, 
 
845
                  word_options, ext_options, hit_options, eff_len_options, 
 
846
                  psi_options, db_options, sbp, diagnostics, hsp_stream);
 
847
            thread_array[index] =
 
848
               NlmThreadCreate(Blast_PrelimSearchThreadRun, 
 
849
                               (void*) search_data);
 
850
         }
 
851
         for (index = 0; index < num_threads; index++) {
 
852
            NlmThreadJoin(thread_array[index], &join_status);
 
853
         }
 
854
  
 
855
         MemFree(thread_array);
685
856
      }
686
857
 
687
858
      if (tabular_output) {
688
859
         void* join_status = NULL;
 
860
         BlastHSPStreamClose(hsp_stream);
689
861
         NlmThreadJoin(format_thread, &join_status);
 
862
      } else if (num_threads > 1) {
 
863
         Blast_RunTracebackSearch(program_number, query, query_info, seq_src, 
 
864
            score_options, ext_options, hit_options, eff_len_options, 
 
865
            db_options, psi_options, sbp, hsp_stream, results_ptr);
690
866
      }
691
867
 
692
868
      hsp_stream = BlastHSPStreamFree(hsp_stream);
702
878
 
703
879
      /* The following works because the ListNodes' data point to simple
704
880
         double-integer structures */
705
 
      lookup_segments = ListNodeFreeData(lookup_segments);
 
881
      lookup_segments = BlastSeqLocFree(lookup_segments);
706
882
      if (!tabular_output) {
707
 
      /* Convert results to the SeqAlign form */
708
 
      BLAST_ResultsToSeqAlign(program_number, results, query_slp, seq_src, 
709
 
         score_options->gapped_calculation, score_options->is_ooframe, 
710
 
         &seqalign);
711
 
 
712
 
      results = Blast_HSPResultsFree(results);
 
883
         /* Get hold of a ReadDB data structure */
 
884
         Blast_SummaryReturn* sum_returns=NULL;
 
885
         ReadDBFILE* rdfp = NULL;
 
886
         if (dbname) 
 
887
            rdfp = readdb_new(dbname, !db_is_na);
 
888
         /* Convert results to the SeqAlign form */
 
889
         BLAST_ResultsToSeqAlign(program_number, results, query_slp, rdfp, subject_slp, 
 
890
            score_options->gapped_calculation, score_options->is_ooframe, 
 
891
            &seqalign);
 
892
 
 
893
         Blast_AdjustOffsetsInSeqAlign(seqalign, query_slp, subject_slp);
 
894
 
 
895
         results = Blast_HSPResultsFree(results);
713
896
      
714
 
      if (myargs[ARG_ASNOUT].strvalue) {
715
 
         AsnIoPtr asnout = AsnIoOpen(myargs[ARG_ASNOUT].strvalue, (char*)"w");
716
 
         GenericSeqAlignSetAsnWrite(seqalign, asnout);
717
 
         asnout = AsnIoClose(asnout);
718
 
      }
 
897
         if (myargs[ARG_ASNOUT].strvalue) {
 
898
            AsnIoPtr asnout = 
 
899
               AsnIoOpen(myargs[ARG_ASNOUT].strvalue, (char*)"w");
 
900
            GenericSeqAlignSetAsnWrite(seqalign, asnout);
 
901
            asnout = AsnIoClose(asnout);
 
902
         }
719
903
 
720
 
      /* Format the results; note that seqalign and filter locations 
721
 
         are freed inside. */
722
 
      status = BLAST_FormatResults(seqalign, dbname, 
723
 
                  blast_program, query_info->num_queries, query_slp,
724
 
                  filter_loc, format_options, score_options->is_ooframe);
725
 
      PrintOutputFooter(program_number, format_options, score_options, sbp, 
726
 
                        lookup_options, word_options, ext_options, 
727
 
                        hit_options, eff_len_options, query_info, 
728
 
                        seq_src, diagnostics);
 
904
         /* Format the results */
 
905
         status = 
 
906
            BLAST_FormatResults(seqalign, dbname, 
 
907
               blast_program, query_info->num_queries, query_slp,
 
908
               filter_loc, format_options, score_options->is_ooframe, NULL, NULL);
 
909
 
 
910
         seqalign = SeqAlignSetFree(seqalign);
 
911
         status = 
 
912
             Blast_SummaryReturnFill(program_number, score_options, sbp,
 
913
                lookup_options, word_options, ext_options, hit_options, 
 
914
                eff_len_options, query_options, query_info, rdfp, subject_slp, 
 
915
                &diagnostics, &sum_returns);
 
916
         Blast_PrintOutputFooter(program_number, format_options, rdfp, sum_returns);
 
917
         sum_returns = Blast_SummaryReturnFree(sum_returns);
 
918
         rdfp = readdb_destruct(rdfp);
729
919
      } /* if not tabular output */
 
920
 
730
921
      query = BlastSequenceBlkFree(query);
731
922
      BlastMaskLocFree(filter_loc);
732
923
      query_info = BlastQueryInfoFree(query_info);
736
927
   
737
928
   seq_src = BlastSeqSrcFree(seq_src);
738
929
   subject_slp = SeqLocSetFree(subject_slp);
739
 
   Blast_DiagnosticsFree(diagnostics);
740
930
   LookupTableOptionsFree(lookup_options);
741
931
   BlastQuerySetUpOptionsFree(query_options);
742
932
   BlastExtensionOptionsFree(ext_options);
747
937
   PSIBlastOptionsFree(psi_options);
748
938
   BlastDatabaseOptionsFree(db_options);
749
939
   if (!tabular_output) { 
 
940
      if(format_options->html && myargs[ARG_FORMAT].intvalue < 7) {
 
941
         fprintf(format_options->outfp, "</PRE>\n</BODY>\n</HTML>\n");
 
942
      }
750
943
      BlastFormattingOptionsFree(format_options);
751
944
   } else {
752
945
      FileClose(outfp);