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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: default_layoutpolicy.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 21:12:29  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: default_layoutpolicy.cpp,v 1000.3 2004/06/01 21:12:29 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:  Vlad Lebedev
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/widgets/seq_graphic/default_layoutpolicy.hpp>
  41. #include <gui/config/feat_config_list.hpp>
  42. #include <gui/objutils/feature.hpp>
  43. #include <gui/objutils/alignment.hpp>
  44. #include <gui/objutils/graph.hpp>
  45. #include <gui/objutils/prot_product.hpp>
  46. #include <gui/objutils/histogram.hpp>
  47. #include <gui/objutils/utils.hpp>
  48. #include <gui/objutils/seq_map.hpp>
  49. #include <gui/objutils/comment.hpp>
  50. #include <gui/objutils/sequence.hpp>
  51. #include <objmgr/seq_vector.hpp>
  52. BEGIN_NCBI_SCOPE
  53. USING_SCOPE(objects);
  54. const int kLabelsColWidth     = 100;  // width of a column small
  55. CDefaultLayoutPolicy::CDefaultLayoutPolicy()
  56. {
  57. }
  58. void CDefaultLayoutPolicy::SetHandle(const CBioseq_Handle& handle)
  59. {
  60.     m_Handle = handle;
  61. }
  62. void CDefaultLayoutPolicy::SetConfig(CSeqGraphicConfig* config)
  63. {
  64.     m_ConfigSettings = config;
  65. }
  66. void CDefaultLayoutPolicy::PrepareData(CGlPane& pane, CLayout& lay_objects)
  67. {
  68.     pane.OpenOrtho();
  69.     if (x_IsOverviewMode(pane)) {
  70.         x_PrepareGenesOverview(pane, lay_objects);
  71.     } else {
  72.         x_PrepareDetailedView(pane, lay_objects);
  73.     }
  74.     pane.Close();
  75. }
  76. bool CDefaultLayoutPolicy::x_IsOverviewMode(CGlPane& pane) const
  77. {
  78.     TModelRect rcV  = pane.GetVisibleRect();
  79.     TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
  80.     TModelUnit scale = pane.GetScaleX();    
  81.     
  82.     TSeqPos over_cut_off = m_ConfigSettings->GetOverviewCutoff();
  83.     TSeqPos gene_cut_off = m_ConfigSettings->GetGenesCutoff();
  84.     
  85.     SAnnotSelector sel = CSeqUtils::GetAnnotSelector(CSeqFeatData::e_Gene);
  86.     CFeat_CI iter(m_Handle, range.GetFrom(), range.GetTo(), sel);
  87.     return scale > over_cut_off  &&  iter.GetSize() > gene_cut_off;
  88. }
  89. void CDefaultLayoutPolicy::x_PrepareGenesOverview(CGlPane& pane, CLayout& lay_objects)
  90. {
  91.     TModelRect rcV = pane.GetVisibleRect();
  92.     TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
  93.     C2DLayoutEngine engine;
  94.     engine.SetMinDist( x_GetMinSpacing(pane) );
  95.     CLayout temporary;
  96.     CLayoutEngine::TObjects objs, obj_tmp;
  97.     CLayoutFeatLabel::TFeatLabelList marks_labels;
  98.     
  99.     lay_objects.Clear();
  100.     engine.Layout(objs, lay_objects);
  101.     
  102.     // Add segment map
  103.     if (m_ConfigSettings->GetShowSegmentMap()) {  // add Segment map
  104.         x_AddSeqSegmentMap(pane, lay_objects, range);
  105.     }
  106.     
  107.     x_AddHistograms(pane, lay_objects, range);
  108.     
  109.     // retrieve landmark features first
  110.     CLayoutFeat::TFeatList land_marks;
  111.     CSeqUtils::GetLandmarkFeatures(m_Handle, range, 200, land_marks);
  112.     // Comments for All Genes
  113.     string str2 = "Only Landmark Genes Shown: " + NStr::UIntToString(land_marks.size());
  114.     CRef<CLayoutObject> comment(new CLayoutComment(str2));
  115.     objs.push_back(comment);
  116.     engine.Layout(objs, temporary);
  117.     lay_objects.Append(temporary);
  118.     // we need to assemble a slightly different structure first
  119.     objs.clear();
  120.     NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, land_marks) {
  121.         CLayoutFeat& feat = **iter;
  122.         CRef<CLayoutFeatLabel> lbl
  123.             (new CLayoutFeatLabel(feat.GetMappedFeature()));
  124.         CRef<CLayoutObject> obj(*iter);
  125.         marks_labels.push_back(lbl);  // store for sorting
  126.         objs.push_back(obj);
  127.     }
  128.     engine.Layout(objs, temporary);
  129.     lay_objects.Append(temporary);
  130.     x_AddFeatureLabelsOverview(marks_labels, pane, lay_objects);
  131. }
  132. void CDefaultLayoutPolicy::x_AddHistograms(CGlPane& pane, 
  133.             CLayout& lay_objects, TSeqRange range)
  134. {
  135.     CLayoutEngine::TObjects objs;
  136.     CLayout temp;
  137.     C2DLayoutEngine engine;
  138.     
  139.     // Show histograms first
  140.     ITERATE(CFeatConfigList, iter, *GetFeatConfigList()) {
  141.         bool hist = m_ConfigSettings->GetHistogram(iter->GetType(), iter->GetSubtype());
  142.         if(!hist) continue;
  143.                 
  144.         SAnnotSelector selector = CSeqUtils::GetAnnotSelector
  145.             (CSeqFeatData::ESubtype(iter->GetSubtype()) );
  146.                             
  147.         selector.SetSortOrder(SAnnotSelector::eSortOrder_None);
  148.         CDensityMap<int> densityMap(range.GetFrom(), range.GetTo(),
  149.                                     TSeqPos(pane.GetScaleX()));
  150.         densityMap.AddFeatures(m_Handle, selector);
  151.         
  152.         if (densityMap.GetBins() == 0) { // skip empty maps
  153.             continue;
  154.         }
  155.         CRef<CLayoutObject> dmap(new CLayoutHistogram(densityMap, 
  156.                                 CSeqFeatData::E_Choice(iter->GetType()), 
  157.                                 CSeqFeatData::ESubtype(iter->GetSubtype())) );
  158.         objs.push_back(dmap);
  159.     }
  160.     
  161.     engine.Layout(objs, temp);
  162.     lay_objects.Append(temp);
  163. }
  164. void CDefaultLayoutPolicy::x_AddFeatureLabelsOverview(
  165.                 CLayoutFeatLabel::TFeatLabelList& labels, 
  166.                 CGlPane& pane, CLayout& lay_objects)
  167. {
  168.     // sort feature labels alphabetically
  169.     sort(labels.begin(), labels.end(), SFeatureByName());
  170.     // a number of columns that will fit
  171.     int cols_count = pane.GetViewport().Width() / kLabelsColWidth;
  172.         
  173.     if (cols_count == 0) {
  174.         cols_count = 1; // always at least 1 column
  175.     }
  176.     // assign columns and repack
  177.     int cur_col = 0;
  178.     CLayoutEngine::TObjects labels_obj;
  179.     NON_CONST_ITERATE (CLayoutFeatLabel::TFeatLabelList, iter, labels) {
  180.         (*iter)->SetColumn(cur_col);  // set the column index
  181.         CRef<CLayoutObject> obj(*iter);
  182.         labels_obj.push_back(obj);
  183.         if (++cur_col >= cols_count) {
  184.             cur_col = 0;
  185.         }
  186.     }
  187.     CLayout labels_layout;
  188.     x_LayoutLabels(labels_obj, labels_layout, cols_count);
  189.     lay_objects.Append(labels_layout);    
  190. }
  191. void CDefaultLayoutPolicy::
  192. x_AddSequenceBar(CGlPane& pane, CLayout& lay_objects, TSeqRange range)
  193. {
  194.     if (pane.GetScaleX() > 1.0f / 8.0f ) { // sequence would not fit
  195.         return;
  196.     }
  197.     
  198.     CLayout temp;
  199.     C2DLayoutEngine engine;
  200.     CLayoutEngine::TObjects obj_tmp;
  201.     
  202.     string seq_str;
  203.     CSeqVector s_vec = m_Handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  204.     s_vec.GetSeqData(range.GetFrom(), range.GetTo(), seq_str);
  205.     
  206.     CRef<CLayoutObject> sequence(new CLayoutSequence(seq_str));
  207.     // Add to layout
  208.     obj_tmp.push_back(sequence);
  209.     engine.Layout(obj_tmp, temp);
  210.     lay_objects.Append(temp);
  211. }
  212. void CDefaultLayoutPolicy::x_AddSeqSegmentMap(CGlPane& pane, CLayout& lay_objects, TSeqRange range)
  213. {
  214.     CLayoutEngine::TObjects objs, obj_tmp;
  215.     
  216.     // Segment maps first
  217.     GetSeqMaps(objs, range);
  218.     
  219.     // Do not do anything if no segments
  220.     if (objs.size() == 0) {
  221.         return;
  222.     }
  223.     
  224.     string str = "Segment Map: " + NStr::UIntToString(objs.size());
  225.     CRef<CLayoutObject> comment(new CLayoutComment(str));
  226.     C2DLayoutEngine engine;
  227.     engine.SetMinDist(x_GetMinSpacing(pane) );
  228.  
  229.     CLayout temp, temp2;   
  230.     obj_tmp.push_back(comment);
  231.     engine.Layout(obj_tmp, temp);
  232.     lay_objects.Append(temp);
  233.     engine.Layout(objs, temp2);
  234.     
  235.     unsigned int kMaxSegMapRows = 4; // no more than 4 rows
  236.     for (size_t idx = 0; idx != temp2.GetLayout().size()  &&  
  237.                                 idx < kMaxSegMapRows; idx++) {
  238.         lay_objects.AddRow(temp2.GetRow(idx));
  239.     }
  240. }
  241. void CDefaultLayoutPolicy::x_LayoutLabels(const CLayoutEngine::TObjects& objects, 
  242.                                   CLayout& layout, int col_count)
  243. {
  244.     // clear our layout to start
  245.     layout.Clear();
  246.     int idx = 0;
  247.     CLayout::TLayoutRow row;
  248.     ITERATE (CLayoutEngine::TObjects, iter, objects) {
  249.         row.push_back(*iter);
  250.         if (++idx >= col_count) {
  251.             idx = 0;
  252.             layout.AddRow(row);  // add row to layout
  253.             row.clear();         // start new empty row
  254.         }
  255.     }
  256.     layout.AddRow(row); // add last partial row
  257. }
  258. void CDefaultLayoutPolicy::GetSeqMaps(CLayoutEngine::TObjects& maps,
  259.                                   const TSeqRange& range)
  260. {
  261.     maps.clear();
  262.     for (size_t levels = 0;  levels < 4;  ++levels) {
  263.         CConstRef<CSeqMap> seq_map(&m_Handle.GetSeqMap());
  264.         CSeqMap::const_iterator seg =
  265.             seq_map->ResolvedRangeIterator(&m_Handle.GetScope(),
  266.                                            range.GetFrom(), range.GetLength(),
  267.                                            eNa_strand_plus, levels);
  268.         for ( ;  seg;  ++seg ) {
  269.             TSeqRange map_range;
  270.             switch (seg.GetType()) {
  271.             case CSeqMap::eSeqRef:
  272.                 /**
  273.                 // FIXME: this will need to wait for ID2, it's too expensive
  274.                 {{
  275.                     CSeq_id_Handle s_hndl = seg.GetRefSeqid();
  276.                     CConstRef<CSeq_id> sid = s_hndl.GetSeqId();
  277.                     CBioseq_Handle handle = m_Handle.GetScope().
  278.                                                      GetBioseqHandle(sid.GetObject());
  279.                     _ASSERT(handle);
  280.                     CSeqVector s_vec = handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  281.                     TSeqPos from   = seg.GetPosition() - seg.GetRefPosition(); 
  282.                     TSeqPos length = s_vec.size();
  283.                     map_range = TSeqRange(from, from + length);
  284.                 }}
  285.                 break;
  286.                 **/
  287.             case CSeqMap::eSeqData:
  288.             case CSeqMap::eSeqGap:
  289.                 map_range = TSeqRange(seg.GetPosition(), seg.GetEndPosition());
  290.                 break;
  291.             case CSeqMap::eSeqEnd:
  292.                 _ASSERT("Unexpected END segment" && 0);
  293.                 break;
  294.             default:
  295.                 _ASSERT("Unexpected segment type" && 0);
  296.                 break;
  297.             }
  298.             TSeqRange ref_range(seg.GetPosition(), seg.GetEndPosition());
  299.         
  300.             try {
  301.                 CRef<CLayoutObject> mref(   
  302.                     new CLayoutSeqMap(seg.GetRefSeqid(), map_range, ref_range)
  303.                 );
  304.                 maps.push_back(mref);
  305.             } catch(...) {
  306.             }
  307.         }
  308.         if (maps.size() != 0) {
  309.             break;
  310.         }
  311.     }
  312. }
  313. void CDefaultLayoutPolicy::x_PrepareDetailedView(CGlPane& pane, 
  314.                             CLayout& lay_objects)
  315. {
  316.     TModelRect rcV = pane.GetVisibleRect();
  317.     
  318.     TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
  319.     CLayoutFeat::TFeatList features;
  320.     lay_objects.Clear();
  321.     // retrieve and sort all features.  we are only interested in a few
  322.     // subtypes, but we'll sort that out below
  323.     CLayoutFeat::TFeatList feats;
  324.     CLayoutFeatLabel::TFeatLabelList feat_labels; 
  325.     
  326.     CLayout other_feat_layout;
  327.     typedef map<int, CLayoutEngine::TObjects> TFeatMap;
  328.     TFeatMap other_features;
  329.     
  330.     CSeqUtils::GetFeatures(m_Handle, range, CSeqFeatData::e_not_set, feats);
  331.     bool show_prot   = m_ConfigSettings->GetShowProtProd();
  332.     bool show_aln    = m_ConfigSettings->GetShowAlignments();
  333.     bool smear_aln   = m_ConfigSettings->GetSmearAlignments();
  334.     bool show_graphs = m_ConfigSettings->GetShowGraphs();
  335.     bool show_feat_labels = false; // ToDO: get from config
  336.     
  337.     NON_CONST_ITERATE (CLayoutFeat::TFeatList, feature_iter, feats) {
  338.         CLayoutFeat&           feat = **feature_iter;
  339.         CRef<CLayoutFeat>      pfeat(&feat);
  340.         CRef<CLayoutObject> obj(*feature_iter);
  341.         CRef<CLayoutFeatLabel> lbl
  342.                 (new CLayoutFeatLabel(feat.GetMappedFeature()));
  343.                 
  344.         const CSeqFeatData& data = feat.GetFeature().GetData();
  345.         bool show = m_ConfigSettings->GetShow(data.Which(), data.GetSubtype());
  346.         if (!show) {
  347.             continue;
  348.         }
  349.         
  350.         //bool hist = m_ConfigSettings->GetHistogram(data.Which(), data.GetSubtype());
  351.         feat_labels.push_back(lbl);  // store for sorting
  352.         
  353.         switch (data.Which()) {
  354.         case CSeqFeatData::e_Gene:
  355.         case CSeqFeatData::e_Rna:
  356.             features.push_back(pfeat);
  357.             break;
  358.         case CSeqFeatData::e_Cdregion:
  359.             features.push_back(pfeat);
  360.             // add protein product for this CDS (if exists)
  361.             if (show_prot  &&  pfeat->GetFeature().IsSetProduct()) {
  362.                 CRef<CLayoutFeat> prot
  363.                     (new CLayoutProtProd(m_Handle.GetScope(),
  364.                                          feat.GetMappedFeature()));
  365.                 features.push_back(prot);
  366.             }
  367.             break;        
  368.         default:
  369.             other_features[data.Which()].push_back(obj);
  370.             break;
  371.         }
  372.     }
  373.     // link our features together
  374.     CSeqUtils::LinkFeatures(features);
  375.     // and finally, do our layout.  this requres translation of the objects
  376.     CLayoutEngine::TObjects objs, tmp_obj;
  377.     NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, features) {
  378.         CRef<CLayoutObject> obj(*iter);
  379.         objs.push_back(obj);
  380.     }
  381.     
  382.     C2DLayoutEngine engine;
  383.     engine.SetMinDist( x_GetMinSpacing(pane) );
  384.     engine.Layout(tmp_obj, lay_objects);
  385.     
  386.     // Add Segment Map
  387.     if (m_ConfigSettings->GetShowSegmentMap()) {  // add Segment map
  388.         x_AddSeqSegmentMap(pane, lay_objects, range);
  389.     }
  390.     
  391.     // Add Sequence Bar
  392.     x_AddSequenceBar(pane, lay_objects, range);
  393.     
  394.     if (show_graphs) {  // add graphs
  395.         CLayout graph_layout;
  396.         CLayoutEngine::TObjects graph_objs;
  397.         CSeqUtils::GetGraphs(m_Handle, range, graph_objs);
  398.         engine.Layout(graph_objs, graph_layout);
  399.         lay_objects.Append(graph_layout);
  400.     }
  401.     CLayout temp_layout;
  402.     engine.Layout(objs, temp_layout);
  403.     lay_objects.Append(temp_layout);
  404.     ITERATE (TFeatMap, feat_map_iter, other_features) {
  405.         //CLayout temp_layout;
  406.         engine.Layout(feat_map_iter->second, temp_layout);
  407.         other_feat_layout.Append(temp_layout);
  408.     }
  409.     lay_objects.Append(other_feat_layout);
  410.     if (show_aln) {  // add alignments
  411.         CLayout alignment_layout;
  412.         CLayoutEngine::TObjects aln_objs;
  413.         if (smear_aln) {
  414.             CSeqUtils::GetAlignmentSmears(m_Handle, range, pane.GetScaleX(), aln_objs);
  415.         } else {
  416.             CSeqUtils::GetAlignments(m_Handle, range, aln_objs);
  417.         }
  418.         engine.Layout(aln_objs, alignment_layout);
  419.         lay_objects.Append(alignment_layout);
  420.     }
  421.         
  422.     if (show_feat_labels) {  // add feature labels
  423.         x_AddFeatureLabelsOverview(feat_labels, pane, lay_objects);
  424.     }
  425. }
  426. TSeqPos CDefaultLayoutPolicy::x_GetMinSpacing(CGlPane& pane) const
  427. {
  428.     // minimum is 2 pixels
  429.     // m_ZoomX is pixels per base
  430.     // we need to return bases
  431.     return TSeqPos( pane.UnProjectWidth(2) );
  432. }
  433. END_NCBI_SCOPE
  434. /*
  435.  * ===========================================================================
  436.  * $Log: default_layoutpolicy.cpp,v $
  437.  * Revision 1000.3  2004/06/01 21:12:29  gouriano
  438.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  439.  *
  440.  * Revision 1.13  2004/05/21 22:27:55  gorelenk
  441.  * Added PCH ncbi_pch.hpp
  442.  *
  443.  * Revision 1.12  2004/05/11 17:57:42  lebedev
  444.  * Render Sequence Graphs on top of all Layout Objects
  445.  *
  446.  * Revision 1.11  2004/05/10 16:00:15  lebedev
  447.  * Aware of Show/Hide segment maps configuration option.
  448.  *
  449.  * Revision 1.10  2004/05/03 13:23:58  dicuccio
  450.  * gui/utils --> gui/objutils where needed
  451.  *
  452.  * Revision 1.9  2004/04/16 14:51:35  dicuccio
  453.  * SetConfig() takes pointer, not CRef<>
  454.  *
  455.  * Revision 1.8  2004/04/14 11:25:48  lebedev
  456.  * Added rendering of Mate Pairs.
  457.  *
  458.  * Revision 1.7  2004/04/07 13:10:33  dicuccio
  459.  * Split GetAnnotSelector() into two APIs for features (featyre type or feature
  460.  * subtype).  Formatting changes.
  461.  *
  462.  * Revision 1.6  2004/03/23 12:33:55  lebedev
  463.  * Made sequence and histograms bars a layout objects in the object panel.
  464.  * Made segment map a number of layout objects. Get rid of fixed size rows in the object panel.
  465.  *
  466.  * Revision 1.5  2004/03/22 16:54:57  rsmith
  467.  * get alignments smears.
  468.  *
  469.  * Revision 1.4  2004/03/11 17:53:06  dicuccio
  470.  * Deprecated typedefs TPosition, TDimension, TIndex, TColor.  Use TSeqRange instead of TRange
  471.  *
  472.  * Revision 1.3  2004/03/02 15:29:13  lebedev
  473.  * Switch to detailed mode if reached certain number of
  474.  * genes in visible range.
  475.  *
  476.  * Revision 1.2  2004/02/24 14:48:25  lebedev
  477.  * Support for new types of layout objects added
  478.  *
  479.  * Revision 1.1  2004/02/13 18:10:46  lebedev
  480.  * Initial revision
  481.  *
  482.  * ===========================================================================
  483.  */