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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: annot_collector.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:22:32  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: annot_collector.cpp,v 1000.3 2004/06/01 19:22:32 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Aleksey Grichenko, Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Annotation collector for annot iterators
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include <objmgr/impl/annot_collector.hpp>
  42. #include <objmgr/scope.hpp>
  43. #include <objmgr/bioseq_handle.hpp>
  44. #include <objmgr/seq_entry_handle.hpp>
  45. #include <objmgr/seq_annot_handle.hpp>
  46. #include <objmgr/seq_map_ci.hpp>
  47. #include <objmgr/impl/annot_object.hpp>
  48. #include <objmgr/impl/tse_info.hpp>
  49. #include <objmgr/impl/annot_type_index.hpp>
  50. #include <objmgr/impl/tse_chunk_info.hpp>
  51. #include <objmgr/impl/data_source.hpp>
  52. #include <objmgr/impl/seq_annot_info.hpp>
  53. #include <objmgr/impl/bioseq_set_info.hpp>
  54. #include <objmgr/impl/handle_range_map.hpp>
  55. #include <objmgr/impl/synonyms.hpp>
  56. #include <objmgr/impl/seq_loc_cvt.hpp>
  57. #include <objmgr/impl/seq_align_mapper.hpp>
  58. #include <objmgr/impl/snp_annot_info.hpp>
  59. #include <objmgr/impl/scope_impl.hpp>
  60. #include <objmgr/objmgr_exception.hpp>
  61. #include <objects/seq/Bioseq.hpp>
  62. #include <objects/seqloc/Seq_loc.hpp>
  63. #include <objects/seqset/Seq_entry.hpp>
  64. #include <objects/seqalign/Seq_align.hpp>
  65. #include <objects/seqfeat/Seq_feat.hpp>
  66. #include <objects/seqres/Seq_graph.hpp>
  67. #include <objects/seqfeat/SeqFeatData.hpp>
  68. #include <objects/seqloc/Seq_loc_equiv.hpp>
  69. #include <objects/seqloc/Seq_bond.hpp>
  70. #include <serial/typeinfo.hpp>
  71. #include <serial/objostr.hpp>
  72. #include <serial/objostrasn.hpp>
  73. #include <serial/serial.hpp>
  74. #include <serial/serialutil.hpp>
  75. #include <algorithm>
  76. #include <typeinfo>
  77. BEGIN_NCBI_SCOPE
  78. BEGIN_SCOPE(objects)
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CAnnotObject_Ref
  81. /////////////////////////////////////////////////////////////////////////////
  82. inline
  83. CAnnotObject_Ref::CAnnotObject_Ref(const CAnnotObject_Info& object)
  84.     : m_Object(&object.GetSeq_annot_Info()),
  85.       m_AnnotObject_Index(object.GetSeq_annot_Info()
  86.                           .GetAnnotObjectIndex(object)),
  87.       m_ObjectType(eType_Seq_annot_Info),
  88.       m_MappedFlags(0),
  89.       m_MappedObjectType(eMappedObjType_not_set),
  90.       m_MappedStrand(eNa_strand_unknown)
  91. {
  92.     if ( object.IsFeat() ) {
  93.         const CSeq_feat& feat = *object.GetFeatFast();
  94.         if ( feat.IsSetPartial() ) {
  95.             SetPartial(feat.GetPartial());
  96.         }
  97.     }
  98. }
  99. inline
  100. CAnnotObject_Ref::CAnnotObject_Ref(const CSeq_annot_SNP_Info& snp_annot,
  101.                                    TSeqPos index)
  102.     : m_Object(&snp_annot),
  103.       m_AnnotObject_Index(index),
  104.       m_ObjectType(eType_Seq_annot_SNP_Info),
  105.       m_MappedFlags(0),
  106.       m_MappedObjectType(eMappedObjType_not_set),
  107.       m_MappedStrand(eNa_strand_unknown)
  108. {
  109. }
  110. const CAnnotObject_Info& CAnnotObject_Ref::GetAnnotObject_Info(void) const
  111. {
  112.     return GetSeq_annot_Info().GetAnnotObject_Info(GetAnnotObjectIndex());
  113. }
  114. const SSNP_Info& CAnnotObject_Ref::GetSNP_Info(void) const
  115. {
  116.     return GetSeq_annot_SNP_Info().GetSNP_Info(GetAnnotObjectIndex());
  117. }
  118. bool CAnnotObject_Ref::IsFeat(void) const
  119. {
  120.     return GetObjectType() == eType_Seq_annot_SNP_Info ||
  121.         (GetObjectType() == eType_Seq_annot_Info &&
  122.          GetAnnotObject_Info().IsFeat());
  123. }
  124. bool CAnnotObject_Ref::IsGraph(void) const
  125. {
  126.     return GetObjectType() == eType_Seq_annot_Info &&
  127.         GetAnnotObject_Info().IsGraph();
  128. }
  129. bool CAnnotObject_Ref::IsAlign(void) const
  130. {
  131.     return GetObjectType() == eType_Seq_annot_Info &&
  132.         GetAnnotObject_Info().IsAlign();
  133. }
  134. const CSeq_feat& CAnnotObject_Ref::GetFeat(void) const
  135. {
  136.     return GetAnnotObject_Info().GetFeat();
  137. }
  138. const CSeq_graph& CAnnotObject_Ref::GetGraph(void) const
  139. {
  140.     return GetAnnotObject_Info().GetGraph();
  141. }
  142. const CSeq_align& CAnnotObject_Ref::GetAlign(void) const
  143. {
  144.     return GetAnnotObject_Info().GetAlign();
  145. }
  146. inline
  147. void CAnnotObject_Ref::SetSNP_Point(const SSNP_Info& snp,
  148.                                     CSeq_loc_Conversion* cvt)
  149. {
  150.     _ASSERT(GetObjectType() == eType_Seq_annot_SNP_Info);
  151.     TSeqPos src_from = snp.GetFrom(), src_to = snp.GetTo();
  152.     ENa_strand src_strand =
  153.         snp.MinusStrand()? eNa_strand_minus: eNa_strand_plus;
  154.     if ( !cvt ) {
  155.         SetTotalRange(TRange(src_from, src_to));
  156.         SetMappedSeq_id(const_cast<CSeq_id&>(GetSeq_annot_SNP_Info().                                             GetSeq_id()),
  157.                         true);
  158.         SetMappedStrand(src_strand);
  159.         return;
  160.     }
  161.     cvt->Reset();
  162.     if ( src_from == src_to ) {
  163.         // point
  164.         _VERIFY(cvt->ConvertPoint(src_from, src_strand));
  165.     }
  166.     else {
  167.         // interval
  168.         _VERIFY(cvt->ConvertInterval(src_from, src_to, src_strand));
  169.     }
  170.     cvt->SetMappedLocation(*this, CSeq_loc_Conversion::eLocation);
  171. }
  172. const CSeq_align&
  173. CAnnotObject_Ref::GetMappedSeq_align(void) const
  174. {
  175.     if (m_MappedObjectType == eMappedObjType_Seq_loc_Conv_Set) {
  176.         // Map the alignment, replace conv-set with the mapped align
  177.         CSeq_loc_Conversion_Set& cvts =
  178.             const_cast<CSeq_loc_Conversion_Set&>(
  179.             *CTypeConverter<CSeq_loc_Conversion_Set>::
  180.             SafeCast(m_MappedObject.GetPointer()));
  181.         CRef<CSeq_align> dst;
  182.         cvts.Convert(GetAlign(), &dst);
  183.         const_cast<CAnnotObject_Ref&>(*this).
  184.             SetMappedSeq_align(dst.GetPointerOrNull());
  185.     }
  186.     _ASSERT(m_MappedObjectType == eMappedObjType_Seq_align);
  187.     return *CTypeConverter<CSeq_align>::
  188.         SafeCast(m_MappedObject.GetPointer());
  189. }
  190. void CAnnotObject_Ref::SetMappedSeq_align_Cvts(CSeq_loc_Conversion_Set& cvts)
  191. {
  192.     _ASSERT(!IsMapped());
  193.     m_MappedObject.Reset(&cvts);
  194.     m_MappedObjectType = eMappedObjType_Seq_loc_Conv_Set;
  195. }
  196. void CAnnotObject_Ref::SetMappedSeq_align(CSeq_align* align)
  197. {
  198.     _ASSERT(m_MappedObjectType == eMappedObjType_Seq_loc_Conv_Set);
  199.     m_MappedObject.Reset(align);
  200.     m_MappedObjectType =
  201.         align? eMappedObjType_Seq_align: eMappedObjType_not_set;
  202. }
  203. void CAnnotObject_Ref::UpdateMappedSeq_loc(CRef<CSeq_loc>& loc) const
  204. {
  205.     _ASSERT(MappedSeq_locNeedsUpdate());
  206.     
  207.     CSeq_id& id = const_cast<CSeq_id&>(GetMappedSeq_id());
  208.     if ( !loc || !loc->ReferencedOnlyOnce() ) {
  209.         loc.Reset(new CSeq_loc);
  210.     }
  211.     else {
  212.         loc->InvalidateTotalRangeCache();
  213.     }
  214.     if ( IsMappedPoint() ) {
  215.         CSeq_point& point = loc->SetPnt();
  216.         point.SetId(id);
  217.         point.SetPoint(m_TotalRange.GetFrom());
  218.         if ( GetMappedStrand() != eNa_strand_unknown )
  219.             point.SetStrand(GetMappedStrand());
  220.         else
  221.             point.ResetStrand();
  222.     }
  223.     else {
  224.         CSeq_interval& interval = loc->SetInt();
  225.         interval.SetId(id);
  226.         interval.SetFrom(GetTotalRange().GetFrom());
  227.         interval.SetTo(GetTotalRange().GetTo());
  228.         if ( GetMappedStrand() != eNa_strand_unknown )
  229.             interval.SetStrand(GetMappedStrand());
  230.         else
  231.             interval.ResetStrand();
  232.     }
  233. }
  234. void CAnnotObject_Ref::UpdateMappedSeq_loc(CRef<CSeq_loc>& loc,
  235.                                            CRef<CSeq_point>& pnt_ref,
  236.                                            CRef<CSeq_interval>& int_ref) const
  237. {
  238.     _ASSERT(MappedSeq_locNeedsUpdate());
  239.     CSeq_id& id = const_cast<CSeq_id&>(GetMappedSeq_id());
  240.     if ( !loc || !loc->ReferencedOnlyOnce() ) {
  241.         loc.Reset(new CSeq_loc);
  242.     }
  243.     else {
  244.         loc->Reset();
  245.         loc->InvalidateTotalRangeCache();
  246.     }
  247.     if ( IsMappedPoint() ) {
  248.         if ( !pnt_ref || !pnt_ref->ReferencedOnlyOnce() ) {
  249.             pnt_ref.Reset(new CSeq_point);
  250.         }
  251.         CSeq_point& point = *pnt_ref;
  252.         loc->SetPnt(point);
  253.         point.SetId(id);
  254.         point.SetPoint(m_TotalRange.GetFrom());
  255.         if ( GetMappedStrand() != eNa_strand_unknown )
  256.             point.SetStrand(GetMappedStrand());
  257.         else
  258.             point.ResetStrand();
  259.     }
  260.     else {
  261.         if ( !int_ref || !int_ref->ReferencedOnlyOnce() ) {
  262.             int_ref.Reset(new CSeq_interval);
  263.         }
  264.         CSeq_interval& interval = *int_ref;
  265.         loc->SetInt(interval);
  266.         interval.SetId(id);
  267.         interval.SetFrom(m_TotalRange.GetFrom());
  268.         interval.SetTo(m_TotalRange.GetTo());
  269.         if ( GetMappedStrand() != eNa_strand_unknown )
  270.             interval.SetStrand(GetMappedStrand());
  271.         else
  272.             interval.ResetStrand();
  273.     }
  274. }
  275. bool CAnnotObject_Ref::operator<(const CAnnotObject_Ref& ref) const
  276. {
  277.     if ( m_Object != ref.m_Object ) {
  278.         return m_Object < ref.m_Object;
  279.     }
  280.     return GetAnnotObjectIndex() < ref.GetAnnotObjectIndex();
  281. }
  282. /////////////////////////////////////////////////////////////////////////////
  283. // CAnnotObject_Ref comparision
  284. /////////////////////////////////////////////////////////////////////////////
  285. struct CAnnotObjectType_Less
  286. {
  287.     bool operator()(const CAnnotObject_Ref& x,
  288.                     const CAnnotObject_Ref& y) const;
  289.     static const CSeq_loc& GetLocation(const CAnnotObject_Ref& ref,
  290.                                        const CSeq_feat& feat);
  291. };
  292. const CSeq_loc& CAnnotObjectType_Less::GetLocation(const CAnnotObject_Ref& ref,
  293.                                                    const CSeq_feat& feat)
  294. {
  295.     if ( ref.GetMappedObjectType() == ref.eMappedObjType_Seq_loc &&
  296.          !ref.IsProduct() ) {
  297.         return ref.GetMappedSeq_loc();
  298.     }
  299.     else {
  300.         return feat.GetLocation();
  301.     }
  302. }
  303. bool CAnnotObjectType_Less::operator()(const CAnnotObject_Ref& x,
  304.                                        const CAnnotObject_Ref& y) const
  305. {
  306.     // gather x annotation type
  307.     const CAnnotObject_Info* x_info;
  308.     CSeq_annot::C_Data::E_Choice x_annot_type;
  309.     if ( !x.IsSNPFeat() ) {
  310.         const CSeq_annot_Info& x_annot = x.GetSeq_annot_Info();
  311.         x_info = &x_annot.GetAnnotObject_Info(x.GetAnnotObjectIndex());
  312.         x_annot_type = x_info->GetAnnotType();
  313.     }
  314.     else {
  315.         x_info = 0;
  316.         x_annot_type = CSeq_annot::C_Data::e_Ftable;
  317.     }
  318.     // gather y annotation type
  319.     const CAnnotObject_Info* y_info;
  320.     CSeq_annot::C_Data::E_Choice y_annot_type;
  321.     if ( !y.IsSNPFeat() ) {
  322.         const CSeq_annot_Info& y_annot = y.GetSeq_annot_Info();
  323.         y_info = &y_annot.GetAnnotObject_Info(y.GetAnnotObjectIndex());
  324.         y_annot_type = y_info->GetAnnotType();
  325.     }
  326.     else {
  327.         y_info = 0;
  328.         y_annot_type = CSeq_annot::C_Data::e_Ftable;
  329.     }
  330.     // compare by annotation type (feature, align, graph)
  331.     if ( x_annot_type != y_annot_type ) {
  332.         return x_annot_type < y_annot_type;
  333.     }
  334.     if ( x_annot_type == CSeq_annot::C_Data::e_Ftable ) {
  335.         // compare features by type
  336.         if ( !x_info != !y_info ) {
  337.             CSeqFeatData::E_Choice x_feat_type = CSeqFeatData::e_Imp;
  338.             CSeqFeatData::ESubtype x_feat_subtype =
  339.                 CSeqFeatData::eSubtype_variation;
  340.             if ( x_info ) {
  341.                 x_feat_type = x_info->GetFeatType();
  342.                 x_feat_subtype = x_info->GetFeatSubtype();
  343.             }
  344.             CSeqFeatData::E_Choice y_feat_type = CSeqFeatData::e_Imp;
  345.             CSeqFeatData::ESubtype y_feat_subtype =
  346.                 CSeqFeatData::eSubtype_variation;
  347.             if ( y_info ) {
  348.                 y_feat_type = y_info->GetFeatType();
  349.                 y_feat_subtype = y_info->GetFeatSubtype();
  350.             }
  351.             // one is simple SNP feature, another is some complex feature
  352.             if ( x_feat_type != y_feat_type ) {
  353.                 int x_order = CSeq_feat::GetTypeSortingOrder(x_feat_type);
  354.                 int y_order = CSeq_feat::GetTypeSortingOrder(y_feat_type);
  355.                 if ( x_order != y_order ) {
  356.                     return x_order < y_order;
  357.                 }
  358.             }
  359.             // non-variations first
  360.             if ( x_feat_subtype != y_feat_subtype ) {
  361.                 return x_feat_subtype < y_feat_subtype;
  362.             }
  363.             // both are variations but one is simple and another is not.
  364.             // required order: simple first.
  365.             // if !x_info == true -> x - simple, y - complex -> return true
  366.             // if !x_info == false -> x - complex, y - simple -> return false
  367.             return !x_info;
  368.         }
  369.         if ( x_info ) {
  370.             // both are complex features
  371.             try {
  372.                 const CSeq_feat* x_feat = x_info->GetFeatFast();
  373.                 const CSeq_feat* y_feat = y_info->GetFeatFast();
  374.                 _ASSERT(x_feat && y_feat);
  375.                 int diff = x_feat->CompareNonLocation(*y_feat,
  376.                                                       GetLocation(x, *x_feat),
  377.                                                       GetLocation(y, *y_feat));
  378.                 if ( diff != 0 ) {
  379.                     return diff < 0;
  380.                 }
  381.             }
  382.             catch ( exception& /*ignored*/ ) {
  383.                 // do not fail sort when compare function throws an exception
  384.             }
  385.         }
  386.     }
  387.     return x < y;
  388. }
  389. struct CAnnotObject_Less
  390. {
  391.     // Compare CRef-s: both must be features
  392.     bool operator()(const CAnnotObject_Ref& x,
  393.                     const CAnnotObject_Ref& y) const
  394.         {
  395.             {
  396.                 // smallest left extreme first
  397.                 TSeqPos x_from = x.GetFrom();
  398.                 TSeqPos y_from = y.GetFrom();
  399.                 if ( x_from != y_from ) {
  400.                     return x_from < y_from;
  401.                 }
  402.             }
  403.             {
  404.                 // longest feature first
  405.                 TSeqPos x_to = x.GetToOpen();
  406.                 TSeqPos y_to = y.GetToOpen();
  407.                 if ( x_to != y_to ) {
  408.                     return x_to > y_to;
  409.                 }
  410.             }
  411.             return type_less(x, y);
  412.         }
  413.     CAnnotObjectType_Less type_less;
  414. };
  415. struct CAnnotObject_LessReverse
  416. {
  417.     // Compare CRef-s: both must be features
  418.     bool operator()(const CAnnotObject_Ref& x,
  419.                     const CAnnotObject_Ref& y) const
  420.         {
  421.             {
  422.                 // largest right extreme first
  423.                 TSeqPos x_to = x.GetToOpen();
  424.                 TSeqPos y_to = y.GetToOpen();
  425.                 if ( x_to != y_to ) {
  426.                     return x_to > y_to;
  427.                 }
  428.             }
  429.             {
  430.                 // longest feature first
  431.                 TSeqPos x_from = x.GetFrom();
  432.                 TSeqPos y_from = y.GetFrom();
  433.                 if ( x_from != y_from ) {
  434.                     return x_from < y_from;
  435.                 }
  436.             }
  437.             return type_less(x, y);
  438.         }
  439.     CAnnotObjectType_Less type_less;
  440. };
  441. /////////////////////////////////////////////////////////////////////////////
  442. // CAnnot_Collector, CAnnotMappingCollector
  443. /////////////////////////////////////////////////////////////////////////////
  444. class CAnnotMappingCollector
  445. {
  446. public:
  447.     typedef map<CAnnotObject_Ref,
  448.                 CRef<CSeq_loc_Conversion_Set> > TAnnotMappingSet;
  449.     // Set of annotations for complex remapping
  450.     TAnnotMappingSet              m_AnnotMappingSet;
  451.     // info of limit object
  452.     CConstRef<CObject>            m_LimitObjectInfo;
  453. };
  454. CAnnot_Collector::CAnnot_Collector(const SAnnotSelector& selector,
  455.                                          CScope&               scope)
  456.     : m_Selector(selector),
  457.       m_Scope(scope),
  458.       m_MappingCollector(new CAnnotMappingCollector)
  459. {
  460.     return;
  461. }
  462. CAnnot_Collector::~CAnnot_Collector(void)
  463. {
  464.     x_Clear();
  465. }
  466. inline
  467. size_t CAnnot_Collector::x_GetAnnotCount(void) const
  468. {
  469.     return m_AnnotSet.size() +
  470.         (m_MappingCollector.get() ?
  471.         m_MappingCollector->m_AnnotMappingSet.size() : 0);
  472. }
  473. void CAnnot_Collector::x_Clear(void)
  474. {
  475.     m_AnnotSet.clear();
  476.     if ( m_MappingCollector.get() ) {
  477.         m_MappingCollector.reset();
  478.     }
  479.     m_TSE_LockSet.clear();
  480.     m_Scope = CHeapScope();
  481. }
  482. void CAnnot_Collector::x_Initialize(const CBioseq_Handle& bioseq,
  483.                                        TSeqPos start, TSeqPos stop)
  484. {
  485.     try {
  486.         if ( start == 0 && stop == 0 ) {
  487.             stop = bioseq.GetBioseqLength()-1;
  488.         }
  489.         CHandleRangeMap master_loc;
  490.         master_loc.AddRange(bioseq.GetSeq_id_Handle(),
  491.                             CHandleRange::TRange(start, stop),
  492.                             eNa_strand_unknown);
  493.         x_Initialize(master_loc);
  494.     } catch (...) {
  495.         // clear all members - GCC 3.0.4 does not do it
  496.         x_Clear();
  497.         throw;
  498.     }
  499. }
  500. void CAnnot_Collector::x_Initialize(const CHandleRangeMap& master_loc)
  501. {
  502.     try {
  503.         if ( !m_Selector.m_LimitObject ) {
  504.             m_Selector.m_LimitObjectType = SAnnotSelector::eLimit_None;
  505.         }
  506.         if ( m_Selector.m_LimitObjectType != SAnnotSelector::eLimit_None ) {
  507.             x_GetTSE_Info();
  508.         }
  509.         bool found = x_Search(master_loc, 0);
  510.         bool deeper = !(found && m_Selector.m_AdaptiveDepth) &&
  511.             m_Selector.m_ResolveMethod != SAnnotSelector::eResolve_None  &&
  512.             m_Selector.m_ResolveDepth > 0;
  513.         if ( deeper ) {
  514.             ITERATE ( CHandleRangeMap::TLocMap, idit, master_loc.GetMap() ) {
  515.                 //### Check for eLoadedOnly
  516.                 CBioseq_Handle bh = m_Scope->GetBioseqHandle(idit->first,
  517.                     CScope::eGetBioseq_All);
  518.                 if ( !bh ) {
  519.                     if (m_Selector.m_IdResolving ==
  520.                         SAnnotSelector::eFailUnresolved) {
  521.                         // resolve by Seq-id only
  522.                         NCBI_THROW(CAnnotException, eFindFailed,
  523.                                    "Cannot resolve master id");
  524.                     }
  525.                     continue; // Do not crash - just skip unresolvable IDs
  526.                 }
  527.                 CRef<CSeq_loc> master_loc_empty(new CSeq_loc);
  528.                 master_loc_empty->SetEmpty(
  529.                     const_cast<CSeq_id&>(*idit->first.GetSeqId()));
  530.                 
  531.                 CHandleRange::TRange idrange =
  532.                     idit->second.GetOverlappingRange();
  533.                 const CSeqMap& seqMap = bh.GetSeqMap();
  534.                 CSeqMap_CI smit(seqMap.FindResolved(idrange.GetFrom(),
  535.                                                     m_Scope,
  536.                                                     m_Selector.m_ResolveDepth-1,
  537.                                                     CSeqMap::fFindRef));
  538.                 while ( smit && smit.GetPosition() < idrange.GetToOpen() ) {
  539.                     _ASSERT(smit.GetType() == CSeqMap::eSeqRef);
  540.                     if ( m_Selector.m_ResolveMethod ==
  541.                         SAnnotSelector::eResolve_TSE &&
  542.                         !m_Scope->GetBioseqHandleFromTSE(smit.GetRefSeqid(),
  543.                                                          bh) ) {
  544.                         smit.Next(false);
  545.                         continue;
  546.                     }
  547.                     found = x_SearchMapped(smit,
  548.                                            *master_loc_empty,
  549.                                            idit->first,
  550.                                            idit->second);
  551.                     deeper = !(found && m_Selector.m_AdaptiveDepth);
  552.                     smit.Next(deeper);
  553.                 }
  554.             }
  555.         }
  556.         NON_CONST_ITERATE(CAnnotMappingCollector::TAnnotMappingSet, amit,
  557.             m_MappingCollector->m_AnnotMappingSet) {
  558.             CAnnotObject_Ref annot_ref = amit->first;
  559.             amit->second->Convert(annot_ref,
  560.                 m_Selector.m_FeatProduct ? CSeq_loc_Conversion::eProduct :
  561.                 CSeq_loc_Conversion::eLocation);
  562.             m_AnnotSet.push_back(annot_ref);
  563.         }
  564.         m_MappingCollector->m_AnnotMappingSet.clear();
  565.         x_Sort();
  566.         m_MappingCollector.reset();
  567.     }
  568.     catch (...) {
  569.         // clear all members - GCC 3.0.4 does not do it
  570.         x_Clear();
  571.         throw;
  572.     }
  573. }
  574. void CAnnot_Collector::x_Initialize(void)
  575. {
  576.     try {
  577.         // Limit must be set, resolving is obsolete
  578.         _ASSERT(m_Selector.m_LimitObjectType != SAnnotSelector::eLimit_None);
  579.         _ASSERT(m_Selector.m_LimitObject);
  580.         _ASSERT(m_Selector.m_ResolveMethod == SAnnotSelector::eResolve_None);
  581.         x_GetTSE_Info();
  582.         x_SearchAll();
  583.         x_Sort();
  584.         m_MappingCollector.reset();
  585.     }
  586.     catch (...) {
  587.         // clear all members - GCC 3.0.4 does not do it
  588.         x_Clear();
  589.         throw;
  590.     }
  591. }
  592. void CAnnot_Collector::x_Sort(void)
  593. {
  594.     _ASSERT(m_MappingCollector->m_AnnotMappingSet.empty());
  595.     switch ( m_Selector.m_SortOrder ) {
  596.     case SAnnotSelector::eSortOrder_Normal:
  597.         sort(m_AnnotSet.begin(), m_AnnotSet.end(), CAnnotObject_Less());
  598.         break;
  599.     case SAnnotSelector::eSortOrder_Reverse:
  600.         sort(m_AnnotSet.begin(), m_AnnotSet.end(), CAnnotObject_LessReverse());
  601.         break;
  602.     default:
  603.         // do nothing
  604.         break;
  605.     }
  606. }
  607. inline
  608. bool
  609. CAnnot_Collector::x_MatchLimitObject(const CAnnotObject_Info& object_info) const
  610. {
  611.     if ( m_Selector.m_LimitObjectType == SAnnotSelector::eLimit_Seq_entry_Info ) {
  612.         const CSeq_entry_Info* info = &object_info.GetSeq_entry_Info();
  613.         _ASSERT(m_MappingCollector->m_LimitObjectInfo);
  614.         _ASSERT(info);
  615.         for ( ;; ) {
  616.             if ( info == m_MappingCollector->m_LimitObjectInfo.GetPointer() ) {
  617.                 return true;
  618.             }
  619.             if ( !info->HasParent_Info() ) {
  620.                 return false;
  621.             }
  622.             info = &info->GetParentSeq_entry_Info();
  623.         }
  624.     }
  625.     else if ( m_Selector.m_LimitObjectType ==
  626.         SAnnotSelector::eLimit_Seq_annot_Info ) {
  627.         const CSeq_annot_Info* info = &object_info.GetSeq_annot_Info();
  628.         _ASSERT(m_MappingCollector->m_LimitObjectInfo);
  629.         return info == m_MappingCollector->m_LimitObjectInfo.GetPointer();
  630.     }
  631.     return true;
  632. }
  633. inline
  634. bool CAnnot_Collector::x_NeedSNPs(void) const
  635. {
  636.     if ( m_Selector.GetAnnotType() != CSeq_annot::C_Data::e_not_set ) {
  637.         if ( m_Selector.GetAnnotType() != CSeq_annot::C_Data::e_Ftable ) {
  638.             return false;
  639.         }
  640.         if ( !m_Selector.IncludedFeatSubtype(
  641.             CSeqFeatData::eSubtype_variation) ) {
  642.             return false;
  643.         }
  644.         else if ( !m_Selector.IncludedFeatType(CSeqFeatData::e_Imp) ) {
  645.             return false;
  646.         }
  647.     }
  648.     return true;
  649. }
  650. inline
  651. bool CAnnot_Collector::x_MatchLocIndex(const SAnnotObject_Index& index) const
  652. {
  653.     return index.m_AnnotObject_Info->IsAlign()  ||
  654.         m_Selector.m_FeatProduct == (index.m_AnnotLocationIndex == 1);
  655. }
  656. inline
  657. bool CAnnot_Collector::x_MatchRange(const CHandleRange& hr,
  658.                                        const CRange<TSeqPos>& range,
  659.                                        const SAnnotObject_Index& index) const
  660. {
  661.     if ( m_Selector.m_OverlapType == SAnnotSelector::eOverlap_Intervals ) {
  662.         if ( index.m_HandleRange ) {
  663.             if ( !hr.IntersectingWith(*index.m_HandleRange) ) {
  664.                 return false;
  665.             }
  666.         }
  667.         else {
  668.             if ( !hr.IntersectingWith(range) ) {
  669.                 return false;
  670.             }
  671.         }
  672.     }
  673.     if ( !x_MatchLocIndex(index) ) {
  674.         return false;
  675.     }
  676.     return true;
  677. }
  678. void CAnnot_Collector::x_GetTSE_Info(void)
  679. {
  680.     // only one TSE is needed
  681.     _ASSERT(m_TSE_LockSet.empty());
  682.     _ASSERT(m_Selector.m_LimitObjectType != SAnnotSelector::eLimit_None);
  683.     _ASSERT(m_Selector.m_LimitObject);
  684.     
  685.     TTSE_Lock tse_info;
  686.     switch ( m_Selector.m_LimitObjectType ) {
  687.     case SAnnotSelector::eLimit_TSE:
  688.     {
  689.         const CSeq_entry* object = CTypeConverter<CSeq_entry>::
  690.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  691.         CSeq_entry_Handle handle = m_Scope->GetSeq_entryHandle(*object);
  692.         if ( !handle ) {
  693.             NCBI_THROW(CAnnotException, eLimitError,
  694.                        "CAnnot_Collector::x_GetTSE_Info: "
  695.                        "unknown top level Seq-entry");
  696.         }
  697.         const CTSE_Info& info = handle.x_GetInfo().GetTSE_Info();
  698.         tse_info.Reset(&info);
  699.         // normalize TSE -> TSE_Info
  700.         m_Selector.m_LimitObjectType = SAnnotSelector::eLimit_TSE_Info;
  701.         m_Selector.m_LimitObject.Reset(&info);
  702.         m_MappingCollector->m_LimitObjectInfo.Reset(&info);
  703.         break;
  704.     }
  705.     case SAnnotSelector::eLimit_Seq_entry:
  706.     {
  707.         const CSeq_entry* object = CTypeConverter<CSeq_entry>::
  708.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  709.         CSeq_entry_Handle handle = m_Scope->GetSeq_entryHandle(*object);
  710.         if ( !handle ) {
  711.             NCBI_THROW(CAnnotException, eLimitError,
  712.                        "CAnnot_Collector::x_GetTSE_Info: "
  713.                        "unknown Seq-entry");
  714.         }
  715.         const CSeq_entry_Info& info = handle.x_GetInfo();
  716.         tse_info.Reset(&info.GetTSE_Info());
  717.         // normalize Seq_entry -> Seq_entry_Info
  718.         m_Selector.m_LimitObjectType = SAnnotSelector::eLimit_Seq_entry_Info;
  719.         m_Selector.m_LimitObject.Reset(&info);
  720.         m_MappingCollector->m_LimitObjectInfo.Reset(&info);
  721.         break;
  722.     }
  723.     case SAnnotSelector::eLimit_Seq_annot:
  724.     {
  725.         const CSeq_annot* object = CTypeConverter<CSeq_annot>::
  726.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  727.         CSeq_annot_Handle handle = m_Scope->GetSeq_annotHandle(*object);
  728.         if ( !handle ) {
  729.             NCBI_THROW(CAnnotException, eLimitError,
  730.                        "CAnnot_Collector::x_GetTSE_Info: "
  731.                        "unknown Seq-annot");
  732.         }
  733.         const CSeq_annot_Info& info = handle.x_GetInfo();
  734.         tse_info.Reset(&info.GetTSE_Info());
  735.         // normalize Seq_annot -> Seq_annot_Info
  736.         m_Selector.m_LimitObjectType = SAnnotSelector::eLimit_Seq_annot_Info;
  737.         m_Selector.m_LimitObject.Reset(&info);
  738.         m_MappingCollector->m_LimitObjectInfo.Reset(&info);
  739.         break;
  740.     }
  741.     case SAnnotSelector::eLimit_TSE_Info:
  742.     {
  743.         const CTSE_Info* info = CTypeConverter<CTSE_Info>::
  744.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  745.         tse_info.Reset(info);
  746.         m_MappingCollector->m_LimitObjectInfo.Reset(info);
  747.         break;
  748.     }
  749.     case SAnnotSelector::eLimit_Seq_entry_Info:
  750.     {
  751.         const CSeq_entry_Info* info = CTypeConverter<CSeq_entry_Info>::
  752.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  753.         tse_info.Reset(&info->GetTSE_Info());
  754.         m_MappingCollector->m_LimitObjectInfo.Reset(info);
  755.         break;
  756.     }
  757.     case SAnnotSelector::eLimit_Seq_annot_Info:
  758.     {
  759.         const CSeq_annot_Info* info = CTypeConverter<CSeq_annot_Info>::
  760.             SafeCast(m_Selector.m_LimitObject.GetPointer());
  761.         tse_info.Reset(&info->GetTSE_Info());
  762.         m_MappingCollector->m_LimitObjectInfo.Reset(info);
  763.         break;
  764.     }
  765.     default:
  766.         // no limit object -> do nothing
  767.         break;
  768.     }
  769.     _ASSERT(m_MappingCollector->m_LimitObjectInfo);
  770.     _ASSERT(tse_info);
  771.     tse_info->UpdateAnnotIndex();
  772.     //if ( !IsSetAnnotsNames() || x_MatchAnnotName(*tse_info) ) {
  773.         m_TSE_LockSet.insert(tse_info);
  774.     //}
  775. }
  776. bool CAnnot_Collector::x_Search(const CSeq_id_Handle& id,
  777.                                    const CBioseq_Handle& bh,
  778.                                    const CHandleRange& hr,
  779.                                    CSeq_loc_Conversion* cvt)
  780. {
  781.     if ( cvt )
  782.         cvt->SetSrcId(id);
  783.     bool found = false;
  784.     if ( m_Selector.m_LimitObjectType == SAnnotSelector::eLimit_None ) {
  785.         // any data source
  786.         CConstRef<CScope_Impl::TAnnotRefSet> tse_set;
  787.         if ( bh ) {
  788.             tse_set = m_Scope->GetTSESetWithAnnots(bh);
  789.         }
  790.         else {
  791.             tse_set = m_Scope->GetTSESetWithAnnots(id);
  792.         }
  793.         if ( tse_set ) {
  794.             found = x_Search(*tse_set, id, hr, cvt) || found;
  795.         }
  796.     }
  797.     else {
  798.         found = x_Search(m_TSE_LockSet, id, hr, cvt) || found;
  799.     }
  800.     return found;
  801. }
  802. static CSeqFeatData::ESubtype s_DefaultAdaptiveTriggers[] = {
  803.     CSeqFeatData::eSubtype_gene,
  804.     CSeqFeatData::eSubtype_cdregion,
  805.     CSeqFeatData::eSubtype_mRNA
  806. };
  807. bool CAnnot_Collector::x_Search(const TTSE_LockSet& tse_set,
  808.                                    const CSeq_id_Handle& id,
  809.                                    const CHandleRange& hr,
  810.                                    CSeq_loc_Conversion* cvt)
  811. {
  812.     bool found = false;
  813.     ITERATE ( TTSE_LockSet, tse_it, tse_set ) {
  814.         const CTSE_Info& tse = **tse_it;
  815.         CTSE_Info::TAnnotReadLockGuard guard(tse.m_AnnotObjsLock);
  816.         // Skip excluded TSEs
  817.         //if ( ExcludedTSE(tse) ) {
  818.         //continue;
  819.         //}
  820.         if ( m_Selector.m_AdaptiveDepth && tse.ContainsSeqid(id) ) {
  821.             const SIdAnnotObjs* objs = tse.x_GetUnnamedIdObjects(id);
  822.             if ( objs ) {
  823.                 vector<char> indexes;
  824.                 if ( m_Selector.m_AdaptiveTriggers.empty() ) {
  825.                     const size_t count =
  826.                         sizeof(s_DefaultAdaptiveTriggers)/
  827.                         sizeof(s_DefaultAdaptiveTriggers[0]);
  828.                     for ( int i = count - 1; i >= 0; --i ) {
  829.                         CSeqFeatData::ESubtype subtype =
  830.                             s_DefaultAdaptiveTriggers[i];
  831.                         size_t index = CAnnotType_Index::GetSubtypeIndex(subtype);
  832.                         if ( index ) {
  833.                             indexes.resize(max(indexes.size(), index + 1));
  834.                             indexes[index] = 1;
  835.                         }
  836.                     }
  837.                 }
  838.                 else {
  839.                     ITERATE ( SAnnotSelector::TAdaptiveTriggers, it,
  840.                         m_Selector.m_AdaptiveTriggers ) {
  841.                         pair<size_t, size_t> idxs =
  842.                             CAnnotType_Index::GetIndexRange(*it);
  843.                         indexes.resize(max(indexes.size(), idxs.second));
  844.                         for ( size_t i = idxs.first; i < idxs.second; ++i ) {
  845.                             indexes[i] = 1;
  846.                         }
  847.                     }
  848.                 }
  849.                 for ( size_t index = 0; index < indexes.size(); ++index ) {
  850.                     if ( !indexes[index] ) {
  851.                         continue;
  852.                     }
  853.                     if ( index >= objs->m_AnnotSet.size() ) {
  854.                         break;
  855.                     }
  856.                     if ( !objs->m_AnnotSet[index].empty() ) {
  857.                         found = true;
  858.                         break;
  859.                     }
  860.                 }
  861.             }
  862.         }
  863.         
  864.         if ( !m_Selector.m_IncludeAnnotsNames.empty() ) {
  865.             // only 'included' annots
  866.             ITERATE ( SAnnotSelector::TAnnotsNames, iter,
  867.                 m_Selector.m_IncludeAnnotsNames ) {
  868.                 _ASSERT(!m_Selector.ExcludedAnnotName(*iter)); // consistency check
  869.                 const SIdAnnotObjs* objs = tse.x_GetIdObjects(*iter, id);
  870.                 if ( objs ) {
  871.                     x_Search(tse, objs, guard, *iter, id, hr, cvt);
  872.                 }
  873.             }
  874.         }
  875.         else {
  876.             // all annots, skipping 'excluded'
  877.             ITERATE (CTSE_Info::TNamedAnnotObjs, iter, tse.m_NamedAnnotObjs) {
  878.                 if ( m_Selector.ExcludedAnnotName(iter->first) ) {
  879.                     continue;
  880.                 }
  881.                 const SIdAnnotObjs* objs =
  882.                     tse.x_GetIdObjects(iter->second, id);
  883.                 if ( objs ) {
  884.                     x_Search(tse, objs, guard, iter->first, id, hr, cvt);
  885.                 }
  886.             }
  887.         }
  888.     }
  889.     return found;
  890. }
  891. bool CAnnot_Collector::x_AddObjectMapping(CAnnotObject_Ref& object_ref,
  892.                                           CSeq_loc_Conversion* cvt,
  893.                                           unsigned int loc_index)
  894. {
  895.     _ASSERT(object_ref.GetAnnotObject_Info().GetMultiIdFlags()
  896.             || cvt->IsPartial()
  897.             || object_ref.IsAlign() );
  898.     object_ref.ResetLocation();
  899.     CRef<CSeq_loc_Conversion_Set>& mapping_set =
  900.         m_MappingCollector->m_AnnotMappingSet[object_ref];
  901.     if ( !mapping_set ) {
  902.         mapping_set.Reset(new CSeq_loc_Conversion_Set(m_Scope));
  903.     }
  904.     CRef<CSeq_loc_Conversion> cvt_copy(new CSeq_loc_Conversion(*cvt));
  905.     mapping_set->Add(*cvt_copy, loc_index);
  906.     return x_GetAnnotCount() >= m_Selector.m_MaxSize;
  907. }
  908. inline
  909. bool CAnnot_Collector::x_AddObject(CAnnotObject_Ref& object_ref)
  910. {
  911.     m_AnnotSet.push_back(object_ref);
  912.     return x_GetAnnotCount() >= m_Selector.m_MaxSize;
  913. }
  914. inline
  915. bool CAnnot_Collector::x_AddObject(CAnnotObject_Ref& object_ref,
  916.                                    CSeq_loc_Conversion* cvt,
  917.                                    unsigned int loc_index)
  918. {
  919.     // Always map aligns through conv. set
  920.     return ( cvt && (cvt->IsPartial() || object_ref.IsAlign()) )?
  921.         x_AddObjectMapping(object_ref, cvt, loc_index)
  922.         : x_AddObject(object_ref);
  923. }
  924. void CAnnot_Collector::x_Search(const CTSE_Info& tse,
  925.                                    const SIdAnnotObjs* objs,
  926.                                    CReadLockGuard& guard,
  927.                                    const CAnnotName& annot_name,
  928.                                    const CSeq_id_Handle& id,
  929.                                    const CHandleRange& hr,
  930.                                    CSeq_loc_Conversion* cvt)
  931. {
  932.     if (m_Selector.m_AnnotTypesSet.size() == 0) {
  933.         pair<size_t, size_t> range =
  934.             CAnnotType_Index::GetIndexRange(m_Selector, *objs);
  935.         if ( range.first < range.second ) {
  936.             x_SearchRange(tse, objs, guard, annot_name, id, hr, cvt,
  937.                 range.first, range.second);
  938.         }
  939.     }
  940.     else {
  941.         pair<size_t, size_t> range(0, 0);
  942.         bool last_bit = false;
  943.         bool cur_bit;
  944.         for (size_t idx = 0; idx < objs->m_AnnotSet.size(); ++idx) {
  945.             cur_bit = m_Selector.m_AnnotTypesSet[idx];
  946.             if (!last_bit  &&  cur_bit) {
  947.                 // open range
  948.                 range.first = idx;
  949.             }
  950.             else if (last_bit  &&  !cur_bit) {
  951.                 // close and search range
  952.                 range.second = idx;
  953.                 x_SearchRange(tse, objs, guard, annot_name, id, hr, cvt,
  954.                     range.first, range.second);
  955.             }
  956.             last_bit = cur_bit;
  957.         }
  958.         if (last_bit) {
  959.             // search to the end of annot set
  960.             x_SearchRange(tse, objs, guard, annot_name, id, hr, cvt,
  961.                 range.first, objs->m_AnnotSet.size());
  962.         }
  963.     }
  964.     if ( x_NeedSNPs() ) {
  965.         CHandleRange::TRange range = hr.GetOverlappingRange();
  966.         ITERATE ( CTSE_Info::TSNPSet, snp_annot_it, objs->m_SNPSet ) {
  967.             const CSeq_annot_SNP_Info& snp_annot = **snp_annot_it;
  968.             CSeq_annot_SNP_Info::const_iterator snp_it =
  969.                 snp_annot.FirstIn(range);
  970.             if ( snp_it != snp_annot.end() ) {
  971.                 m_TSE_LockSet.insert(ConstRef(&tse));
  972.                 TSeqPos index = snp_it - snp_annot.begin() - 1;
  973.                 do {
  974.                     ++index;
  975.                     const SSNP_Info& snp = *snp_it;
  976.                     if ( snp.NoMore(range) ) {
  977.                         break;
  978.                     }
  979.                     if ( snp.NotThis(range) ) {
  980.                         continue;
  981.                     }
  982.                     CAnnotObject_Ref annot_ref(snp_annot, index);
  983.                     annot_ref.SetSNP_Point(snp, cvt);
  984.                     if ( x_AddObject(annot_ref, cvt, 0) ) {
  985.                         return;
  986.                     }
  987.                 } while ( ++snp_it != snp_annot.end() );
  988.             }
  989.         }
  990.     }
  991. }
  992. void CAnnot_Collector::x_SearchRange(const CTSE_Info& tse,
  993.                                         const SIdAnnotObjs* objs,
  994.                                         CReadLockGuard& guard,
  995.                                         const CAnnotName& annot_name,
  996.                                         const CSeq_id_Handle& id,
  997.                                         const CHandleRange& hr,
  998.                                         CSeq_loc_Conversion* cvt,
  999.                                         size_t from_idx, size_t to_idx)
  1000. {
  1001.     _ASSERT(objs);
  1002.     CHandleRange::TRange range = hr.GetOverlappingRange();
  1003.     m_TSE_LockSet.insert(ConstRef(&tse));
  1004.     for ( size_t index = from_idx; index < to_idx; ++index ) {
  1005.         size_t start_size = m_AnnotSet.size(); // for rollback
  1006.         
  1007.         const CTSE_Info::TRangeMap& rmap = objs->m_AnnotSet[index];
  1008.         if ( rmap.empty() ) {
  1009.             continue;
  1010.         }
  1011.         for ( CTSE_Info::TRangeMap::const_iterator aoit(rmap.begin(range));
  1012.               aoit; ++aoit ) {
  1013.             const CAnnotObject_Info& annot_info =
  1014.                 *aoit->second.m_AnnotObject_Info;
  1015.             _ASSERT(m_Selector.MatchType(annot_info));
  1016.             if ( annot_info.IsChunkStub() ) {
  1017.                 const CTSE_Chunk_Info& chunk = annot_info.GetChunk_Info();
  1018.                 if ( chunk.NotLoaded() ) {
  1019.                     // New annot objects are to be loaded,
  1020.                     // so we'll need to restart scan of current range.
  1021.                     // Forget already found object
  1022.                     // as they will be found again:
  1023.                     m_AnnotSet.resize(start_size);
  1024.                     CAnnotName name(annot_name);
  1025.                     // Release lock for tse update:
  1026.                     guard.Release();
  1027.                         
  1028.                     // Load the stub:
  1029.                     const_cast<CTSE_Chunk_Info&>(chunk).Load();
  1030.                     // Acquire the lock again:
  1031.                     guard.Guard(tse.m_AnnotObjsLock);
  1032.                     // Reget range map pointer as it may change:
  1033.                     objs = tse.x_GetIdObjects(name, id);
  1034.                     _ASSERT(objs);
  1035.                     // Restart this index again:
  1036.                     --index;
  1037.                     break;
  1038.                 }
  1039.                 else {
  1040.                     // Skip chunk stub
  1041.                     continue;
  1042.                 }
  1043.             }
  1044.             if ( !x_MatchLimitObject(annot_info) ) {
  1045.                 continue;
  1046.             }
  1047.                 
  1048.             if ( !x_MatchRange(hr, aoit->first, aoit->second) ) {
  1049.                 continue;
  1050.             }
  1051.             CAnnotObject_Ref annot_ref(annot_info);
  1052.             if (!cvt  &&  annot_info.GetMultiIdFlags()) {
  1053.                 // Create self-conversion, add to conversion set
  1054.                 CRef<CSeq_loc_Conversion> cvt_ref
  1055.                     (new CSeq_loc_Conversion(id, m_Scope));
  1056.                 if (x_AddObjectMapping(annot_ref,
  1057.                     &*cvt_ref, aoit->second.m_AnnotLocationIndex)) {
  1058.                     return;
  1059.                 }
  1060.             }
  1061.             else {
  1062.                 if (cvt  &&  !annot_ref.IsAlign() ) {
  1063.                     cvt->Convert
  1064.                         (annot_ref,
  1065.                          m_Selector.m_FeatProduct ?
  1066.                          CSeq_loc_Conversion::eProduct :
  1067.                          CSeq_loc_Conversion::eLocation);
  1068.                 }
  1069.                 else {
  1070.                     annot_ref.SetAnnotObjectRange(aoit->first,
  1071.                                                   m_Selector.m_FeatProduct);
  1072.                 }
  1073.                 if ( x_AddObject(annot_ref, cvt,
  1074.                     aoit->second.m_AnnotLocationIndex) ) {
  1075.                     return;
  1076.                 }
  1077.             }
  1078.         }
  1079.     }
  1080. }
  1081. bool CAnnot_Collector::x_Search(const CHandleRangeMap& loc,
  1082.                                    CSeq_loc_Conversion* cvt)
  1083. {
  1084.     bool found = false;
  1085.     ITERATE ( CHandleRangeMap, idit, loc ) {
  1086.         if ( idit->second.Empty() ) {
  1087.             continue;
  1088.         }
  1089.         bool have_main = false;
  1090.         CConstRef<CSynonymsSet> syns = m_Scope->GetSynonyms(idit->first);
  1091.         if ( !syns ) {
  1092.             if (m_Selector.m_IdResolving == SAnnotSelector::eFailUnresolved) {
  1093.                 NCBI_THROW(CAnnotException, eFindFailed,
  1094.                            "Cannot find id synonyms");
  1095.             }
  1096.         }
  1097.         else {
  1098.             ITERATE ( CSynonymsSet, synit, *syns ) {
  1099.                 CSeq_id_Handle idh = CSynonymsSet::GetSeq_id_Handle(synit);
  1100.                 if ( !have_main ) {
  1101.                     have_main = idit->first == idh;
  1102.                 }
  1103.                 found = x_Search(idh, CSynonymsSet::GetBioseqHandle(synit),
  1104.                                  idit->second, cvt)  ||  found;
  1105.             }
  1106.         }
  1107.         if ( !have_main ) {
  1108.             found = x_Search(idit->first, CBioseq_Handle(),
  1109.                              idit->second, cvt)  ||  found;
  1110.         }
  1111.     }
  1112.     return found;
  1113. }
  1114. void CAnnot_Collector::x_SearchAll(void)
  1115. {
  1116.     _ASSERT(m_Selector.m_LimitObjectType != SAnnotSelector::eLimit_None);
  1117.     _ASSERT(m_Selector.m_LimitObject);
  1118.     _ASSERT(m_MappingCollector->m_LimitObjectInfo);
  1119.     if ( m_TSE_LockSet.empty() ) {
  1120.         // data source name not matched
  1121.         return;
  1122.     }
  1123.     switch ( m_Selector.m_LimitObjectType ) {
  1124.     case SAnnotSelector::eLimit_TSE_Info:
  1125.         x_SearchAll(*CTypeConverter<CTSE_Info>::
  1126.                     SafeCast(m_MappingCollector->
  1127.                     m_LimitObjectInfo.GetPointer()));
  1128.         break;
  1129.     case SAnnotSelector::eLimit_Seq_entry_Info:
  1130.         x_SearchAll(*CTypeConverter<CSeq_entry_Info>::
  1131.                     SafeCast(m_MappingCollector->
  1132.                     m_LimitObjectInfo.GetPointer()));
  1133.         break;
  1134.     case SAnnotSelector::eLimit_Seq_annot_Info:
  1135.         x_SearchAll(*CTypeConverter<CSeq_annot_Info>::
  1136.                     SafeCast(m_MappingCollector->
  1137.                     m_LimitObjectInfo.GetPointer()));
  1138.         break;
  1139.     default:
  1140.         // no limit object -> do nothing
  1141.         break;
  1142.     }
  1143. }
  1144. void CAnnot_Collector::x_SearchAll(const CSeq_entry_Info& entry_info)
  1145. {
  1146.     {{
  1147.         CConstRef<CBioseq_Base_Info> base = entry_info.m_Contents;
  1148.         // Collect all annotations from the entry
  1149.         ITERATE( CBioseq_Base_Info::TAnnot, ait, base->GetAnnot() ) {
  1150.             x_SearchAll(**ait);
  1151.             if ( x_GetAnnotCount() >= m_Selector.m_MaxSize )
  1152.                 return;
  1153.         }
  1154.     }}
  1155.     if ( entry_info.IsSet() ) {
  1156.         CConstRef<CBioseq_set_Info> set(&entry_info.GetSet());
  1157.         // Collect annotations from all children
  1158.         ITERATE( CBioseq_set_Info::TSeq_set, cit, set->GetSeq_set() ) {
  1159.             x_SearchAll(**cit);
  1160.             if ( x_GetAnnotCount() >= m_Selector.m_MaxSize )
  1161.                 return;
  1162.         }
  1163.     }
  1164. }
  1165. void CAnnot_Collector::x_SearchAll(const CSeq_annot_Info& annot_info)
  1166. {
  1167.     // Collect all annotations from the annot
  1168.     ITERATE ( SAnnotObjects_Info::TObjectInfos, aoit,
  1169.               annot_info.m_ObjectInfos.GetInfos() ) {
  1170.         if ( !m_Selector.MatchType(*aoit) ) {
  1171.             continue;
  1172.         }
  1173.         CAnnotObject_Ref annot_ref(*aoit);
  1174.         if ( x_AddObject(annot_ref) ) {
  1175.             return;
  1176.         }
  1177.     }
  1178.     if ( x_NeedSNPs() && annot_info.x_HasSNP_annot_Info() ) {
  1179.         const CSeq_annot_SNP_Info& snp_annot =
  1180.             annot_info.x_GetSNP_annot_Info();
  1181.         TSeqPos index = 0;
  1182.         ITERATE ( CSeq_annot_SNP_Info, snp_it, snp_annot ) {
  1183.             const SSNP_Info& snp = *snp_it;
  1184.             CAnnotObject_Ref annot_ref(snp_annot, index);
  1185.             annot_ref.SetSNP_Point(snp, 0);
  1186.             if ( x_AddObject(annot_ref) ) {
  1187.                 return;
  1188.             }
  1189.             ++index;
  1190.         }
  1191.     }
  1192. }
  1193. bool CAnnot_Collector::x_SearchMapped(const CSeqMap_CI& seg,
  1194.                                       CSeq_loc& master_loc_empty,
  1195.                                       const CSeq_id_Handle& master_id,
  1196.                                       const CHandleRange& master_hr)
  1197. {
  1198.     CHandleRange::TOpenRange master_seg_range(seg.GetPosition(),
  1199.                                               seg.GetEndPosition());
  1200.     CHandleRange::TOpenRange ref_seg_range(seg.GetRefPosition(),
  1201.                                            seg.GetRefEndPosition());
  1202.     bool reversed = seg.GetRefMinusStrand();
  1203.     TSignedSeqPos shift;
  1204.     if ( !reversed ) {
  1205.         shift = ref_seg_range.GetFrom() - master_seg_range.GetFrom();
  1206.     }
  1207.     else {
  1208.         shift = ref_seg_range.GetTo() + master_seg_range.GetFrom();
  1209.     }
  1210.     CSeq_id_Handle ref_id = seg.GetRefSeqid();
  1211.     CHandleRangeMap ref_loc;
  1212.     {{ // translate master_loc to ref_loc
  1213.         CHandleRange& hr = ref_loc.AddRanges(ref_id);
  1214.         ITERATE ( CHandleRange, mlit, master_hr ) {
  1215.             CHandleRange::TOpenRange range =
  1216.                 master_seg_range.IntersectionWith(mlit->first);
  1217.             if ( !range.Empty() ) {
  1218.                 ENa_strand strand = mlit->second;
  1219.                 if ( !reversed ) {
  1220.                     range.SetOpen(range.GetFrom() + shift,
  1221.                                   range.GetToOpen() + shift);
  1222.                 }
  1223.                 else {
  1224.                     strand = Reverse(strand);
  1225.                     range.Set(shift - range.GetTo(), shift - range.GetFrom());
  1226.                 }
  1227.                 hr.AddRange(range, strand);
  1228.             }
  1229.         }
  1230.         if ( hr.Empty() )
  1231.             return false;
  1232.     }}
  1233.     if (m_Selector.m_NoMapping) {
  1234.         return x_Search(ref_loc, 0);
  1235.     }
  1236.     else {
  1237.         CRef<CSeq_loc_Conversion> cvt(new CSeq_loc_Conversion(master_loc_empty,
  1238.                                                               master_id,
  1239.                                                               seg,
  1240.                                                               ref_id,
  1241.                                                               m_Scope));
  1242.         return x_Search(ref_loc, &*cvt);
  1243.     }
  1244. }
  1245. END_SCOPE(objects)
  1246. END_NCBI_SCOPE
  1247. /*
  1248. * ---------------------------------------------------------------------------
  1249. * $Log: annot_collector.cpp,v $
  1250. * Revision 1000.3  2004/06/01 19:22:32  gouriano
  1251. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.7
  1252. *
  1253. * Revision 1.7  2004/05/26 14:29:20  grichenk
  1254. * Redesigned CSeq_align_Mapper: preserve non-mapping intervals,
  1255. * fixed strands handling, improved performance.
  1256. *
  1257. * Revision 1.6  2004/05/21 21:42:12  gorelenk
  1258. * Added PCH ncbi_pch.hpp
  1259. *
  1260. * Revision 1.5  2004/05/10 18:26:37  grichenk
  1261. * Fixed 'not used' warnings
  1262. *
  1263. * Revision 1.4  2004/05/03 17:01:03  grichenk
  1264. * Invalidate total range before reusing seq-loc.
  1265. *
  1266. * Revision 1.3  2004/04/13 21:14:27  vasilche
  1267. * Fixed wrong order of object deletion causing "tse is locked" error.
  1268. *
  1269. * Revision 1.2  2004/04/13 15:59:35  grichenk
  1270. * Added CScope::GetBioseqHandle() with id resolving flag.
  1271. *
  1272. * Revision 1.1  2004/04/05 15:54:26  grichenk
  1273. * Initial revision
  1274. *
  1275. *
  1276. * ===========================================================================
  1277. */