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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: utils.cpp,v $
  4.  * PRODUCTION Revision 1000.0  2004/06/01 21:21:32  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.7
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: utils.cpp,v 1000.0 2004/06/01 21:21: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.  * Authors:  Mike DiCuccio
  35.  *
  36.  * File Description:
  37.  *    General utility classes for GUI projects.
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/objutils/utils.hpp>
  41. #include <gui/objutils/label.hpp>
  42. #include <gui/objutils/prot_product.hpp>
  43. #include <gui/objutils/alignment.hpp>
  44. #include <gui/objutils/graph.hpp>
  45. #include <gui/objutils/alignment_smear_layout.hpp>
  46. #include <gui/objutils/mate_pair.hpp>
  47. #include <gui/objutils/prot_product.hpp>
  48. #include <gui/objutils/graph.hpp>
  49. #include <algorithm>
  50. #include <objects/seqloc/Seq_loc.hpp>
  51. #include <objects/seqloc/Seq_interval.hpp>
  52. #include <objects/seq/Bioseq.hpp>
  53. #include <objects/seq/Seq_inst.hpp>
  54. #include <objects/seqset/Seq_entry.hpp>
  55. #include <objects/seqalign/Score.hpp>
  56. #include <objects/seqloc/Seq_loc.hpp>
  57. #include <objects/seqloc/Seq_loc_mix.hpp>
  58. #include <objects/seqloc/Seq_point.hpp>
  59. #include <objects/seqloc/Seq_interval.hpp>
  60. #include <objects/seqloc/Packed_seqint.hpp>
  61. #include <objects/seqloc/Packed_seqpnt.hpp>
  62. #include <objects/seqloc/Seq_bond.hpp>
  63. #include <objects/general/Int_fuzz.hpp>
  64. #include <objects/general/Dbtag.hpp>
  65. #include <objects/general/Object_id.hpp>
  66. #include <objmgr/align_ci.hpp>
  67. #include <objmgr/annot_ci.hpp>
  68. #include <objmgr/graph_ci.hpp>
  69. #include <objmgr/feat_ci.hpp>
  70. #include <objmgr/scope.hpp>
  71. #include <objmgr/util/feature.hpp>
  72. #include <objmgr/util/sequence.hpp>
  73. #include <objtools/alnmgr/alnmix.hpp>
  74. #include <serial/iterator.hpp>
  75. BEGIN_NCBI_SCOPE
  76. USING_SCOPE(objects);
  77. //
  78. // functor for sorting features based on their length
  79. //
  80. struct SFeatLengthPredicate
  81. {
  82.     bool operator()(const CMappedFeat& feat0,
  83.                     const CMappedFeat& feat1) const
  84.     {
  85.         TSeqRange r0 = feat0.GetLocation().GetTotalRange();
  86.         TSeqRange r1 = feat1.GetLocation().GetTotalRange();
  87.         return (r0.GetLength() < r1.GetLength());
  88.     }
  89. };
  90. //
  91. // functor for sorting features based on the NCBI feature sort order
  92. //
  93. struct SFeatSortPredicate
  94. {
  95.     bool operator()(const CMappedFeat& feat0,
  96.                     const CMappedFeat& feat1) const
  97.     {
  98.         const CSeq_feat& f0 = feat0.GetOriginalFeature();
  99.         const CSeq_feat& f1 = feat1.GetOriginalFeature();
  100.         return (f0.Compare(f1, feat0.GetLocation(), feat1.GetLocation()) < 0);
  101.     }
  102. };
  103. //
  104. // retrieve an annot selector
  105. //
  106. SAnnotSelector CSeqUtils::GetAnnotSelector(void)
  107. {
  108.     SAnnotSelector sel;
  109.     sel
  110.         // consider overlaps by total range...
  111.         .SetOverlapTotalRange()
  112.         // resolve all segments...
  113.         .SetResolveAll()
  114.         // make sure we see all named annots (except SNPs)
  115.         .ExcludeNamedAnnots("SNP")
  116.         // stop at the first set of whatever
  117.         .SetAdaptiveDepth(true)
  118.         // stop at the first set of whatever
  119.         .SetSegmentSelectFirst();
  120.     return sel;
  121. }
  122. //
  123. // retrieve an annot selector for our selected annotations
  124. //
  125. SAnnotSelector CSeqUtils::GetAnnotSelector(SAnnotSelector::TAnnotType c)
  126. {
  127.     SAnnotSelector sel = GetAnnotSelector();
  128.     sel
  129.         // limit by our annotation type
  130.         .SetAnnotType(c);
  131.     return sel;
  132. }
  133. //
  134. // retrieve an annot selector for our selected annotations
  135. //
  136. SAnnotSelector CSeqUtils::GetAnnotSelector(SAnnotSelector::TFeatType  feat)
  137. {
  138.     SAnnotSelector sel = GetAnnotSelector(CSeq_annot::TData::e_Ftable);
  139.     sel
  140.         // retrieve feature type and subtype of interest
  141.         .SetFeatType(feat);
  142.     return sel;
  143. }
  144. SAnnotSelector CSeqUtils::GetAnnotSelector(SAnnotSelector::TFeatSubtype sub)
  145. {
  146.     SAnnotSelector sel = GetAnnotSelector(CSeq_annot::TData::e_Ftable);
  147.     sel
  148.         // retrieve feature type and subtype of interest
  149.         .SetFeatSubtype(sub);
  150.     return sel;
  151. }
  152. //
  153. // GetLandmarkFeatures()
  154. // This returns a list of landmark features for a given sequence.  The current
  155. // implementation is a bit hackish; this function is mostly a hook and will be
  156. // replaced in ID2 by a retrieval for a specific named annotation that
  157. // contains precalculated landmark features
  158. //
  159. void CSeqUtils::GetLandmarkFeatures(const CBioseq_Handle&  handle,
  160.                                     const TSeqRange&          range,
  161.                                     size_t                 max_feats,
  162.                                     CLayoutFeat::TFeatList&   feats)
  163. {
  164.     // begin with all gene features
  165.     SAnnotSelector sel = GetAnnotSelector(CSeqFeatData::e_Gene);
  166.     //SetResolveDepth(handle, range, sel);
  167.     // retrieve all of our genes
  168.     CFeat_CI iter(handle, range.GetFrom(), range.GetTo(), sel);
  169.     if (iter.GetSize() < max_feats) {
  170.         // retrieve them all
  171.         for ( ;  iter;  ++iter) {
  172.             CRef<CLayoutFeat> ref(new CLayoutFeat(*iter));
  173.             feats.push_back(ref);
  174.         }
  175.     } else {
  176.         // we do some screening - separate hypothetical and actual
  177.         vector<CMappedFeat> hyp_feats;
  178.         vector<CMappedFeat> act_feats;
  179.         // preallocate a rough approximation of the right amount of space
  180.         hyp_feats.reserve(iter.GetSize() / 2);
  181.         act_feats.reserve(iter.GetSize() / 2);
  182.         string str;
  183.         // sift through our features, separating hypothetical from
  184.         // real
  185.         for ( ;  iter;  ++iter) {
  186.             str.erase();
  187.             feature::GetLabel(iter->GetOriginalFeature(),
  188.                               &str, feature::eContent);
  189.             // hypothetical is defined as having a gene name like
  190.             // 'LOC123456'
  191.             if (str.find("LOC") == 0  &&
  192.                 str.find_first_not_of("0123456789", 3) == string::npos) {
  193.                 hyp_feats.push_back(*iter);
  194.             } else {
  195.                 act_feats.push_back(*iter);
  196.             }
  197.         }
  198.         if (act_feats.size() < max_feats) {
  199.             // we need to add some hypothetical genes to the pool
  200.             std::sort(hyp_feats.begin(), hyp_feats.end(),
  201.                       SFeatLengthPredicate());
  202.             act_feats.insert(act_feats.end(),
  203.                              hyp_feats.end() - (max_feats - act_feats.size()),
  204.                              hyp_feats.end());
  205.             std::sort(act_feats.begin(), act_feats.end(),
  206.                       SFeatSortPredicate());
  207.         } else if (act_feats.size() > max_feats) {
  208.             // we have too many genes, so eliminate the short ones
  209.             std::sort(act_feats.begin(), act_feats.end(),
  210.                       SFeatLengthPredicate());
  211.             act_feats.erase(act_feats.begin(),
  212.                 act_feats.begin() + (act_feats.size() - max_feats));
  213.             std::sort(act_feats.begin(), act_feats.end(),
  214.                       SFeatSortPredicate());
  215.         }
  216.         //
  217.         // now we've got enough genes
  218.         //
  219.         ITERATE (vector<CMappedFeat>, iter, act_feats) {
  220.             CRef<CLayoutFeat> ref(new CLayoutFeat(*iter));
  221.             feats.push_back(ref);
  222.         }
  223.     }
  224. }
  225. //
  226. // GetFeatures()
  227. // this retrieves and cross-links a set of features from the document
  228. // representing the basic molecular biology pathway.  This will detail the
  229. // relationship between genes <-> rnas <-> coding regions <-> proteins, where
  230. // known.
  231. //
  232. void CSeqUtils::GetFeatures(const CBioseq_Handle&   handle,
  233.                             const TSeqRange&        range,
  234.                             CSeqFeatData::E_Choice  feat_type,
  235.                             CLayoutFeat::TFeatList& feats,
  236.                             TFeatureFlags           flags)
  237. {
  238.     SAnnotSelector selector = GetAnnotSelector(feat_type);
  239.     GetFeatures(handle, range, selector, feats, flags);
  240. }
  241. void CSeqUtils::GetFeatures(const CBioseq_Handle&   handle,
  242.                             const TSeqRange&        range,
  243.                             SAnnotSelector          sel,
  244.                             CLayoutFeat::TFeatList& feats,
  245.                             TFeatureFlags           flags)
  246. {
  247.     feats.clear();
  248.     if ( !handle ) {
  249.         return;
  250.     }
  251.     CFeat_CI feature_iter(handle, range.GetFrom(), range.GetTo(), sel);
  252.     feats.clear();
  253.     feats.reserve(feature_iter.GetSize());
  254.     for (;  feature_iter ;  ++feature_iter) {
  255.         const CMappedFeat& feat = *feature_iter;
  256.         CRef<CLayoutFeat> fref(new CLayoutFeat(feat));
  257.         feats.push_back(fref);
  258.     }
  259.     if (flags & fFeature_LinkFeatures) {
  260.         LinkFeatures(feats);
  261.     }
  262. }
  263. //
  264. // LinkFeatures()
  265. // This builds explicit links between features, creating a hierarchical tree of
  266. // features.
  267. //
  268. void CSeqUtils::LinkFeatures(CLayoutFeat::TFeatList& feats)
  269. {
  270.     CLayoutFeat::TFeatList out_feats;
  271.     out_feats.reserve(feats.size());
  272.     NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, feats) {
  273.         CLayoutFeat&        feat = **iter;
  274.         string label;
  275.         feature::GetLabel(feat.GetFeature(), &label, feature::eBoth);
  276.         CSeqFeatData::ESubtype parent_type = CSeqFeatData::eSubtype_bad;
  277.         switch (feat.GetFeature().GetData().GetSubtype()) {
  278.         case CSeqFeatData::eSubtype_cdregion:
  279.             if (dynamic_cast<const CLayoutProtProd*> (&feat)) {
  280.                 // search for preceding CDS for this protein product
  281.                 parent_type = CSeqFeatData::eSubtype_cdregion;
  282.             } else {
  283.                 // search for preceding mRNA
  284.                 parent_type = CSeqFeatData::eSubtype_mRNA;
  285.             }
  286.             break;
  287.         case CSeqFeatData::eSubtype_gene:
  288.             // don't link
  289.             out_feats.push_back(*iter);
  290.             continue;
  291.         case CSeqFeatData::eSubtype_mRNA:
  292.             parent_type = CSeqFeatData::eSubtype_gene;
  293.             break;
  294.         default:
  295.             // don't link
  296.             out_feats.push_back(*iter);
  297.             continue;
  298.         }
  299.         //
  300.         // find the suitable pool of features we can look at
  301.         //
  302.         bool linked = false;
  303.         CLayoutFeat::TFeatList::reverse_iterator start(iter);
  304.         CLayoutFeat::TFeatList::reverse_iterator end  (feats.begin());
  305.         for ( ;  start != end;  ++start) {
  306.             CLayoutFeat& curr = **start;
  307.             // only link features if they live in the same annotation
  308.             if (curr.GetMappedFeature().GetAnnot().IsNamed()  &&
  309.                 feat.GetMappedFeature().GetAnnot().IsNamed()  &&
  310.                 curr.GetMappedFeature().GetAnnot().GetName() !=
  311.                 feat.GetMappedFeature().GetAnnot().GetName()) {
  312.                 continue;
  313.             }
  314.             // make sure we're looking at the right parent type
  315.             CSeqFeatData::ESubtype type =
  316.                 curr.GetFeature().GetData().GetSubtype();
  317.             if (type != parent_type) {
  318.                 continue;
  319.             }
  320.             // an mRNA can have only one child bound to it
  321.             if (type == CSeqFeatData::eSubtype_mRNA  &&
  322.                 curr.GetChildren().size() >= 1) {
  323.                 continue;
  324.             }
  325.             // only link features if their locations are swallowable
  326.             sequence::ECompare comp =
  327.                 sequence::Compare(curr.GetLocation(), feat.GetLocation());
  328.             if (comp != sequence::eContains  &&  comp != sequence::eSame) {
  329.                 continue;
  330.             }
  331.             feat.SetParent(&curr);
  332.             curr.SetChildren().push_back(*iter);
  333.             linked = true;
  334.             break;
  335.         }
  336.         if ( !linked ) {
  337.             out_feats.push_back(*iter);
  338.         }
  339.     }
  340.     out_feats.swap(feats);
  341. }
  342. //
  343. // GetAlignments()
  344. // this retrieves the of alignments in a document by annotation
  345. // as a set of smears.
  346. //
  347. void CSeqUtils::GetAlignmentSmears(const CBioseq_Handle&    handle,
  348.                                    const TSeqRange&         range,
  349.                                    TSeqPos                  window,
  350.                                    CLayoutEngine::TObjects& aligns)
  351. {
  352.     aligns.clear();
  353.     if ( !handle ) {
  354.         return;
  355.     }
  356.     SAnnotSelector sel_annot;
  357.     CAnnot_CI   annot_iter(handle, range.GetFrom(), range.GetTo(), sel_annot);
  358.     
  359.     for (int an_i = 0;  annot_iter;  ++annot_iter, ++an_i)  {
  360.     
  361.         // TODO: remember the annotation's name. That is the smear's label.
  362.         if (annot_iter->IsNamed()) {
  363.             // cout << an_i << " Named: " << annot_iter->GetName() << endl;
  364.         } else {
  365.             // cout << an_i << " Unnamed: " << endl;
  366.         }
  367.         
  368.         const CSeq_annot& seq_annot = annot_iter->GetSeq_annot();
  369.         if ( ! seq_annot.GetData().IsAlign()) {
  370.             continue;
  371.         }
  372.         
  373.         
  374.         CRef<CLayoutObject> ref;
  375.         if (CAlignmentSmear::SeparateStrands(seq_annot)) {
  376.             ref.Reset(new CLayoutAlignSmear(handle,
  377.                                             range.GetFrom(), range.GetTo(), 
  378.                                             window,
  379.                                             CAlignmentSmear::eSmearStrand_Pos,
  380.                                             seq_annot));
  381.             if (ref) {
  382.                 aligns.push_back(ref);
  383.             }
  384.             ref.Reset(new CLayoutAlignSmear(handle,
  385.                                             range.GetFrom(), range.GetTo(), 
  386.                                             window,
  387.                                             CAlignmentSmear::eSmearStrand_Neg,
  388.                                             seq_annot));
  389.             if (ref) {
  390.                 aligns.push_back(ref);
  391.             }
  392.         } else {
  393.             ref.Reset(new CLayoutAlignSmear(handle,
  394.                                             range.GetFrom(), range.GetTo(), 
  395.                                             window,
  396.                                             CAlignmentSmear::eSmearStrand_Both,
  397.                                             seq_annot));
  398.             if (ref) {
  399.                 aligns.push_back(ref);
  400.             }
  401.         }
  402.     }
  403. }
  404. static bool
  405. s_CheckTraceMateAlign(const CSeq_align& align,
  406.                       int& ti,
  407.                       int& mate_ti,
  408.                       int expect_mate_ti = 0)
  409. {
  410.     //
  411.     // specific requirements for mate pair alignments:
  412.     //
  413.     // must be a pairwise dense-seg
  414.     if ( !align.GetSegs().IsDenseg()  ||
  415.          align.GetSegs().GetDenseg().GetIds().size() != 2) {
  416.         return false;
  417.     }
  418.     // check the IDs for a trace ID
  419.     ti = 0;
  420.     ITERATE (CDense_seg::TIds, iter,
  421.              align.GetSegs().GetDenseg().GetIds()) {
  422.         const CSeq_id& id = **iter;
  423.         if (id.IsGeneral()  &&
  424.             (id.GetGeneral().GetDb() == "ti"  ||
  425.             id.GetGeneral().GetDb() == "TRACE")) {
  426.             ti = id.GetGeneral().GetTag().GetId();
  427.             break;
  428.         }
  429.     }
  430.     if (ti == 0) {
  431.         return false;
  432.     }
  433.     // must have a score field named 'matepair_ti'
  434.     mate_ti = 0;
  435.     if ( !align.GetNamedScore("matepair ti", mate_ti)) {
  436.         if ( !align.GetNamedScore("bad matepair ti", mate_ti)) {
  437.             return false;
  438.         }
  439.     }
  440.     if (expect_mate_ti  &&  mate_ti != expect_mate_ti) {
  441.         return false;
  442.     }
  443.     return true;
  444. }
  445. //
  446. // GetAlignments()
  447. // this retrieves a set of alignments from the document
  448. //
  449. void CSeqUtils::GetAlignments(const CBioseq_Handle&    handle,
  450.                               const TSeqRange&         range,
  451.                               CLayoutEngine::TObjects& aligns,
  452.                               TAlignFlags flags)
  453. {
  454.     aligns.clear();
  455.     if ( !handle ) {
  456.         return;
  457.     }
  458.     SAnnotSelector selector = GetAnnotSelector(CSeq_annot::TData::e_Align);
  459.     CAlign_CI align_iter(handle, range.GetFrom(), range.GetTo(), selector);
  460.     typedef pair<CRef<CLayoutPWAlign> , int> TMatedAlign;
  461.     typedef map<int, TMatedAlign> TMatedAlignments;
  462.     TMatedAlignments mated_aligns;
  463.     for (;  align_iter ;  ++align_iter) {
  464.         const CSeq_align& align = *align_iter;
  465.         try {
  466.             // generate an alignment manager for this alignment
  467.             CRef<CAlnVec> aln_mgr;
  468.             if (align.GetSegs().IsDenseg()) {
  469.                 aln_mgr.Reset(new CAlnVec(align.GetSegs().GetDenseg(),
  470.                                           handle.GetScope()));
  471.             } else {
  472.                 CAlnMix mix(handle.GetScope());
  473.                 mix.Add(align);
  474.                 mix.Merge(CAlnMix::fGen2EST |
  475.                           CAlnMix::fTryOtherMethodOnFail |
  476.                           CAlnMix::fGapJoin);
  477.                 aln_mgr.Reset(new CAlnVec(mix.GetDenseg(), handle.GetScope()));
  478.             }
  479.             // anchor on the referent sequence
  480.             CAlnVec::TNumrow row = 0;
  481.             CAlnVec::TNumrow anchor = 0;
  482.             for (row = 0;  row != aln_mgr->GetNumRows();  ++row) {
  483.                 if ( handle.IsSynonym(aln_mgr->GetSeqId(row)) ) {
  484.                     aln_mgr->SetAnchor(row);
  485.                     anchor = row;
  486.                     break;
  487.                 }
  488.             }
  489.             //
  490.             // check to see if this is a mate pair alignment
  491.             //
  492.             int ti = 0;
  493.             int mate_ti = 0;
  494.             if ( s_CheckTraceMateAlign(align, ti, mate_ti) ) {
  495.                 CRef<CLayoutPWAlign> pwal
  496.                     (new CLayoutPWAlign(*aln_mgr, align));
  497.                 if (flags & fAlign_LinkMatePairs) {
  498.                     // we will process mate mair alignments in a separate pass
  499.                     // after we complete all other alignments
  500.                     TMatedAlign mp(pwal, mate_ti);
  501.                     mated_aligns[ti] = mp;
  502.                 } else {
  503.                     CLayoutMatePair::TAlignList als;
  504.                     als.push_back(pwal);
  505.                     CRef<CLayoutObject> obj(new CLayoutMatePair(als));
  506.                     aligns.push_back(obj);
  507.                 }
  508.             } else {
  509.                 // "normal" alignment
  510.                 CRef<CLayoutObject> ref;
  511.                 if (aln_mgr->GetNumRows() == 2) {
  512.                     ref.Reset(new CLayoutPWAlign(*aln_mgr, align));
  513.                 } else {
  514.                     ref.Reset(new CLayoutAlign(*aln_mgr, align));
  515.                 }
  516.                 aligns.push_back(ref);
  517.             }
  518.         }
  519.         catch (CException& e) {
  520.             // errors ignored
  521.             _TRACE("error in GetAlignments(): " << e.GetMsg());
  522.         }
  523.     }
  524.     //
  525.     // final pass - connect our mate pair alignments, if we can
  526.     //
  527.     NON_CONST_ITERATE (TMatedAlignments, iter, mated_aligns) {
  528.         if ( !iter->second.first ) {
  529.             continue;
  530.         }
  531.         CLayoutPWAlign& first_mate    = *iter->second.first;
  532.         const CSeq_align&     align   = first_mate.GetAlignment();
  533.         int                   ti      = iter->first;
  534.         int                   mate_ti = iter->second.second;
  535.         //
  536.         // verify that we have a mated alignment for this trace alignment
  537.         //
  538.         CRef<CLayoutPWAlign> second_mate;
  539.         TMatedAlignments::iterator mate_iter = mated_aligns.find(mate_ti);
  540.         if (mate_iter == mated_aligns.end()) {
  541.             //
  542.             // NOT FOUND
  543.             // try iterating
  544.             //
  545.             CSeq_id id("gnl|ti|" + NStr::IntToString(mate_ti));
  546.             CBioseq_Handle h = 
  547.                 handle.GetScope().GetBioseqHandle(id);
  548.             CAlign_CI second_mate_iter(h, 0, h.GetBioseqLength(),
  549.                                        selector);
  550.             for ( ;  second_mate_iter;  ++second_mate_iter) {
  551.                 int temp = 0;
  552.                 if ( !s_CheckTraceMateAlign(*second_mate_iter, temp,
  553.                                             mate_ti, ti) ) {
  554.                     continue;
  555.                 }
  556.                 CRef<CAlnVec> aln_mgr(new CAlnVec(align.GetSegs().GetDenseg(),
  557.                                                   handle.GetScope()));
  558.                 // anchor on the referent sequence
  559.                 CAlnVec::TNumrow row = 0;
  560.                 CAlnVec::TNumrow anchor = 0;
  561.                 for (row = 0;  row != aln_mgr->GetNumRows();  ++row) {
  562.                     if ( handle.IsSynonym(aln_mgr->GetSeqId(row)) ) {
  563.                         aln_mgr->SetAnchor(row);
  564.                         anchor = row;
  565.                         break;
  566.                     }
  567.                 }
  568.                 second_mate.Reset(new CLayoutPWAlign(*aln_mgr, align));
  569.                 break;
  570.             }
  571.             if ( !second_mate ) {
  572.                 LOG_POST(Error << "failed to find mate pair for ti = " << ti);
  573.                 // no mate available, so treat it as a normal alignment
  574.                 // we need to trim leading and trailing gaps to get a good
  575.                 // placement
  576.                 CRef<CLayoutObject> ref
  577.                     (new CLayoutPWAlign(first_mate.GetAlignMgr(), align));
  578.                 aligns.push_back(ref);
  579.                 continue;
  580.             }
  581.         } else if ( !mate_iter->second.first ) {
  582.             // already processed
  583.             continue;
  584.         } else {
  585.             second_mate = mate_iter->second.first;
  586.             mate_iter->second.first.Reset();
  587.         }
  588.         CLayoutMatePair::TAlignList als;
  589.         als.push_back(CRef<CLayoutPWAlign>(&first_mate));
  590.         als.push_back(second_mate);
  591.         CRef<CLayoutObject> obj(new CLayoutMatePair(als));
  592.         aligns.push_back(obj);
  593.     }
  594.     {//if (mated_aligns.size()) {
  595.         vector< CRef<CLayoutObject> > vec;
  596.         vec.reserve(aligns.size());
  597.         std::copy(aligns.begin(), aligns.end(), back_inserter(vec));
  598.         // we need to sort our alignments when done
  599.         std::sort(vec.begin(), vec.end(), SLayoutByPos());
  600.         aligns.clear();
  601.         std::copy(vec.begin(), vec.end(), back_inserter(aligns));
  602.     }
  603. }
  604. void CSeqUtils::GetGraphs(const CBioseq_Handle&  handle,
  605.                           const TSeqRange&          range,
  606.                           CLayoutEngine::TObjects& graphs)
  607. {
  608.     graphs.clear();
  609.     if ( !handle ) {
  610.         return;
  611.     }
  612.     SAnnotSelector selector = GetAnnotSelector(CSeq_annot::TData::e_Graph);
  613.     
  614.     CGraph_CI graph_iter(handle, range.GetFrom(), range.GetTo(), selector);
  615.     for (;  graph_iter ;  ++graph_iter) {
  616.         const CMappedGraph& graph = *graph_iter;
  617.         CRef<CLayoutObject> fref(new CLayoutGraph(graph));
  618.         graphs.push_back(fref);
  619.     }
  620. }
  621. //
  622. // remap a child location to a parent
  623. //
  624. CRef<CSeq_loc> CSeqUtils::RemapChildToParent(const CSeq_loc& parent,
  625.                                              const CSeq_loc& child,
  626.                                              CScope* scope)
  627. {
  628.     CSeq_loc dummy_parent;
  629.     dummy_parent.SetWhole(const_cast<CSeq_id&>(sequence::GetId(parent)));
  630.     SRelLoc converter(dummy_parent, child, scope);
  631.     converter.m_ParentLoc = &parent;
  632.     return converter.Resolve(scope);
  633. }
  634. bool CSeqUtils::Match(const CSeq_id& id1, const CSeq_id& id2, CScope* scope)
  635. {
  636.     if (id1.Match(id2))  {
  637.         return true;
  638.     } else if (scope) {
  639.         CBioseq_Handle handle = scope->GetBioseqHandle(id1);
  640.         if (handle)  {
  641.             return handle.IsSynonym(id2);
  642.         }
  643.     }
  644.     return false;
  645. }
  646. END_NCBI_SCOPE
  647. /*
  648.  * ===========================================================================
  649.  * $Log: utils.cpp,v $
  650.  * Revision 1000.0  2004/06/01 21:21:32  gouriano
  651.  * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.7
  652.  *
  653.  * Revision 1.7  2004/05/21 22:27:44  gorelenk
  654.  * Added PCH ncbi_pch.hpp
  655.  *
  656.  * Revision 1.6  2004/05/20 12:31:16  dicuccio
  657.  * Added missing includes
  658.  *
  659.  * Revision 1.5  2004/05/14 16:08:05  dicuccio
  660.  * Added additional #includes for missing layout objects.  Restored final sort of
  661.  * seq-aligns
  662.  *
  663.  * Revision 1.4  2004/05/10 18:23:32  dicuccio
  664.  * Reworked mate pair checking routines to use GetNamedScore()
  665.  *
  666.  * Revision 1.3  2004/05/09 23:57:13  dicuccio
  667.  * Added flags controlling retrieval of alignments
  668.  *
  669.  * Revision 1.2  2004/05/07 15:39:22  dicuccio
  670.  * Removed CSeqUtils::GetLabel() - should use CLabel directly
  671.  *
  672.  * Revision 1.1  2004/04/30 11:48:16  dicuccio
  673.  * Initial commit - split out from src/gui/utils
  674.  *
  675.  * Revision 1.67  2004/04/20 19:17:55  dicuccio
  676.  * Minor revision.  Amendment to last commit:  Reworked GetLabel() to use
  677.  * pluggable label architecture
  678.  *
  679.  * Revision 1.66  2004/04/20 19:17:04  dicuccio
  680.  * Reworked GetAlignments() - added pairwise alignments, revised handing of mate
  681.  * pair alignments
  682.  *
  683.  * Revision 1.65  2004/04/15 13:00:01  lebedev
  684.  * do not use GetObject() in CLayoutObject
  685.  *
  686.  * Revision 1.64  2004/04/12 16:52:27  dicuccio
  687.  * Removed unnecessary debugging output
  688.  *
  689.  * Revision 1.63  2004/04/12 16:51:36  dicuccio
  690.  * Merged GetMatePairs() into GetAlignments()
  691.  *
  692.  * Revision 1.62  2004/04/07 13:06:56  dicuccio
  693.  * Use CSeq_annot_Handle for proper mapping of annotation names.  Split
  694.  * GetAnnotSelector() API to request feature type or subtype separately
  695.  *
  696.  * Revision 1.61  2004/04/06 19:28:34  ucko
  697.  * Tweak GetMatePairs to avoid confusing GCC.
  698.  *
  699.  * Revision 1.60  2004/04/06 18:30:05  dicuccio
  700.  * Added GetMatePairs()
  701.  *
  702.  * Revision 1.59  2004/04/02 16:13:16  yazhuk
  703.  * Added Match() function for comparing CSeq_id-s
  704.  *
  705.  * Revision 1.58  2004/03/23 13:40:57  dicuccio
  706.  * Deprecated a bunch of old conversion routines.  Moved #include from .hpp to .cpp
  707.  *
  708.  * Revision 1.57  2004/03/22 16:45:48  rsmith
  709.  * add GetAlignmentSmears and comment out obsolete code.
  710.  *
  711.  * Revision 1.56  2004/03/05 17:38:28  dicuccio
  712.  * Avoid using CAlnMix on alignments that are already only one dense-seg.
  713.  * Commented spurious pathway in s_GetSeqLabel()
  714.  *
  715.  * Revision 1.55  2004/03/01 20:10:29  dicuccio
  716.  * Fixed incorrect assignment of parent features
  717.  *
  718.  * Revision 1.54  2004/02/17 17:21:04  dicuccio
  719.  * Added handling of flags to GetFeatures()
  720.  *
  721.  * Revision 1.53  2004/02/13 21:25:04  dicuccio
  722.  * Fixed brain-dead omission of seq-id string
  723.  *
  724.  * Revision 1.52  2004/02/04 19:09:25  dicuccio
  725.  * Cleaned up LinkFeatures()
  726.  *
  727.  * Revision 1.51  2004/02/04 18:05:37  grichenk
  728.  * Added annotation filtering by set of types/subtypes.
  729.  * Renamed *Choice to *Type in SAnnotSelector.
  730.  *
  731.  * Revision 1.50  2004/01/30 17:14:13  dicuccio
  732.  * Moved GetLabel() from CPluginUtils
  733.  *
  734.  * Revision 1.49  2004/01/27 18:47:41  dicuccio
  735.  * Use TSeqRange instead of TRange.  Fixed computation of covered range of an
  736.  * alignment.  Added work-around for unsorted alignments from CAlign_CI
  737.  *
  738.  * Revision 1.48  2004/01/20 18:19:31  dicuccio
  739.  * Handle alignments more effectively - don't assume they're always dense-segs
  740.  *
  741.  * Revision 1.47  2004/01/05 19:12:52  dicuccio
  742.  * Restrict feature linking to features living in the same annotation.  Dropped
  743.  * unnecessary CAlnMix calls.
  744.  *
  745.  * Revision 1.46  2003/12/30 15:04:25  dicuccio
  746.  * Remove SNP removal (still too slow...)
  747.  *
  748.  * Revision 1.45  2003/12/22 19:36:48  dicuccio
  749.  * Turned on SNP retrieval
  750.  *
  751.  * Revision 1.44  2003/11/10 15:48:36  lebedev
  752.  * Typo fixed in GetGraphs (e_Graph instead of e_Align)
  753.  *
  754.  * Revision 1.43  2003/10/28 15:24:06  lebedev
  755.  * GetFeatures method that takes a selector added
  756.  *
  757.  * Revision 1.42  2003/10/22 15:40:57  dicuccio
  758.  * Added API to create a dummy seq-entry to wrap a seq-annot
  759.  *
  760.  * Revision 1.41  2003/10/20 18:04:35  dicuccio
  761.  * Disabled SNP retrieval
  762.  *
  763.  * Revision 1.40  2003/10/14 14:44:12  dicuccio
  764.  * Reimplemented RemapChildToParent() using SRelLoc internally
  765.  *
  766.  * Revision 1.39  2003/10/14 12:20:13  dicuccio
  767.  * Added RemapChildToParent() for remapping locations
  768.  *
  769.  * Revision 1.38  2003/10/10 17:21:02  dicuccio
  770.  * Commented out addition of SNP annot to named annots
  771.  *
  772.  * Revision 1.37  2003/10/10 12:02:51  dicuccio
  773.  * Fix for recent API change in SAnnotSelector
  774.  *
  775.  * Revision 1.36  2003/10/09 12:57:37  dicuccio
  776.  * Mkae sure we always iterate over all annotations, named or otherwise.
  777.  *
  778.  * Revision 1.35  2003/10/08 14:16:39  dicuccio
  779.  * Really use adaptive depth searching for annot selectors...
  780.  *
  781.  * Revision 1.34  2003/10/07 13:44:10  dicuccio
  782.  * CLeaned up preparation of alignments.  Alignments are now prepared as sets of
  783.  * separate seq-aligns, not a merged alignment (better data representation)
  784.  *
  785.  * Revision 1.33  2003/10/03 16:02:29  dicuccio
  786.  * Temporary fix: limit feature retrieval to one level of recursion
  787.  *
  788.  * Revision 1.32  2003/09/24 18:29:28  dicuccio
  789.  * Introduced additional prototype for GetAnnotSelector() - takes no params
  790.  *
  791.  * Revision 1.31  2003/09/19 00:28:59  ucko
  792.  * CLayoutAlign: use an unsigned range per CAlnMap::GetSeqRange's new rettype.
  793.  *
  794.  * Revision 1.30  2003/09/17 16:28:45  dicuccio
  795.  * Optimized and standardized use of annotation selectors.  Introduced standard
  796.  * formatting function for setting options in annot selectors; removed old depth
  797.  * setting functions in favor of explicitly setting adaptive retrieval
  798.  *
  799.  * Revision 1.29  2003/08/22 15:48:39  dicuccio
  800.  * Added 'USING_SCOPE(objects)'
  801.  *
  802.  * Revision 1.28  2003/08/21 12:04:28  dicuccio
  803.  * Rewored GetLandmarkFeatures() to return a better set of landmark genes
  804.  *
  805.  * Revision 1.27  2003/08/18 14:47:55  dicuccio
  806.  * Changed nales: CFeature -> CLayoutFeat; CAlignment -> CLayoutAlign; CGraph ->
  807.  * CLayoutGraph; CProtProduct -> CLayoutProtProd.
  808.  *
  809.  * Revision 1.26  2003/08/15 19:36:06  dicuccio
  810.  * Added SetResolveDepth() to correctly determine the depth of annotation
  811.  * resolution
  812.  *
  813.  * Revision 1.25  2003/08/12 16:48:16  dicuccio
  814.  * Disable retrieval of SNPs in all circumstances
  815.  *
  816.  * Revision 1.24  2003/07/29 13:41:07  lebedev
  817.  * GetGraphs method added
  818.  *
  819.  * Revision 1.23  2003/07/28 11:51:50  dicuccio
  820.  * Rewrote CTablePanel<> to be more flexible and better contained.  Added standard
  821.  * multicolumn list dialog.  Deprecated use of COutputDlg.
  822.  *
  823.  * Revision 1.22  2003/07/21 19:35:21  dicuccio
  824.  * Changed storage mechanism - CLayoutObject::GetObject() is now pure virtual.
  825.  * Changed CFeature to wrap a CMappedFeat instead of a CSeq_feat / CSeq_loc pair
  826.  *
  827.  * Revision 1.21  2003/07/18 13:34:53  lebedev
  828.  * Method to retrieve alignments added
  829.  *
  830.  * Revision 1.20  2003/07/08 19:00:05  dicuccio
  831.  * Added better resolution of features fr large records
  832.  *
  833.  * Revision 1.19  2003/06/23 13:23:14  dicuccio
  834.  * Deprecated seq_utils.[h,c]pp - moved functions into gui.utils/utils.hpp
  835.  *
  836.  * Revision 1.18  2003/06/13 12:38:54  dicuccio
  837.  * Fixed bugs in determination of mouse button state
  838.  *
  839.  * Revision 1.17  2003/06/10 13:35:11  dicuccio
  840.  * Added new API for retrieving landmark features.  Removed lots of dead code
  841.  *
  842.  * Revision 1.16  2003/06/02 16:06:25  dicuccio
  843.  * Rearranged src/objects/ subtree.  This includes the following shifts:
  844.  *     - src/objects/asn2asn --> arc/app/asn2asn
  845.  *     - src/objects/testmedline --> src/objects/ncbimime/test
  846.  *     - src/objects/objmgr --> src/objmgr
  847.  *     - src/objects/util --> src/objmgr/util
  848.  *     - src/objects/alnmgr --> src/objtools/alnmgr
  849.  *     - src/objects/flat --> src/objtools/flat
  850.  *     - src/objects/validator --> src/objtools/validator
  851.  *     - src/objects/cddalignview --> src/objtools/cddalignview
  852.  * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  853.  * replaces the three libmmdb? libs.
  854.  *
  855.  * Revision 1.15  2003/05/19 18:45:24  dicuccio
  856.  * Fixed bug in feature collection - forgot to pass in desired feature subtype
  857.  *
  858.  * Revision 1.14  2003/05/16 18:20:05  dicuccio
  859.  * Change mechanism of feature iteration - retrieve features from first
  860.  * available location
  861.  *
  862.  * Revision 1.13  2003/05/07 17:28:40  dicuccio
  863.  * Removed operator<< for CFeature.  Added missing link to xobjutil
  864.  *
  865.  * Revision 1.12  2003/05/07 13:07:29  dicuccio
  866.  * Code clean-up.  Removed dead functions.
  867.  *
  868.  * Revision 1.11  2003/05/07 12:34:15  dicuccio
  869.  * Removed CFeature::GetExtent()
  870.  *
  871.  * Revision 1.10  2003/03/18 21:55:24  grichenk
  872.  * Removed obsolete class CAnnot_CI
  873.  *
  874.  * Revision 1.9  2003/03/11 15:25:12  kuznets
  875.  * iterate -> ITERATE
  876.  *
  877.  * Revision 1.8  2003/02/10 18:10:59  dicuccio
  878.  * Fixed compilation errors relating to change in CFeat_CI API
  879.  *
  880.  * Revision 1.7  2003/01/15 21:15:48  dicuccio
  881.  * Rewored feature retrieval.  Added separate (explicit) call to link features
  882.  *
  883.  * Revision 1.6  2003/01/13 13:10:11  dicuccio
  884.  * Namespace clean-up.  Retired namespace gui -> converted all to namespace
  885.  * ncbi.  Moved all FLUID-generated code into namespace ncbi.
  886.  *
  887.  * Revision 1.5  2003/01/09 14:52:25  dicuccio
  888.  * Use 'const CBioseq_Handle&' instead of 'CBioseq_Handle&'
  889.  *
  890.  * Revision 1.4  2002/12/30 17:57:37  dicuccio
  891.  * Added cast to avoid compiler warning
  892.  *
  893.  * Revision 1.3  2002/12/06 19:12:44  dicuccio
  894.  * Updated to match change in API to ctor of CFeat_CI
  895.  *
  896.  * Revision 1.2  2002/12/06 14:08:18  dicuccio
  897.  * Moved feature sorting predicates into feature.[h,c]pp
  898.  *
  899.  * Revision 1.1  2002/11/29 15:30:38  dicuccio
  900.  * Initial revision - split out from gui/core/view/graphic
  901.  *
  902.  * ===========================================================================
  903.  */