seq_map.cpp

来自「ncbi源码」· C++ 代码 · 共 1,029 行 · 第 1/3 页

CPP
1,029
字号
/* * =========================================================================== * PRODUCTION $Log: seq_map.cpp,v $ * PRODUCTION Revision 1000.4  2004/06/01 19:24:15  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.53 * PRODUCTION * =========================================================================== *//*  $Id: seq_map.cpp,v 1000.4 2004/06/01 19:24:15 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: Aleksey Grichenko, Michael Kimelman, Eugene Vasilchenko,*          Andrei Gourianov** File Description:*   Sequence map for the Object Manager. Describes sequence as a set of*   segments of different types (data, reference, gap or end).**/#include <ncbi_pch.hpp>#include <objmgr/seq_map.hpp>#include <objmgr/seq_map_ci.hpp>#include <objmgr/seq_map_ext.hpp>#include <objmgr/seq_id_mapper.hpp>#include <objmgr/scope.hpp>#include <objmgr/bioseq_handle.hpp>#include <objects/seq/Bioseq.hpp>#include <objects/seq/Seq_data.hpp>#include <objects/seq/Seq_inst.hpp>#include <objects/seq/Delta_ext.hpp>#include <objects/seq/Delta_seq.hpp>#include <objects/seq/Seq_literal.hpp>#include <objects/seq/Seq_ext.hpp>#include <objects/seq/Seg_ext.hpp>#include <objects/seq/Ref_ext.hpp>#include <objects/seqloc/Seq_loc.hpp>#include <objects/seqloc/Seq_point.hpp>#include <objects/seqloc/Seq_loc_mix.hpp>#include <objects/seqloc/Seq_loc_equiv.hpp>#include <objects/seqloc/Seq_interval.hpp>#include <objects/seqloc/Packed_seqint.hpp>#include <objects/seqloc/Packed_seqpnt.hpp>#include <algorithm>BEGIN_NCBI_SCOPEBEGIN_SCOPE(objects)//////////////////////////////////////////////////////////////////////  CSeqMap::CSegmentinlineCSeqMap::CSegment::CSegment(ESegmentType seg_type,                            TSeqPos length)    : m_Position(kInvalidSeqPos),      m_Length(length),      m_SegType(seg_type),      m_RefMinusStrand(false),      m_RefPosition(0){}//////////////////////////////////////////////////////////////////////  CSeqMapCSeqMap::CSeqMap(void)    : m_Resolved(0),      m_Mol(CSeq_inst::eMol_not_set),      m_SeqLength(kInvalidSeqPos){}CSeqMap::CSeqMap(CSeqMap* /*parent*/, size_t /*index*/)    : m_Resolved(0),      m_Mol(CSeq_inst::eMol_not_set),      m_SeqLength(kInvalidSeqPos){}CSeqMap::CSeqMap(const CSeq_loc& ref)    : m_Resolved(0),      m_Mol(CSeq_inst::eMol_not_set),      m_SeqLength(kInvalidSeqPos){    x_AddEnd();    x_Add(ref);    x_AddEnd();}CSeqMap::CSeqMap(const CSeq_data& data, TSeqPos length)    : m_Resolved(0),      m_Mol(CSeq_inst::eMol_not_set),      m_SeqLength(kInvalidSeqPos){    x_AddEnd();    x_Add(data, length);    x_AddEnd();}CSeqMap::CSeqMap(TSeqPos length)    : m_Resolved(0),      m_Mol(CSeq_inst::eMol_not_set),      m_SeqLength(length){    x_AddEnd();    x_AddGap(length);    x_AddEnd();}CSeqMap::~CSeqMap(void){    m_Resolved = 0;    m_Segments.clear();}void CSeqMap::x_GetSegmentException(size_t /*index*/) const{    NCBI_THROW(CSeqMapException, eInvalidIndex,               "Invalid segment index");}CSeqMap::CSegment& CSeqMap::x_SetSegment(size_t index){    if ( index >= x_GetSegmentsCount() ) {        NCBI_THROW(CSeqMapException, eInvalidIndex,                   "Invalid segment index");    }    return m_Segments[index];}CBioseq_Handle CSeqMap::x_GetBioseqHandle(const CSegment& seg, CScope* scope) const{    if ( !scope ) {        NCBI_THROW(CSeqMapException, eNullPointer,                   "Null scope pointer");    }    CBioseq_Handle bh = scope->GetBioseqHandle(x_GetRefSeqid(seg));    if ( !bh ) {        NCBI_THROW(CSeqMapException, eFail,                   "Cannot resolve reference");    }    return bh;}TSeqPos CSeqMap::x_ResolveSegmentLength(size_t index, CScope* scope) const{    const CSegment& seg = x_GetSegment(index);    TSeqPos length = seg.m_Length;    if ( length == kInvalidSeqPos ) {        if ( seg.m_SegType == eSeqSubMap ) {            length = x_GetSubSeqMap(seg, scope)->GetLength(scope);        }        else if ( seg.m_SegType == eSeqRef ) {            length = x_GetBioseqHandle(seg, scope).GetBioseqLength();        }        _ASSERT(length != kInvalidSeqPos);        seg.m_Length = length;    }    return length;}TSeqPos CSeqMap::x_ResolveSegmentPosition(size_t index, CScope* scope) const{    if ( index > x_GetSegmentsCount() ) {        NCBI_THROW(CSeqMapException, eInvalidIndex,                   "Invalid segment index");    }    size_t resolved = m_Resolved;    if ( index <= resolved )        return x_GetSegment(index).m_Position;    TSeqPos resolved_pos = x_GetSegment(resolved).m_Position;    do {        resolved_pos += x_GetSegmentLength(resolved, scope);        m_Segments[++resolved].m_Position = resolved_pos;    } while ( resolved < index );    {{        CFastMutexGuard guard(m_SeqMap_Mtx);        if ( m_Resolved < resolved )            m_Resolved = resolved;    }}    return resolved_pos;}size_t CSeqMap::x_FindSegment(TSeqPos pos, CScope* scope) const{    size_t resolved = m_Resolved;    TSeqPos resolved_pos = x_GetSegment(resolved).m_Position;    if ( resolved_pos <= pos ) {        do {            if ( resolved >= x_GetSegmentsCount() ) {                // end of segments                m_Resolved = resolved;                return size_t(-1);            }            resolved_pos += x_GetSegmentLength(resolved, scope);            m_Segments[++resolved].m_Position = resolved_pos;        } while ( resolved_pos <= pos );        {{            CFastMutexGuard guard(m_SeqMap_Mtx);            if ( m_Resolved < resolved )                m_Resolved = resolved;        }}        return resolved - 1;    }    else {        TSegments::const_iterator end = m_Segments.begin()+resolved;        TSegments::const_iterator it =             upper_bound(m_Segments.begin(), end,                        pos, SPosLessSegment());        if ( it == end ) {            return size_t(-1);        }        return it - m_Segments.begin();    }}void CSeqMap::x_LoadObject(const CSegment& seg) const{    _ASSERT(seg.m_Position != kInvalidSeqPos);    if ( !seg.m_RefObject ) {        NCBI_THROW(CSeqMapException, eFail, "Cannot load part of seqmap");    }}CConstRef<CSeqMap> CSeqMap::x_GetSubSeqMap(const CSegment& seg, CScope* scope,                                           bool resolveExternal) const{    CConstRef<CSeqMap> ret;    if ( seg.m_SegType == eSeqSubMap ) {        if ( !seg.m_RefObject ) {            x_LoadObject(seg);        }        if ( !seg.m_RefObject ) {        NCBI_THROW(CSeqMapException, eNullPointer, "Null CSeqMap pointer");        }        ret.Reset(static_cast<const CSeqMap*>(seg.m_RefObject.GetPointer()));    }    else if ( resolveExternal && seg.m_SegType == eSeqRef ) {        ret.Reset(&x_GetBioseqHandle(seg, scope).GetSeqMap());    }    return ret;}void CSeqMap::x_SetSubSeqMap(size_t /*index*/, CSeqMap_Delta_seqs* /*subMap*/){    // not valid in generic seq map -> incompatible objects    NCBI_THROW(CSeqMapException, eDataError, "Invalid parent map");}const CSeq_data& CSeqMap::x_GetSeq_data(const CSegment& seg) const{    if ( seg.m_SegType == eSeqData ) {        if ( !seg.m_RefObject ) {            x_LoadObject(seg);        }        if ( !seg.m_RefObject ) {            NCBI_THROW(CSeqMapException, eNullPointer,                       "Null CSeq_data pointer");        }        return *static_cast<const CSeq_data*>(seg.m_RefObject.GetPointer());    }    NCBI_THROW(CSeqMapException, eSegmentTypeError,               "Invalid segment type");}void CSeqMap::x_SetSeq_data(size_t index, CSeq_data& data){    // check segment type    CSegment& seg = x_SetSegment(index);    if ( seg.m_SegType != eSeqData ) {        NCBI_THROW(CSeqMapException, eSegmentTypeError,                   "Invalid segment type");    }    // lock for object modification    CFastMutexGuard guard(m_SeqMap_Mtx);    // check for object    if ( seg.m_RefObject ) {        NCBI_THROW(CSeqMapException, eDataError, "CSeq_data already set");    }    // set object    seg.m_RefObject.Reset(&data);}const CSeq_id& CSeqMap::x_GetRefSeqid(const CSegment& seg) const{    if ( seg.m_SegType == eSeqRef ) {        if ( !seg.m_RefObject ) {            NCBI_THROW(CSeqMapException, eNullPointer, "Null CSeq_id pointer");        }        return static_cast<const CSeq_id&>(*seg.m_RefObject);    }    NCBI_THROW(CSeqMapException, eSegmentTypeError,               "Invalid segment type");}TSeqPos CSeqMap::x_GetRefPosition(const CSegment& seg) const{    return seg.m_RefPosition;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?