obj_convert.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:39k
- /*
- * ===========================================================================
- * PRODUCTION $Log: obj_convert.cpp,v $
- * PRODUCTION Revision 1000.4 2004/06/01 20:44:10 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.19
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: obj_convert.cpp,v 1000.4 2004/06/01 20:44:10 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Mike DiCuccio
- *
- * File Description:
- *
- */
- #include <ncbi_pch.hpp>
- #include <corelib/ncbimtx.hpp>
- #include <gui/core/obj_convert.hpp>
- #include <gui/core/idocument.hpp>
- #include <gui/objutils/utils.hpp>
- #include <gui/utils/message_box.hpp>
- #include <objects/seq/Bioseq.hpp>
- #include <objects/seq/Seq_annot.hpp>
- #include <objects/seqalign/Seq_align.hpp>
- #include <objects/seqalign/Seq_align_set.hpp>
- #include <objects/seqloc/Seq_id.hpp>
- #include <objects/seqloc/Seq_loc.hpp>
- #include <objects/seqset/Seq_entry.hpp>
- #include <objects/seqset/Bioseq_set.hpp>
- #include <objects/seqfeat/Seq_feat.hpp>
- #include <objects/submit/Seq_submit.hpp>
- #include <objmgr/annot_selector.hpp>
- #include <objmgr/annot_ci.hpp>
- #include <serial/iterator.hpp>
- #include <objmgr/feat_ci.hpp>
- #include <objmgr/align_ci.hpp>
- BEGIN_NCBI_SCOPE
- USING_SCOPE(objects);
- //////////////////////////////////////////////////////////////////////////
- //
- // generic conversions
- //
- void CObjConverter::ToObject(CScope& scope, const CObject& obj,
- const string& type_name,
- TObjList& objs) const
- {
- if (type_name == "Seq-submit") {
- ToSeqSubmit(scope, obj, objs);
- } else if (type_name == "Seq-entry") {
- ToSeqEntry(scope, obj, objs);
- } else if (type_name == "Bioseq-set") {
- ToBioseqSet(scope, obj, objs);
- } else if (type_name == "Bioseq") {
- ToBioseq(scope, obj, objs);
- } else if (type_name == "Seq-id") {
- ToSeqId(scope, obj, objs);
- } else if (type_name == "Seq-loc") {
- ToSeqLoc(scope, obj, objs);
- } else if (type_name == "Seq-feat") {
- ToSeqFeat(scope, obj, objs);
- } else if (type_name == "Seq-align") {
- ToSeqAlign(scope, obj, objs);
- } else if (type_name == "Seq-annot") {
- ToSeqAnnot(scope, obj, objs);
- }
- }
- // object -> seq-submit
- // this is a simple wrapping of a seq-entry
- void CObjConverter::ToSeqSubmit(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList ents;
- ToSeqEntry(scope, obj, ents);
- if ( !ents.empty() ) {
- CRef<CSeq_submit> sub(new CSeq_submit());
- objs.push_back(CConstRef<CObject>(sub.GetPointer()));
- ITERATE (TObjList, iter, ents) {
- CRef<CSeq_entry> entry
- (const_cast<CSeq_entry*>
- (dynamic_cast<const CSeq_entry*> (iter->GetPointer())));
- sub->SetData().SetEntrys().push_back(entry);
- }
- }
- }
- // seq-loc -> seq-entry
- // we pass through seq-id to seq-entry conversion
- void CObjConverter::ToSeqEntry(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList ids;
- ToSeqId(scope, obj, ids);
- ITERATE (TObjList, id_iter, ids) {
- CObjectConverter::Convert(scope, **id_iter,
- CSeq_entry::GetTypeInfo()->GetName(), objs);
- }
- }
- // seq-loc -> bioseq
- // we pass through seq-id to seq-entry conversion
- void CObjConverter::ToBioseq(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList ids;
- ToSeqId(scope, obj, ids);
- ITERATE (TObjList, id_iter, ids) {
- CObjectConverter::Convert(scope, **id_iter,
- CBioseq::GetTypeInfo()->GetName(), objs);
- }
- }
- // object -> bioseq-set
- void CObjConverter::ToBioseqSet(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList ents;
- ToSeqEntry(scope, obj, ents);
- ITERATE (TObjList, ent_iter, ents) {
- const CSeq_entry& entry =
- dynamic_cast<const CSeq_entry&>(**ent_iter);
- if (entry.IsSet()) {
- objs.push_back(CConstRef<CObject>(&entry.GetSet()));
- }
- }
- }
- // object -> seq-loc
- // we feed out of CSeq_id conversion here
- void CObjConverter::ToSeqLoc(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList ids;
- ToSeqId(scope, obj, ids);
- ITERATE (TObjList, iter, ids) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_loc::GetTypeInfo()->GetName(), objs);
- }
- }
- // object -> seq-annot
- // we feed out of CSeq_loc conversion here
- void CObjConverter::ToSeqAnnot(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList locs;
- ToSeqLoc(scope, obj, locs);
- ITERATE (TObjList, iter, locs) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_annot::GetTypeInfo()->GetName(), objs);
- }
- // FIXME: is this necessary?
- objs.sort();
- objs.unique();
- }
- // object -> seq-feat
- // we feed out of CSeq_loc conversion here
- void CObjConverter::ToSeqFeat(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList loc;
- ToSeqLoc(scope, obj, loc);
- ITERATE (TObjList, iter, loc) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_feat::GetTypeInfo()->GetName(), objs);
- }
- }
- // object -> seq-align
- // we feed out of CSeq_entry conversion here
- void CObjConverter::ToSeqAlign(CScope& scope, const CObject& obj,
- TObjList& objs) const
- {
- TObjList loc;
- ToSeqLoc(scope, obj, loc);
- ITERATE (TObjList, iter, loc) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_align::GetTypeInfo()->GetName(), objs);
- }
- // FIXME: is this necessary?
- objs.sort();
- objs.unique();
- }
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-entry conversions
- //
- class CSeq_entryConverter : public CObjConverter
- {
- public:
- // seq-entry -> seq-submit
- // this is a simple wrapping; we overload this to avoid allocation
- void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
- if (entry) {
- CRef<CSeq_submit> sub(new CSeq_submit());
- sub->SetData().SetEntrys().push_back
- (CRef<CSeq_entry>(const_cast<CSeq_entry*>(entry)));
- objs.push_back(CConstRef<CObject>(sub.GetPointer()));
- }
- }
- // seq-entry -> seq-entry
- // identity operation
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
- if (entry) {
- objs.push_back(CConstRef<CObject>(entry));
- }
- }
- // seq-entry -> bioseq-set
- // NULL function
- void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
- if (entry && entry->IsSet()) {
- objs.push_back(CConstRef<CObject>(&entry->GetSet()));
- }
- }
- // seq-entry -> bioseq
- // identity operation
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_entry* entry = dynamic_cast<const CSeq_entry*> (&obj);
- if (entry) {
- CTypeConstIterator<CBioseq> iter(*entry);
- for ( ; iter; ++iter) {
- objs.push_back(CConstRef<CObject>(&*iter));
- }
- }
- }
- // seq-entry -> seq-id
- // we return only one of the seq-ids for each bioseq
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList seqs;
- ToBioseq(scope, obj, seqs);
- ITERATE (TObjList, iter, seqs) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_id::GetTypeInfo()->GetName(), objs);
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // bioseq conversions
- //
- class CBioseqConverter : public CObjConverter
- {
- public:
- // bioseq -> seq-entry
- // here we favor the parent seq-entry, if it exists
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
- if (bs) {
- CConstRef<CObject> o;
- if ( bs->GetParentEntry() ) {
- o.Reset(bs->GetParentEntry());
- } else {
- CRef<CSeq_entry> se(new CSeq_entry());
- se->SetSeq(const_cast<CBioseq&>(*bs));
- o.Reset(se.GetPointer());
- }
- objs.push_back(o);
- }
- }
- // bioseq -> bioseq-set
- void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList temp;
- ToSeqEntry(scope, obj, temp);
- ITERATE (TObjList, iter, temp) {
- CRef<CSeq_entry> entry
- (const_cast<CSeq_entry*>(
- dynamic_cast<const CSeq_entry*>(iter->GetPointer())));
- CRef<CBioseq_set> bs_set(new CBioseq_set());
- bs_set->SetSeq_set().push_back(entry);
- objs.push_back(CConstRef<CObject>(bs_set.GetPointer()));
- }
- }
- // bioseq -> bioseq
- // identity operation
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
- if (bs) {
- objs.push_back(CConstRef<CObject>(bs));
- }
- }
- // bioseq -> seq-id
- // we return only one of the seq-ids for this bioseq
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CBioseq* bs = dynamic_cast<const CBioseq*> (&obj);
- if (bs) {
- CConstRef<CSeq_id> id = FindBestChoice(bs->GetId(), CSeq_id::Score);
- if (id) {
- objs.push_back(CConstRef<CObject>(id.GetPointer()));
- }
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // bioseq-set conversions
- //
- class CBioseq_setConverter : public CObjConverter
- {
- public:
- // bioseq-set -> seq-entry
- // we create a dummy seq-entry to hold our data
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
- if (bs) {
- CRef<CSeq_entry> entry(new CSeq_entry());
- entry->SetSet(const_cast<CBioseq_set&>(*bs));
- objs.push_back(CConstRef<CObject>(entry.GetPointer()));
- }
- }
- // bioseq-set -> bioseq
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
- if (bs) {
- CTypeConstIterator<CBioseq> iter(*bs);
- for ( ; iter; ++iter) {
- const CBioseq& bioseq = *iter;
- objs.push_back(CConstRef<CObject>(&bioseq));
- }
- }
- }
- // bioseq-set -> bioseq-set
- // identity conversion
- void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs)
- {
- const CBioseq_set* bs = dynamic_cast<const CBioseq_set*> (&obj);
- if (bs) {
- objs.push_back(CConstRef<CObject>(bs));
- }
- }
- // bioseq -> seq-id
- // we return only one of the seq-ids for this bioseq
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList temp;
- ToBioseq(scope, obj, temp);
- ITERATE (TObjList, iter, temp) {
- CObjectConverter::Convert(scope, **iter,
- CSeq_id::GetTypeInfo(), objs);
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-submit conversions
- //
- class CSeq_submitConverter : public CObjConverter
- {
- public:
- // seq-submit -> seq-submit
- // identity conversion
- void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_submit* sub = dynamic_cast<const CSeq_submit*> (&obj);
- if (sub) {
- objs.push_back(CConstRef<CObject>(sub));
- }
- }
- // seq-submit -> seq-entry
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_submit* sub = dynamic_cast<const CSeq_submit*> (&obj);
- if (sub && sub->GetData().IsEntrys()) {
- ITERATE (CSeq_submit::TData::TEntrys, iter,
- sub->GetData().GetEntrys()) {
- CConstRef<CObject> obj(iter->GetPointer());
- objs.push_back(obj);
- }
- }
- }
- // seq-submit -> bioseq
- // identity operation
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList ents;
- ToSeqEntry(scope, obj, ents);
- ITERATE (TObjList, ent_iter, ents) {
- CObjectConverter::Convert(scope, **ent_iter,
- CBioseq::GetTypeInfo()->GetName(), objs);
- }
- }
- // seq-submit -> seq-id
- // we return only one of the seq-ids for this seq-submit
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList ents;
- ToSeqEntry(scope, obj, ents);
- ITERATE (TObjList, ent_iter, ents) {
- CObjectConverter::Convert(scope, **ent_iter,
- CSeq_id::GetTypeInfo()->GetName(), objs);
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-id conversions
- //
- class CSeq_idConverter : public CObjConverter
- {
- public:
- // seq-id -> seq-entry
- // retrieve the seq-entry from the scope
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- // retrieve our handle from the scope and proceed
- CBioseq_Handle handle = scope.GetBioseqHandle(*id);
- if (handle) {
- const CSeq_entry& entry = handle.GetTopLevelSeqEntry();
- CConstRef<CObject> obj(&entry);
- objs.push_back(obj);
- }
- }
- }
- // seq-id -> bioseq-set
- // retrieve the seq-entry from the scope and return its bioseq-set
- void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- // retrieve our handle from the scope and proceed
- CBioseq_Handle handle = scope.GetBioseqHandle(*id);
- if (handle) {
- const CSeq_entry& entry = handle.GetTopLevelSeqEntry();
- if (entry.IsSet()) {
- objs.push_back(CConstRef<CObject>(&entry.GetSet()));
- }
- }
- }
- }
- // seq-id -> bioseq
- // retrieve the bioseq from the scope
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- // retrieve our handle from the scope and proceed
- CBioseq_Handle handle = scope.GetBioseqHandle(*id);
- if (handle) {
- const CBioseq& bs = *handle.GetCompleteBioseq();
- objs.push_back(CConstRef<CObject>(&bs));
- }
- }
- }
- // seq-id -> seq-id
- // we return only one of the seq-ids for each bioseq
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- objs.push_back(CConstRef<CObject>(id));
- }
- }
- // seq-id -> seq-loc
- // this is a very simple conversion; we create a new CSeq_loc
- // of type whole
- void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_id* id = dynamic_cast<const CSeq_id*>(&obj);
- if (id) {
- CRef<CSeq_loc> loc(new CSeq_loc());
- loc->SetWhole(const_cast<CSeq_id&>(*id));
- objs.push_back(CConstRef<CObject>(loc.GetPointer()));
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-loc conversions
- //
- class CSeq_locConverter : public CObjConverter
- {
- public:
- // seq-loc -> seq-id
- // we return a set of unique seq-ids for each location
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*> (&obj);
- if (loc) {
- CTypeConstIterator<CSeq_id> id_iter(*loc);
- for ( ; id_iter; ++id_iter) {
- const CSeq_id& id = *id_iter;
- bool add = true;
- ITERATE(TObjList, obj_iter, objs) {
- const CSeq_id* other_id =
- dynamic_cast<const CSeq_id*> (obj_iter->GetPointer());
- if ( !other_id ) {
- continue;
- }
- CSeq_id::E_SIC cmp = other_id->Compare(id);
- if (cmp == CSeq_id::e_YES) {
- add = false;
- break;
- }
- if (cmp == CSeq_id::e_DIFF) {
- _TRACE("Warning: seq-id compare ineffective");
- }
- }
- if (add) {
- objs.push_back(CConstRef<CObject>(&id));
- }
- }
- }
- }
- // seq-loc -> seq-loc
- // identity conversion
- void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
- if (loc) {
- objs.push_back(CConstRef<CObject>(loc));
- }
- }
- // seq-loc -> seq-feat
- // we use CFeat_CI
- void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
- if (loc) {
- SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
- CFeat_CI iter(scope, *loc, sel);
- for (; iter; ++iter) {
- const CSeq_feat& feat = iter->GetOriginalFeature();
- objs.push_back(CConstRef<CObject>(&feat));
- }
- }
- }
- // seq-loc -> seq-align
- // we use CAlign_CI
- void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
- if (loc) {
- SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
- CAlign_CI iter(scope, *loc, sel);
- for (; iter; ++iter) {
- objs.push_back(CConstRef<CObject>(&(*iter)));
- }
- }
- }
- // seq-loc --> seq-annot
- // we use CAnnot_CI here
- void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(&obj);
- if (loc) {
- SAnnotSelector sel = CSeqUtils::GetAnnotSelector();
- CAnnot_CI iter(scope, *loc, sel);
- for (; iter; ++iter) {
- const CSeq_annot& annot = iter->GetSeq_annot();
- objs.push_back(CConstRef<CObject>(&annot));
- }
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-annot conversions
- //
- class CSeq_annotConverter : public CObjConverter
- {
- public:
- // seq-annot -> seq-entry: we create a dummy CSeq_entry to hold our object
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
- if (annot) {
- CRef<CSeq_entry> entry(new CSeq_entry());
- entry->SetSet().SetSeq_set();
- entry->SetSet().SetAnnot()
- .push_back(CRef<CSeq_annot>(const_cast<CSeq_annot*>(annot)));
- objs.push_back( CConstRef<CObject> (entry.GetPointer()) );
- }
- }
- // seq-annot -> seq-id: use CTypeConstIterator<>
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_annot* annot = dynamic_cast<const CSeq_annot*> (&obj);
- if (annot) {
- CTypeConstIterator<CSeq_id> id_iter(*annot);
- for ( ; id_iter; ++id_iter) {
- objs.push_back( CConstRef<CObject> (&*id_iter) );
- }
- }
- }
- // seq-annot -> seq-align
- void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_annot* annot = dynamic_cast<const CSeq_annot*>(&obj);
- if (annot && annot->GetData().IsAlign()) {
- ITERATE (CSeq_annot::TData::TAlign, iter,
- annot->GetData().GetAlign()) {
- objs.push_back(CConstRef<CObject>(&**iter));
- }
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-align conversions
- //
- class CSeq_alignConverter : public CObjConverter
- {
- public:
- // functor for evaluating whether a seq-id matches that inside
- // of a seq-interval
- struct SSortByIdRef {
- bool operator() (const CConstRef<CSeq_id>& id1,
- const CConstRef<CSeq_id>& id2) const
- {
- return (*id1 < *id2);
- }
- };
- // seq-align -> seq-id
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align* align = dynamic_cast<const CSeq_align*> (&obj);
- if (align) {
- typedef set<CConstRef<CSeq_id>, SSortByIdRef> TIdSet;
- TIdSet id_set;
- CTypeConstIterator<CSeq_id> id_iter(*align);
- for ( ; id_iter; ++id_iter) {
- id_set.insert( CConstRef<CSeq_id>(&*id_iter) );
- }
- ITERATE (TIdSet, iter, id_set) {
- objs.push_back( CConstRef<CObject>(iter->GetPointer()) );
- }
- }
- }
- // seq-align -> seq-align
- // identity conversion
- void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align* align = dynamic_cast<const CSeq_align*>(&obj);
- if (align) {
- objs.push_back(CConstRef<CObject>(align));
- }
- }
- // seq-align -> seq-annot
- void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align* align = dynamic_cast<const CSeq_align*>(&obj);
- if (align) {
- CRef<CSeq_annot> annot(new CSeq_annot());
- annot->SetData().SetAlign()
- .push_back(CRef<CSeq_align>(const_cast<CSeq_align*>(align)));
- objs.push_back(CConstRef<CObject>(annot.GetPointer()));
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-align-set conversions
- //
- class CSeq_align_setConverter : public CObjConverter
- {
- public:
- // functor for evaluating whether a seq-id matches that inside
- // of a seq-interval
- struct SSortByIdRef {
- bool operator() (const CConstRef<CSeq_id>& id1,
- const CConstRef<CSeq_id>& id2) const
- {
- return (*id1 < *id2);
- }
- };
- // seq-align-set -> seq-id
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align_set* align =
- dynamic_cast<const CSeq_align_set*> (&obj);
- if (align) {
- typedef set<CConstRef<CSeq_id>, SSortByIdRef> TIdSet;
- TIdSet id_set;
- CTypeConstIterator<CSeq_id> id_iter(*align);
- for ( ; id_iter; ++id_iter) {
- id_set.insert( CConstRef<CSeq_id>(&*id_iter) );
- }
- ITERATE (TIdSet, iter, id_set) {
- objs.push_back( CConstRef<CObject>(iter->GetPointer()) );
- }
- }
- }
- // seq-align-set -> seq-align
- // identity conversion
- void ToSeqAlign(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align_set* align =
- dynamic_cast<const CSeq_align_set*>(&obj);
- if (align) {
- ITERATE (CSeq_align_set::Tdata, iter, align->Get()) {
- objs.push_back(CConstRef<CObject>(iter->GetPointer()));
- }
- }
- }
- // seq-align-set -> seq-annot
- void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_align_set* align =
- dynamic_cast<const CSeq_align_set*>(&obj);
- if (align) {
- CRef<CSeq_annot> annot(new CSeq_annot());
- ITERATE (CSeq_align_set::Tdata, iter, align->Get()) {
- CRef<CSeq_align> ref
- (const_cast<CSeq_align*>(iter->GetPointer()));
- annot->SetData().SetAlign().push_back(ref);
- }
- objs.push_back(CConstRef<CObject>(annot.GetPointer()));
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // seq-feat conversions
- //
- class CSeq_featConverter : public CObjConverter
- {
- public:
- // seq-feat -> seq-id
- // we return a set of unique seq-feats for each location
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_feat* feat = dynamic_cast<const CSeq_feat*> (&obj);
- if (feat) {
- CObjectConverter::Convert(scope, feat->GetLocation(),
- CSeq_id::GetTypeInfo()->GetName(), objs);
- // deal with IDs from product location
- if (feat->IsSetProduct()) {
- CObjectConverter::Convert(scope, feat->GetProduct(),
- CSeq_id::GetTypeInfo()->GetName(),
- objs);
- }
- // deal with dbxrefs
- if (feat->IsSetDbxref()) {
- ITERATE (CSeq_feat::TDbxref, iter, feat->GetDbxref()) {
- const CDbtag& dbtag = **iter;
- CRef<CSeq_id> id(new CSeq_id(dbtag, false));
- if (id->Which() != CSeq_id::e_not_set) {
- objs.push_back( CConstRef<CObject> (id.GetPointer()) );
- }
- }
- }
- }
- }
- // seq-feat -> seq-loc
- // identity conversion
- void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(&obj);
- if ( !feat ) {
- return;
- }
- objs.push_back(CConstRef<CObject>(&feat->GetLocation()));
- if (feat->IsSetProduct()) {
- objs.push_back(CConstRef<CObject>(&feat->GetProduct()));
- }
- // deal with dbxrefs
- if (feat->IsSetDbxref()) {
- ITERATE (CSeq_feat::TDbxref, iter, feat->GetDbxref()) {
- const CDbtag& dbtag = **iter;
- CRef<CSeq_id> id(new CSeq_id(dbtag, false));
- if (id->Which() != CSeq_id::e_not_set) {
- CRef<CSeq_loc> loc(new CSeq_loc());
- loc->SetWhole(*id);
- objs.push_back( CConstRef<CObject> (loc.GetPointer()) );
- }
- }
- }
- }
- // seq-feat -> seq-feat
- // identity conversion
- void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(&obj);
- if (feat) {
- objs.push_back(CConstRef<CObject>(feat));
- }
- }
- // seq-feat -> seq-annot
- // this should ideally return the parent annot of the feature
- // we compromise by returning the annots for the location
- void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- TObjList locs;
- ToSeqLoc(scope, obj, locs);
- ITERATE (TObjList, loc_iter, locs) {
- CObjectConverter::Convert(scope, **loc_iter,
- CSeq_annot::GetTypeInfo(), objs);
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // document conversions
- //
- class CDocumentConverter : public CObjConverter
- {
- public:
- // all forms of document conversion rely on the underlying object
- // exposed by the document. So, CDocConverter::ToObject merely passes
- // control back to convert with the underlying object.
- void ToObject(CScope& scope, const CObject& obj,
- const string& to_type, TObjList& objs) const
- {
- const IDocument* doc = dynamic_cast<const IDocument*> (&obj);
- if (doc) {
- CObjectConverter::Convert(scope, *doc->GetObject(), to_type, objs);
- }
- }
- //
- // all remaining API calls to this class are exceptions
- //
- class CDocConvertException : EXCEPTION_VIRTUAL_BASE public CException
- {
- public:
- // Enumerated list of document management errors
- enum EErrCode {
- eConversionNotSupported
- };
- // Translate the specific error code into a string representations of
- // that error code.
- virtual const char* GetErrCodeString(void) const
- {
- switch (GetErrCode()) {
- case eConversionNotSupported: return "eConversionNotSupported";
- default: return CException::GetErrCodeString();
- }
- }
- NCBI_EXCEPTION_DEFAULT(CDocConvertException, CException);
- };
- void ToSeqSubmit(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToSeqEntry(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToBioseqSet(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToBioseq(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToSeqId(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToSeqLoc(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToSeqFeat(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- void ToSeqAnnot(CScope& scope, const CObject& obj, TObjList& objs) const
- {
- NCBI_THROW(CDocConvertException, eConversionNotSupported,
- "Direct conversion not supported");
- }
- };
- //////////////////////////////////////////////////////////////////////////
- //
- // converter cache
- DEFINE_STATIC_MUTEX(s_ObjCvtMutex);
- typedef map<string, CRef<IObjConverter> > TCvtMap;
- static TCvtMap s_CvtMap;
- struct SFillDefaultConverters
- {
- SFillDefaultConverters()
- {
- CMutexGuard LOCK(s_ObjCvtMutex);
- if ( !s_CvtMap.empty() ) {
- return;
- }
- CObjectConverter::Register(CSeq_submit::GetTypeInfo(), *new CSeq_submitConverter());
- CObjectConverter::Register(CSeq_entry::GetTypeInfo(), *new CSeq_entryConverter());
- CObjectConverter::Register(CBioseq_set::GetTypeInfo(), *new CBioseq_setConverter());
- CObjectConverter::Register(CBioseq::GetTypeInfo(), *new CBioseqConverter());
- CObjectConverter::Register(CSeq_id::GetTypeInfo(), *new CSeq_idConverter());
- CObjectConverter::Register(CSeq_loc::GetTypeInfo(), *new CSeq_locConverter());
- CObjectConverter::Register(CSeq_feat::GetTypeInfo(), *new CSeq_featConverter());
- CObjectConverter::Register(CSeq_align::GetTypeInfo(), *new CSeq_alignConverter());
- CObjectConverter::Register(CSeq_align_set::GetTypeInfo(), *new CSeq_align_setConverter());
- CObjectConverter::Register(CSeq_annot::GetTypeInfo(), *new CSeq_annotConverter());
- // internal-only types!
- s_CvtMap["Document"] = CRef<IObjConverter>(new CDocumentConverter());
- }
- };
- static SFillDefaultConverters s_InitConverters;
- //////////////////////////////////////////////////////////////////////////
- //
- // object conversion
- //
- void CObjectConverter::Convert(CScope& scope, const CObject& obj,
- const CTypeInfo* info, TObjList& objs)
- {
- Convert(scope, obj, info->GetName(), objs);
- }
- void CObjectConverter::Convert(CScope& scope, const CObject& obj,
- const string& to_type, TObjList& objs)
- {
- //
- // check to see if our object is a serial object first
- //
- string from_type;
- {{
- const CSerialObject* so = dynamic_cast<const CSerialObject*> (&obj);
- if (so) {
- from_type = so->GetThisTypeInfo()->GetName();
- }
- }}
- //
- // the only other supported object is an IDocument-derived document
- //
- if (from_type.empty()) {
- const IDocument* doc = dynamic_cast<const IDocument*> (&obj);
- if (doc) {
- from_type = "Document";
- }
- }
- // short-circuit: identity transforms
- if (from_type == to_type) {
- objs.push_back(CConstRef<CObject>(&obj));
- return;
- }
- TCvtMap::const_iterator iter = s_CvtMap.find(from_type);
- if (iter != s_CvtMap.end()) {
- iter->second->ToObject(scope, obj, to_type, objs);
- return;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //
- // converter registration
- //
- void CObjectConverter::Register(const CTypeInfo* info, IObjConverter& cvt)
- {
- CMutexGuard LOCK(s_ObjCvtMutex);
- s_CvtMap[info->GetName()] = CRef<IObjConverter>(&cvt);
- }
- //////////////////////////////////////////////////////////////////////////
- //
- // conversion cache
- //
- const CConvertCache::TObjList&
- CConvertCache::Convert(CScope& scope,
- const CObject& obj,
- const CTypeInfo* info)
- {
- if (info) {
- return Convert(scope, obj, info->GetName());
- }
- return m_EmptyObjList;
- }
- const CConvertCache::TObjList&
- CConvertCache::Convert(CScope& scope,
- const CObject& obj,
- const string& type_name)
- {
- SCacheKey key(scope, obj, type_name);
- CConvertCache::TCache::iterator pos;
- if ((pos = m_ObjCache.find(key)) == m_ObjCache.end()) {
- TCache::value_type val(key, m_EmptyObjList);
- CObjectConverter::Convert(scope, obj, type_name, val.second);
- pair<CConvertCache::TCache::iterator, bool>
- r(m_ObjCache.insert(val));
- if (!r.second) {
- return m_EmptyObjList;
- }
- pos = r.first;
- }
- return pos->second;
- }
- bool CConvertCache::SCacheKeySort::operator() (const SCacheKey& key1,
- const SCacheKey& key2) const
- {
- if (key1.m_Scope.GetPointer() < key2.m_Scope.GetPointer()) {
- return true;
- }
- if (key1.m_Scope.GetPointer() > key2.m_Scope.GetPointer()) {
- return false;
- }
- // key1.m_Scope == key2.m_Scope
- if (key1.m_Obj.GetPointer() < key2.m_Obj.GetPointer()) {
- return true;
- }
- if (key1.m_Obj.GetPointer() > key2.m_Obj.GetPointer()) {
- return false;
- }
- // (key1.m_Scope == key2.m_Scope) && (key1.m_Obj == key2.m_Obj)
- return (NStr::CompareCase(key1.m_Type, key2.m_Type) < 0);
- };
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: obj_convert.cpp,v $
- * Revision 1000.4 2004/06/01 20:44:10 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.19
- *
- * Revision 1.19 2004/05/21 22:27:40 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.18 2004/05/07 15:40:50 dicuccio
- * Reworked initialization to be more robust
- *
- * Revision 1.17 2004/05/03 12:48:46 dicuccio
- * gui/utils --> gui/objutils where needed
- *
- * Revision 1.16 2004/04/16 14:37:46 dicuccio
- * Use GetCompleteBioseq() instead of GetBioseq()
- *
- * Revision 1.15 2004/04/05 14:25:38 dicuccio
- * Don't forget to save results of seq-align-set -> annot conversion
- *
- * Revision 1.14 2004/04/05 12:17:23 dicuccio
- * Added CSeq_align_set converter
- *
- * Revision 1.13 2004/03/05 17:29:12 dicuccio
- * Added bioseq -> bioseq-set conversion
- *
- * Revision 1.12 2004/01/21 19:21:17 dicuccio
- * Added handling of dbxrefs as seq-ids and seq-locs for seq-feats
- *
- * Revision 1.11 2004/01/21 12:38:18 dicuccio
- * redesigned CObjectCOnverter API to eliminate temporary object creation
- *
- * Revision 1.10 2004/01/15 18:00:02 dicuccio
- * First pass at clean-up and elimination of temporary object creation
- *
- * Revision 1.9 2003/12/09 15:44:04 dicuccio
- * Use CExpcetion::GetMsg() instead of what()
- *
- * Revision 1.8 2003/11/18 17:43:43 dicuccio
- * Added conversion for CBioseq_set
- *
- * Revision 1.7 2003/10/14 19:43:58 dicuccio
- * Return the product's seq-loc as well as the main feature seq-loc for features
- * with products
- *
- * Revision 1.6 2003/10/10 17:14:37 dicuccio
- * Added safety net around object manager calls to trap exceptions. Added better
- * conversion of seq-align -> seq-loc. Reformatted some code.
- *
- * Revision 1.5 2003/10/10 16:00:48 friedman
- * Added CConvertCache
- *
- * Revision 1.4 2003/09/30 15:17:28 dicuccio
- * Cleaned up object conversion for seq-align, seq-feat. Added default pathways
- * for seq-entry, bioseq. Added seq-annot conversion
- *
- * Revision 1.3 2003/09/25 12:25:08 friedman
- * Implemented:
- * ToSeqFeat
- * Added:
- * ToSeqAlign
- * CSeq_alignConverter
- *
- * Revision 1.2 2003/09/24 18:23:17 dicuccio
- * Use standard annot selector retrieval function from CSeqUtils
- *
- * Revision 1.1 2003/09/16 13:58:08 dicuccio
- * Initial revision
- *
- * ===========================================================================
- */