NCBI C++ ToolKit
segment_map_ds.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

00001 /*  $Id: segment_map_ds.cpp 28325 2013-06-18 21:20:48Z wuliangs $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Authors:  Liangshou Wu
00027  *
00028  */
00029 
00030 #include <ncbi_pch.hpp>
00031 #include <gui/widgets/seq_graphic/segment_map_ds.hpp>
00032 #include <gui/widgets/seq_graphic/seqgraphic_job.hpp>
00033 #include <gui/widgets/seq_graphic/seqgraphic_utils.hpp>
00034 #include <gui/widgets/seq_graphic/segment_smear_glyph.hpp>
00035 #include <gui/widgets/seq_graphic/seqgraphic_job_result.hpp>
00036 #include <gui/widgets/seq_graphic/segment_glyph.hpp>
00037 #include <gui/widgets/seq_graphic/comment_glyph.hpp>
00038 #include <gui/widgets/seq_graphic/switch_point_glyph.hpp>
00039 
00040 #include <objmgr/table_field.hpp>
00041 #include <objmgr/annot_ci.hpp>
00042 #include <objmgr/seq_map_switch.hpp>
00043 #include <objmgr/seqdesc_ci.hpp>
00044 #include <objects/seq/MolInfo.hpp>
00045 #include <objects/seq/Seq_hist.hpp>
00046 #include <objects/seqtable/Seq_table.hpp>
00047 #include <objects/seqtable/SeqTable_column.hpp>
00048 
00049 BEGIN_NCBI_SCOPE
00050 USING_SCOPE(objects);
00051 
00052 ///////////////////////////////////////////////////////////////////////////////
00053 /// CSGSegmentMapJob declaration
00054 ///
00055 class CSGSegmentMapJob : public CSeqGraphicJob
00056 {
00057 public:
00058     CSGSegmentMapJob(const string& desc, objects::CBioseq_Handle handle,
00059         const TSeqRange& range, int depth, int cutoff, TJobToken token);
00060 
00061     static int GetSegmentMapLevels(const objects::CBioseq_Handle& handle,
00062         const TSeqRange& range);
00063 
00064     static bool HasSegmentMap(const objects::CBioseq_Handle& Handle, int level,
00065         const TSeqRange& range);
00066 
00067 protected:
00068     virtual EJobState x_Execute();
00069 
00070 private:
00071     bool x_AdaptiveDepth() const
00072     {   return m_Depth == -1; }
00073 
00074     /// merge equal segment maps into one map.
00075     IAppJob::EJobState x_MergeSeqSegments(CSegmentGlyph::TSeqMapList& seg_maps,
00076         CSeqGlyph::TObjects& objs);
00077 
00078 private:
00079     objects::CBioseq_Handle m_Handle;   ///< target sequence
00080     TSeqRange               m_Range;    ///< target range
00081 
00082     /// Resolve depth for selector.
00083     /// Valid numbers include: -1: adaptive, 0: first level, 1: second
00084     /// Depending on the sequence currently shown, first level may be
00085     /// the scaffolds (chromosome) or the compoments (config)
00086     int                     m_Depth;
00087 
00088     /// limit of number of segments we want to show.
00089     /// <=0 means there is no limit.
00090     int                     m_Cutoff;
00091 };
00092 
00093 ///////////////////////////////////////////////////////////////////////////////
00094 /// CSGSegmentSmearJob declaration
00095 ///
00096 class CSGSegmentSmearJob : public CSGAnnotJob
00097 {
00098 public:
00099     CSGSegmentSmearJob(const string& desc, objects::CBioseq_Handle handle,
00100         const TSeqRange& range, TModelUnit scale, const string& annot);
00101 
00102     static void GetAnnotNames(const objects::CBioseq_Handle& handle,
00103         const TSeqRange& range, objects::SAnnotSelector& sel,
00104         TAnnotNameTitleMap& annots);
00105 
00106 protected:
00107     virtual EJobState x_Execute();
00108 
00109 private:
00110     IAppJob::EJobState x_LoadFromDeltaSeqs();
00111 
00112     IAppJob::EJobState x_LoadFromNA();
00113 
00114     bool x_IsGap(vector<char> is_gaps, int row) const
00115     {
00116         return is_gaps[row / 8] & 0x01 << (8 - row % 8);
00117     }
00118 
00119 private:
00120     TModelUnit              m_Scale;    ///< bases per pixel
00121     string                  m_Annot;    ///< annotation storing the segments
00122 };
00123 
00124 ///////////////////////////////////////////////////////////////////////////////
00125 /// CSGSegmentsSeqIDJob declaration
00126 ///
00127 class CSGSegmentsSeqIDJob : public CSeqGraphicJob
00128 {
00129 public:
00130     CSGSegmentsSeqIDJob(const string& desc, CSeqGlyph::TObjects& objs,
00131         objects::CScope& scope, TJobToken token);
00132 
00133 protected:
00134     virtual EJobState x_Execute();
00135 
00136     CSeqGlyph::TObjects     m_Objs;     ///< objects for post-processing
00137     objects::CScope&        m_Scope;    ///< scope for retrieving the CBioseq
00138 };
00139 
00140 
00141 ///////////////////////////////////////////////////////////////////////////////
00142 /// CSGSwitchPointJob declaration
00143 ///
00144 class CSGSwitchPointJob : public CSeqGraphicJob
00145 {
00146 public:
00147     CSGSwitchPointJob(const string& desc, objects::CBioseq_Handle handle);
00148 
00149 protected:
00150     virtual EJobState x_Execute();
00151 
00152 private:
00153     objects::CBioseq_Handle m_Handle;   ///< target sequence
00154 };
00155 
00156 
00157 ///////////////////////////////////////////////////////////////////////////////
00158 /// CSGSegmentMapDS implementation
00159 ///
00160 CSGSegmentMapDS::CSGSegmentMapDS(CScope& scope, const CSeq_id& id)
00161     : CSGGenBankDS(scope, id)
00162     , m_IsChromosome(true)
00163 {}
00164 
00165 
00166 void CSGSegmentMapDS::LoadSegmentMap(const TSeqRange& range,
00167                                   int cutoff, TJobToken token)
00168 {
00169     CRef<CSGSegmentMapJob> job(
00170         new CSGSegmentMapJob("SegmentMap", m_Handle,
00171         range, m_Depth, cutoff, token));
00172     x_LaunchJob(*job);
00173 }
00174 
00175 
00176 void CSGSegmentMapDS::LoadSegmentSmear(const TSeqRange& range,
00177                                        TModelUnit scale)
00178 {
00179     CRef<CSGSegmentSmearJob> job(
00180         new CSGSegmentSmearJob("SegmentSmear",
00181         m_Handle, range, scale, m_Annot));
00182     x_LaunchJob(*job);
00183 }
00184 
00185 
00186 void CSGSegmentMapDS::LoadSegmentMapSeqIDs(CSeqGlyph::TObjects& objs,
00187                                         TJobToken token)
00188 {
00189     CRef<CSGSegmentsSeqIDJob> job(
00190         new CSGSegmentsSeqIDJob("Resolving component IDs",
00191         objs, GetScope(), token) );
00192     x_LaunchJob(*job);
00193 }
00194 
00195 
00196 void CSGSegmentMapDS::LoadSwitchPoints()
00197 {
00198     CRef<CSGSwitchPointJob> job(
00199         new CSGSwitchPointJob("Switch points", m_Handle) );
00200     x_LaunchJob(*job);
00201 }
00202 
00203 
00204 int CSGSegmentMapDS::GetSegmentMapLevels(const TSeqRange& range) const
00205 {
00206     return CSGSegmentMapJob::GetSegmentMapLevels(m_Handle, range);
00207 }
00208 
00209 
00210 bool CSGSegmentMapDS::HasSegmentMap(int level, const TSeqRange& range) const
00211 {
00212     return CSGSegmentMapJob::HasSegmentMap(m_Handle, level, range);
00213 }
00214 
00215 
00216 bool CSGSegmentMapDS::HasComponent(const TSeqRange& range) const
00217 {
00218     int level = IsChromosome() ? 1 : 0;
00219     return HasSegmentMap(level, range);
00220 }
00221 
00222 
00223 bool CSGSegmentMapDS::HasScaffold(const TSeqRange& range) const
00224 {
00225     if (IsChromosome()) {
00226         return HasSegmentMap(0, range);
00227     }
00228 
00229     return false;
00230 }
00231 
00232 
00233 void CSGSegmentMapDS::GetAnnotNames(objects::SAnnotSelector& sel,
00234                                  const TSeqRange& range,
00235                                  TAnnotNameTitleMap& names) const
00236 {
00237     CSeqUtils::SetResolveDepth(sel, true, -1);
00238     CSGSegmentSmearJob::GetAnnotNames(m_Handle, range, sel, names);
00239 }
00240 
00241 
00242 void CSGSegmentMapDS::SetSegmentLevel(ESegmentLevel level)
00243 {
00244     int depth = x_ConceptualToRealDepth(level);
00245     SetDepth(depth);
00246 }
00247 
00248 
00249 int CSGSegmentMapDS::x_ConceptualToRealDepth(ESegmentLevel level) const
00250 {
00251     int depth = level;
00252     if ( !m_IsChromosome ) {
00253         if (level == eComponent) {
00254             depth = 0;
00255         } else if (level == eContig) {
00256             depth = -2; /// invalid
00257         }
00258     }
00259     return depth;
00260 }
00261 
00262 
00263 ///////////////////////////////////////////////////////////////////////////////
00264 /// CSGSegmentMapDSType implementation
00265 ///
00266 ISGDataSource*
00267 CSGSegmentMapDSType::CreateDS(SConstScopedObject& object) const
00268 {
00269     const CSeq_id& id = dynamic_cast<const CSeq_id&>(object.object.GetObject());
00270     return new CSGSegmentMapDS(object.scope.GetObject(), id);
00271 }
00272 
00273 
00274 string CSGSegmentMapDSType::GetExtensionIdentifier() const
00275 {
00276     static string sid("seqgraphic_segment_map_ds_type");
00277     return sid;
00278 }
00279 
00280 
00281 string CSGSegmentMapDSType::GetExtensionLabel() const
00282 {
00283     static string slabel("Graphical View Segment Map Data Source Type");
00284     return slabel;
00285 }
00286 
00287 
00288 bool CSGSegmentMapDSType::IsSharable() const
00289 {
00290     return false;
00291 }
00292 
00293 
00294 
00295 ///////////////////////////////////////////////////////////////////////////////
00296 /// CSGSegmentMapJob implementation
00297 ///
00298 CSGSegmentMapJob::CSGSegmentMapJob(const string& desc, CBioseq_Handle handle,
00299                                    const TSeqRange& range, int depth,
00300                                    int cutoff, TJobToken token)
00301     : CSeqGraphicJob(desc)
00302     , m_Handle(handle)
00303     , m_Range(range)
00304     , m_Depth(depth)
00305     , m_Cutoff(cutoff)
00306 {
00307     SetToken(token);
00308 }
00309 
00310 
00311 int CSGSegmentMapJob::GetSegmentMapLevels(const objects::CBioseq_Handle& handle,
00312                                           const TSeqRange& range)
00313 {
00314     SSeqMapSelector sel(CSeqMap::fFindAnyLeaf | CSeqMap::fFindExactLevel);
00315     int total_levels = 0;
00316     for (int level = 0;  level < 2;  ++level) {
00317         sel.SetResolveCount(level);
00318         TSeqPos start = range.GetFrom();
00319         TSeqPos stop = range.GetTo();
00320         TSeqPos step = 1000000;
00321         while (start <= stop) {
00322             TSeqRange r(start, min(start + step - 1, stop));
00323             start += step;
00324             CSeqMap::const_iterator seg(handle, sel, r);
00325             while (seg  &&  seg.GetType() != CSeqMap::eSeqRef) {
00326                 ++seg;
00327             }
00328             if (seg) {
00329                 ++total_levels;
00330                 break;
00331             }
00332         }
00333     }
00334     return total_levels;
00335 }
00336 
00337 
00338 bool CSGSegmentMapJob::HasSegmentMap(const objects::CBioseq_Handle& handle,
00339                                      int level, const TSeqRange& range)
00340 {
00341     int max_level = 3;
00342     SSeqMapSelector sel(CSeqMap::fFindAnyLeaf | CSeqMap::fFindExactLevel);
00343     level = min(level, max_level);
00344 
00345     int start_l = level;
00346     int end_l = level;
00347     if (level < 0) { 
00348         start_l = 0;
00349         end_l = max_level;
00350     }
00351 
00352     for (int l = start_l;  l <= end_l;  ++l) {
00353         sel.SetResolveCount(l);
00354         CSeqMap::const_iterator seg(handle, sel, range);
00355         while (seg  &&  seg.GetType() != CSeqMap::eSeqRef) {
00356             ++seg;
00357         }
00358         if (seg) return true;
00359     }
00360     return false;
00361 }
00362 
00363 
00364 IAppJob::EJobState CSGSegmentMapJob::x_Execute()
00365 {
00366     CSGJobResult* result = new CSGJobResult();
00367     m_Result.Reset(result);
00368     result->m_Token = m_Token;
00369 
00370     // -2 means we have already known there is no data for 
00371     // the given level.
00372     if (m_Depth == -2){
00373         return eCompleted;
00374     }
00375 
00376     bool over_limit = false;
00377     CSegmentGlyph::TSeqMapList seg_maps;
00378 
00379     CSeq_id_Handle target_sih = m_Handle.GetSeq_id_Handle();
00380     /*
00381     LOG_POST(Info << "CSGSegmentMapJob::x_Execute() started "
00382                   << " SeqId=" << target_sih.AsString()
00383                   << " Range.GetFrom()=" << m_Range.GetFrom()
00384                   << " Range.GetLength()=" << m_Range.GetLength()
00385                   << " Depth=" << m_Depth
00386              );
00387     */
00388 
00389     for (size_t levels = 0;  levels < 4;  ++levels) {
00390         SSeqMapSelector sel(CSeqMap::fFindAnyLeaf | CSeqMap::fFindExactLevel,
00391                             x_AdaptiveDepth() ? levels : m_Depth);
00392 
00393         seg_maps.clear();
00394 
00395         if (IsCanceled()) {
00396             return eCanceled;
00397         }
00398 
00399         /// determine how many segments we have here
00400         /// this determines if we should try to retrieve the skeletons
00401         size_t seg_count = 0;
00402 
00403         try {
00404             for (CSeqMap_CI seg(m_Handle, sel, m_Range);
00405                  seg  &&  seg.GetPosition() < m_Range.GetTo();
00406                  ++seg)
00407             {
00408                 if (IsCanceled()) {
00409                     return eCanceled;
00410                 }
00411 
00412                 if (seg.GetType() == CSeqMap::eSeqRef) {
00413                     ++seg_count;
00414                 }
00415                 if (seg.GetEndPosition() > m_Range.GetTo()) {
00416                     break;
00417                 }
00418                 if (m_Cutoff > 0  &&  seg_count > (size_t)m_Cutoff) {
00419                     over_limit = true;
00420                     break;
00421                 }
00422             }
00423 
00424             if (over_limit) break;
00425 
00426             // We set a limit on the number of components to retrieve
00427             // if more than 50 components are visible, the component overlaps will
00428             // not be displayed. If the component sequence already been in scope,
00429             // it will!
00430             bool fetch_sequences = (seg_count < 50);
00431 
00432             seg_count = 0;
00433             for (CSeqMap_CI seg(m_Handle, sel, m_Range);
00434                  seg  &&  seg.GetPosition() < m_Range.GetTo();
00435                  ++seg)
00436             {
00437                 if (IsCanceled()) {
00438                     return eCanceled;
00439                 }
00440 
00441                 if ( seg.GetType() == CSeqMap::eSeqRef ) {
00442                     ++seg_count;
00443                     CSeq_id_Handle sih = seg.GetRefSeqid();
00444 
00445                     /// these are the mapped coordinates - i.e., the chunk of
00446                     /// the main sequence (in main sequence coordinates)
00447                     /// represented by this piece
00448                     TSeqPos seg_from = seg.GetPosition();
00449                     TSeqPos seg_to   = seg.GetEndPosition() - 1;
00450 
00451                     /// these are the coordinates on the actual chunk
00452                     TSeqPos ref_from = seg.GetRefPosition();
00453                     TSeqPos ref_to   = seg.GetRefEndPosition() - 1;
00454 
00455 
00456 
00457                     CScope::EGetBioseqFlag flag = fetch_sequences ?
00458                                     CScope::eGetBioseq_All :
00459                                     CScope::eGetBioseq_Loaded;
00460 
00461                     CRef<CSegmentGlyph> seqmap;
00462                     CBioseq_Handle bsh = m_Handle.GetScope().GetBioseqHandle(sih, flag);
00463                     TSeqRange ref_r = TSeqRange(ref_from, ref_to);
00464                     TSeqRange seg_r = TSeqRange(seg_from, seg_to);
00465                     bool neg = seg.GetRefMinusStrand();
00466 
00467                     if (bsh) {
00468                         TSeqPos length = bsh.GetBioseqLength();
00469                         seqmap.Reset(new CSegmentGlyph(sih, ref_r, target_sih,
00470                                                        seg_r, neg, length));
00471                     } else {
00472                         seqmap.Reset(new CSegmentGlyph(sih, ref_r, target_sih,
00473                                                        seg_r, neg ));
00474                     }
00475 
00476                     //CRef<CSeqGlyph> ref;
00477                     //ref.Reset(seqmap.GetPointer());
00478                     seg_maps.push_back(seqmap);
00479                 }
00480                 if (seg.GetEndPosition() > m_Range.GetTo()) {
00481                     break;
00482                 }
00483             }
00484         }
00485         catch (CException& e) {
00486             LOG_POST(Info << "CSGSegmentMapJob::GetSeqMaps(): "
00487                      "exception in retrieval of seq-maps: " << e.GetMsg());
00488         }
00489 
00490         /// make sure we preserve the last state - it is possible we will
00491         /// get through our iteration and leave maps empty
00492         if (seg_maps.size()) {
00493             CSeqGlyph::TObjects tmp;
00494             EJobState state = x_MergeSeqSegments(seg_maps, tmp);
00495             if (state != eCompleted) {
00496                 return state;
00497             }
00498             result->m_ObjectList.swap(tmp);
00499         }
00500 
00501         if (result->Size() > 1  ||
00502             (m_Range.GetLength() >= 1000000  &&  result->Size() > 0)) {
00503             break;
00504         }
00505 
00506         if (!x_AdaptiveDepth()) {
00507             break;
00508         }
00509     }
00510 
00511     if (over_limit  &&  result->m_ObjectList.empty()) {
00512         string msg = "There are more than ";
00513         msg += NStr::IntToString(m_Cutoff);
00514         msg += " segments for the given range. Segment map is not shown at this zooming level!";
00515         TModelUnit x = (m_Range.GetFrom() + m_Range.GetTo() ) * 0.5;
00516         CRef<CSeqGlyph> message_glyph(
00517             new CCommentGlyph(msg, TModelPoint(x, 0.0)));
00518         result->m_ObjectList.push_back(message_glyph);
00519     }
00520     //::wxWakeUpIdle();
00521     return eCompleted;
00522 }
00523 
00524 
00525 IAppJob::EJobState
00526 CSGSegmentMapJob::x_MergeSeqSegments(CSegmentGlyph::TSeqMapList& seg_maps,
00527                                      CSeqGlyph::TObjects& objs)
00528 {
00529     CSeqGlyph::TObjects merged;
00530     typedef pair<const TSeqRange, CRef<CSegmentGlyph> > TSegMapPair;
00531     typedef multimap<const TSeqRange, CRef<CSegmentGlyph> > TSegMapMap;
00532     TSegMapMap merge_map;
00533     set <TSeqRange> map_keys;
00534 
00535     // first, build out structure
00536     ITERATE(CSegmentGlyph::TSeqMapList, iter, seg_maps) {
00537         if (IsCanceled()) {
00538             return eCanceled;
00539         }
00540 
00541         CRef<CSegmentGlyph> segmap = *iter;
00542         const TSeqRange& range = segmap->GetLocation().GetTotalRange();
00543 
00544         merge_map.insert( TSegMapPair(range, segmap) );  // values
00545         map_keys.insert( range );  // keys (ranges)
00546     }
00547 
00548     // do the merger
00549     ITERATE(set <TSeqRange>, iter, map_keys) {
00550         if (IsCanceled()) {
00551             return eCanceled;
00552         }
00553 
00554         pair<TSegMapMap::iterator, TSegMapMap::iterator> the_bounds;
00555         the_bounds = merge_map.equal_range(*iter);
00556 
00557         CRef<CSegmentGlyph> ref;  // resulting map
00558         set<TSeqRange> comp_range;  // accumulated ranges
00559         set<TSeqRange> mapped_range;
00560         for (TSegMapMap::iterator it = the_bounds.first;
00561              it != the_bounds.second; it++)
00562         {
00563             TSegMapPair pair = *it;
00564             CRef<CSegmentGlyph> segmap = pair.second;
00565 
00566             ITERATE (set<TSeqRange>, cr_it, segmap->GetComponentRanges())
00567                 comp_range.insert(*cr_it);
00568 
00569             ITERATE (set<TSeqRange>, mr_it, segmap->GetMappedRanges())
00570                 mapped_range.insert(*mr_it);
00571 
00572             if (ref.Empty())
00573                 ref.Reset(pair.second.GetPointer());
00574         }
00575 
00576         ref->SetComponentRanges(comp_range);
00577         ref->SetMappedRanges(mapped_range);
00578 
00579         CRef<CSeqGlyph> obj_ref;
00580         obj_ref.Reset(ref.GetPointer());
00581         objs.push_back(obj_ref);
00582     }
00583     return eCompleted;
00584 }
00585 
00586 
00587 
00588 /// utility function
00589 CSegmentConfig::ESequenceQuality SGetSeqQuality(CMolInfo_Base::TTech tech)
00590 {
00591     switch (tech) {
00592         case CMolInfo::eTech_htgs_1:
00593         case CMolInfo::eTech_htgs_2:
00594             return CSegmentConfig::eDraft;
00595         case CMolInfo::eTech_htgs_3:
00596             return CSegmentConfig::eFinished;
00597         case CMolInfo::eTech_wgs:
00598             return CSegmentConfig::eWgs;
00599         default:
00600             return CSegmentConfig::eOther;
00601     }
00602 }
00603 
00604 ///////////////////////////////////////////////////////////////////////////////
00605 /// CSGSegmentSmearJob implementation
00606 ///
00607 CSGSegmentSmearJob::CSGSegmentSmearJob(const string& desc,
00608                                        objects::CBioseq_Handle handle,
00609                                        const TSeqRange& range,
00610                                        TModelUnit scale,
00611                                        const string& annot)
00612     : CSGAnnotJob(desc, handle,
00613         CSeqUtils::GetAnnotSelector(CSeq_annot::C_Data::e_Seq_table), range)
00614     , m_Scale(scale)
00615     , m_Annot(annot)
00616 {
00617     SetTaskName("Loading segment map...");
00618     if ( !m_Annot.empty() ) {
00619         m_Sel.AddNamedAnnots(m_Annot);
00620         m_Sel.IncludeNamedAnnotAccession(m_Annot);
00621     }
00622 }
00623 
00624 
00625 void CSGSegmentSmearJob::GetAnnotNames(const objects::CBioseq_Handle& handle,
00626                                        const TSeqRange& /*range*/,
00627                                        objects::SAnnotSelector& sel,
00628                                        TAnnotNameTitleMap& annots)
00629 {
00630     CAnnotTypes_CI annot_it(CSeq_annot::C_Data::e_Seq_table, handle,
00631         TSeqRange::GetWhole(), eNa_strand_unknown, &sel);
00632     ITERATE (CAnnotTypes_CI::TAnnotNames, iter, annot_it.GetAnnotNames()) {
00633         if (iter->IsNamed()) {
00634             if (iter->GetName().find("@@") == string::npos) {
00635                 annots.insert(TAnnotNameTitleMap::value_type(iter->GetName(), ""));
00636             }
00637         } else {
00638             annots.insert(TAnnotNameTitleMap::value_type(
00639                 CSeqUtils::GetUnnamedAnnot(), ""));
00640         }
00641     }
00642 }
00643 
00644 
00645 IAppJob::EJobState CSGSegmentSmearJob::x_Execute()
00646 {
00647     if (m_Annot.empty()) {
00648         // brute force, load data from delta seqs
00649         return x_LoadFromDeltaSeqs();
00650     }
00651     return x_LoadFromNA();
00652 }
00653 
00654 
00655 IAppJob::EJobState CSGSegmentSmearJob::x_LoadFromDeltaSeqs()
00656 {
00657     CSGJobResult* result = new CSGJobResult();
00658     m_Result.Reset(result);
00659     typedef CSegmentSmearGlyph::TValueType TValType;
00660 
00661     bool is_chromosome =
00662         CSGUtils::IsChromosome(m_Handle, m_Handle.GetScope());;
00663     int depth = is_chromosome ? 1 : 0;
00664     CSeq_id_Handle target_sih = m_Handle.GetSeq_id_Handle();
00665 
00666     auto_ptr<CSegmentSmearGlyph::TSegMap>
00667         the_map(new CSegmentSmearGlyph::TSegMap(
00668             m_Range.GetFrom(), m_Range.GetTo(),
00669             (float)m_Scale, new max_func<TValType>));
00670 
00671     TSeqPos pre_to = m_Range.GetFrom();
00672     TValType gap_val = (TValType)CSegmentConfig::eGap;
00673     SSeqMapSelector sel(CSeqMap::fFindAnyLeaf | CSeqMap::fFindExactLevel, depth);
00674     for (CSeqMap_CI seg(m_Handle, sel, m_Range);
00675         seg  &&  seg.GetPosition() < m_Range.GetTo();
00676         ++seg)
00677     {
00678         if (IsCanceled()) {
00679             return eCanceled;
00680         }
00681 
00682         if ( seg.GetType() == CSeqMap::eSeqRef ) {
00683             CSeq_id_Handle sih = seg.GetRefSeqid();
00684 
00685             /// these are the mapped coordinates
00686             TSeqPos seg_from = seg.GetPosition();
00687             TSeqPos seg_to   = seg.GetEndPosition() - 1;
00688 
00689             if (pre_to < seg_from) {
00690                 the_map->AddRange(TSeqRange(pre_to, seg_from - 1), gap_val, false);
00691             }
00692 
00693             CSegmentConfig::ESequenceQuality qual = CSegmentConfig::eOther;
00694             CBioseq_Handle bsh = m_Handle.GetScope().GetBioseqHandle(sih);
00695             if (bsh  &&  bsh.CanGetInst_Mol()) {
00696                 CSeqdesc_CI di (bsh, CSeqdesc::e_Molinfo);
00697                 if (di  &&  di->GetMolinfo().IsSetTech()) {
00698                     qual = SGetSeqQuality(di->GetMolinfo().GetTech());
00699                 }
00700             }
00701 
00702             the_map->AddRange(TSeqRange(seg_from, seg_to), (TValType)(qual), false);
00703             pre_to = seg_to + 1;
00704         }
00705         if (seg.GetEndPosition() > m_Range.GetTo()) {
00706             break;
00707         }
00708     }
00709     if (pre_to < m_Range.GetTo()) {
00710         the_map->AddRange(TSeqRange(pre_to, m_Range.GetTo()), gap_val, false);
00711     }
00712 
00713     CRef<CSeqGlyph> glyph(new CSegmentSmearGlyph(the_map));
00714     result->m_ObjectList.push_back(glyph);
00715         
00716     return eCompleted;
00717 }
00718 
00719 
00720 IAppJob::EJobState CSGSegmentSmearJob::x_LoadFromNA()
00721 {
00722     CSGJobResult* result = new CSGJobResult();
00723     m_Result.Reset(result);
00724 
00725     typedef CSegmentSmearGlyph::TValueType TValType;
00726     CConstRef<CSeq_loc> loc =
00727         m_Handle.GetRangeSeq_loc(m_Range.GetFrom(), m_Range.GetTo());
00728     CAnnot_CI it(m_Handle.GetScope(), *loc, m_Sel);
00729 
00730     if (it) {
00731         TSeqPos r_from = m_Range.GetFrom();
00732         TSeqPos r_to = m_Range.GetTo();
00733 
00734         auto_ptr<CSegmentSmearGlyph::TSegMap> the_map(
00735             new CSegmentSmearGlyph::TSegMap(r_from, r_to, (float)m_Scale,
00736                                             new max_func<TValType>));
00737         CTableFieldHandle<int> col_from(CSeqTable_column_info::eField_id_location_from);
00738         CTableFieldHandle<int> col_to(CSeqTable_column_info::eField_id_location_to);
00739         CTableFieldHandle<int> col_tech("data");
00740         for (; it; ++it) {
00741             CSeq_annot_Handle annot = *it;
00742             size_t rows = annot.GetSeq_tableNumRows();
00743 
00744             int from = 0;
00745             int to = 0;
00746 
00747             col_to.TryGet(annot, rows - 1, to);
00748             if ((TSeqPos)to < r_from) {
00749                 continue;
00750             }
00751 
00752             col_from.TryGet(annot, 0, from);
00753             if (r_to < (TSeqPos)from) break;
00754 
00755             // for case that 'is_gap' column is stored as bit
00756             const CSeq_table::TColumns& cols =
00757                 annot.GetCompleteSeq_annot()->GetData().GetSeq_table().GetColumns();
00758             const CSeqTable_column* col_gap = NULL;
00759             ITERATE (CSeq_table::TColumns, iter, cols) {
00760                 if ((*iter)->GetHeader().CanGetField_name()  &&
00761                     (*iter)->GetHeader().GetField_name() == "is_gap") {
00762                     col_gap = iter->GetPointer();
00763                     break;
00764                 }
00765             }
00766             if ( !col_gap ) return eFailed;
00767 
00768             // for case that 'is_gap' column is stored as types
00769             //vector<char> is_gaps;
00770             //CTableFieldHandle<int> col_gap("is_gap");
00771             //if ( !col_gap.TryGet(annot, 0, is_gaps) ) return eFailed;
00772 
00773             // find the start row
00774             int row = 0;
00775             int value = 0;
00776             int r_start = 0;
00777             int r_end = rows - 1;
00778             bool is_gap = true;
00779             do {
00780                 row = (r_start + r_end) / 2;
00781                 col_from.TryGet(annot, row, from);
00782                 if ((TSeqPos)from < r_from )  r_start = row;
00783                 else                          r_end = row;
00784             } while ((TSeqPos)from != r_from  &&  r_start < r_end - 1);
00785 
00786 
00787             for (row = (r_start + r_end) / 2;  (size_t)row < rows;  ++row) {
00788                 if (col_from.TryGet(annot, row, from)  &&
00789                     col_to.TryGet(annot, row, to)  &&
00790                     col_tech.TryGet(annot, row, value) &&
00791                     col_gap->TryGetBool(row, is_gap)) {
00792                         if ((TSeqPos)from > r_to) break;
00793                         CSegmentConfig::ESequenceQuality qual = CSegmentConfig::eGap;
00794                         //if ( !is_gaps[row] > 0 ) {
00795                         if ( !is_gap ) {
00796                             qual = SGetSeqQuality((CMolInfo_Base::TTech)value);
00797                         }
00798                         the_map->AddRange(TSeqRange(from, to), (TValType)qual, false);
00799                 }
00800             }
00801         }
00802 
00803         CRef<CSeqGlyph> hist(new CSegmentSmearGlyph(the_map));
00804         result->m_ObjectList.push_back(hist);
00805     }
00806 
00807     return eCompleted;
00808 }
00809 
00810 
00811 ///////////////////////////////////////////////////////////////////////////////
00812 /// CSGSegmentsSeqIDJob implementation
00813 ///
00814 CSGSegmentsSeqIDJob::CSGSegmentsSeqIDJob(const string& desc,
00815                                          CSeqGlyph::TObjects& objs,
00816                                          objects::CScope& scope,
00817                                          TJobToken token)
00818     : CSeqGraphicJob(desc)
00819     , m_Objs(objs)
00820     , m_Scope(scope)
00821 {
00822     SetToken(token);
00823     SetTaskName("Resolving component seq-ids...");
00824 }
00825 
00826 
00827 IAppJob::EJobState CSGSegmentsSeqIDJob::x_Execute()
00828 {
00829     CJobResultBase* result = new CJobResultBase();
00830     m_Result.Reset(result);
00831     result->m_Token = m_Token;
00832     SetTaskTotal(m_Objs.size());
00833     SetTaskCompleted(0);
00834     ITERATE (CSeqGlyph::TObjects, iter, m_Objs) {
00835         if (IsCanceled()) {
00836             return eCanceled;
00837         }
00838 
00839         CSeqGlyph* obj = const_cast<CSeqGlyph*>(iter->GetPointer());
00840         CSegmentGlyph* seq_map = dynamic_cast<CSegmentGlyph*>(obj);
00841         if ( !seq_map ) {
00842             return eFailed;
00843         }
00844         const CSeq_id* seq_id = seq_map->GetLocation().GetId();
00845         CBioseq_Handle bsh = m_Scope.GetBioseqHandle(*seq_id);
00846         if (bsh  &&  bsh.CanGetInst_Mol()) {
00847             CSeqdesc_CI di (bsh, CSeqdesc::e_Molinfo);
00848             if (di  &&  di->GetMolinfo().IsSetTech()) {
00849                 seq_map->SetSeqQuality(SGetSeqQuality(di->GetMolinfo().GetTech()));
00850             }
00851         }
00852         AddTaskCompleted(1);
00853     }
00854     return eCompleted;
00855 }
00856 
00857 
00858 ///////////////////////////////////////////////////////////////////////////////
00859 /// CSGSwitchPointJob implementation
00860 ///
00861 
00862 CSGSwitchPointJob::CSGSwitchPointJob(const string& desc, CBioseq_Handle handle)
00863     : CSeqGraphicJob(desc)
00864     , m_Handle(handle)
00865 {}
00866 
00867 IAppJob::EJobState CSGSwitchPointJob::x_Execute()
00868 {
00869     CSGJobResult* result = new CSGJobResult();
00870     m_Result.Reset(result);
00871 
00872     CSeqGlyph::TObjects all_objs;
00873 
00874     CConstRef<CBioseq> bioseq = m_Handle.GetCompleteBioseq();
00875     if ( !bioseq->IsSetInst() )
00876         return eFailed;
00877 
00878     const CBioseq::TInst& inst = bioseq->GetInst();
00879     if ( !inst.IsSetHist() )
00880         return eFailed;
00881 
00882     const CSeq_hist& hist = inst.GetHist();
00883     if ( !hist.IsSetAssembly() )
00884         return eFailed;
00885 
00886     const CSeq_hist::TAssembly& assm = hist.GetAssembly();
00887     if (assm.empty()) // do nothing if no assembly at all
00888         return eFailed;
00889 
00890     TSeqMapSwitchPoints spoints = GetAllSwitchPoints(m_Handle);
00891     ITERATE(TSeqMapSwitchPoints, iter, spoints) {
00892         if (IsCanceled()) {
00893             return eCanceled;
00894         }
00895 
00896         CRef<CSeqMapSwitchPoint> one_point = *iter;
00897 
00898         CRef<CSeqGlyph> sp(new CSwitchPointGlyph(one_point));
00899         all_objs.push_back(sp);
00900     }  // ITERATE
00901 
00902     result->m_ObjectList.swap(all_objs);
00903     result->m_Token = m_Token;
00904     return eCompleted;
00905 }
00906 
00907 
00908 
00909 END_NCBI_SCOPE
Modified on Sat Jul 12 17:03:24 2014 by modify_doxy.py rev. 426318