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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: indexed_export.cpp,v $
  4.  * PRODUCTION Revision 1000.5  2004/06/01 20:58:04  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: indexed_export.cpp,v 1000.5 2004/06/01 20:58:04 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.  * Authors:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *    CDataPlugin_IndexedExport - save a sequence and all of its referenced components
  38.  *                     into a directory
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include "indexed_export.hpp"
  42. #include <corelib/ncbiapp.hpp>
  43. #include <corelib/ncbireg.hpp>
  44. #include <gui/core/idocument.hpp>
  45. #include <gui/core/plugin_utils.hpp>
  46. #include <gui/core/version.hpp>
  47. #include <gui/plugin/PluginCommandSet.hpp>
  48. #include <gui/plugin/PluginInfo.hpp>
  49. #include <gui/plugin/PluginValueConstraint.hpp>
  50. #include <gui/utils/message_box.hpp>
  51. #include <gui/dialogs/progress/progress_dlg_ex.hpp>
  52. #include <objects/seqset/Seq_entry.hpp>
  53. #include <objmgr/util/sequence.hpp>
  54. #include <objmgr/bioseq_ci.hpp>
  55. #include <objmgr/seq_map_ci.hpp>
  56. #include <serial/objostrasn.hpp>
  57. BEGIN_NCBI_SCOPE
  58. USING_SCOPE(objects);
  59. static const string sc_text_str  ("Text ASN.1");
  60. static const string sc_binary_str("Binary ASN.1");
  61. static const string sc_xml_str   ("XML");
  62. static const string sc_fasta_str ("FastA");
  63. static const string sc_flat_str  ("GenBank Flat-File");
  64. void CDataPlugin_IndexedExport::GetInfo(CPluginInfo& info)
  65. {
  66.     info.Reset();
  67.     // version info macro
  68.     info.SetInfo(CPluginVersion::eMajor, CPluginVersion::eMinor, 0,
  69.                  string(__DATE__) + " " + string(__TIME__),
  70.                  "CDataPlugin_IndexedExport", "Indexed Directory",
  71.                  "Save this record and all its components "
  72.                  "into a directory that can be indexed", "");
  73.     // command info
  74.     CPluginCommandSet& cmds     = info.SetCommands();
  75.     CPluginCommand& save_args   = cmds.AddDataCommand(eDataCommand_save);
  76.     save_args.AddArgument("seqid", "Sequence", CSeq_id::GetTypeInfo());
  77.     save_args.AddDefaultArgument("fmt", "Format", CPluginArg::eString,
  78.                                  sc_binary_str);
  79.     save_args.SetConstraint("fmt",
  80.                             (*CPluginValueConstraint::CreateSet(),
  81.                              sc_text_str,
  82.                              sc_binary_str,
  83.                              sc_xml_str,
  84.                              sc_fasta_str
  85.                              ));
  86.     save_args.AddArgument("file", "File name", CPluginArg::eFile);
  87.     save_args.AddArgument("alias", "Alias", CPluginArg::eString);
  88. }
  89. class CCancelButtonException : EXCEPTION_VIRTUAL_BASE public CException
  90. {
  91. public:
  92.     // Enumerated list of document management errors
  93.     enum EErrCode {
  94.         eCancelPressed
  95.     };
  96.     // Translate the specific error code into a string representations of
  97.     // that error code.
  98.     virtual const char* GetErrCodeString(void) const
  99.     {
  100.         switch (GetErrCode()) {
  101.         case eCancelPressed: return "eCancelPressed";
  102.         default:             return CException::GetErrCodeString();
  103.         }
  104.     }
  105.     NCBI_EXCEPTION_DEFAULT(CCancelButtonException, CException);
  106. };
  107. //
  108. // Save()
  109. // Save the information in a given document into a file
  110. //
  111. void CDataPlugin_IndexedExport::Save(CPluginMessage& msg)
  112. {
  113.     const CPluginCommand& args = msg.GetRequest().GetCommand();
  114.     CPluginReply& reply = msg.SetReply();
  115.     const IDocument& doc = *args["seqid"].GetDocument();
  116.     const CSeq_id* id = dynamic_cast<const CSeq_id*> (&args["seqid"].AsObject());
  117.     if ( !id ) {
  118.         reply.SetStatus(eMessageStatus_failed);
  119.         return;
  120.     }
  121.     CProgressDlgEx dlg;
  122.     dlg.Show();
  123.     try {
  124.         string fmt_str   = args["fmt"].AsString();
  125.         string file_base = args["file"].AsString();
  126.         string alias     = args["alias"].AsString();
  127.         string path;
  128.         string base;
  129.         string sub_path;
  130.         {{
  131.             CDirEntry::SplitPath(file_base, &path, &base);
  132.             sub_path = path;
  133.             sub_path += base + ".data";
  134.             sub_path += CDirEntry::GetPathSeparator();
  135.             CDir dir(sub_path);
  136.             if ( !dir.Exists() ) {
  137.                 dir.Create();
  138.             }
  139.         }}
  140.         // find out what object to serialize
  141.         // in general, we serialize precisely what the document contains
  142.         // the exception to this is that we dereference any seq-id
  143.         // to its largest component (= top-level seq-entry)
  144.         CConstRef<CSerialObject> obj
  145.             (dynamic_cast<const CSerialObject*> (doc.GetObject()));
  146.         if (obj.GetPointer()  &&
  147.             obj->GetThisTypeInfo() == CSeq_id::GetTypeInfo()) {
  148.             const CSeq_id& id =
  149.                 dynamic_cast<const CSeq_id&>(*doc.GetObject());
  150.             CBioseq_Handle handle = doc.GetScope().GetBioseqHandle(id);
  151.             obj.Reset(&handle.GetTopLevelSeqEntry());
  152.         }
  153.         //
  154.         // format handling
  155.         //
  156.         EFormat fmt = eFormat_text_asn;
  157.         if (fmt_str == sc_text_str) {
  158.             // ASN.1 text
  159.             fmt = eFormat_text_asn;
  160.         } else if (fmt_str == sc_binary_str) {
  161.             // ASN.1 binary
  162.             fmt = eFormat_binary_asn;
  163.         } else if (fmt_str == sc_xml_str) {
  164.             // XML
  165.             fmt = eFormat_xml;
  166.         } else if (fmt_str == sc_fasta_str) {
  167.             // FastA
  168.             fmt = eFormat_fasta;
  169.         }
  170.         try {
  171.             //
  172.             // first, save the sequence of interest
  173.             //
  174.             set< CConstRef<CSeq_entry> > entries;
  175.             list< CConstRef<CSeq_entry> > entries_for_products;
  176.             dlg.SetMessage("Saving document...");
  177.             CScope& scope = doc.GetScope();
  178.             CBioseq_Handle handle = scope.GetBioseqHandle(*id);
  179.             x_Save(scope, handle.GetTopLevelSeqEntry(), fmt, file_base);
  180.             {{
  181.                 CConstRef<CSeq_entry> ref(&handle.GetTopLevelSeqEntry());
  182.                 entries.insert(ref);
  183.                 entries_for_products.push_back(ref);
  184.             }}
  185.             //
  186.             // now, we iterate all sequences referred to by this sequence
  187.             //
  188.             int count = 0;
  189.             const CSeqMap& seqmap = handle.GetSeqMap();
  190.             CSeqMap::const_iterator map_iter =
  191.                 seqmap.begin_resolved(&scope, -1, CSeqMap::fFindRef);
  192.             for ( ;  map_iter;  ++map_iter) {
  193.                 if (map_iter.GetType() != CSeqMap::eSeqRef) {
  194.                     continue;
  195.                 }
  196.                 CSeq_id_Handle idh = map_iter.GetRefSeqid();
  197.                 dlg.SetMessage("Retrieving sequence: " + idh.AsString());
  198.                 LOG_POST(Info << "retrieving " << idh.AsString()); 
  199.                 CBioseq_Handle h = scope.GetBioseqHandle(idh);
  200.                 const CSeq_entry& entry = h.GetTopLevelSeqEntry();
  201.                 CConstRef<CSeq_entry> ref(&entry);
  202.                 if ( !entries.insert(ref).second ) {
  203.                     continue;
  204.                 }
  205.                 entries_for_products.push_back(ref);
  206.                 dlg.SetMessage("Saving sequence: " + idh.AsString());
  207.                 LOG_POST(Info << "saving " << idh.AsString()); 
  208.                 string file_name =
  209.                     sub_path + base + "." + NStr::IntToString(++count);
  210.                 x_Save(scope, entry, fmt, file_name);
  211.                 Fl::check();
  212.                 if ( !dlg.IsShown() ) {
  213.                     NCBI_THROW(CCancelButtonException,
  214.                                eCancelPressed, "");
  215.                 }
  216.             }
  217.             //
  218.             // now, iterate all products in all seq-entries
  219.             //
  220.             ITERATE (list< CConstRef<CSeq_entry> >, iter, entries_for_products) {
  221.                 CTypeConstIterator<CSeq_feat> feat_iter(**iter);
  222.                 for ( ; feat_iter;  ++feat_iter) {
  223.                     const CSeq_feat& feat = *feat_iter;
  224.                     if ( !feat.IsSetProduct() ) {
  225.                         continue;
  226.                     }
  227.                     string id_label;
  228.                     sequence::GetId(feat.GetProduct()).GetLabel(&id_label);
  229.                     dlg.SetMessage("Retrieving product sequence: " + id_label);
  230.                     LOG_POST(Info << "retrieving " << id_label); 
  231.                     CBioseq_Handle h = scope.GetBioseqHandle(feat.GetLocation());
  232.                     const CSeq_entry& entry = h.GetTopLevelSeqEntry();
  233.                     CConstRef<CSeq_entry> ref(&entry);
  234.                     if ( !entries.insert(ref).second ) {
  235.                         continue;
  236.                     }
  237.                     entries_for_products.push_back(ref);
  238.                     dlg.SetMessage("Saving product sequence: " + id_label);
  239.                     LOG_POST(Info << "saving " << id_label); 
  240.                     string file_name =
  241.                         sub_path + base + "." + NStr::IntToString(++count);
  242.                     x_Save(scope, entry, fmt, file_name);
  243.                     Fl::check();
  244.                     if ( !dlg.IsShown() ) {
  245.                         NCBI_THROW(CCancelButtonException,
  246.                                    eCancelPressed, "");
  247.                     }
  248.                 }
  249.             }
  250.         }
  251.         catch (CCancelButtonException&) {
  252.         }
  253.         //
  254.         // configure this path to be indexed at app start-up
  255.         //
  256.         CNcbiApplication* app = CNcbiApplication::Instance();
  257.         _ASSERT(app);
  258.         CNcbiRegistry& reg = app->GetConfig();
  259.         string section_name = "LDS";
  260.         {{
  261.             list<string> sections;
  262.             reg.EnumerateSections(&sections);
  263.             size_t count = 0;
  264.             ITERATE (list<string>, iter, sections) {
  265.                 if (iter->find("LDS") == 0) {
  266.                     ++count;
  267.                 }
  268.             }
  269.             section_name += NStr::IntToString(count + 1);
  270.         }}
  271.         reg.Set(section_name, "Path",  path, CNcbiRegistry::ePersistent);
  272.         reg.Set(section_name, "Alias", alias, CNcbiRegistry::ePersistent);
  273.         reply.SetStatus(eMessageStatus_success);
  274.     }
  275.     catch (CException& e) {
  276.         string msg("Failed to save file:n");
  277.         msg += e.GetMsg();
  278.         NcbiMessageBox(msg);
  279.         reply.SetStatus(eMessageStatus_failed);
  280.     }
  281. #ifndef _DEBUG
  282.     catch (...) {
  283.         NcbiMessageBox("Failed to save file:nUnknown errorn");
  284.         reply.SetStatus(eMessageStatus_failed);
  285.     }
  286. #endif
  287. }
  288. void CDataPlugin_IndexedExport::x_Save(CScope& scope, const CSeq_entry& entry,
  289.                             EFormat fmt, const string& file_name)
  290. {
  291.     CNcbiOfstream ostr(file_name.c_str(), ios::binary);
  292.     switch (fmt) {
  293.     case eFormat_text_asn:
  294.         {{
  295.             auto_ptr<CObjectOStream> os
  296.                 (CObjectOStream::Open(eSerial_AsnText, ostr));
  297.             *os << entry;
  298.         }}
  299.         break;
  300.     case eFormat_binary_asn:
  301.         {{
  302.             auto_ptr<CObjectOStream> os
  303.                 (CObjectOStream::Open(eSerial_AsnBinary, ostr));
  304.             *os << entry;
  305.         }}
  306.         break;
  307.     case eFormat_xml:
  308.         {{
  309.             auto_ptr<CObjectOStream> os
  310.                 (CObjectOStream::Open(eSerial_Xml, ostr));
  311.             *os << entry;
  312.         }}
  313.         break;
  314.     case eFormat_fasta:
  315.         {{
  316.             CFastaOstream fasta_ostr(ostr);
  317.             CBioseq_CI bioseq_iter(scope, entry);
  318.             for ( ;  bioseq_iter;  ++bioseq_iter) {
  319.                 fasta_ostr.Write(*bioseq_iter);
  320.             }
  321.         }}
  322.         break;
  323.     }
  324. }
  325. END_NCBI_SCOPE
  326. /*
  327.  * ===========================================================================
  328.  * $Log: indexed_export.cpp,v $
  329.  * Revision 1000.5  2004/06/01 20:58:04  gouriano
  330.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  331.  *
  332.  * Revision 1.10  2004/05/25 17:21:59  dicuccio
  333.  * Modified class names.  Fonts to 12 point
  334.  *
  335.  * Revision 1.9  2004/05/21 22:27:48  gorelenk
  336.  * Added PCH ncbi_pch.hpp
  337.  *
  338.  * Revision 1.8  2004/03/11 17:43:41  dicuccio
  339.  * Use new file chooser dialog
  340.  *
  341.  * Revision 1.7  2004/02/05 18:05:07  dicuccio
  342.  * Added better (GUI) handling of sequence download.  Added saving of products as
  343.  * well as main sequence.
  344.  *
  345.  * Revision 1.6  2004/01/27 18:44:25  dicuccio
  346.  * Added progress dialog.  Added missing headers.  Added parameter handling of
  347.  * fiel to save to.  CHanged directory layout of indexed structure to show master
  348.  * record in top-level directory
  349.  *
  350.  * Revision 1.5  2003/12/05 13:07:54  dicuccio
  351.  * Split management interface into a separate plugin.  Fixed linker error
  352.  * introduced with status bar
  353.  *
  354.  * Revision 1.4  2003/11/24 15:45:37  dicuccio
  355.  * Renamed CVersion to CPluginVersion
  356.  *
  357.  * Revision 1.3  2003/11/06 20:12:15  dicuccio
  358.  * Cleaned up handling of USING_SCOPE - removed from all headers
  359.  *
  360.  * Revision 1.2  2003/11/04 17:49:25  dicuccio
  361.  * Changed calling parameters for plugins - pass CPluginMessage instead of paired
  362.  * CPluginCommand/CPluginReply
  363.  *
  364.  * Revision 1.1  2003/10/07 13:41:13  dicuccio
  365.  * Added indexed export plugin
  366.  *
  367.  * Revision 1.1  2003/09/16 14:06:48  dicuccio
  368.  * Initial revision - split from CFileLoader
  369.  *
  370.  * ===========================================================================
  371.  */