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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: obj_convert.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 20:44:10  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.19
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: obj_convert.cpp,v 1000.4 2004/06/01 20:44:10 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.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbimtx.hpp>
  41. #include <gui/core/obj_convert.hpp>
  42. #include <gui/core/idocument.hpp>
  43. #include <gui/objutils/utils.hpp>
  44. #include <gui/utils/message_box.hpp>
  45. #include <objects/seq/Bioseq.hpp>
  46. #include <objects/seq/Seq_annot.hpp>
  47. #include <objects/seqalign/Seq_align.hpp>
  48. #include <objects/seqalign/Seq_align_set.hpp>
  49. #include <objects/seqloc/Seq_id.hpp>
  50. #include <objects/seqloc/Seq_loc.hpp>
  51. #include <objects/seqset/Seq_entry.hpp>
  52. #include <objects/seqset/Bioseq_set.hpp>
  53. #include <objects/seqfeat/Seq_feat.hpp>
  54. #include <objects/submit/Seq_submit.hpp>
  55. #include <objmgr/annot_selector.hpp>
  56. #include <objmgr/annot_ci.hpp>
  57. #include <serial/iterator.hpp> 
  58. #include <objmgr/feat_ci.hpp>
  59. #include <objmgr/align_ci.hpp>
  60. BEGIN_NCBI_SCOPE
  61. USING_SCOPE(objects);
  62. //////////////////////////////////////////////////////////////////////////
  63. //
  64. // generic conversions
  65. //
  66. void CObjConverter::ToObject(CScope& scope, const CObject& obj,
  67.                              const string& type_name,
  68.                              TObjList& objs) const
  69. {
  70.     if (type_name == "Seq-submit") {
  71.         ToSeqSubmit(scope, obj, objs);
  72.     } else if (type_name == "Seq-entry") {
  73.         ToSeqEntry(scope, obj, objs);
  74.     } else if (type_name == "Bioseq-set") {
  75.         ToBioseqSet(scope, obj, objs);
  76.     } else if (type_name == "Bioseq") {
  77.         ToBioseq(scope, obj, objs);
  78.     } else if (type_name == "Seq-id") {
  79.         ToSeqId(scope, obj, objs);
  80.     } else if (type_name == "Seq-loc") {
  81.         ToSeqLoc(scope, obj, objs);
  82.     } else if (type_name == "Seq-feat") {
  83.         ToSeqFeat(scope, obj, objs);
  84.     } else if (type_name == "Seq-align") {
  85.         ToSeqAlign(scope, obj, objs);
  86.     } else if (type_name == "Seq-annot") {
  87.         ToSeqAnnot(scope, obj, objs);
  88.     }
  89. }
  90. // object -> seq-submit
  91. // this is a simple wrapping of a seq-entry
  92. void CObjConverter::ToSeqSubmit(CScope& scope, const CObject& obj,
  93.                                 TObjList& objs) const
  94. {
  95.     TObjList ents;
  96.     ToSeqEntry(scope, obj, ents);
  97.     if ( !ents.empty() ) {
  98.         CRef<CSeq_submit> sub(new CSeq_submit());
  99.         objs.push_back(CConstRef<CObject>(sub.GetPointer()));
  100.         ITERATE (TObjList, iter, ents) {
  101.             CRef<CSeq_entry> entry
  102.                 (const_cast<CSeq_entry*>
  103.                  (dynamic_cast<const CSeq_entry*> (iter->GetPointer())));
  104.             sub->SetData().SetEntrys().push_back(entry);
  105.         }
  106.     }
  107. }
  108. // seq-loc -> seq-entry
  109. // we pass through seq-id to seq-entry conversion
  110. void CObjConverter::ToSeqEntry(CScope& scope, const CObject& obj,
  111.                                TObjList& objs) const
  112. {
  113.     TObjList ids;
  114.     ToSeqId(scope, obj, ids);
  115.     ITERATE (TObjList, id_iter, ids) {
  116.         CObjectConverter::Convert(scope, **id_iter,
  117.                                   CSeq_entry::GetTypeInfo()->GetName(), objs);
  118.     }
  119. }
  120. // seq-loc -> bioseq
  121. // we pass through seq-id to seq-entry conversion
  122. void CObjConverter::ToBioseq(CScope& scope, const CObject& obj,
  123.                              TObjList& objs) const
  124. {
  125.     TObjList ids;
  126.     ToSeqId(scope, obj, ids);
  127.     ITERATE (TObjList, id_iter, ids) {
  128.         CObjectConverter::Convert(scope, **id_iter,
  129.                                   CBioseq::GetTypeInfo()->GetName(), objs);
  130.     }
  131. }
  132. // object -> bioseq-set
  133. void CObjConverter::ToBioseqSet(CScope& scope, const CObject& obj,
  134.                                 TObjList& objs) const
  135. {
  136.     TObjList ents;
  137.     ToSeqEntry(scope, obj, ents);
  138.     ITERATE (TObjList, ent_iter, ents) {
  139.         const CSeq_entry& entry =
  140.             dynamic_cast<const CSeq_entry&>(**ent_iter);
  141.         if (entry.IsSet()) {
  142.             objs.push_back(CConstRef<CObject>(&entry.GetSet()));
  143.         }
  144.     }
  145. }
  146. // object -> seq-loc
  147. // we feed out of CSeq_id conversion here
  148. void CObjConverter::ToSeqLoc(CScope& scope, const CObject& obj,
  149.                              TObjList& objs) const
  150. {
  151.     TObjList ids;
  152.     ToSeqId(scope, obj, ids);
  153.     ITERATE (TObjList, iter, ids) {
  154.         CObjectConverter::Convert(scope, **iter,
  155.                                   CSeq_loc::GetTypeInfo()->GetName(), objs);
  156.     }
  157. }
  158. // object -> seq-annot
  159. // we feed out of CSeq_loc conversion here
  160. void CObjConverter::ToSeqAnnot(CScope& scope, const CObject& obj,
  161.                                TObjList& objs) const
  162. {
  163.     TObjList locs;
  164.     ToSeqLoc(scope, obj, locs);
  165.     ITERATE (TObjList, iter, locs) {
  166.         CObjectConverter::Convert(scope, **iter,
  167.                                   CSeq_annot::GetTypeInfo()->GetName(), objs);
  168.     }
  169.     // FIXME: is this necessary?
  170.     objs.sort();
  171.     objs.unique();
  172. }
  173. // object -> seq-feat
  174. // we feed out of CSeq_loc conversion here
  175. void CObjConverter::ToSeqFeat(CScope& scope, const CObject& obj,
  176.                               TObjList& objs) const
  177. {
  178.     TObjList loc;
  179.     ToSeqLoc(scope, obj, loc);
  180.     ITERATE (TObjList, iter, loc) {
  181.         CObjectConverter::Convert(scope, **iter,
  182.                                   CSeq_feat::GetTypeInfo()->GetName(), objs);
  183.     }
  184. }
  185. // object -> seq-align
  186. // we feed out of CSeq_entry conversion here
  187. void CObjConverter::ToSeqAlign(CScope& scope, const CObject& obj,
  188.                                TObjList& objs) const
  189. {
  190.     TObjList loc;
  191.     ToSeqLoc(scope, obj, loc);
  192.     ITERATE (TObjList, iter, loc) {
  193.         CObjectConverter::Convert(scope, **iter,
  194.                                   CSeq_align::GetTypeInfo()->GetName(), objs);
  195.     }
  196.     // FIXME: is this necessary?
  197.     objs.sort();
  198.     objs.unique();
  199. }
  200. //////////////////////////////////////////////////////////////////////////
  201. //
  202. // seq-entry conversions
  203. //
  204. class CSeq_entryConverter : public CObjConverter
  205. {
  206. public:
  207.     // seq-entry -> seq-submit
  208.     // this is a simple wrapping; we overload this to avoid allocation
  209.     void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
  210.     {
  211.         const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
  212.         if (entry) {
  213.             CRef<CSeq_submit> sub(new CSeq_submit());
  214.             sub->SetData().SetEntrys().push_back
  215.                 (CRef<CSeq_entry>(const_cast<CSeq_entry*>(entry)));
  216.             objs.push_back(CConstRef<CObject>(sub.GetPointer()));
  217.         }
  218.     }
  219.     // seq-entry -> seq-entry
  220.     // identity operation
  221.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  222.     {
  223.         const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
  224.         if (entry) {
  225.             objs.push_back(CConstRef<CObject>(entry));
  226.         }
  227.     }
  228.     // seq-entry -> bioseq-set
  229.     // NULL function
  230.     void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
  231.     {
  232.         const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
  233.         if (entry  &&  entry->IsSet()) {
  234.             objs.push_back(CConstRef<CObject>(&entry->GetSet()));
  235.         }
  236.     }
  237.     // seq-entry -> bioseq
  238.     // identity operation
  239.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  240.     {
  241.         const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
  242.         if (entry) {
  243.             CTypeConstIterator<CBioseq> iter(*entry);
  244.             for ( ;  iter;  ++iter) {
  245.                 objs.push_back(CConstRef<CObject>(&*iter));
  246.             }
  247.         }
  248.     }
  249.     // seq-entry -> seq-id
  250.     // we return only one of the seq-ids for each bioseq
  251.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  252.     {
  253.         TObjList seqs;
  254.         ToBioseq(scope, obj, seqs);
  255.         ITERATE (TObjList, iter, seqs) {
  256.             CObjectConverter::Convert(scope, **iter,
  257.                                       CSeq_id::GetTypeInfo()->GetName(), objs);
  258.         }
  259.     }
  260. };
  261. //////////////////////////////////////////////////////////////////////////
  262. //
  263. // bioseq conversions
  264. //
  265. class CBioseqConverter : public CObjConverter
  266. {
  267. public:
  268.     // bioseq -> seq-entry
  269.     // here we favor the parent seq-entry, if it exists
  270.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  271.     {
  272.         const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
  273.         if (bs) {
  274.             CConstRef<CObject> o;
  275.             if ( bs->GetParentEntry() ) {
  276.                 o.Reset(bs->GetParentEntry());
  277.             } else {
  278.                 CRef<CSeq_entry> se(new CSeq_entry());
  279.                 se->SetSeq(const_cast<CBioseq&>(*bs));
  280.                 o.Reset(se.GetPointer());
  281.             }
  282.             objs.push_back(o);
  283.         }
  284.     }
  285.     // bioseq -> bioseq-set
  286.     void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
  287.     {
  288.         TObjList temp;
  289.         ToSeqEntry(scope, obj, temp);
  290.         ITERATE (TObjList, iter, temp) {
  291.             CRef<CSeq_entry> entry
  292.                 (const_cast<CSeq_entry*>(
  293.                 dynamic_cast<const CSeq_entry*>(iter->GetPointer())));
  294.             CRef<CBioseq_set> bs_set(new CBioseq_set());
  295.             bs_set->SetSeq_set().push_back(entry);
  296.             objs.push_back(CConstRef<CObject>(bs_set.GetPointer()));
  297.         }
  298.     }
  299.     // bioseq -> bioseq
  300.     // identity operation
  301.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  302.     {
  303.         const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
  304.         if (bs) {
  305.             objs.push_back(CConstRef<CObject>(bs));
  306.         }
  307.     }
  308.     // bioseq -> seq-id
  309.     // we return only one of the seq-ids for this bioseq
  310.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  311.     {
  312.         const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
  313.         if (bs) {
  314.             CConstRef<CSeq_id> id = FindBestChoice(bs->GetId(), CSeq_id::Score);
  315.             if (id) {
  316.                 objs.push_back(CConstRef<CObject>(id.GetPointer()));
  317.             }
  318.         }
  319.     }
  320. };
  321. //////////////////////////////////////////////////////////////////////////
  322. //
  323. // bioseq-set conversions
  324. //
  325. class CBioseq_setConverter : public CObjConverter
  326. {
  327. public:
  328.     // bioseq-set -> seq-entry
  329.     // we create a dummy seq-entry to hold our data
  330.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  331.     {
  332.         const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
  333.         if (bs) {
  334.             CRef<CSeq_entry> entry(new CSeq_entry());
  335.             entry->SetSet(const_cast<CBioseq_set&>(*bs));
  336.             objs.push_back(CConstRef<CObject>(entry.GetPointer()));
  337.         }
  338.     }
  339.     // bioseq-set -> bioseq
  340.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  341.     {
  342.         const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
  343.         if (bs) {
  344.             CTypeConstIterator<CBioseq> iter(*bs);
  345.             for ( ;  iter;  ++iter) {
  346.                 const CBioseq& bioseq = *iter;
  347.                 objs.push_back(CConstRef<CObject>(&bioseq));
  348.             }
  349.         }
  350.     }
  351.     // bioseq-set -> bioseq-set
  352.     // identity conversion
  353.     void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs)
  354.     {
  355.         const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
  356.         if (bs) {
  357.             objs.push_back(CConstRef<CObject>(bs));
  358.         }
  359.     }
  360.     // bioseq -> seq-id
  361.     // we return only one of the seq-ids for this bioseq
  362.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  363.     {
  364.         TObjList temp;
  365.         ToBioseq(scope, obj, temp);
  366.         ITERATE (TObjList, iter, temp) {
  367.             CObjectConverter::Convert(scope, **iter,
  368.                                       CSeq_id::GetTypeInfo(), objs);
  369.         }
  370.     }
  371. };
  372. //////////////////////////////////////////////////////////////////////////
  373. //
  374. // seq-submit conversions
  375. //
  376. class CSeq_submitConverter : public CObjConverter
  377. {
  378. public:
  379.     // seq-submit -> seq-submit
  380.     // identity conversion
  381.     void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
  382.     {
  383.         const CSeq_submit* sub = dynamic_cast<const CSeq_submit*> (&obj);
  384.         if (sub) {
  385.             objs.push_back(CConstRef<CObject>(sub));
  386.         }
  387.     }
  388.     // seq-submit -> seq-entry
  389.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  390.     {
  391.         const CSeq_submit* sub = dynamic_cast<const CSeq_submit*> (&obj);
  392.         if (sub  &&  sub->GetData().IsEntrys()) {
  393.             ITERATE (CSeq_submit::TData::TEntrys, iter,
  394.                      sub->GetData().GetEntrys()) {
  395.                 CConstRef<CObject> obj(iter->GetPointer());
  396.                 objs.push_back(obj);
  397.             }
  398.         }
  399.     }
  400.     // seq-submit -> bioseq
  401.     // identity operation
  402.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  403.     {
  404.         TObjList ents;
  405.         ToSeqEntry(scope, obj, ents);
  406.         ITERATE (TObjList, ent_iter, ents) {
  407.             CObjectConverter::Convert(scope, **ent_iter,
  408.                                       CBioseq::GetTypeInfo()->GetName(), objs);
  409.         }
  410.     }
  411.     // seq-submit -> seq-id
  412.     // we return only one of the seq-ids for this seq-submit
  413.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  414.     {
  415.         TObjList ents;
  416.         ToSeqEntry(scope, obj, ents);
  417.         ITERATE (TObjList, ent_iter, ents) {
  418.             CObjectConverter::Convert(scope, **ent_iter,
  419.                                       CSeq_id::GetTypeInfo()->GetName(), objs);
  420.         }
  421.     }
  422. };
  423. //////////////////////////////////////////////////////////////////////////
  424. //
  425. // seq-id conversions
  426. //
  427. class CSeq_idConverter : public CObjConverter
  428. {
  429. public:
  430.     // seq-id -> seq-entry
  431.     // retrieve the seq-entry from the scope
  432.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  433.     {
  434.         const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
  435.         if (id) {
  436.             // retrieve our handle from the scope and proceed
  437.             CBioseq_Handle handle = scope.GetBioseqHandle(*id);
  438.             if (handle) {
  439.                 const CSeq_entry& entry = handle.GetTopLevelSeqEntry();
  440.                 CConstRef<CObject> obj(&entry);
  441.                 objs.push_back(obj);
  442.             }
  443.         }
  444.     }
  445.     // seq-id -> bioseq-set
  446.     // retrieve the seq-entry from the scope and return its bioseq-set
  447.     void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
  448.     {
  449.         const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
  450.         if (id) {
  451.             // retrieve our handle from the scope and proceed
  452.             CBioseq_Handle handle = scope.GetBioseqHandle(*id);
  453.             if (handle) {
  454.                 const CSeq_entry& entry = handle.GetTopLevelSeqEntry();
  455.                 if (entry.IsSet()) {
  456.                     objs.push_back(CConstRef<CObject>(&entry.GetSet()));
  457.                 }
  458.             }
  459.         }
  460.     }
  461.     // seq-id -> bioseq
  462.     // retrieve the bioseq from the scope
  463.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  464.     {
  465.         const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
  466.         if (id) {
  467.             // retrieve our handle from the scope and proceed
  468.             CBioseq_Handle handle = scope.GetBioseqHandle(*id);
  469.             if (handle) {
  470.                 const CBioseq& bs = *handle.GetCompleteBioseq();
  471.                 objs.push_back(CConstRef<CObject>(&bs));
  472.             }
  473.         }
  474.     }
  475.     // seq-id -> seq-id
  476.     // we return only one of the seq-ids for each bioseq
  477.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  478.     {
  479.         const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
  480.         if (id) {
  481.             objs.push_back(CConstRef<CObject>(id));
  482.         }
  483.     }
  484.     // seq-id -> seq-loc
  485.     // this is a very simple conversion; we create a new CSeq_loc
  486.     // of type whole
  487.     void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
  488.     {
  489.         const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
  490.         if (id) {
  491.             CRef<CSeq_loc> loc(new CSeq_loc());
  492.             loc->SetWhole(const_cast<CSeq_id&>(*id));
  493.             objs.push_back(CConstRef<CObject>(loc.GetPointer()));
  494.         }
  495.     }
  496. };
  497. //////////////////////////////////////////////////////////////////////////
  498. //
  499. // seq-loc conversions
  500. //
  501. class CSeq_locConverter : public CObjConverter
  502. {
  503. public:
  504.     // seq-loc -> seq-id
  505.     // we return a set of unique seq-ids for each location
  506.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  507.     {
  508.         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*> (&obj);
  509.         if (loc) {
  510.             CTypeConstIterator<CSeq_id> id_iter(*loc);
  511.             for ( ;  id_iter;  ++id_iter) {
  512.                 const CSeq_id& id = *id_iter;
  513.                 bool add = true;
  514.                 ITERATE(TObjList, obj_iter, objs) {
  515.                     const CSeq_id* other_id =
  516.                         dynamic_cast<const CSeq_id*> (obj_iter->GetPointer());
  517.                     if ( !other_id ) {
  518.                         continue;
  519.                     }
  520.                     CSeq_id::E_SIC cmp = other_id->Compare(id);
  521.                     if (cmp == CSeq_id::e_YES) {
  522.                         add = false;
  523.                         break;
  524.                     }
  525.                     if (cmp == CSeq_id::e_DIFF) {
  526.                         _TRACE("Warning: seq-id compare ineffective");
  527.                     }
  528.                 }
  529.                 if (add) {
  530.                     objs.push_back(CConstRef<CObject>(&id));
  531.                 }
  532.             }
  533.         }
  534.     }
  535.     // seq-loc -> seq-loc
  536.     // identity conversion
  537.     void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
  538.     {
  539.         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
  540.         if (loc) {
  541.             objs.push_back(CConstRef<CObject>(loc));
  542.         }
  543.     }
  544.     // seq-loc -> seq-feat
  545.     // we use CFeat_CI
  546.     void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
  547.     {
  548.         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
  549.         if (loc) {
  550.             SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
  551.             CFeat_CI iter(scope, *loc, sel);
  552.             for (;  iter;  ++iter) {
  553.                 const CSeq_feat& feat = iter->GetOriginalFeature();
  554.                 objs.push_back(CConstRef<CObject>(&feat));
  555.             }
  556.         }
  557.     }
  558.     // seq-loc -> seq-align
  559.     // we use CAlign_CI
  560.     void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
  561.     {
  562.         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
  563.         if (loc) {
  564.             SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
  565.             CAlign_CI iter(scope, *loc, sel);
  566.             for (;  iter;  ++iter) {
  567.                 objs.push_back(CConstRef<CObject>(&(*iter)));
  568.             }
  569.         }
  570.     }
  571.     // seq-loc --> seq-annot
  572.     // we use CAnnot_CI here
  573.     void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
  574.     {
  575.         const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
  576.         if (loc) {
  577.             SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
  578.             CAnnot_CI iter(scope, *loc, sel);
  579.             for (;  iter;  ++iter) {
  580.                 const CSeq_annot& annot = iter->GetSeq_annot();
  581.                 objs.push_back(CConstRef<CObject>(&annot));
  582.             }
  583.         }
  584.     }
  585. };
  586. //////////////////////////////////////////////////////////////////////////
  587. //
  588. // seq-annot conversions
  589. //
  590. class CSeq_annotConverter : public CObjConverter
  591. {
  592. public:
  593.     // seq-annot -> seq-entry: we create a dummy CSeq_entry to hold our object
  594.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  595.     {
  596.         const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
  597.         if (annot) {
  598.             CRef<CSeq_entry> entry(new CSeq_entry());
  599.             entry->SetSet().SetSeq_set();
  600.             entry->SetSet().SetAnnot()
  601.                 .push_back(CRef<CSeq_annot>(const_cast<CSeq_annot*>(annot)));
  602.             objs.push_back( CConstRef<CObject> (entry.GetPointer()) );
  603.         }
  604.     }
  605.     // seq-annot -> seq-id: use CTypeConstIterator<>
  606.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  607.     {
  608.         const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
  609.         if (annot) {
  610.             CTypeConstIterator<CSeq_id> id_iter(*annot);
  611.             for ( ;  id_iter;  ++id_iter) {
  612.                 objs.push_back( CConstRef<CObject> (&*id_iter) );
  613.             }
  614.         }
  615.     }
  616.     // seq-annot -> seq-align
  617.     void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
  618.     {
  619.         const CSeq_annot* annot = dynamic_cast<const CSeq_annot*>(&obj);
  620.         if (annot  &&  annot->GetData().IsAlign()) {
  621.             ITERATE (CSeq_annot::TData::TAlign, iter,
  622.                      annot->GetData().GetAlign()) {
  623.                 objs.push_back(CConstRef<CObject>(&**iter));
  624.             }
  625.         }
  626.     }
  627. };
  628. //////////////////////////////////////////////////////////////////////////
  629. //
  630. // seq-align conversions
  631. //
  632. class CSeq_alignConverter : public CObjConverter
  633. {
  634. public:
  635.     // functor for evaluating whether a seq-id matches that inside
  636.     // of a seq-interval
  637.     struct SSortByIdRef {
  638.         bool operator() (const CConstRef<CSeq_id>& id1,
  639.                          const CConstRef<CSeq_id>& id2) const
  640.         {
  641.             return (*id1 < *id2);
  642.         }
  643.     };
  644.     // seq-align -> seq-id
  645.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  646.     {
  647.         const CSeq_align* align = dynamic_cast<const CSeq_align*> (&obj);
  648.         if (align) {
  649.             typedef set<CConstRef<CSeq_id>, SSortByIdRef> TIdSet;
  650.             TIdSet id_set;
  651.             CTypeConstIterator<CSeq_id> id_iter(*align);
  652.             for ( ;  id_iter;  ++id_iter) {
  653.                 id_set.insert( CConstRef<CSeq_id>(&*id_iter) );
  654.             }
  655.             ITERATE (TIdSet, iter, id_set) {
  656.                 objs.push_back( CConstRef<CObject>(iter->GetPointer()) );
  657.             }
  658.         }
  659.     }
  660.     // seq-align -> seq-align
  661.     // identity conversion
  662.     void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
  663.     {
  664.         const CSeq_align* align = dynamic_cast<const CSeq_align*>(&obj);
  665.         if (align) {
  666.             objs.push_back(CConstRef<CObject>(align));
  667.         }
  668.     }
  669.     // seq-align -> seq-annot
  670.     void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
  671.     {
  672.         const CSeq_align* align = dynamic_cast<const CSeq_align*>(&obj);
  673.         if (align) {
  674.             CRef<CSeq_annot> annot(new CSeq_annot());
  675.             annot->SetData().SetAlign()
  676.                 .push_back(CRef<CSeq_align>(const_cast<CSeq_align*>(align)));
  677.             objs.push_back(CConstRef<CObject>(annot.GetPointer()));
  678.         }
  679.     }
  680. };
  681. //////////////////////////////////////////////////////////////////////////
  682. //
  683. // seq-align-set conversions
  684. //
  685. class CSeq_align_setConverter : public CObjConverter
  686. {
  687. public:
  688.     // functor for evaluating whether a seq-id matches that inside
  689.     // of a seq-interval
  690.     struct SSortByIdRef {
  691.         bool operator() (const CConstRef<CSeq_id>& id1,
  692.                          const CConstRef<CSeq_id>& id2) const
  693.         {
  694.             return (*id1 < *id2);
  695.         }
  696.     };
  697.     // seq-align-set -> seq-id
  698.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  699.     {
  700.         const CSeq_align_set* align =
  701.             dynamic_cast<const CSeq_align_set*> (&obj);
  702.         if (align) {
  703.             typedef set<CConstRef<CSeq_id>, SSortByIdRef> TIdSet;
  704.             TIdSet id_set;
  705.             CTypeConstIterator<CSeq_id> id_iter(*align);
  706.             for ( ;  id_iter;  ++id_iter) {
  707.                 id_set.insert( CConstRef<CSeq_id>(&*id_iter) );
  708.             }
  709.             ITERATE (TIdSet, iter, id_set) {
  710.                 objs.push_back( CConstRef<CObject>(iter->GetPointer()) );
  711.             }
  712.         }
  713.     }
  714.     // seq-align-set -> seq-align
  715.     // identity conversion
  716.     void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
  717.     {
  718.         const CSeq_align_set* align =
  719.             dynamic_cast<const CSeq_align_set*>(&obj);
  720.         if (align) {
  721.             ITERATE (CSeq_align_set::Tdata, iter, align->Get()) {
  722.                 objs.push_back(CConstRef<CObject>(iter->GetPointer()));
  723.             }
  724.         }
  725.     }
  726.     // seq-align-set -> seq-annot
  727.     void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
  728.     {
  729.         const CSeq_align_set* align =
  730.             dynamic_cast<const CSeq_align_set*>(&obj);
  731.         if (align) {
  732.             CRef<CSeq_annot> annot(new CSeq_annot());
  733.             ITERATE (CSeq_align_set::Tdata, iter, align->Get()) {
  734.                 CRef<CSeq_align> ref
  735.                     (const_cast<CSeq_align*>(iter->GetPointer()));
  736.                 annot->SetData().SetAlign().push_back(ref);
  737.             }
  738.             objs.push_back(CConstRef<CObject>(annot.GetPointer()));
  739.         }
  740.     }
  741. };
  742. //////////////////////////////////////////////////////////////////////////
  743. //
  744. // seq-feat conversions
  745. //
  746. class CSeq_featConverter : public CObjConverter
  747. {
  748. public:
  749.     // seq-feat -> seq-id
  750.     // we return a set of unique seq-feats for each location
  751.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  752.     {
  753.         const CSeq_feat* feat = dynamic_cast<const CSeq_feat*> (&obj);
  754.         if (feat) {
  755.             CObjectConverter::Convert(scope, feat->GetLocation(),
  756.                                       CSeq_id::GetTypeInfo()->GetName(), objs);
  757.             // deal with IDs from product location
  758.             if (feat->IsSetProduct()) {
  759.                 CObjectConverter::Convert(scope, feat->GetProduct(),
  760.                                           CSeq_id::GetTypeInfo()->GetName(),
  761.                                           objs);
  762.             }
  763.             // deal with dbxrefs
  764.             if (feat->IsSetDbxref()) {
  765.                 ITERATE (CSeq_feat::TDbxref, iter, feat->GetDbxref()) {
  766.                     const CDbtag& dbtag = **iter;
  767.                     CRef<CSeq_id> id(new CSeq_id(dbtag, false));
  768.                     if (id->Which() != CSeq_id::e_not_set) {
  769.                         objs.push_back( CConstRef<CObject> (id.GetPointer()) );
  770.                     }
  771.                 }
  772.             }
  773.         }
  774.     }
  775.     // seq-feat -> seq-loc
  776.     // identity conversion
  777.     void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
  778.     {
  779.         const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(&obj);
  780.         if ( !feat ) {
  781.             return;
  782.         }
  783.         objs.push_back(CConstRef<CObject>(&feat->GetLocation()));
  784.         if (feat->IsSetProduct()) {
  785.             objs.push_back(CConstRef<CObject>(&feat->GetProduct()));
  786.         }
  787.         // deal with dbxrefs
  788.         if (feat->IsSetDbxref()) {
  789.             ITERATE (CSeq_feat::TDbxref, iter, feat->GetDbxref()) {
  790.                 const CDbtag& dbtag = **iter;
  791.                 CRef<CSeq_id> id(new CSeq_id(dbtag, false));
  792.                 if (id->Which() != CSeq_id::e_not_set) {
  793.                     CRef<CSeq_loc> loc(new CSeq_loc());
  794.                     loc->SetWhole(*id);
  795.                     objs.push_back( CConstRef<CObject> (loc.GetPointer()) );
  796.                 }
  797.             }
  798.         }
  799.     }
  800.     // seq-feat -> seq-feat
  801.     // identity conversion
  802.     void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
  803.     {
  804.         const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(&obj);
  805.         if (feat) {
  806.             objs.push_back(CConstRef<CObject>(feat));
  807.         }
  808.     }
  809.     // seq-feat -> seq-annot
  810.     // this should ideally return the parent annot of the feature
  811.     // we compromise by returning the annots for the location
  812.     void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
  813.     {
  814.         TObjList locs;
  815.         ToSeqLoc(scope, obj, locs);
  816.         ITERATE (TObjList, loc_iter, locs) {
  817.             CObjectConverter::Convert(scope, **loc_iter,
  818.                                       CSeq_annot::GetTypeInfo(), objs);
  819.         }
  820.     }
  821. };
  822. //////////////////////////////////////////////////////////////////////////
  823. //
  824. // document conversions
  825. //
  826. class CDocumentConverter : public CObjConverter
  827. {
  828. public:
  829.     // all forms of document conversion rely on the underlying object
  830.     // exposed by the document.  So, CDocConverter::ToObject merely passes
  831.     // control back to convert with the underlying object.
  832.     void ToObject(CScope& scope, const CObject& obj,
  833.                   const string& to_type, TObjList& objs) const
  834.     {
  835.         const IDocument* doc = dynamic_cast<const IDocument*> (&obj);
  836.         if (doc) {
  837.             CObjectConverter::Convert(scope, *doc->GetObject(), to_type, objs);
  838.         }
  839.     }
  840.     //
  841.     // all remaining API calls to this class are exceptions
  842.     //
  843.     class CDocConvertException  : EXCEPTION_VIRTUAL_BASE public CException
  844.     {
  845.     public:
  846.         // Enumerated list of document management errors
  847.         enum EErrCode {
  848.             eConversionNotSupported
  849.         };
  850.         // Translate the specific error code into a string representations of
  851.         // that error code.
  852.         virtual const char* GetErrCodeString(void) const
  853.         {
  854.             switch (GetErrCode()) {
  855.             case eConversionNotSupported: return "eConversionNotSupported";
  856.             default:                      return CException::GetErrCodeString();
  857.             }
  858.         }
  859.         NCBI_EXCEPTION_DEFAULT(CDocConvertException, CException);
  860.     };
  861.     void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
  862.     {
  863.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  864.                    "Direct conversion not supported");
  865.     }
  866.     void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
  867.     {
  868.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  869.                    "Direct conversion not supported");
  870.     }
  871.     void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
  872.     {
  873.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  874.                    "Direct conversion not supported");
  875.     }
  876.     void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
  877.     {
  878.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  879.                    "Direct conversion not supported");
  880.     }
  881.     void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
  882.     {
  883.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  884.                    "Direct conversion not supported");
  885.     }
  886.     void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
  887.     {
  888.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  889.                    "Direct conversion not supported");
  890.     }
  891.     void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
  892.     {
  893.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  894.                    "Direct conversion not supported");
  895.     }
  896.     void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
  897.     {
  898.         NCBI_THROW(CDocConvertException, eConversionNotSupported,
  899.                    "Direct conversion not supported");
  900.     }
  901. };
  902. //////////////////////////////////////////////////////////////////////////
  903. //
  904. // converter cache
  905. DEFINE_STATIC_MUTEX(s_ObjCvtMutex);
  906. typedef map<string, CRef<IObjConverter> > TCvtMap;
  907. static TCvtMap s_CvtMap;
  908. struct SFillDefaultConverters
  909. {
  910.     SFillDefaultConverters()
  911.     {
  912.         CMutexGuard LOCK(s_ObjCvtMutex);
  913.         if ( !s_CvtMap.empty() ) {
  914.             return;
  915.         }
  916.         CObjectConverter::Register(CSeq_submit::GetTypeInfo(), *new CSeq_submitConverter());
  917.         CObjectConverter::Register(CSeq_entry::GetTypeInfo(),  *new CSeq_entryConverter());
  918.         CObjectConverter::Register(CBioseq_set::GetTypeInfo(), *new CBioseq_setConverter());
  919.         CObjectConverter::Register(CBioseq::GetTypeInfo(),     *new CBioseqConverter());
  920.         CObjectConverter::Register(CSeq_id::GetTypeInfo(),     *new CSeq_idConverter());
  921.         CObjectConverter::Register(CSeq_loc::GetTypeInfo(),    *new CSeq_locConverter());
  922.         CObjectConverter::Register(CSeq_feat::GetTypeInfo(),   *new CSeq_featConverter());
  923.         CObjectConverter::Register(CSeq_align::GetTypeInfo(),  *new CSeq_alignConverter());
  924.         CObjectConverter::Register(CSeq_align_set::GetTypeInfo(),  *new CSeq_align_setConverter());
  925.         CObjectConverter::Register(CSeq_annot::GetTypeInfo(),  *new CSeq_annotConverter());
  926.         // internal-only types!
  927.         s_CvtMap["Document"] = CRef<IObjConverter>(new CDocumentConverter());
  928.     }
  929. };
  930. static SFillDefaultConverters s_InitConverters;
  931. //////////////////////////////////////////////////////////////////////////
  932. //
  933. // object conversion
  934. //
  935. void CObjectConverter::Convert(CScope& scope, const CObject& obj,
  936.                                const CTypeInfo* info, TObjList& objs)
  937. {
  938.     Convert(scope, obj, info->GetName(), objs);
  939. }
  940. void CObjectConverter::Convert(CScope& scope, const CObject& obj,
  941.                                const string& to_type, TObjList& objs)
  942. {
  943.     //
  944.     // check to see if our object is a serial object first
  945.     //
  946.     string from_type;
  947.     {{
  948.          const CSerialObject* so = dynamic_cast<const CSerialObject*> (&obj);
  949.          if (so) {
  950.              from_type = so->GetThisTypeInfo()->GetName();
  951.          }
  952.      }}
  953.     //
  954.     // the only other supported object is an IDocument-derived document
  955.     //
  956.     if (from_type.empty()) {
  957.         const IDocument* doc = dynamic_cast<const IDocument*> (&obj);
  958.         if (doc) {
  959.             from_type = "Document";
  960.         }
  961.     }
  962.     // short-circuit: identity transforms
  963.     if (from_type == to_type) {
  964.         objs.push_back(CConstRef<CObject>(&obj));
  965.         return;
  966.     }
  967.     TCvtMap::const_iterator iter = s_CvtMap.find(from_type);
  968.     if (iter != s_CvtMap.end()) {
  969.         iter->second->ToObject(scope, obj, to_type, objs);
  970.         return;
  971.     }
  972. }
  973. //////////////////////////////////////////////////////////////////////////
  974. //
  975. // converter registration
  976. //
  977. void CObjectConverter::Register(const CTypeInfo* info, IObjConverter& cvt)
  978. {
  979.     CMutexGuard LOCK(s_ObjCvtMutex);
  980.     s_CvtMap[info->GetName()] = CRef<IObjConverter>(&cvt);
  981. }
  982. //////////////////////////////////////////////////////////////////////////
  983. //
  984. //  conversion cache
  985. //
  986. const CConvertCache::TObjList& 
  987. CConvertCache::Convert(CScope& scope, 
  988.                        const CObject& obj,
  989.                        const CTypeInfo* info)
  990. {
  991.     if (info) {
  992.         return Convert(scope, obj, info->GetName());
  993.     }
  994.     return m_EmptyObjList;
  995. }
  996. const CConvertCache::TObjList& 
  997. CConvertCache::Convert(CScope& scope,
  998.                        const CObject& obj,
  999.                        const string& type_name)
  1000. {
  1001.     SCacheKey key(scope, obj, type_name);
  1002.     CConvertCache::TCache::iterator pos;
  1003.     if ((pos = m_ObjCache.find(key)) == m_ObjCache.end()) {
  1004.         TCache::value_type val(key, m_EmptyObjList);
  1005.         CObjectConverter::Convert(scope, obj, type_name, val.second);
  1006.         pair<CConvertCache::TCache::iterator, bool>
  1007.             r(m_ObjCache.insert(val));
  1008.         if (!r.second) {
  1009.             return m_EmptyObjList;
  1010.         }
  1011.         pos = r.first;
  1012.     }
  1013.     return pos->second;
  1014. }
  1015. bool CConvertCache::SCacheKeySort::operator() (const SCacheKey& key1,
  1016.                                                const SCacheKey& key2) const
  1017. {
  1018.     if (key1.m_Scope.GetPointer() < key2.m_Scope.GetPointer()) {
  1019.         return true;
  1020.     }
  1021.     if (key1.m_Scope.GetPointer() >  key2.m_Scope.GetPointer()) {
  1022.         return false;
  1023.     }
  1024.     // key1.m_Scope == key2.m_Scope
  1025.     if (key1.m_Obj.GetPointer() < key2.m_Obj.GetPointer()) {
  1026.         return true;
  1027.     }
  1028.     if (key1.m_Obj.GetPointer() > key2.m_Obj.GetPointer()) {
  1029.         return false;
  1030.     }
  1031.     // (key1.m_Scope == key2.m_Scope) && (key1.m_Obj == key2.m_Obj)
  1032.     return (NStr::CompareCase(key1.m_Type, key2.m_Type) < 0);
  1033. };
  1034. END_NCBI_SCOPE
  1035. /*
  1036.  * ===========================================================================
  1037.  * $Log: obj_convert.cpp,v $
  1038.  * Revision 1000.4  2004/06/01 20:44:10  gouriano
  1039.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.19
  1040.  *
  1041.  * Revision 1.19  2004/05/21 22:27:40  gorelenk
  1042.  * Added PCH ncbi_pch.hpp
  1043.  *
  1044.  * Revision 1.18  2004/05/07 15:40:50  dicuccio
  1045.  * Reworked initialization to be more robust
  1046.  *
  1047.  * Revision 1.17  2004/05/03 12:48:46  dicuccio
  1048.  * gui/utils --> gui/objutils where needed
  1049.  *
  1050.  * Revision 1.16  2004/04/16 14:37:46  dicuccio
  1051.  * Use GetCompleteBioseq() instead of GetBioseq()
  1052.  *
  1053.  * Revision 1.15  2004/04/05 14:25:38  dicuccio
  1054.  * Don't forget to save results of seq-align-set -> annot conversion
  1055.  *
  1056.  * Revision 1.14  2004/04/05 12:17:23  dicuccio
  1057.  * Added CSeq_align_set converter
  1058.  *
  1059.  * Revision 1.13  2004/03/05 17:29:12  dicuccio
  1060.  * Added bioseq -> bioseq-set conversion
  1061.  *
  1062.  * Revision 1.12  2004/01/21 19:21:17  dicuccio
  1063.  * Added handling of dbxrefs as seq-ids and seq-locs for seq-feats
  1064.  *
  1065.  * Revision 1.11  2004/01/21 12:38:18  dicuccio
  1066.  * redesigned CObjectCOnverter API to eliminate temporary object creation
  1067.  *
  1068.  * Revision 1.10  2004/01/15 18:00:02  dicuccio
  1069.  * First pass at clean-up and elimination of temporary object creation
  1070.  *
  1071.  * Revision 1.9  2003/12/09 15:44:04  dicuccio
  1072.  * Use CExpcetion::GetMsg() instead of what()
  1073.  *
  1074.  * Revision 1.8  2003/11/18 17:43:43  dicuccio
  1075.  * Added conversion for CBioseq_set
  1076.  *
  1077.  * Revision 1.7  2003/10/14 19:43:58  dicuccio
  1078.  * Return the product's seq-loc as well as the main feature seq-loc for features
  1079.  * with products
  1080.  *
  1081.  * Revision 1.6  2003/10/10 17:14:37  dicuccio
  1082.  * Added safety net around object manager calls to trap exceptions.  Added better
  1083.  * conversion of seq-align -> seq-loc.  Reformatted some code.
  1084.  *
  1085.  * Revision 1.5  2003/10/10 16:00:48  friedman
  1086.  * Added CConvertCache
  1087.  *
  1088.  * Revision 1.4  2003/09/30 15:17:28  dicuccio
  1089.  * Cleaned up object conversion for seq-align, seq-feat.  Added default pathways
  1090.  * for seq-entry, bioseq.  Added seq-annot conversion
  1091.  *
  1092.  * Revision 1.3  2003/09/25 12:25:08  friedman
  1093.  * Implemented:
  1094.  *         ToSeqFeat
  1095.  * Added:
  1096.  *         ToSeqAlign
  1097.  *         CSeq_alignConverter
  1098.  *
  1099.  * Revision 1.2  2003/09/24 18:23:17  dicuccio
  1100.  * Use standard annot selector retrieval function from CSeqUtils
  1101.  *
  1102.  * Revision 1.1  2003/09/16 13:58:08  dicuccio
  1103.  * Initial revision
  1104.  *
  1105.  * ===========================================================================
  1106.  */