default_layoutpolicy.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:18k
- /*
- * ===========================================================================
- * PRODUCTION $Log: default_layoutpolicy.cpp,v $
- * PRODUCTION Revision 1000.3 2004/06/01 21:12:29 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: default_layoutpolicy.cpp,v 1000.3 2004/06/01 21:12:29 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Vlad Lebedev
- *
- * File Description:
- *
- */
- #include <ncbi_pch.hpp>
- #include <gui/widgets/seq_graphic/default_layoutpolicy.hpp>
- #include <gui/config/feat_config_list.hpp>
- #include <gui/objutils/feature.hpp>
- #include <gui/objutils/alignment.hpp>
- #include <gui/objutils/graph.hpp>
- #include <gui/objutils/prot_product.hpp>
- #include <gui/objutils/histogram.hpp>
- #include <gui/objutils/utils.hpp>
- #include <gui/objutils/seq_map.hpp>
- #include <gui/objutils/comment.hpp>
- #include <gui/objutils/sequence.hpp>
- #include <objmgr/seq_vector.hpp>
- BEGIN_NCBI_SCOPE
- USING_SCOPE(objects);
- const int kLabelsColWidth = 100; // width of a column small
- CDefaultLayoutPolicy::CDefaultLayoutPolicy()
- {
- }
- void CDefaultLayoutPolicy::SetHandle(const CBioseq_Handle& handle)
- {
- m_Handle = handle;
- }
- void CDefaultLayoutPolicy::SetConfig(CSeqGraphicConfig* config)
- {
- m_ConfigSettings = config;
- }
- void CDefaultLayoutPolicy::PrepareData(CGlPane& pane, CLayout& lay_objects)
- {
- pane.OpenOrtho();
- if (x_IsOverviewMode(pane)) {
- x_PrepareGenesOverview(pane, lay_objects);
- } else {
- x_PrepareDetailedView(pane, lay_objects);
- }
- pane.Close();
- }
- bool CDefaultLayoutPolicy::x_IsOverviewMode(CGlPane& pane) const
- {
- TModelRect rcV = pane.GetVisibleRect();
- TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
- TModelUnit scale = pane.GetScaleX();
-
- TSeqPos over_cut_off = m_ConfigSettings->GetOverviewCutoff();
- TSeqPos gene_cut_off = m_ConfigSettings->GetGenesCutoff();
-
- SAnnotSelector sel = CSeqUtils::GetAnnotSelector(CSeqFeatData::e_Gene);
- CFeat_CI iter(m_Handle, range.GetFrom(), range.GetTo(), sel);
- return scale > over_cut_off && iter.GetSize() > gene_cut_off;
- }
- void CDefaultLayoutPolicy::x_PrepareGenesOverview(CGlPane& pane, CLayout& lay_objects)
- {
- TModelRect rcV = pane.GetVisibleRect();
- TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
- C2DLayoutEngine engine;
- engine.SetMinDist( x_GetMinSpacing(pane) );
- CLayout temporary;
- CLayoutEngine::TObjects objs, obj_tmp;
- CLayoutFeatLabel::TFeatLabelList marks_labels;
-
- lay_objects.Clear();
- engine.Layout(objs, lay_objects);
-
- // Add segment map
- if (m_ConfigSettings->GetShowSegmentMap()) { // add Segment map
- x_AddSeqSegmentMap(pane, lay_objects, range);
- }
-
- x_AddHistograms(pane, lay_objects, range);
-
- // retrieve landmark features first
- CLayoutFeat::TFeatList land_marks;
- CSeqUtils::GetLandmarkFeatures(m_Handle, range, 200, land_marks);
- // Comments for All Genes
- string str2 = "Only Landmark Genes Shown: " + NStr::UIntToString(land_marks.size());
- CRef<CLayoutObject> comment(new CLayoutComment(str2));
- objs.push_back(comment);
- engine.Layout(objs, temporary);
- lay_objects.Append(temporary);
- // we need to assemble a slightly different structure first
- objs.clear();
- NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, land_marks) {
- CLayoutFeat& feat = **iter;
- CRef<CLayoutFeatLabel> lbl
- (new CLayoutFeatLabel(feat.GetMappedFeature()));
- CRef<CLayoutObject> obj(*iter);
- marks_labels.push_back(lbl); // store for sorting
- objs.push_back(obj);
- }
- engine.Layout(objs, temporary);
- lay_objects.Append(temporary);
- x_AddFeatureLabelsOverview(marks_labels, pane, lay_objects);
- }
- void CDefaultLayoutPolicy::x_AddHistograms(CGlPane& pane,
- CLayout& lay_objects, TSeqRange range)
- {
- CLayoutEngine::TObjects objs;
- CLayout temp;
- C2DLayoutEngine engine;
-
- // Show histograms first
- ITERATE(CFeatConfigList, iter, *GetFeatConfigList()) {
- bool hist = m_ConfigSettings->GetHistogram(iter->GetType(), iter->GetSubtype());
- if(!hist) continue;
-
- SAnnotSelector selector = CSeqUtils::GetAnnotSelector
- (CSeqFeatData::ESubtype(iter->GetSubtype()) );
-
- selector.SetSortOrder(SAnnotSelector::eSortOrder_None);
- CDensityMap<int> densityMap(range.GetFrom(), range.GetTo(),
- TSeqPos(pane.GetScaleX()));
- densityMap.AddFeatures(m_Handle, selector);
-
- if (densityMap.GetBins() == 0) { // skip empty maps
- continue;
- }
- CRef<CLayoutObject> dmap(new CLayoutHistogram(densityMap,
- CSeqFeatData::E_Choice(iter->GetType()),
- CSeqFeatData::ESubtype(iter->GetSubtype())) );
- objs.push_back(dmap);
- }
-
- engine.Layout(objs, temp);
- lay_objects.Append(temp);
- }
- void CDefaultLayoutPolicy::x_AddFeatureLabelsOverview(
- CLayoutFeatLabel::TFeatLabelList& labels,
- CGlPane& pane, CLayout& lay_objects)
- {
- // sort feature labels alphabetically
- sort(labels.begin(), labels.end(), SFeatureByName());
- // a number of columns that will fit
- int cols_count = pane.GetViewport().Width() / kLabelsColWidth;
-
- if (cols_count == 0) {
- cols_count = 1; // always at least 1 column
- }
- // assign columns and repack
- int cur_col = 0;
- CLayoutEngine::TObjects labels_obj;
- NON_CONST_ITERATE (CLayoutFeatLabel::TFeatLabelList, iter, labels) {
- (*iter)->SetColumn(cur_col); // set the column index
- CRef<CLayoutObject> obj(*iter);
- labels_obj.push_back(obj);
- if (++cur_col >= cols_count) {
- cur_col = 0;
- }
- }
- CLayout labels_layout;
- x_LayoutLabels(labels_obj, labels_layout, cols_count);
- lay_objects.Append(labels_layout);
- }
- void CDefaultLayoutPolicy::
- x_AddSequenceBar(CGlPane& pane, CLayout& lay_objects, TSeqRange range)
- {
- if (pane.GetScaleX() > 1.0f / 8.0f ) { // sequence would not fit
- return;
- }
-
- CLayout temp;
- C2DLayoutEngine engine;
- CLayoutEngine::TObjects obj_tmp;
-
- string seq_str;
- CSeqVector s_vec = m_Handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
- s_vec.GetSeqData(range.GetFrom(), range.GetTo(), seq_str);
-
- CRef<CLayoutObject> sequence(new CLayoutSequence(seq_str));
- // Add to layout
- obj_tmp.push_back(sequence);
- engine.Layout(obj_tmp, temp);
- lay_objects.Append(temp);
- }
- void CDefaultLayoutPolicy::x_AddSeqSegmentMap(CGlPane& pane, CLayout& lay_objects, TSeqRange range)
- {
- CLayoutEngine::TObjects objs, obj_tmp;
-
- // Segment maps first
- GetSeqMaps(objs, range);
-
- // Do not do anything if no segments
- if (objs.size() == 0) {
- return;
- }
-
- string str = "Segment Map: " + NStr::UIntToString(objs.size());
- CRef<CLayoutObject> comment(new CLayoutComment(str));
- C2DLayoutEngine engine;
- engine.SetMinDist(x_GetMinSpacing(pane) );
-
- CLayout temp, temp2;
- obj_tmp.push_back(comment);
- engine.Layout(obj_tmp, temp);
- lay_objects.Append(temp);
- engine.Layout(objs, temp2);
-
- unsigned int kMaxSegMapRows = 4; // no more than 4 rows
- for (size_t idx = 0; idx != temp2.GetLayout().size() &&
- idx < kMaxSegMapRows; idx++) {
- lay_objects.AddRow(temp2.GetRow(idx));
- }
- }
- void CDefaultLayoutPolicy::x_LayoutLabels(const CLayoutEngine::TObjects& objects,
- CLayout& layout, int col_count)
- {
- // clear our layout to start
- layout.Clear();
- int idx = 0;
- CLayout::TLayoutRow row;
- ITERATE (CLayoutEngine::TObjects, iter, objects) {
- row.push_back(*iter);
- if (++idx >= col_count) {
- idx = 0;
- layout.AddRow(row); // add row to layout
- row.clear(); // start new empty row
- }
- }
- layout.AddRow(row); // add last partial row
- }
- void CDefaultLayoutPolicy::GetSeqMaps(CLayoutEngine::TObjects& maps,
- const TSeqRange& range)
- {
- maps.clear();
- for (size_t levels = 0; levels < 4; ++levels) {
- CConstRef<CSeqMap> seq_map(&m_Handle.GetSeqMap());
- CSeqMap::const_iterator seg =
- seq_map->ResolvedRangeIterator(&m_Handle.GetScope(),
- range.GetFrom(), range.GetLength(),
- eNa_strand_plus, levels);
- for ( ; seg; ++seg ) {
- TSeqRange map_range;
- switch (seg.GetType()) {
- case CSeqMap::eSeqRef:
- /**
- // FIXME: this will need to wait for ID2, it's too expensive
- {{
- CSeq_id_Handle s_hndl = seg.GetRefSeqid();
- CConstRef<CSeq_id> sid = s_hndl.GetSeqId();
- CBioseq_Handle handle = m_Handle.GetScope().
- GetBioseqHandle(sid.GetObject());
- _ASSERT(handle);
- CSeqVector s_vec = handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
- TSeqPos from = seg.GetPosition() - seg.GetRefPosition();
- TSeqPos length = s_vec.size();
- map_range = TSeqRange(from, from + length);
- }}
- break;
- **/
- case CSeqMap::eSeqData:
- case CSeqMap::eSeqGap:
- map_range = TSeqRange(seg.GetPosition(), seg.GetEndPosition());
- break;
- case CSeqMap::eSeqEnd:
- _ASSERT("Unexpected END segment" && 0);
- break;
- default:
- _ASSERT("Unexpected segment type" && 0);
- break;
- }
- TSeqRange ref_range(seg.GetPosition(), seg.GetEndPosition());
-
- try {
- CRef<CLayoutObject> mref(
- new CLayoutSeqMap(seg.GetRefSeqid(), map_range, ref_range)
- );
- maps.push_back(mref);
- } catch(...) {
- }
- }
- if (maps.size() != 0) {
- break;
- }
- }
- }
- void CDefaultLayoutPolicy::x_PrepareDetailedView(CGlPane& pane,
- CLayout& lay_objects)
- {
- TModelRect rcV = pane.GetVisibleRect();
-
- TSeqRange range( TSeqPos(rcV.Left()), TSeqPos(rcV.Right()) );
- CLayoutFeat::TFeatList features;
- lay_objects.Clear();
- // retrieve and sort all features. we are only interested in a few
- // subtypes, but we'll sort that out below
- CLayoutFeat::TFeatList feats;
- CLayoutFeatLabel::TFeatLabelList feat_labels;
-
- CLayout other_feat_layout;
- typedef map<int, CLayoutEngine::TObjects> TFeatMap;
- TFeatMap other_features;
-
- CSeqUtils::GetFeatures(m_Handle, range, CSeqFeatData::e_not_set, feats);
- bool show_prot = m_ConfigSettings->GetShowProtProd();
- bool show_aln = m_ConfigSettings->GetShowAlignments();
- bool smear_aln = m_ConfigSettings->GetSmearAlignments();
- bool show_graphs = m_ConfigSettings->GetShowGraphs();
- bool show_feat_labels = false; // ToDO: get from config
-
- NON_CONST_ITERATE (CLayoutFeat::TFeatList, feature_iter, feats) {
- CLayoutFeat& feat = **feature_iter;
- CRef<CLayoutFeat> pfeat(&feat);
- CRef<CLayoutObject> obj(*feature_iter);
- CRef<CLayoutFeatLabel> lbl
- (new CLayoutFeatLabel(feat.GetMappedFeature()));
-
- const CSeqFeatData& data = feat.GetFeature().GetData();
- bool show = m_ConfigSettings->GetShow(data.Which(), data.GetSubtype());
- if (!show) {
- continue;
- }
-
- //bool hist = m_ConfigSettings->GetHistogram(data.Which(), data.GetSubtype());
- feat_labels.push_back(lbl); // store for sorting
-
- switch (data.Which()) {
- case CSeqFeatData::e_Gene:
- case CSeqFeatData::e_Rna:
- features.push_back(pfeat);
- break;
- case CSeqFeatData::e_Cdregion:
- features.push_back(pfeat);
- // add protein product for this CDS (if exists)
- if (show_prot && pfeat->GetFeature().IsSetProduct()) {
- CRef<CLayoutFeat> prot
- (new CLayoutProtProd(m_Handle.GetScope(),
- feat.GetMappedFeature()));
- features.push_back(prot);
- }
- break;
- default:
- other_features[data.Which()].push_back(obj);
- break;
- }
- }
- // link our features together
- CSeqUtils::LinkFeatures(features);
- // and finally, do our layout. this requres translation of the objects
- CLayoutEngine::TObjects objs, tmp_obj;
- NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, features) {
- CRef<CLayoutObject> obj(*iter);
- objs.push_back(obj);
- }
-
- C2DLayoutEngine engine;
- engine.SetMinDist( x_GetMinSpacing(pane) );
- engine.Layout(tmp_obj, lay_objects);
-
- // Add Segment Map
- if (m_ConfigSettings->GetShowSegmentMap()) { // add Segment map
- x_AddSeqSegmentMap(pane, lay_objects, range);
- }
-
- // Add Sequence Bar
- x_AddSequenceBar(pane, lay_objects, range);
-
- if (show_graphs) { // add graphs
- CLayout graph_layout;
- CLayoutEngine::TObjects graph_objs;
- CSeqUtils::GetGraphs(m_Handle, range, graph_objs);
- engine.Layout(graph_objs, graph_layout);
- lay_objects.Append(graph_layout);
- }
- CLayout temp_layout;
- engine.Layout(objs, temp_layout);
- lay_objects.Append(temp_layout);
- ITERATE (TFeatMap, feat_map_iter, other_features) {
- //CLayout temp_layout;
- engine.Layout(feat_map_iter->second, temp_layout);
- other_feat_layout.Append(temp_layout);
- }
- lay_objects.Append(other_feat_layout);
- if (show_aln) { // add alignments
- CLayout alignment_layout;
- CLayoutEngine::TObjects aln_objs;
- if (smear_aln) {
- CSeqUtils::GetAlignmentSmears(m_Handle, range, pane.GetScaleX(), aln_objs);
- } else {
- CSeqUtils::GetAlignments(m_Handle, range, aln_objs);
- }
- engine.Layout(aln_objs, alignment_layout);
- lay_objects.Append(alignment_layout);
- }
-
- if (show_feat_labels) { // add feature labels
- x_AddFeatureLabelsOverview(feat_labels, pane, lay_objects);
- }
- }
- TSeqPos CDefaultLayoutPolicy::x_GetMinSpacing(CGlPane& pane) const
- {
- // minimum is 2 pixels
- // m_ZoomX is pixels per base
- // we need to return bases
- return TSeqPos( pane.UnProjectWidth(2) );
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: default_layoutpolicy.cpp,v $
- * Revision 1000.3 2004/06/01 21:12:29 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
- *
- * Revision 1.13 2004/05/21 22:27:55 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.12 2004/05/11 17:57:42 lebedev
- * Render Sequence Graphs on top of all Layout Objects
- *
- * Revision 1.11 2004/05/10 16:00:15 lebedev
- * Aware of Show/Hide segment maps configuration option.
- *
- * Revision 1.10 2004/05/03 13:23:58 dicuccio
- * gui/utils --> gui/objutils where needed
- *
- * Revision 1.9 2004/04/16 14:51:35 dicuccio
- * SetConfig() takes pointer, not CRef<>
- *
- * Revision 1.8 2004/04/14 11:25:48 lebedev
- * Added rendering of Mate Pairs.
- *
- * Revision 1.7 2004/04/07 13:10:33 dicuccio
- * Split GetAnnotSelector() into two APIs for features (featyre type or feature
- * subtype). Formatting changes.
- *
- * Revision 1.6 2004/03/23 12:33:55 lebedev
- * Made sequence and histograms bars a layout objects in the object panel.
- * Made segment map a number of layout objects. Get rid of fixed size rows in the object panel.
- *
- * Revision 1.5 2004/03/22 16:54:57 rsmith
- * get alignments smears.
- *
- * Revision 1.4 2004/03/11 17:53:06 dicuccio
- * Deprecated typedefs TPosition, TDimension, TIndex, TColor. Use TSeqRange instead of TRange
- *
- * Revision 1.3 2004/03/02 15:29:13 lebedev
- * Switch to detailed mode if reached certain number of
- * genes in visible range.
- *
- * Revision 1.2 2004/02/24 14:48:25 lebedev
- * Support for new types of layout objects added
- *
- * Revision 1.1 2004/02/13 18:10:46 lebedev
- * Initial revision
- *
- * ===========================================================================
- */