blast_app.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:28k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: blast_app.cpp,v $
  4.  * PRODUCTION Revision 1000.8  2004/06/01 18:06:35  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.49
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. static char const rcsid[] = "$Id: blast_app.cpp,v 1000.8 2004/06/01 18:06:35 gouriano Exp $";
  10. /*
  11. * ===========================================================================
  12. *
  13. *                            PUBLIC DOMAIN NOTICE
  14. *               National Center for Biotechnology Information
  15. *
  16. *  This software/database is a "United States Government Work" under the
  17. *  terms of the United States Copyright Act.  It was written as part of
  18. *  the author's offical duties as a United States Government employee and
  19. *  thus cannot be copyrighted.  This software/database is freely available
  20. *  to the public for use. The National Library of Medicine and the U.S.
  21. *  Government have not placed any restriction on its use or reproduction.
  22. *
  23. *  Although all reasonable efforts have been taken to ensure the accuracy
  24. *  and reliability of the software and data, the NLM and the U.S.
  25. *  Government do not and cannot warrant the performance or results that
  26. *  may be obtained by using this software or data. The NLM and the U.S.
  27. *  Government disclaim all warranties, express or implied, including
  28. *  warranties of performance, merchantability or fitness for any particular
  29. *  purpose.
  30. *
  31. *  Please cite the author in any work or product based on this material.
  32. *
  33. * ===========================================================================*/
  34. /*****************************************************************************
  35. File name: blast_app.cpp
  36. Author: Ilya Dondoshansky
  37. Contents: C++ driver for running BLAST
  38. ******************************************************************************/
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbiapp.hpp>
  41. #include <corelib/ncbifile.hpp>
  42. #include <objects/seq/seq__.hpp>
  43. #include <objects/seq/seqport_util.hpp>
  44. #include <objects/seqfeat/Genetic_code_table.hpp>
  45. #include <objmgr/object_manager.hpp>
  46. #include <objtools/data_loaders/blastdb/bdbloader.hpp>
  47. #include <objtools/data_loaders/genbank/gbloader.hpp>
  48. #include <objmgr/util/sequence.hpp>
  49. #include <algo/blast/api/blast_options.hpp>
  50. #include <algo/blast/api/blast_nucl_options.hpp>
  51. #include <algo/blast/api/db_blast.hpp>
  52. #include <algo/blast/api/blast_aux.hpp>
  53. #include "blast_input.hpp"
  54. #include <algo/blast/api/seqdb_src.hpp>
  55. #include <objtools/alnmgr/util/blast_format.hpp>
  56. #ifndef NCBI_C_TOOLKIT
  57. #define NCBI_C_TOOLKIT
  58. #endif
  59. // C include files
  60. #include <algo/blast/core/blast_setup.h>
  61. #include <algo/blast/core/blast_util.h>
  62. #include <algo/blast/core/lookup_wrap.h>
  63. #include <algo/blast/core/blast_engine.h>
  64. // For writing out seqalign only
  65. #include <ctools/asn_converter.hpp>
  66. #include <objalign.h>
  67. USING_NCBI_SCOPE;
  68. USING_SCOPE(blast);
  69. USING_SCOPE(objects);
  70. class CBlastApplication : public CNcbiApplication
  71. {
  72. private:
  73.     virtual void Init(void);
  74.     virtual int Run(void);
  75.     virtual void Exit(void);
  76.     void InitScope(void);
  77.     void InitOptions(void);
  78.     void SetOptions(const CArgs& args);
  79.     void ProcessCommandLineArgs(CBlastOptionsHandle* opt, 
  80.                                 BlastSeqSrc* bssp, RPSInfo *rps_info);
  81.     int BlastSearch(void);
  82.     void RegisterBlastDbLoader(char* dbname, bool is_na);
  83.     void FormatResults(CDbBlast& blaster, TSeqAlignVector& seqalignv);
  84.     CRef<CObjectManager> m_ObjMgr;
  85.     CRef<CScope>         m_Scope;
  86. };
  87. void CBlastApplication::Init(void)
  88. {
  89.     HideStdArgs(fHideLogfile | fHideConffile | fHideVersion);
  90.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  91.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(), "basic local alignment search tool");
  92.     arg_desc->AddKey("program", "program", "Type of BLAST program",
  93.         CArgDescriptions::eString);
  94.     arg_desc->SetConstraint
  95.         ("program", &(*new CArgAllow_Strings, 
  96.                 "blastp", "blastn", "blastx", "tblastn", "tblastx", 
  97.                 "rpsblast", "rpstblastn"));
  98.     arg_desc->AddDefaultKey("query", "query", "Query file name",
  99.                      CArgDescriptions::eInputFile, "stdin");
  100.     arg_desc->AddKey("db", "database", "BLAST database name",
  101.                      CArgDescriptions::eString);
  102.     arg_desc->AddDefaultKey("strand", "strand", 
  103.         "Query strands to search: 1 forward, 2 reverse, 0,3 both",
  104.         CArgDescriptions::eInteger, "0");
  105.     arg_desc->SetConstraint("strand", new CArgAllow_Integers(0,3));
  106.     arg_desc->AddDefaultKey("filter", "filter", "Filtering option",
  107.                             CArgDescriptions::eString, "T");
  108.     arg_desc->AddDefaultKey("lcase", "lcase", "Should lower case be masked?",
  109.                             CArgDescriptions::eBoolean, "F");
  110.     arg_desc->AddDefaultKey("lookup", "lookup", 
  111.         "Type of lookup table: 0 default, 1 megablast",
  112.         CArgDescriptions::eInteger, "0");
  113.     arg_desc->AddDefaultKey("matrix", "matrix", "Scoring matrix name",
  114.                             CArgDescriptions::eString, "BLOSUM62");
  115.     arg_desc->AddDefaultKey("mismatch", "penalty", "Penalty score for a mismatch",
  116.                             CArgDescriptions::eInteger, "0");
  117.     arg_desc->AddDefaultKey("match", "reward", "Reward score for a match",
  118.                             CArgDescriptions::eInteger, "0");
  119.     arg_desc->AddDefaultKey("word", "wordsize", "Word size",
  120.                             CArgDescriptions::eInteger, "0");
  121.     arg_desc->AddDefaultKey("templen", "templen", 
  122.         "Discontiguous word template length",
  123.         CArgDescriptions::eInteger, "0");
  124.     arg_desc->SetConstraint("templen", 
  125.                             &(*new CArgAllow_Strings, "0", "16", "18", "21"));
  126.     arg_desc->AddDefaultKey("templtype", "templtype", 
  127.         "Discontiguous word template type",
  128.         CArgDescriptions::eInteger, "0");
  129.     arg_desc->SetConstraint("templtype", new CArgAllow_Integers(0,2));
  130.     arg_desc->AddDefaultKey("thresh", "threshold", 
  131.         "Score threshold for neighboring words",
  132.         CArgDescriptions::eInteger, "0");
  133.     arg_desc->AddDefaultKey("window","window", "Window size for two-hit extension",
  134.                             CArgDescriptions::eInteger, "0");
  135.     arg_desc->AddDefaultKey("scantype", "scantype", 
  136.         "Method for scanning the database: 0 traditional, 1 AG",
  137.         CArgDescriptions::eInteger, "1");
  138.     arg_desc->SetConstraint("scantype", new CArgAllow_Integers(0,1));
  139.     arg_desc->AddDefaultKey("varword", "varword", 
  140.         "Should variable word size be used?",
  141.         CArgDescriptions::eBoolean, "F");
  142.     arg_desc->AddDefaultKey("stride","stride", "Database scanning stride",
  143.                             CArgDescriptions::eInteger, "0");
  144.     arg_desc->AddDefaultKey("xungap", "xungapped", 
  145.         "X-dropoff value for ungapped extensions",
  146.         CArgDescriptions::eDouble, "0");
  147.     arg_desc->AddDefaultKey("ungapped", "ungapped", 
  148.         "Perform only an ungapped alignment search?",
  149.         CArgDescriptions::eBoolean, "F");
  150.     arg_desc->AddDefaultKey("greedy", "greedy", 
  151.         "Use greedy algorithm for gapped extensions: 0 no, 1 one-step, 2 two-step, 3 two-step with ungapped",
  152.         CArgDescriptions::eInteger, "0");
  153.     arg_desc->AddDefaultKey("gopen", "gapopen", "Penalty for opening a gap",
  154.                             CArgDescriptions::eInteger, "0");
  155.     arg_desc->AddDefaultKey("gext", "gapext", "Penalty for extending a gap",
  156.                             CArgDescriptions::eInteger, "0");
  157.     arg_desc->AddDefaultKey("xgap", "xdrop", 
  158.         "X-dropoff value for preliminary gapped extensions",
  159.         CArgDescriptions::eDouble, "0");
  160.     arg_desc->AddDefaultKey("xfinal", "xfinal", 
  161.         "X-dropoff value for final gapped extensions with traceback",
  162.         CArgDescriptions::eDouble, "0");
  163.     arg_desc->AddDefaultKey("evalue", "evalue", 
  164.         "E-value threshold for saving hits",
  165.         CArgDescriptions::eDouble, "0");
  166.     arg_desc->AddDefaultKey("searchsp", "searchsp", 
  167.         "Virtual search space to be used for statistical calculations",
  168.         CArgDescriptions::eDouble, "0");
  169.     arg_desc->AddDefaultKey("perc", "percident", 
  170.         "Percentage of identities cutoff for saving hits",
  171.         CArgDescriptions::eDouble, "0");
  172.     arg_desc->AddDefaultKey("hitlist", "hitlist_size",
  173.         "How many best matching sequences to find?",
  174.         CArgDescriptions::eInteger, "500");
  175.     arg_desc->AddDefaultKey("descr", "descriptions",
  176.         "How many matching sequence descriptions to show?",
  177.         CArgDescriptions::eInteger, "500");
  178.     arg_desc->AddDefaultKey("align", "alignments", 
  179.         "How many matching sequence alignments to show?",
  180.         CArgDescriptions::eInteger, "250");
  181.     arg_desc->AddOptionalKey("out", "outfile", 
  182.         "File name for writing output",
  183.         CArgDescriptions::eOutputFile);
  184.     arg_desc->AddDefaultKey("format", "format", 
  185.         "How to format the results?",
  186.         CArgDescriptions::eInteger, "0");
  187.     arg_desc->AddDefaultKey("html", "html", "Produce HTML output?",
  188.                             CArgDescriptions::eBoolean, "F");
  189.     arg_desc->AddDefaultKey("gencode", "gencode", "Query genetic code",
  190.                             CArgDescriptions::eInteger, "1");
  191.     arg_desc->AddDefaultKey("dbgencode", "dbgencode", "Database genetic code",
  192.                             CArgDescriptions::eInteger, "1");
  193.     arg_desc->AddDefaultKey("maxintron", "maxintron", 
  194.                             "Longest allowed intron length for linking HSPs",
  195.                             CArgDescriptions::eInteger, "0");
  196.     arg_desc->AddDefaultKey("frameshift", "frameshift",
  197.                             "Frame shift penalty (blastx only)",
  198.                             CArgDescriptions::eInteger, "0");
  199.     arg_desc->AddOptionalKey("asnout", "seqalignasn", 
  200.         "File name for writing the seqalign results in ASN.1 form",
  201.         CArgDescriptions::eOutputFile);
  202.     arg_desc->AddDefaultKey("qstart", "query_start",
  203.                             "Starting offset in query location",
  204.                             CArgDescriptions::eInteger, "0");
  205.     arg_desc->AddDefaultKey("qend", "query_end",
  206.                             "Ending offset in query location",
  207.                             CArgDescriptions::eInteger, "0");
  208.     arg_desc->AddOptionalKey("pattern", "phipattern",
  209.                             "Pattern for PHI-BLAST",
  210.                              CArgDescriptions::eString);
  211.     arg_desc->AddOptionalKey("pssm", "pssm", 
  212.         "File name for uploading a PSSM for PSI BLAST seach",
  213.         CArgDescriptions::eInputFile);
  214.     arg_desc->AddOptionalKey("dbrange", "databaserange",
  215.                             "Range of ordinal ids in the BLAST database.n"
  216.                              "Format: "oid1 oid2"",
  217.                              CArgDescriptions::eString);
  218.     SetupArgDescriptions(arg_desc.release());
  219. }
  220. void 
  221. CBlastApplication::InitScope(void)
  222. {
  223.     if (m_Scope.Empty()) {
  224.         m_ObjMgr.Reset(new CObjectManager());
  225.         m_ObjMgr->RegisterDataLoader(*new CGBDataLoader("ID", 0, 2),
  226.                 CObjectManager::eDefault);
  227.         m_Scope.Reset(new CScope(*m_ObjMgr));
  228.         m_Scope->AddDefaults();
  229.         _TRACE("Blast2seqApp: Initializing scope");
  230.     }
  231. }
  232. void 
  233. CBlastApplication::RegisterBlastDbLoader(char *dbname, bool db_is_na)
  234. {
  235.     m_ObjMgr->RegisterDataLoader(*new CBlastDbDataLoader("BLASTDB", dbname, 
  236.                   db_is_na? (CBlastDbDataLoader::eNucleotide) : 
  237.                             (CBlastDbDataLoader::eProtein)),  
  238.                   CObjectManager::eDefault);
  239. }
  240. void
  241. CBlastApplication::ProcessCommandLineArgs(CBlastOptionsHandle* opts_handle, 
  242.                                           BlastSeqSrc* bssp, RPSInfo *rps_info)
  243. {
  244.     CArgs args = GetArgs();
  245.     CBlastOptions& opt = opts_handle->SetOptions();
  246.     EProgram program_number = opt.GetProgram();
  247.     if (args["strand"].AsInteger()) {
  248.         switch (args["strand"].AsInteger()) {
  249.         case 1: opt.SetStrandOption(eNa_strand_plus); break;
  250.         case 2: opt.SetStrandOption(eNa_strand_minus); break;
  251.         case 3: opt.SetStrandOption(eNa_strand_both); break;
  252.         default: abort();
  253.         }
  254.     }
  255.     opt.SetFilterString(args["filter"].AsString().c_str());
  256.     // FIXME: Handle lcase masking
  257.     // If lookup table type argument value is 0, the type will be set correctly
  258.     // automatically. Value 1 corresponds to megablast lookup table;
  259.     switch (args["lookup"].AsInteger()) {
  260.     case 1:
  261.         opt.SetLookupTableType(MB_LOOKUP_TABLE);
  262.         break;
  263.     default:
  264.         break;
  265.     }
  266.     if (program_number == eRPSBlast ||
  267.         program_number == eRPSTblastn) {
  268.         ASSERT(rps_info != NULL);
  269.         opt.SetGapOpeningCost(rps_info->aux_info.gap_open_penalty);
  270.         opt.SetGapExtensionCost(rps_info->aux_info.gap_extend_penalty);
  271.     }
  272.     else {
  273.         if (args["matrix"]) {
  274.             opt.SetMatrixName(args["matrix"].AsString().c_str());
  275.         }
  276.         if (args["gopen"].AsInteger() || args["greedy"].AsInteger()) {
  277.             opt.SetGapOpeningCost(args["gopen"].AsInteger());
  278.         }
  279.         if (args["gext"].AsInteger() || args["greedy"].AsInteger()) {
  280.             opt.SetGapExtensionCost(args["gext"].AsInteger());
  281.         }
  282.     }
  283.     if (args["mismatch"].AsInteger()) {
  284.         opt.SetMismatchPenalty(args["mismatch"].AsInteger());
  285.     }
  286.     if (args["match"].AsInteger()) {
  287.         opt.SetMatchReward(args["match"].AsInteger());
  288.     }
  289.     if (args["word"].AsInteger()) {
  290.         opt.SetWordSize(args["word"].AsInteger());
  291.     }
  292.     if (args["templen"].AsInteger()) {
  293.         opt.SetMBTemplateLength(args["templen"].AsInteger());
  294.     }
  295.     if (args["templtype"].AsInteger()) {
  296.         opt.SetMBTemplateType(args["templtype"].AsInteger());
  297.     }
  298.     if (args["thresh"].AsInteger()) {
  299.         opt.SetWordThreshold(args["thresh"].AsInteger());
  300.     }
  301.     if (args["window"].AsInteger()) {
  302.         opt.SetWindowSize(args["window"].AsInteger());
  303.     }
  304.     // The next 3 apply to nucleotide searches only
  305.     string program = args["program"].AsString();
  306.     if (program == "blastn") {
  307.         // Setting seed extension method involves changing the scanning 
  308.         // stride as well, which is handled in the derived 
  309.         // CBlastNucleotideOptionsHandle class, but not in the base
  310.         // CBlastOptionsHandle class.
  311.         CBlastNucleotideOptionsHandle* nucl_handle = 
  312.             dynamic_cast<CBlastNucleotideOptionsHandle*>(opts_handle);
  313.         if (!args["templen"].AsInteger()) {
  314.             opt.SetVariableWordSize(args["varword"].AsBoolean());
  315.             switch(args["scantype"].AsInteger()) {
  316.             case 1:
  317.                 nucl_handle->SetSeedExtensionMethod(eRightAndLeft);
  318.                 break;
  319.             default:
  320.                 nucl_handle->SetSeedExtensionMethod(eRight);
  321.                 break;
  322.             }
  323.         } else {
  324.             // Discontiguous Mega BLAST: only one extension method.
  325.             nucl_handle->SetSeedExtensionMethod(eRight); 
  326.         }
  327.         // Override the scan step value if it is set by user
  328.         if (args["stride"].AsInteger()) {
  329.             opt.SetScanStep(args["stride"].AsInteger());
  330.         }
  331.     }
  332.     if (args["xungap"].AsDouble()) {
  333.         opt.SetXDropoff(args["xungap"].AsDouble());
  334.     }
  335.     if (args["ungapped"].AsBoolean()) {
  336.         opt.SetGappedMode(false);
  337.     }
  338.     switch (args["greedy"].AsInteger()) {
  339.     case 1: /* Immediate greedy gapped extension with traceback */
  340.         opt.SetGapExtnAlgorithm(eGreedyWithTracebackExt);
  341.         opt.SetUngappedExtension(false);
  342.         break;
  343.     case 2: /* Two-step greedy extension, no ungapped extension */
  344.         opt.SetGapExtnAlgorithm(eGreedyExt);
  345.         opt.SetUngappedExtension(false);
  346.         break;
  347.     case 3: /* Two-step greedy extension after ungapped extension*/
  348.         opt.SetGapExtnAlgorithm(eGreedyExt);
  349.         opt.SetUngappedExtension(true);
  350.         break;
  351.     default: break;
  352.     }
  353.     if (args["xgap"].AsDouble()) {
  354.         opt.SetGapXDropoff(args["xgap"].AsDouble());
  355.     }
  356.     if (args["xfinal"].AsDouble()) {
  357.         opt.SetGapXDropoffFinal(args["xfinal"].AsDouble());
  358.     }
  359.     if (args["evalue"].AsDouble()) {
  360.         opt.SetEvalueThreshold(args["evalue"].AsDouble());
  361.     }
  362.     if (args["searchsp"].AsDouble()) {
  363.         opt.SetEffectiveSearchSpace((Int8) args["searchsp"].AsDouble());
  364.     } else if (bssp) {
  365.         opt.SetDbLength(BLASTSeqSrcGetTotLen(bssp));
  366.         opt.SetDbSeqNum(BLASTSeqSrcGetNumSeqs(bssp));
  367.     }
  368.     if (args["hitlist"].AsInteger()) {
  369.         opt.SetHitlistSize(args["hitlist"].AsInteger());
  370.         /* Hitlist size for preliminary alignments is increased, unless 
  371.            no traceback is performed. */
  372.         if (args["ungapped"].AsBoolean() || args["greedy"].AsInteger() == 1) {
  373.             opt.SetPrelimHitlistSize(args["hitlist"].AsInteger());
  374.         } else {
  375.             opt.SetPrelimHitlistSize(MIN(2*args["hitlist"].AsInteger(),
  376.                                          args["hitlist"].AsInteger() + 50));
  377.         }
  378.     }
  379.     if (args["perc"].AsDouble()) {
  380.         opt.SetPercentIdentity(args["perc"].AsDouble());
  381.     }
  382.     if (args["gencode"].AsInteger()) {
  383.         opt.SetQueryGeneticCode(args["gencode"].AsInteger());
  384.     }
  385.   
  386.     if ((program == "tblastn" || program == "tblastx") &&
  387.         args["dbgencode"].AsInteger() != BLAST_GENETIC_CODE) {
  388.         opt.SetDbGeneticCode(args["dbgencode"].AsInteger());
  389.     }
  390.     if (args["maxintron"].AsInteger()) {
  391.         opt.SetLongestIntronLength(args["maxintron"].AsInteger());
  392.     }
  393.     if (args["frameshift"].AsInteger()) {
  394.         opt.SetFrameShiftPenalty(args["frameshift"].AsInteger());
  395.         opt.SetOutOfFrameMode();
  396.     }
  397.     if (args["pattern"]) {
  398.         opt.SetPHIPattern(args["pattern"].AsString().c_str(),
  399.                                  (program == "blastn"));
  400.     }
  401.     if (args["pssm"]) {
  402. #if 0
  403.         FILE* pssmfp = fopen(args["pssm"].AsInputFile(), "r");
  404.         // Read the pssm string and fill the posMatrix
  405.         bool use_pssm = TRUE;
  406.         fclose(pssmfp);
  407. #endif
  408.     }
  409.     return;
  410. }
  411. static CDisplaySeqalign::TranslatedFrames 
  412. Context2TranslatedFrame(int context)
  413. {
  414.     switch (context) {
  415.     case 1: return CDisplaySeqalign::ePlusStrand1;
  416.     case 2: return CDisplaySeqalign::ePlusStrand2;
  417.     case 3: return CDisplaySeqalign::ePlusStrand3;
  418.     case 4: return CDisplaySeqalign::eMinusStrand1;
  419.     case 5: return CDisplaySeqalign::eMinusStrand2;
  420.     case 6: return CDisplaySeqalign::eMinusStrand3;
  421.     default: return CDisplaySeqalign::eFrameNotSet;
  422.     }
  423. }
  424. #define NUM_FRAMES 6
  425. static TSeqLocInfoVector
  426. BlastMaskLoc2CSeqLoc(const BlastMaskLoc* mask, const TSeqLocVector& slp,
  427.     EProgram program)
  428. {
  429.     TSeqLocInfoVector retval;
  430.     int frame, num_frames;
  431.     bool translated_query;
  432.     int index;
  433.     translated_query = (program == eBlastx ||
  434.                         program == eTblastx);
  435.     num_frames = (translated_query ? NUM_FRAMES : 1);
  436.     TSeqLocInfo mask_info_list;
  437.     for (index = 0; index < (int)slp.size(); ++index) {
  438.         mask_info_list.clear();
  439.         if (!mask) {
  440.             retval.push_back(mask_info_list);
  441.             continue;
  442.         }
  443.         for ( ; mask && mask->index < index*num_frames;
  444.               mask = mask->next);
  445.         BlastSeqLoc* loc;
  446.         CDisplaySeqalign::SeqlocInfo* seqloc_info =
  447.             new CDisplaySeqalign::SeqlocInfo;
  448.         for ( ; mask && mask->index < (index+1)*num_frames;
  449.               mask = mask->next) {
  450.             frame = (translated_query ? (mask->index % num_frames) + 1 : 0);
  451.             for (loc = mask->loc_list; loc; loc = loc->next) {
  452.                 seqloc_info->frame = Context2TranslatedFrame(frame);
  453.                 CRef<CSeq_loc> seqloc(new CSeq_loc());
  454.                 seqloc->SetInt().SetFrom(((SSeqRange*) loc->ptr)->left);
  455.                 seqloc->SetInt().SetTo(((SSeqRange*) loc->ptr)->right);
  456.                 seqloc->SetInt().SetId(*(const_cast<CSeq_id*>(&sequence::GetId(*
  457. slp[index].seqloc, slp[index].scope))));
  458.                 seqloc_info->seqloc = seqloc;
  459.                 mask_info_list.push_back(seqloc_info);
  460.             }
  461.         }
  462.         retval.push_back(mask_info_list);
  463.     }
  464.     return retval;
  465. }
  466. void CBlastApplication::FormatResults(CDbBlast& blaster, 
  467.                                       TSeqAlignVector& seqalignv)
  468. {
  469.     CArgs args = GetArgs();
  470.     if (args["asnout"]) {
  471.         auto_ptr<CObjectOStream> asnout(
  472.             CObjectOStream::Open(args["asnout"].AsString(), eSerial_AsnText));
  473.         unsigned int query_index;
  474.         for (query_index = 0; query_index < seqalignv.size(); ++query_index)
  475.         {
  476.             if (!seqalignv[query_index]->IsSet())
  477.                 continue;
  478.             *asnout << *seqalignv[query_index];
  479.         }
  480.     }
  481.     if (args["out"]) {
  482.         EProgram program = blaster.SetOptions().GetProgram();
  483.         char* dbname = const_cast<char*>(args["db"].AsString().c_str());
  484.         bool db_is_na = (program == eBlastn || program == eTblastn || 
  485.                          program == eTblastx);
  486.         /* Revert RPS program names to their conventional
  487.            counterparts, to avoid confusing the C toolkit
  488.            formatter */
  489.         if (program == eRPSBlast)
  490.             program = eBlastp;
  491.         if (program == eRPSTblastn)
  492.             program = eTblastn;
  493.         CBlastFormatOptions* format_options = 
  494.             new CBlastFormatOptions(program, args["out"].AsOutputFile());
  495.         
  496.         format_options->SetAlignments(args["align"].AsInteger());
  497.         format_options->SetDescriptions(args["descr"].AsInteger());
  498.         format_options->SetAlignView(args["format"].AsInteger());
  499.         format_options->SetHtml(args["html"].AsBoolean());
  500.         
  501. #ifdef C_FORMATTING
  502.         if (dbname) {
  503.             BLAST_PrintOutputHeader(format_options, 
  504.                 args["greedy"].AsBoolean(), dbname, db_is_na);
  505.         }
  506. #endif
  507.         
  508.         RegisterBlastDbLoader(dbname, db_is_na);
  509.         /* Format the results */
  510.         TSeqLocInfoVector maskv =
  511.             BlastMaskLoc2CSeqLoc(blaster.GetFilteredQueryRegions(), 
  512.                               blaster.GetQueries(), program);
  513.         
  514.         if (BLAST_FormatResults(seqalignv, program, blaster.GetQueries(), 
  515.                 maskv, format_options, blaster.GetOptions().GetOutOfFrameMode())) {
  516.             NCBI_THROW(CBlastException, eInternal, 
  517.                        "Error in formatting results");
  518.         }
  519.         
  520. #ifdef C_FORMATTING
  521.         PrintOutputFooter(program, format_options, score_options, 
  522.             m_sbp, lookup_options, word_options, ext_options, hit_options, 
  523.             blaster.GetQueryInfo(), dbname, blaster.GetDiagnostics());
  524. #endif
  525.         
  526.     }
  527. }
  528. static Int2 BLAST_FillRPSInfo( RPSInfo **ppinfo, Nlm_MemMap **rps_mmap,
  529.                                Nlm_MemMap **rps_pssm_mmap, const char* dbname )
  530. {
  531.    char pathname[PATH_MAX];
  532.    char filename[PATH_MAX];
  533.    RPSInfo *info;
  534.    FILE *auxfile;
  535.    Int4 i;
  536.    Int4 seq_size;
  537.    Int4 num_db_seqs;
  538.    Nlm_MemMapPtr lut_mmap;
  539.    Nlm_MemMapPtr pssm_mmap;
  540.    char buffer[PATH_MAX];
  541.    info = (RPSInfo *)malloc(sizeof(RPSInfo));
  542.    if (info == NULL)
  543.       ErrPostEx(SEV_FATAL, 1, 0, "Memory allocation failed");
  544.    /* construct the full path to the DB file. Look in
  545.       the local directory, then BLASTDB environment 
  546.       variable (if any), then .ncbirc */
  547.    sprintf(filename, "%s.loo", dbname);
  548.    if (FileLength(filename) > 0) {
  549.       strcpy(pathname, dbname);
  550.    } else {
  551. #ifdef OS_UNIX
  552.       if (getenv("BLASTDB"))
  553.          Nlm_GetAppParam("NCBI", "BLAST", "BLASTDB", 
  554.                          getenv("BLASTDB"), pathname, PATH_MAX);
  555.       else
  556. #endif
  557.          Nlm_GetAppParam ("NCBI", "BLAST", "BLASTDB", 
  558.                           BLASTDB_DIR, pathname, PATH_MAX);
  559.       sprintf(filename, "%s%s%s", pathname, DIRDELIMSTR, dbname);
  560.       strcpy(pathname, filename);
  561.    }
  562.    sprintf(filename, "%s.loo", pathname);
  563.    lut_mmap = Nlm_MemMapInit(filename);
  564.    if (lut_mmap == NULL)
  565.       ErrPostEx(SEV_FATAL, 1, 0, "Cannot map RPS BLAST lookup file");
  566.    info->lookup_header = (RPSLookupFileHeader *)lut_mmap->mmp_begin;
  567.    sprintf(filename, "%s.rps", pathname);
  568.    pssm_mmap = Nlm_MemMapInit(filename);
  569.    if (pssm_mmap == NULL)
  570.       ErrPostEx(SEV_FATAL, 1, 0, "Cannot map RPS BLAST profile file");
  571.    info->profile_header = (RPSProfileHeader *)pssm_mmap->mmp_begin;
  572.    num_db_seqs = info->profile_header->num_profiles;
  573.    sprintf(filename, "%s.aux", pathname);
  574.    auxfile = FileOpen(filename, "r");
  575.    if (auxfile == NULL)
  576.       ErrPostEx(SEV_FATAL, 1, 0,"Cannot open RPS BLAST parameters file");
  577.    fscanf(auxfile, "%s", buffer);
  578.    info->aux_info.orig_score_matrix = strdup(buffer);
  579.    fscanf(auxfile, "%d", &info->aux_info.gap_open_penalty);
  580.    fscanf(auxfile, "%d", &info->aux_info.gap_extend_penalty);
  581.    fscanf(auxfile, "%le", &info->aux_info.ungapped_k);
  582.    fscanf(auxfile, "%le", &info->aux_info.ungapped_h);
  583.    fscanf(auxfile, "%d", &info->aux_info.max_db_seq_length);
  584.    fscanf(auxfile, "%d", &info->aux_info.db_length);
  585.    fscanf(auxfile, "%lf", &info->aux_info.scale_factor);
  586.    info->aux_info.karlin_k = (double *)malloc(num_db_seqs * sizeof(double));
  587.    for (i = 0; i < num_db_seqs && !feof(auxfile); i++) {
  588.       fscanf(auxfile, "%d", &seq_size); /* not used */
  589.       fscanf(auxfile, "%le", &info->aux_info.karlin_k[i]);
  590.    }
  591.    if (i < num_db_seqs)
  592.       ErrPostEx(SEV_FATAL, 1, 0, "Missing Karlin parameters");
  593.    FileClose(auxfile);
  594.    *ppinfo = info;
  595.    *rps_mmap = lut_mmap;
  596.    *rps_pssm_mmap = pssm_mmap;
  597.    return 0;
  598. }
  599. int CBlastApplication::Run(void)
  600. {
  601.     Uint1 program_number;
  602.     int status = 0;
  603.     // Process command line args
  604.     const CArgs& args = GetArgs();
  605.     
  606.     BlastProgram2Number(args["program"].AsString().c_str(), &program_number);
  607.     EProgram program = static_cast<EProgram>(program_number);
  608.     Int4 strand_number = args["strand"].AsInteger();
  609.     ENa_strand strand;
  610.     Int4 from = args["qstart"].AsInteger();
  611.     Int4 to = args["qend"].AsInteger();
  612.     Int4 first_oid = 0;
  613.     Int4 last_oid = 0;
  614.     if (program == eBlastn ||
  615.         program == eBlastx ||
  616.         program == eRPSTblastn) {
  617.         if (strand_number == 1)
  618.             strand = eNa_strand_plus;
  619.         else if (strand_number == 2)
  620.             strand = eNa_strand_minus;
  621.         else
  622.             strand = eNa_strand_both;
  623.     }
  624.     else {
  625.         strand = eNa_strand_unknown;
  626.     }
  627.     InitScope();
  628.     int id_counter = 0;
  629.     // Read the query(ies) from input file; perform the setup
  630.     TSeqLocVector query_loc = 
  631.         BLASTGetSeqLocFromStream(args["query"].AsInputFile(),
  632.             *m_ObjMgr, strand, from, to, &id_counter,
  633.             args["lcase"].AsBoolean());
  634.     if (args["dbrange"]) {
  635.         const char* delimiters = " ,:;";
  636.         char* range_str = strdup(args["dbrange"].AsString().c_str());
  637.         first_oid = atoi(strtok(range_str, delimiters));
  638.         last_oid = atoi(strtok(NULL, delimiters));
  639.         sfree(range_str);
  640.     }
  641.     
  642.     bool db_is_na = (program == eBlastn || program == eTblastn || 
  643.                      program == eTblastx);
  644.     BlastSeqSrc* seq_src = 
  645.         SeqDbSrcInit(args["db"].AsString().c_str(), !db_is_na,
  646.                      first_oid, last_oid, NULL);
  647.     CBlastOptionsHandle* opts = CBlastOptionsFactory::Create(program);
  648.     Nlm_MemMapPtr rps_mmap = NULL;
  649.     Nlm_MemMapPtr rps_pssm_mmap = NULL;
  650.     RPSInfo *rps_info = NULL;
  651.     // Need to set up the RPS database information structure too
  652.     if (program == eRPSBlast || program == eRPSTblastn) {
  653.         if (BLAST_FillRPSInfo(&rps_info, &rps_mmap,
  654.             &rps_pssm_mmap, args["db"].AsString().c_str()) != 0) 
  655.         {
  656.             NCBI_THROW(CBlastException, eBadParameter, 
  657.                        "Cannot initialize RPS BLAST database");
  658.         }        
  659.     }
  660.     
  661.     ProcessCommandLineArgs(opts, seq_src, rps_info);
  662.     CDbBlast blaster(query_loc, seq_src, *opts, rps_info);
  663.     TSeqAlignVector seqalignv = blaster.Run();
  664.     BlastSeqSrcFree(seq_src);
  665.     if (rps_info) {
  666.         Nlm_MemMapFini(rps_mmap);
  667.         Nlm_MemMapFini(rps_pssm_mmap);
  668.         sfree(rps_info->aux_info.karlin_k);
  669.         sfree(rps_info->aux_info.orig_score_matrix);
  670.         sfree(rps_info);
  671.     }
  672.     FormatResults(blaster, seqalignv);
  673.     return status;
  674. }
  675. void CBlastApplication::Exit(void)
  676. {
  677.     SetDiagStream(0);
  678. }
  679. int main(int argc, const char* argv[] /*, const char* envp[]*/)
  680. {
  681.     return CBlastApplication().AppMain(argc, argv, 0, eDS_Default, 0);
  682. }