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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: density_map.hpp,v $
  4.  * PRODUCTION Revision 1000.0  2004/06/01 19:54:41  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef GUI_UTILS___DENSITY_GRAPH__HPP
  10. #define GUI_UTILS___DENSITY_GRAPH__HPP
  11. /*  $Id: density_map.hpp,v 1000.0 2004/06/01 19:54:41 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Authors:  Mike DiCuccio
  37.  *
  38.  * File Description:
  39.  *
  40.  */
  41. #include <corelib/ncbistd.hpp>
  42. #include <objmgr/bioseq_handle.hpp>
  43. #include <objmgr/feat_ci.hpp>
  44. #include <objmgr/align_ci.hpp>
  45. #include <objmgr/annot_ci.hpp>
  46. #include <objtools/alnmgr/alnmap.hpp>
  47. #include <objtools/alnmgr/alnmix.hpp>
  48. #include <util/range.hpp>
  49. #include <deque>
  50. /** @addtogroup GUI_UTILS
  51.  *
  52.  * @{
  53.  */
  54. BEGIN_NCBI_SCOPE
  55. /// Run iterator.  iterate through runs of equal values in the bins.
  56. template <typename CntType>
  57. class CDenMapRunIterator {
  58. public:
  59.     typedef vector<CntType> container_type;
  60.     typedef typename container_type::size_type   position_type;
  61.         
  62.     CDenMapRunIterator(position_type here, const container_type& bins, TSeqPos start, TSeqPos window)
  63.     : m_Bins(bins), m_Pos(here), m_RunLength(x_CalcRunLength()), m_Start(start), m_Window(window)
  64.     {}
  65.     CntType       Advance();
  66.         
  67.     position_type GetPosition() const { return m_Pos; }
  68.     position_type GetRunLength() const{ return m_RunLength; }
  69.     TSeqPos       GetSeqPosition() const;
  70.     TSeqPos       GetSeqRunLength() const;
  71.     
  72.     CntType       GetValue() const { return Valid() ? m_Bins[m_Pos]: 0 ; }
  73.     
  74.     bool operator ==(CDenMapRunIterator<CntType>& rhs) const { return m_Pos == rhs.m_Pos; }
  75.     
  76.     operator bool() const { return Valid(); }
  77.     bool        Valid() const { return  m_Pos >= 0 &&  m_Pos < m_Bins.size() && m_RunLength != 0; }
  78. private:
  79.     
  80.     position_type   x_CalcRunLength() const;
  81.     
  82.     const container_type&   m_Bins;
  83.     position_type       m_Pos;
  84.     position_type       m_RunLength;
  85.     
  86.     const TSeqPos       m_Start;
  87.     const TSeqPos       m_Window;
  88.     
  89. };
  90. template <typename CntType>
  91. TSeqPos CDenMapRunIterator<CntType>::GetSeqPosition() const
  92. {
  93.     return GetPosition() * m_Window + m_Start; 
  94. }
  95. template <typename CntType>
  96. TSeqPos CDenMapRunIterator<CntType>::GetSeqRunLength() const 
  97.     return GetRunLength() * m_Window; 
  98. }
  99. template <typename CntType>
  100. typename CDenMapRunIterator<CntType>::position_type 
  101. CDenMapRunIterator<CntType>::x_CalcRunLength() const
  102. {
  103.     if (m_Pos >= 0 &&  m_Pos < m_Bins.size()) {
  104.         CntType this_value = m_Bins[m_Pos];
  105.         position_type i;
  106.         for (i = m_Pos + 1; 
  107.              i < m_Bins.size()  &&  m_Bins[i] == this_value;
  108.              ++i) {}
  109.         return i - m_Pos;
  110.     }
  111.     return 0;
  112. }
  113. template <typename CntType>
  114. CntType
  115. CDenMapRunIterator<CntType>::Advance() {
  116.     m_Pos += m_RunLength;
  117.     m_RunLength = x_CalcRunLength();
  118.     return GetValue();
  119. }
  120. ///
  121. /// class CDensityMap generates a low-resolution view of a set of features.
  122. /// The features to be processed are defined by the SAnnotSelector object.
  123. /// The return value is a vector of counts, one for each of the bins
  124. /// defined by the window width and spanning the range from start to stop.
  125. /// If start and stop are both zero, then the entire sequence is evaluated.
  126. ///
  127. template <typename CntType, typename Accum  = plus<CntType> >
  128. class CDensityMap {
  129. public:
  130.     typedef vector<CntType> container_type;
  131.     typedef typename container_type::const_iterator const_iterator;
  132.     typedef typename container_type::iterator       iterator;
  133.     typedef CDenMapRunIterator<CntType>             runlen_iterator;
  134.     
  135.     CDensityMap(TSeqPos start, TSeqPos stop, TSeqPos window = 1,
  136.                 Accum ac = Accum());
  137.     CDensityMap(const objects::CBioseq_Handle& handle, TSeqPos window = 1,
  138.                 Accum ac = Accum());
  139.     
  140.     void AddRange(TSeqRange range, CntType score = 1, bool expand = false);
  141.     
  142.     /// All features on this bioseq selected by sel in the range of this.
  143.     CntType AddFeatures(const objects::CBioseq_Handle& handle,
  144.                         objects::SAnnotSelector sel);
  145.     
  146.     /// All alignments on this bioseq selected by sel in the range of this.
  147.     CntType AddAlignments(const objects::CBioseq_Handle& handle, 
  148.                           objects::SAnnotSelector sel);
  149.     /// All alignments in a given annotation on this bioseq within the range of this.
  150.     CntType AddAlignments(const objects::CBioseq_Handle& handle, 
  151.                           const objects::CSeq_annot& seq_annot);
  152.     void  Clear() { m_Max = 0; fill(m_Bins.begin(), m_Bins.end(), 0); }
  153.     TSeqPos     GetStart() const { return m_Range.GetFrom(); }
  154.     TSeqPos     GetStop() const { return m_Range.GetTo(); }
  155.     TSeqRange   GetRange() const { return m_Range; }
  156.     TSeqPos     GetWindow() const { return m_Window; }
  157.     size_t      GetBins() const { return m_Bins.size(); }
  158.     CntType     GetMax() const { return m_Max; }
  159.     Accum       GetAccum() const { return m_AccumFunc; }
  160.     
  161.     /// extend our density map to cover the sequence position stop.
  162.     /// can only be used to extend to the right, that is only Stop is affected, not Start.
  163.     void            ExtendTo(TSeqPos stop);
  164.     
  165.     const_iterator  begin() const { return m_Bins.begin(); }
  166.     const_iterator  end() const { return m_Bins.end(); }
  167.     iterator        begin()  { return m_Bins.begin(); }
  168.     iterator        end()  { return m_Bins.end(); }
  169.     
  170.     runlen_iterator RunLenBegin() const { return RunLenIterator(0); }
  171.     runlen_iterator RunLenIterator(typename container_type::size_type n) const 
  172.         { return runlen_iterator(n, m_Bins, m_Range.GetFrom(), m_Window); }
  173.     
  174.     CntType operator[](typename container_type::size_type n) { return m_Bins[n]; }
  175.     /// OLD static method. Use AddFeatures method instead.
  176.     /// retrieve a density map.  The return value is the maximum value
  177.     /// in the density graph.
  178.     static TSeqPos GetDensityMap(const objects::CBioseq_Handle& handle,
  179.                                  TSeqPos start, TSeqPos stop,
  180.                                  TSeqPos window,
  181.                                  objects::SAnnotSelector sel,
  182.                                  vector<TSeqPos>& density);
  183. private:
  184.     /// given the range and window size, how many bins should there be?
  185.     size_t  x_CalcNbins() { return (m_Range.GetTo() - m_Range.GetFrom() + m_Window) / m_Window; }
  186.     /// convert from sequence coords to a bin number.
  187.     size_t  x_BinN(TSeqPos p) { return (p - m_Range.GetFrom())/m_Window; }
  188.     /// closed range on a sequence this covers.
  189.     TSeqRange       m_Range;
  190.     /// coordinates per bin.
  191.     TSeqPos         m_Window;
  192.     /// maximum Count accumulated in the bins so far.
  193.     CntType         m_Max;
  194.     
  195.     /// Where we actually keep the accumulated counts/scores/whatever.
  196.     container_type  m_Bins;
  197.     
  198.     Accum           m_AccumFunc;
  199. };
  200. template <typename CntType, typename Accum >
  201. CDensityMap<CntType, Accum>::CDensityMap(TSeqPos start, 
  202.                                          TSeqPos stop,
  203.                                          TSeqPos window /* = 1 */, 
  204.                                          Accum ac /*= Accum() */)
  205. :   m_Range(start, stop), 
  206.     m_Window(window < 1 ? 1 : window), 
  207.     m_Max(0), 
  208.     m_Bins(x_CalcNbins()), 
  209.     m_AccumFunc(ac)
  210. {
  211. }
  212. template <typename CntType, typename Accum >
  213. CDensityMap<CntType, Accum>::CDensityMap(const objects::CBioseq_Handle& handle, 
  214.                                          TSeqPos window /* = 1 */, 
  215.                                          Accum ac /*= Accum() */)
  216. :   m_Range(0, handle.GetSeqVector().size()), 
  217.     m_Window(window < 1 ? 1 : window),  
  218.     m_Max(0), 
  219.     m_Bins(x_CalcNbins()), 
  220.     m_AccumFunc(ac)
  221. {
  222. }
  223. template <typename CntType, typename Accum >
  224. void  CDensityMap<CntType, Accum>::ExtendTo(TSeqPos stop) 
  225. {
  226.     if (stop > GetStop()) {
  227.         m_Range.SetTo(stop);
  228.         m_Bins.resize(x_CalcNbins(), 0);
  229.     }
  230. }
  231. template <typename CntType, typename Accum >
  232. void CDensityMap<CntType, Accum>::AddRange(TSeqRange range, CntType score, bool expand)
  233. {   
  234.     //_ASSERT(range.GetFrom() <= range.GetTo());
  235.     if (range.GetFrom() > range.GetTo()) {
  236.         range = TSeqRange(range.GetTo(), range.GetFrom());
  237.     }
  238.     
  239.     if ( expand ) {
  240.         ExtendTo( range.GetTo());
  241.     }
  242.     
  243.     TSeqRange usable_range(m_Range.IntersectionWith(range));
  244.     if (usable_range.Empty()) {
  245.         return;
  246.     }
  247.     
  248.     size_t begin_bin = x_BinN(usable_range.GetFrom());
  249.     size_t end_bin   = x_BinN(usable_range.GetTo()) + 1;
  250.     for (size_t i = begin_bin;  i < end_bin ;  ++i) {
  251.         CntType new_val = m_AccumFunc(m_Bins[i], score);
  252.         m_Bins[i] = new_val;
  253.         m_Max = max(m_Max, new_val);
  254.     }
  255. }
  256. template <typename CntType, typename Accum >
  257. CntType CDensityMap<CntType, Accum>::AddFeatures(
  258.     const objects::CBioseq_Handle& handle, 
  259.     objects::SAnnotSelector sel)
  260. {
  261.     TSeqPos start(GetStart());
  262.     TSeqPos stop(GetStop());
  263.    // grab a feature iterator for our range
  264.     objects::CFeat_CI feat_iter(handle, start, stop, sel);
  265.     if (feat_iter.GetSize() == 0) {
  266.         return 0;
  267.     }
  268.     for (;  feat_iter;  ++feat_iter) {
  269.         objects::CMappedFeat feat = *feat_iter;
  270.         TSeqRange range = feat.GetLocation().GetTotalRange();
  271.         AddRange(range, 1, false);
  272.     }
  273.     return GetMax();
  274. }
  275.     
  276. template <typename CntType, typename Accum >
  277. CntType CDensityMap<CntType, Accum>::AddAlignments(
  278.     const objects::CBioseq_Handle& handle, 
  279.     objects::SAnnotSelector sel)
  280. {
  281.     TSeqPos start(GetStart());
  282.     TSeqPos stop(GetStop());
  283.       
  284.     
  285.     // grab a feature iterator for our range
  286.     objects::CAlign_CI align_iter(handle, start, stop, sel);
  287.     for (size_t ai = 0;  align_iter;  ++align_iter, ++ai) {
  288.         const objects::CSeq_align& align = *align_iter;
  289.         if (! align.CanGetDim()) {
  290.             _TRACE("Dimension not set. " << ai);
  291.             continue;
  292.         }
  293.         int dim = align.GetDim();
  294.         if (dim != 2) {
  295.             _TRACE("Dimension not 2. " << ai);
  296.             continue;
  297.         }
  298. /*
  299.         CAlnMix mix(handle.GetScope());
  300.         mix.Add(align);
  301.         mix.Merge(CAlnMix::fGen2EST |
  302.                   CAlnMix::fTryOtherMethodOnFail |
  303.                   CAlnMix::fGapJoin);
  304.         CRef<CAlnMap> aln_map
  305.             (new CAlnMap(mix.GetDenseg()));
  306. */
  307.         CRef< objects::CAlnMap> aln_map;
  308.         if (align.GetSegs().IsStd()) {
  309.              _TRACE(ai << ": Std seg");
  310.             CRef<objects::CSeq_align> ds_align
  311.                 = align.CreateDensegFromStdseg();
  312.             aln_map =  new objects::CAlnMap( ds_align->GetSegs().GetDenseg());
  313.             continue;
  314.         } else if (align.GetSegs().IsDenseg()) {
  315.             aln_map = new objects::CAlnMap(align.GetSegs().GetDenseg());
  316.              _TRACE(ai << ": Dense seg");
  317.         }
  318.         
  319.         {{ 
  320.             string all_ids = ": ";
  321.             for (objects::CAlnMap::TDim di = 0;  di < aln_map->GetNumRows();
  322.                  ++di) {
  323.                 all_ids += aln_map->GetSeqId(di).AsFastaString() + ", ";
  324.             }
  325.             _TRACE(all_ids);;
  326.         }}
  327.         
  328.         TSeqRange range(aln_map->GetSeqStart(0), aln_map->GetSeqStop(0));
  329.         AddRange(range, 1, false);
  330.     }
  331.     return GetMax();
  332. }
  333. template <typename CntType, typename Accum >
  334. CntType CDensityMap<CntType, Accum>::AddAlignments(
  335.     const objects::CBioseq_Handle& handle, 
  336.     const objects::CSeq_annot& seq_annot)
  337. {
  338.     TSeqPos start(GetStart());
  339.     TSeqPos stop(GetStop());
  340.     int ai = 0;
  341.     
  342.     objects::SAnnotSelector sel;
  343.     sel.SetLimitSeqAnnot(&seq_annot)
  344.        .SetSortOrder(objects::SAnnotSelector::eSortOrder_None);
  345.     // grab an alignment iterator for our range
  346.     objects::CAlign_CI align_iter(handle, start, stop, sel);
  347.     
  348.     objects::CAlnMix mix(handle.GetScope());
  349.     for (int ai = 0; align_iter; ++align_iter, ++ai) {
  350.         const objects::CSeq_align& align = *align_iter;
  351.         // check number of dimensions
  352.         if (! align.CanGetDim()  ||  align.GetDim() != 2) {
  353.             // _TRACE("Dimension not 2. " << ai);
  354.             continue;
  355.         }
  356.         // conver to a AlnMap.
  357.         CRef<objects::CAlnMap> aln_map;
  358.         if (align.GetSegs().IsStd()) {
  359.            // _TRACE(ai << ": Std seg" );
  360.            continue; // IGNORE std segs for now.
  361.            try {
  362.                 CRef<objects::CSeq_align> ds_align =
  363.                     align.CreateDensegFromStdseg();
  364.                 aln_map =
  365.                     new objects::CAlnMap(ds_align->GetSegs().GetDenseg());
  366.                 {{ 
  367.                     string all_ids = ": ";
  368.                     for (objects::CAlnMap::TDim di = 0;
  369.                          di < aln_map->GetNumRows();  ++di) {
  370.                         all_ids += aln_map->GetSeqId(di).AsFastaString() + ", ";
  371.                     }
  372.                     _TRACE(all_ids);
  373.                 }}
  374.             } catch (const objects::CSeqalignException& e) {
  375.                 // _TRACE(" : FAILED! " << e.what());
  376.                 continue;
  377.             }
  378.         } else if (align.GetSegs().IsDenseg()) {
  379.             mix.Add(align);//, CAlnMix::fDontUseObjMgr);
  380.             mix.Merge();
  381.             aln_map = new objects::CAlnMap(mix.GetDenseg());
  382.             //aln_map = new CAlnMap(align.GetSegs().GetDenseg());
  383.             if (aln_map->GetNumSegs() < 2)
  384.                 continue;
  385.             _TRACE(ai << ": Dense seg");
  386.         }
  387.         
  388.         // find out what row our bioseq is on.        
  389.         objects::CAlnMap::TNumrow row = 0;
  390.         objects::CAlnMap::TNumrow anchor = 0;
  391.         for (row = 0;  row != aln_map->GetNumRows();  ++row) {
  392.             if ( handle.IsSynonym(aln_map->GetSeqId(row)) ) {
  393.                 aln_map->SetAnchor(row);
  394.                 anchor = row;
  395.                 break;
  396.             }
  397.         }
  398.         if (row == aln_map->GetNumRows()) {
  399.             continue;
  400.         }
  401.         // works since dimension always 2.
  402.         objects::CAlnMap::TNumrow other_row = 1 - row;
  403.         /**
  404.         // total range
  405.         _TRACE(" (" << aln_map->GetSeqStart(row) << "," << aln_map->GetSeqStop(row) << ")");
  406.         // IDs
  407.         {{ 
  408.             _TRACE(" Segs: " << aln_map->GetNumSegs());
  409.             string all_ids = ": ";
  410.             for (CAlnMap::TDim di = 0; di < aln_map->GetNumRows(); ++di) {
  411.                 all_ids += aln_map->GetSeqId(di).AsFastaString() + ", ";
  412.             }
  413.             _TRACE(all_ids);
  414.         }}
  415.         // Segments.
  416.         _TRACE("            ");
  417.         for (CAlnMap::TNumseg s = 0; s < aln_map->GetNumSegs(); ++s) {
  418.             // if (aln_map->GetSegType(row, s) && CAlnMap:: )
  419.             _TRACE(" (" << aln_map->GetStart(row, s) << "," << aln_map->GetStop(row, s) << ")");
  420.         }
  421.         // Chunks
  422.         _TRACE("     Chunks: "  );
  423.         CRef<CAlnMap::CAlnChunkVec> chunks = 
  424.             aln_map->GetSeqChunks(row, CAlnMap::TSignedRange(start, stop), CAlnMap::fAlnSegsOnly);
  425.         for (CAlnMap::TNumchunk c = 0; c < chunks->size(); ++c) {
  426.             CConstRef<CAlnMap::CAlnChunk> chunk = (*chunks)[c];
  427.             _TRACE("(" << chunk->GetRange().GetFrom() << "," << chunk->GetRange().GetTo() << ") ");
  428.         }
  429.         **/
  430. /*
  431.         TSeqRange range(aln_map->GetSeqRange(row));
  432.         TSeqRange other_range(aln_map->GetSeqRange(other_row));
  433.         if (GetRange().IntersectingWith(range)) {
  434.             AddRange(range, 1, false);
  435.         }
  436. */
  437.     }
  438. /*
  439.     mix.Merge(CAlnMix::fTryOtherMethodOnFail );
  440.     CRef< CAlnMap> aln_map;
  441.     aln_map = new CAlnMap(mix.GetDenseg());
  442. */
  443.     return GetMax();
  444. }
  445. template <typename CntType, typename Accum >
  446. TSeqPos CDensityMap<CntType, Accum>::GetDensityMap(const objects::CBioseq_Handle& handle,
  447.                                    TSeqPos start, TSeqPos stop,
  448.                                    TSeqPos window,
  449.                                    objects::SAnnotSelector sel,
  450.                                    vector<TSeqPos>& density)
  451. {
  452.     // set up our bins to handle pooled feature counts
  453.     if (stop == start  &&  stop == 0) {
  454.         objects::CSeqVector vec = handle.GetSeqVector();
  455.         stop = vec.size();
  456.     }
  457.     // grab a feature iterator for our range
  458.     objects::CFeat_CI feat_iter(handle, start, stop, sel);
  459.     if (feat_iter.GetSize() == 0) {
  460.         return 0;
  461.     }
  462.     size_t bins = (stop - start) / window;
  463.     if (bins * window < stop - start) {
  464.         ++bins;
  465.     }
  466.     density.resize(bins, 0);
  467.     TSeqPos max_val = 0;
  468.     // we keep a temporary list of mapped features - we use these
  469.     // the screen what's in our visible range
  470.     deque<objects::CMappedFeat> feats;
  471.     TSeqPos bin_count = 0;
  472.     NON_CONST_ITERATE(vector<TSeqPos>, bin_iter, density) {
  473.         TSeqPos bin_start = start + bin_count * window;
  474.         TSeqPos bin_stop = bin_start + window;
  475.         // accumulate features for this bin
  476.         if (feat_iter) {
  477.             objects::CMappedFeat feat = *feat_iter;
  478.             TSeqRange range = feat.GetLocation().GetTotalRange();
  479.             while (range.GetFrom() < bin_stop) {
  480.                 feats.push_back(feat);
  481.                 ++feat_iter;
  482.                 if ( !feat_iter ) {
  483.                     break;
  484.                 }
  485.                 feat = *feat_iter;
  486.                 range = feat.GetLocation().GetTotalRange();
  487.             }
  488.         }
  489.         // remove features outside this bin
  490.         while (feats.size()) {
  491.             objects::CMappedFeat& feat = feats.front();
  492.             TSeqRange range = feat.GetLocation().GetTotalRange();
  493.             if (range.GetTo() < bin_start) {
  494.                 feats.pop_front();
  495.             } else {
  496.                 break;
  497.             }
  498.         }
  499.         // store our count and go to the next bin
  500.         *bin_iter = feats.size();
  501.         max_val = max(*bin_iter, max_val);
  502.         ++bin_count;
  503.     }
  504.     return max_val;
  505. }
  506. END_NCBI_SCOPE
  507. /* @} */
  508. /*
  509.  * ===========================================================================
  510.  * $Log: density_map.hpp,v $
  511.  * Revision 1000.0  2004/06/01 19:54:41  gouriano
  512.  * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.1
  513.  *
  514.  * Revision 1.1  2004/04/30 11:52:52  dicuccio
  515.  * Split out from gui/utils
  516.  *
  517.  * Revision 1.17  2004/04/16 17:11:13  dicuccio
  518.  * Clean-up: use _TRACE(), not cout
  519.  *
  520.  * Revision 1.16  2004/04/16 16:55:51  ucko
  521.  * Add several missing occurrences of objects::, needed now that we
  522.  * (rightly) no longer pull in the whole namespace.
  523.  *
  524.  * Revision 1.15  2004/04/16 14:24:14  dicuccio
  525.  * Formatting changes.  Dropped using namespace objects.  Added doxygen modules tag
  526.  *
  527.  * Revision 1.14  2004/04/07 12:39:09  dicuccio
  528.  * Formatting changes
  529.  *
  530.  * Revision 1.13  2004/03/22 23:04:00  jcherry
  531.  * Added "return"
  532.  *
  533.  * Revision 1.12  2004/03/22 19:18:31  gorelenk
  534.  * Added missed typename(s).
  535.  * Added objects namespace to parameters list of CDensityMap::AddAlignments .
  536.  *
  537.  * Revision 1.11  2004/03/22 18:39:29  ucko
  538.  * Indicate that CDenMapRunIterator<>::operator== returns bool.
  539.  *
  540.  * Revision 1.10  2004/03/22 16:38:56  rsmith
  541.  * add AddAlignments in various flavors.  add RunLength iterators.
  542.  *
  543.  * Revision 1.9  2004/03/16 15:37:21  vasilche
  544.  * Added required include
  545.  *
  546.  * Revision 1.8  2004/02/17 17:16:50  dicuccio
  547.  * Drop export specifier (the class is a template now).  Code clean-up and
  548.  * reformatting.
  549.  *
  550.  * Revision 1.7  2004/02/10 00:19:24  ucko
  551.  * Add missing "typename"
  552.  *
  553.  * Revision 1.6  2004/02/09 21:00:46  rsmith
  554.  * Make CDensityMap a template class. Add methods AddFeatures and AddRange.
  555.  *
  556.  * Revision 1.5  2003/09/16 14:36:10  dicuccio
  557.  * Minor clarification in comments
  558.  *
  559.  * Revision 1.4  2003/08/22 15:57:11  dicuccio
  560.  * Removed 'USING_SCOPE(objects)'.  Removed export specifier from inline structs
  561.  *
  562.  * Revision 1.3  2003/08/13 16:23:20  dicuccio
  563.  * Changed return value - maximum value in the graph
  564.  *
  565.  * Revision 1.2  2003/08/13 13:36:18  dicuccio
  566.  * Filled in remaining description
  567.  *
  568.  * Revision 1.1  2003/08/13 13:34:37  dicuccio
  569.  * Initial revision
  570.  *
  571.  * ===========================================================================
  572.  */
  573. #endif  // GUI_UTILS___DENSITY_GRAPH__HPP