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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: asn2flat.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:27:20  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: asn2flat.cpp,v 1000.1 2004/06/01 18:27:20 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author:  Aaron Ucko, Mati Shomrat, NCBI
  35. *
  36. * File Description:
  37. *   flat-file generator application
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbiapp.hpp>
  43. #include <serial/objistr.hpp>
  44. #include <serial/serial.hpp>
  45. #include <objects/seqset/Seq_entry.hpp>
  46. #include <objects/seqloc/Seq_loc.hpp>
  47. #include <objects/seqloc/Seq_interval.hpp>
  48. #include <objmgr/object_manager.hpp>
  49. #include <objmgr/scope.hpp>
  50. #include <objmgr/seq_entry_ci.hpp>
  51. #include <objtools/data_loaders/genbank/gbloader.hpp>
  52. #include <objtools/format/flat_file_config.hpp>
  53. #include <objtools/format/flat_file_generator.hpp>
  54. #include <objtools/format/flat_expt.hpp>
  55. #include <objects/seqset/gb_release_file.hpp>
  56. BEGIN_NCBI_SCOPE
  57. USING_SCOPE(objects);
  58. class CAsn2FlatApp : public CNcbiApplication, public CGBReleaseFile::ISeqEntryHandler
  59. {
  60. public:
  61.     void Init(void);
  62.     int  Run (void);
  63.     bool HandleSeqEntry(CRef<CSeq_entry>& se);
  64. private:
  65.     // types
  66.     typedef CFlatFileConfig::TFormat    TFormat;
  67.     typedef CFlatFileConfig::TMode      TMode;
  68.     typedef CFlatFileConfig::TStyle     TStyle;
  69.     typedef CFlatFileConfig::TFlags     TFlags;
  70.     typedef CFlatFileConfig::TView      TView;
  71.     CObjectIStream* x_OpenIStream(const CArgs& args);
  72.     CFlatFileGenerator* x_CreateFlatFileGenerator(const CArgs& args);
  73.     TFormat         x_GetFormat(const CArgs& args);
  74.     TMode           x_GetMode(const CArgs& args);
  75.     TStyle          x_GetStyle(const CArgs& args);
  76.     TFlags          x_GetFlags(const CArgs& args);
  77.     TView           x_GetView(const CArgs& args);
  78.     TSeqPos x_GetFrom(const CArgs& args);
  79.     TSeqPos x_GetTo  (const CArgs& args);
  80.     void x_GetLocation(const CSeq_entry_Handle& entry,
  81.         const CArgs& args, CSeq_loc& loc);
  82.     CBioseq_Handle x_DeduceTarget(const CSeq_entry_Handle& entry);
  83.     // data
  84.     CRef<CObjectManager>        m_Objmgr;       // Object Manager
  85.     CNcbiOstream*               m_Os;           // Output stream
  86.     CRef<CFlatFileGenerator>    m_FFGenerator;  // Flat-file generator
  87. };
  88. void CAsn2FlatApp::Init(void)
  89. {
  90.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  91.     arg_desc->SetUsageContext(
  92.         GetArguments().GetProgramBasename(),
  93.         "Convert an ASN.1 Seq-entry into a flat report",
  94.         false);
  95.     
  96.     // input
  97.     {{
  98.         // name
  99.         arg_desc->AddOptionalKey("i", "InputFile", 
  100.             "Input file name", CArgDescriptions::eInputFile);
  101.         
  102.         // input file serial format (AsnTextAsnBinaryXML, default: AsnText)
  103.         arg_desc->AddDefaultKey("serial", "SerialFormat", "Input file format",
  104.             CArgDescriptions::eString, "text");
  105.         arg_desc->SetConstraint("serial", &(*new CArgAllow_Strings,
  106.             "text", "binary", "XML"));
  107.     }}
  108.     // batch processing
  109.     {{
  110.         arg_desc->AddOptionalKey("batch", "BatchMode",
  111.             "Process NCBI release file", CArgDescriptions::eString);
  112.         // compression
  113.         arg_desc->AddFlag("c", "Compressed file");
  114.         // propogate top descriptors
  115.         arg_desc->AddFlag("p", "Propogate top descriptors");
  116.     }}
  117.     
  118.     // output
  119.     {{ 
  120.         // name
  121.         arg_desc->AddOptionalKey("o", "OutputFile", 
  122.             "Output file name", CArgDescriptions::eOutputFile);
  123.     }}
  124.     
  125.     // loaders
  126.     {{
  127.         arg_desc->AddOptionalKey("load", "Loader", "Add data loader",
  128.             CArgDescriptions::eString);
  129.         // currently we support only the Genbank loader.
  130.         arg_desc->SetConstraint("load", &(*new CArgAllow_Strings, "gb"));
  131.     }}
  132.     // report
  133.     {{
  134.         // format (default: genbank)
  135.         arg_desc->AddDefaultKey("format", "Format", "Output format",
  136.             CArgDescriptions::eString, "genbank");
  137.         arg_desc->SetConstraint("format", &(*new CArgAllow_Strings,
  138.             "genbank", "embl", "ddbj", "gbseq", "ftable", "gff"));
  139.         // mode (default: dump)
  140.         arg_desc->AddDefaultKey("mode", "Mode", "Restriction level",
  141.             CArgDescriptions::eString, "gbench");
  142.         arg_desc->SetConstraint("mode", 
  143.             &(*new CArgAllow_Strings, "release", "entrez", "gbench", "dump"));
  144.         // style (default: normal)
  145.         arg_desc->AddDefaultKey("style", "Style", "Formatting style",
  146.             CArgDescriptions::eString, "normal");
  147.         arg_desc->SetConstraint("style", 
  148.             &(*new CArgAllow_Strings, "normal", "segment", "master", "contig"));
  149.         // flags (default: 0)
  150.         arg_desc->AddDefaultKey("flags", "Flags", "Custom flags",
  151.             CArgDescriptions::eInteger, "0");
  152.         // view (default: nucleotide)
  153.         arg_desc->AddDefaultKey("view", "View", "View",
  154.             CArgDescriptions::eString, "nuc");
  155.         arg_desc->SetConstraint("view", 
  156.             &(*new CArgAllow_Strings, "all", "prot", "nuc"));
  157.         
  158.         // id
  159.         arg_desc->AddOptionalKey("id", "ID", 
  160.             "Specific ID to display", CArgDescriptions::eString);
  161.         // from
  162.         arg_desc->AddOptionalKey("from", "From",
  163.             "Begining of shown range", CArgDescriptions::eInteger);
  164.         
  165.         // to
  166.         arg_desc->AddOptionalKey("to", "To",
  167.             "End of shown range", CArgDescriptions::eInteger);
  168.         
  169.         // strand
  170.         
  171.         // accession to extract
  172.     }}
  173.     
  174.     SetupArgDescriptions(arg_desc.release());
  175. }
  176. int CAsn2FlatApp::Run(void)
  177. {
  178.     const CArgs&   args = GetArgs();
  179.     // create object manager
  180.     m_Objmgr.Reset(new CObjectManager);
  181.     if ( !m_Objmgr ) {
  182.         NCBI_THROW(CFlatException, eInternal, "Could not create object manager");
  183.     }
  184.     if ( args["load"]  &&  args["load"].AsString() == "gb" ) {
  185.         m_Objmgr->RegisterDataLoader(*new CGBDataLoader("ID"),
  186.                                  CObjectManager::eDefault);
  187.     }
  188.     // open the output stream
  189.     m_Os = args["o"] ? &(args["o"].AsOutputFile()) : &cout;
  190.     if ( m_Os == 0 ) {
  191.         NCBI_THROW(CFlatException, eInternal, "Could not open output stream");
  192.     }
  193.     // create the flat-file generator
  194.     m_FFGenerator.Reset(x_CreateFlatFileGenerator(args));
  195.     if ( args["batch"] ) {
  196.         CGBReleaseFile in(args["i"].AsString());
  197.         in.RegisterHandler(this);
  198.         in.Read();  // HandleSeqEntry will be called from this function
  199.     } else {
  200.         // open the input file (default: stdin)
  201.         auto_ptr<CObjectIStream> in(x_OpenIStream(args));
  202.         // read in the seq-entry
  203.         CRef<CSeq_entry> se(new CSeq_entry);
  204.         if ( !se ) {
  205.             NCBI_THROW(CFlatException, eInternal, 
  206.                 "Could not allocate Seq-entry object");
  207.         }
  208.         in->Read(ObjectInfo(*se));
  209.         if ( se->Which() == CSeq_entry::e_not_set ) {
  210.             NCBI_THROW(CFlatException, eInternal, "Invalid Seq-entry");
  211.         }
  212.         HandleSeqEntry(se);
  213.     }
  214.     m_Os->flush();
  215.     return 0;
  216. }
  217. bool CAsn2FlatApp::HandleSeqEntry(CRef<CSeq_entry>& se)
  218. {
  219.     const CArgs&   args = GetArgs();
  220.     // create new scope
  221.     CRef<CScope> scope(new CScope(*m_Objmgr));
  222.     if ( !scope ) {
  223.         NCBI_THROW(CFlatException, eInternal, "Could not create scope");
  224.     }
  225.     scope->AddDefaults();
  226.     // add entry to scope    
  227.     CSeq_entry_Handle entry = scope->AddTopLevelSeqEntry(*se);
  228.     if ( !entry ) {
  229.         NCBI_THROW(CFlatException, eInternal, "Failed to insert entry to scope.");
  230.     }
  231.     // generate flat file
  232.     if ( args["from"]  ||  args["to"] ) {
  233.         CSeq_loc loc;
  234.         x_GetLocation(entry, args, loc);
  235.         m_FFGenerator->Generate(loc, *scope, *m_Os);
  236.     } else {
  237.         m_FFGenerator->Generate(entry, *m_Os);
  238.     }
  239.     m_FFGenerator->Reset();
  240.     return true;
  241. }
  242. CObjectIStream* CAsn2FlatApp::x_OpenIStream(const CArgs& args)
  243. {
  244.     // determine the file serialization format.
  245.     // use user specifications (if available) otherwise the defualt
  246.     // is AsnText.
  247.     ESerialDataFormat serial = eSerial_AsnText;
  248.     if ( args["serial"] ) {
  249.         const string& val = args["serial"].AsString();
  250.         if ( val == "text" ) {
  251.             serial = eSerial_AsnText;
  252.         } else if ( val == "binary" ) {
  253.             serial = eSerial_AsnBinary;
  254.         } else if ( val == "XML" ) {
  255.             serial = eSerial_Xml;
  256.         }
  257.     }
  258.     // open the input file, or standard input if no file specified.
  259.     return args["i"] ?
  260.         CObjectIStream::Open(args["i"].AsString(), serial) :
  261.         CObjectIStream::Open(serial, cin);
  262. }
  263. CFlatFileGenerator* CAsn2FlatApp::x_CreateFlatFileGenerator(const CArgs& args)
  264. {
  265.     TFormat    format = x_GetFormat(args);
  266.     TMode      mode   = x_GetMode(args);
  267.     TStyle     style  = x_GetStyle(args);
  268.     TFlags     flags  = x_GetFlags(args);
  269.     TView      view   = x_GetView(args);
  270.     CFlatFileConfig cfg(format, mode, style, flags, view);
  271.     return new CFlatFileGenerator(cfg);
  272. }
  273. CAsn2FlatApp::TFormat CAsn2FlatApp::x_GetFormat(const CArgs& args)
  274. {
  275.     const string& format = args["format"].AsString();
  276.     if ( format == "genbank" ) {
  277.         return CFlatFileConfig::eFormat_GenBank;
  278.     } else if ( format == "embl" ) {
  279.         return CFlatFileConfig::eFormat_EMBL;
  280.     } else if ( format == "ddbj" ) {
  281.         return CFlatFileConfig::eFormat_DDBJ;
  282.     } else if ( format == "gbseq" ) {
  283.         return CFlatFileConfig::eFormat_GBSeq;
  284.     } else if ( format == "ftable" ) {
  285.         return CFlatFileConfig::eFormat_FTable;
  286.     } else if ( format == "gff" ) {
  287.         return CFlatFileConfig::eFormat_GFF;
  288.     }
  289.     // default
  290.     return CFlatFileConfig::eFormat_GenBank;
  291. }
  292. CAsn2FlatApp::TMode CAsn2FlatApp::x_GetMode(const CArgs& args)
  293. {
  294.     const string& mode = args["mode"].AsString();
  295.     if ( mode == "release" ) {
  296.         return CFlatFileConfig::eMode_Release;
  297.     } else if ( mode == "entrez" ) {
  298.         return CFlatFileConfig::eMode_Entrez;
  299.     } else if ( mode == "gbench" ) {
  300.         return CFlatFileConfig::eMode_GBench;
  301.     } else if ( mode == "dump" ) {
  302.         return CFlatFileConfig::eMode_Dump;
  303.     } 
  304.     // default
  305.     return CFlatFileConfig::eMode_GBench;
  306. }
  307. CAsn2FlatApp::TStyle CAsn2FlatApp::x_GetStyle(const CArgs& args)
  308. {
  309.     const string& style = args["style"].AsString();
  310.     if ( style == "normal" ) {
  311.         return CFlatFileConfig::eStyle_Normal;
  312.     } else if ( style == "segment" ) {
  313.         return CFlatFileConfig::eStyle_Segment;
  314.     } else if ( style == "master" ) {
  315.         return CFlatFileConfig::eStyle_Master;
  316.     } else if ( style == "contig" ) {
  317.         return CFlatFileConfig::eStyle_Contig;
  318.     } 
  319.     // default
  320.     return CFlatFileConfig::eStyle_Normal;
  321. }
  322. CAsn2FlatApp::TFlags CAsn2FlatApp::x_GetFlags(const CArgs& args)
  323. {
  324.     return args["flags"].AsInteger();
  325. }
  326. CAsn2FlatApp::TView CAsn2FlatApp::x_GetView(const CArgs& args)
  327. {
  328.     const string& view = args["view"].AsString();
  329.     if ( view == "all" ) {
  330.         return CFlatFileConfig::fViewAll;
  331.     } else if ( view == "prot" ) {
  332.         return CFlatFileConfig::fViewProteins;
  333.     } else if ( view == "nuc" ) {
  334.         return CFlatFileConfig::fViewNucleotides;
  335.     } 
  336.     // default
  337.     return CFlatFileConfig::fViewNucleotides;
  338. }
  339. TSeqPos CAsn2FlatApp::x_GetFrom(const CArgs& args)
  340. {
  341.     return args["from"] ? 
  342.         static_cast<TSeqPos>(args["from"].AsInteger() - 1) :
  343.         CRange<TSeqPos>::GetWholeFrom(); 
  344. }
  345. TSeqPos CAsn2FlatApp::x_GetTo(const CArgs& args)
  346. {
  347.     return args["to"] ? 
  348.         static_cast<TSeqPos>(args["to"].AsInteger() - 1) :
  349.         CRange<TSeqPos>::GetWholeTo();
  350. }
  351. void CAsn2FlatApp::x_GetLocation
  352. (const CSeq_entry_Handle& entry,
  353.  const CArgs& args,
  354.  CSeq_loc& loc)
  355. {
  356.     _ASSERT(entry);
  357.         
  358.     CBioseq_Handle h = x_DeduceTarget(entry);
  359.     if ( !h ) {
  360.         NCBI_THROW(CFlatException, eInvalidParam,
  361.             "Cannot deduce target bioseq.");
  362.     }
  363.     TSeqPos length = h.GetInst_Length();
  364.     TSeqPos from   = x_GetFrom(args);
  365.     TSeqPos to     = min(x_GetTo(args), length);
  366.     
  367.     if ( from == CRange<TSeqPos>::GetWholeFrom()  &&  to == length ) {
  368.         // whole
  369.         loc.SetWhole().Assign(*h.GetSeqId());
  370.     } else {
  371.         // interval
  372.         loc.SetInt().SetId().Assign(*h.GetSeqId());
  373.         loc.SetInt().SetFrom(from);
  374.         loc.SetInt().SetTo(to);
  375.     }
  376. }
  377. // if the 'from' or 'to' flags are specified try to guess the bioseq.
  378. CBioseq_Handle CAsn2FlatApp::x_DeduceTarget(const CSeq_entry_Handle& entry)
  379. {
  380.     if ( entry.IsSeq() ) {
  381.         return entry.GetSeq();
  382.     }
  383.     _ASSERT(entry.IsSet());
  384.     CBioseq_set_Handle bsst = entry.GetSet();
  385.     if ( !bsst.IsSetClass() ) {
  386.         NCBI_THROW(CFlatException, eInvalidParam,
  387.             "Cannot deduce target bioseq.");
  388.     }
  389.     _ASSERT(bsst.IsSetClass());
  390.     switch ( bsst.GetClass() ) {
  391.     case CBioseq_set::eClass_nuc_prot:
  392.         // return the nucleotide
  393.         for ( CSeq_entry_CI it(entry); it; ++it ) {
  394.             if ( it->IsSeq() ) {
  395.                 CBioseq_Handle h = it->GetSeq();
  396.                 if ( h  &&  CSeq_inst::IsNa(h.GetInst_Mol()) ) {
  397.                     return h;
  398.                 }
  399.             }
  400.         }
  401.         break;
  402.     case CBioseq_set::eClass_gen_prod_set:
  403.         // return the genomic
  404.         for ( CSeq_entry_CI it(bsst); it; ++it ) {
  405.             if ( it->IsSeq()  &&
  406.                  it->GetSeq().GetInst_Mol() == CSeq_inst::eMol_dna ) {
  407.                  return it->GetSeq();
  408.             }
  409.         }
  410.         break;
  411.     case CBioseq_set::eClass_segset:
  412.         // return the segmented bioseq
  413.         for ( CSeq_entry_CI it(bsst); it; ++it ) {
  414.             if ( it->IsSeq() ) {
  415.                 return it->GetSeq();
  416.             }
  417.         }
  418.         break;
  419.     default:
  420.         break;
  421.     }
  422.     NCBI_THROW(CFlatException, eInvalidParam,
  423.             "Cannot deduce target bioseq.");
  424. }
  425. END_NCBI_SCOPE
  426. USING_NCBI_SCOPE;
  427. /////////////////////////////////////////////////////////////////////////////
  428. //
  429. // Main
  430. int main(int argc, const char** argv)
  431. {
  432.     return CAsn2FlatApp().AppMain(argc, argv, 0, eDS_Default, 0);
  433. }
  434. /*
  435. * ===========================================================================
  436. *
  437. * $Log: asn2flat.cpp,v $
  438. * Revision 1000.1  2004/06/01 18:27:20  gouriano
  439. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  440. *
  441. * Revision 1.9  2004/05/21 21:41:38  gorelenk
  442. * Added PCH ncbi_pch.hpp
  443. *
  444. * Revision 1.8  2004/05/19 14:48:36  shomrat
  445. * Implemented batch processing
  446. *
  447. * Revision 1.7  2004/04/22 16:04:37  shomrat
  448. * Support partial region
  449. *
  450. * Revision 1.6  2004/03/31 19:23:47  shomrat
  451. * name changes
  452. *
  453. * Revision 1.5  2004/03/25 21:07:54  shomrat
  454. * Use handles
  455. *
  456. * Revision 1.4  2004/03/05 18:51:45  shomrat
  457. * use view instead of filter
  458. *
  459. * Revision 1.3  2004/02/11 22:58:26  shomrat
  460. * using flags from flag file
  461. *
  462. * Revision 1.2  2004/01/20 20:41:53  ucko
  463. * Don't try to return auto_ptrs, or construct them with "=".
  464. *
  465. * Revision 1.1  2004/01/14 15:03:29  shomrat
  466. * Initial Revision
  467. *
  468. *
  469. * ===========================================================================
  470. */