diff --git a/modules/seq/base/pymod/export_sequence.cc b/modules/seq/base/pymod/export_sequence.cc index 1c48ec3279da13605f4eeb58ade58b824b9eb7e1..ce9d50ad2e7bca497a6c163a4e708ed3fd41ff9b 100644 --- a/modules/seq/base/pymod/export_sequence.cc +++ b/modules/seq/base/pymod/export_sequence.cc @@ -161,6 +161,8 @@ void export_sequence() .def("GetSequences", &AlignmentHandle::GetSequences) .def("AttachView", attach_view_a) .def("AttachView", attach_view_b) + .def("Cut", &AlignmentHandle::Cut) + .def("Replace",&AlignmentHandle::Replace) .def("__getitem__", &slice_aln) .def("__getitem__", &AlignmentHandle::operator[]) .def("__iter__", iterator<AlignmentHandle>()) @@ -174,6 +176,7 @@ void export_sequence() ; class_<AlignedRegion>("AlignedRegion", no_init) .def("Delete", &AlignedRegion::Delete) + .def("Replace", &AlignedRegion::Replace) .def("ShiftLeft", &AlignedRegion::ShiftLeft) .def("ShiftRight", &AlignedRegion::ShiftRight) .def("GetStart", &AlignedRegion::GetStart) @@ -181,6 +184,7 @@ void export_sequence() .def("GetLength", &AlignedRegion::GetLength) .def("SetMaster", &AlignedRegion::SetMaster) .def("GetMaster", &AlignedRegion::GetMaster) + .def("GetAlignmentHandle",&AlignedRegion::GetAlignmentHandle) .add_property("master", &AlignedRegion::GetMaster, &AlignedRegion::SetMaster) .def("__getitem__", &AlignedRegion::operator[]) diff --git a/modules/seq/base/src/aligned_region.cc b/modules/seq/base/src/aligned_region.cc index 151e1441a1b207c087aea0b4f9ccdaff610179c8..decb966ef0533f5c9d0a1383d4f8ccb2f1ce36e4 100644 --- a/modules/seq/base/src/aligned_region.cc +++ b/modules/seq/base/src/aligned_region.cc @@ -50,6 +50,11 @@ void AlignedRegion::Delete() end_=start_; } +void AlignedRegion::Replace(const AlignedRegion& aln_r) +{ + aln_.Replace(aln_r,start_, end_); + end_=start_+end_; +} void AlignedRegion::ShiftLeft(int n) { @@ -118,4 +123,9 @@ int AlignedRegion::GetLength() const return end_-start_; } +AlignmentHandle AlignedRegion::GetAlignmentHandle() const +{ + return aln_; +} + }} diff --git a/modules/seq/base/src/aligned_region.hh b/modules/seq/base/src/aligned_region.hh index 9590be824bf40b606625bc7a2e4a221612bb61fd..cfd6f757d485b72eb25c62c126cdd3039795f23c 100644 --- a/modules/seq/base/src/aligned_region.hh +++ b/modules/seq/base/src/aligned_region.hh @@ -47,9 +47,10 @@ public: int GetStart() const; int GetMaster() const; void SetMaster(int master); - /// \brief delete interval + /// \brief delete interval and update length of AlignedRegion void Delete(); - + ///\brief replace region with content of AlignedRegion and set length to length of \p aln_r + void Replace(const AlignedRegion& aln_r); /// \brief shift the aligned region of the master sequence to the left by /// n characters. void ShiftLeft(int n); @@ -64,6 +65,9 @@ public: /// \sa AlignmentHandle::GetLength() int GetLength() const; + ///\brief retrieve alignment handle for aligned region + AlignmentHandle GetAlignmentHandle() const; + /// \brief get aligned column at given index /// /// The indices range from 0 to GetLength()-1. diff --git a/modules/seq/base/src/alignment_handle.cc b/modules/seq/base/src/alignment_handle.cc index 7f23a937896d1b7a4e4993d7ffdf2b72a2891252..6d6d5bb63489b1e4463199081f34825850ea34c0 100644 --- a/modules/seq/base/src/alignment_handle.cc +++ b/modules/seq/base/src/alignment_handle.cc @@ -23,9 +23,11 @@ #include <ost/invalid_handle.hh> #include <ost/seq/alignment_handle.hh> #include <ost/seq/impl/sequence_list_impl.hh> +#include <ost/seq/impl/sequence_impl.hh> #include <ost/seq/sequence_list.hh> #include <ost/seq/aligned_region.hh> #include <ost/seq/aligned_column_iterator.hh> +#include <ost/integrity_error.hh> namespace ost { namespace seq { @@ -47,24 +49,24 @@ AlignmentHandle::AlignmentHandle(const impl::SequenceListImplPtr& impl): int AlignmentHandle::GetPos(int seq_index, int residue_index) const { this->CheckValidity(); - return impl_->GetPos(seq_index, residue_index); + return impl_->GetPos(seq_index, residue_index); } int AlignmentHandle::GetResidueIndex(int seq_index, int pos) const { this->CheckValidity(); - return impl_->GetResidueIndex(seq_index, pos); + return impl_->GetResidueIndex(seq_index, pos); } void AlignmentHandle::AddSequence(const ConstSequenceHandle& sequence) { - this->CheckValidity(); + this->CheckValidity(); if (impl_->GetCount()>0 && impl_->GetSequence(0)->GetLength()!=sequence.GetLength()) { - throw InvalidAlignment(); + throw InvalidAlignment(); } - return impl_->AddSequence(sequence.Impl()); + return impl_->AddSequence(sequence.Impl()); } ConstSequenceHandle AlignmentHandle::GetSequence(int seq_id) const @@ -77,7 +79,7 @@ ConstSequenceHandle AlignmentHandle::GetSequence(int seq_id) const String AlignmentHandle::ToString(int width) const { this->CheckValidity(); - return impl_->ToString(width); + return impl_->ToString(width); } int AlignmentHandle::GetLength() const @@ -163,7 +165,23 @@ void AlignmentHandle::Cut(int start, int end) (*i)->Cut(start, end-start); } } - + +void AlignmentHandle::Replace(const AlignedRegion& aln_r, int start, int end){ + this->CheckValidity(); + //check that alignment handle and aligned region contain same number of sequences + if (impl_->GetCount() != aln_r.GetAlignmentHandle().GetCount()) { + throw IntegrityError("alignment handle and aligned region are required "\ + "to share the same number of sequences"); + } + int aln_rStart=aln_r.GetStart(); + int aln_rEnd=aln_r.GetEnd(); + AlignmentHandle aln=aln_r.GetAlignmentHandle(); + //iterate over sequences and replace part of sequences with the substrings + //from aligned region + for (int i=0;i<impl_->GetCount() ;++i) { + this->GetSequence(i).Impl()->Replace(aln.GetSequence(i).GetString().substr(aln_rStart,aln_rEnd), start, end); + } +} void AlignmentHandle::ShiftRegion(int start, int end, int amount, int master) diff --git a/modules/seq/base/src/alignment_handle.hh b/modules/seq/base/src/alignment_handle.hh index 1dde2b25fa625b578eddd878ac278f9f98489f01..893ec4cf86a0ad6d02bccbe74ee2b4908c7bd4ff 100644 --- a/modules/seq/base/src/alignment_handle.hh +++ b/modules/seq/base/src/alignment_handle.hh @@ -138,6 +138,8 @@ public: /// \brief cut out half-closed interval start, end void Cut(int start, int end); + ///\brief Replace part of an alignment + void Replace(const AlignedRegion& rhs, int start, int end); /// \brief shift half-closed interval by amount /// /// if master is -1, all sequences of the alignment will be shifted. Otherwise diff --git a/modules/seq/base/src/impl/sequence_impl.cc b/modules/seq/base/src/impl/sequence_impl.cc index 97d2b223e2a543a4f069cfb60b983dde9e793484..69fd3f42f4d3cd3b377f2991e282ff27d86ba116 100644 --- a/modules/seq/base/src/impl/sequence_impl.cc +++ b/modules/seq/base/src/impl/sequence_impl.cc @@ -265,6 +265,12 @@ void SequenceImpl::Cut(int start, int n) this->ShiftsFromSequence(); } +void SequenceImpl::Replace(const String& str,int start, int end) +{ + seq_string_.replace(start, end-start, str); + this->ShiftsFromSequence(); +} + void SequenceImpl::ShiftRegion(int start, int end, int amount) { String str1=seq_string_.substr(start, end-start); diff --git a/modules/seq/base/src/impl/sequence_impl.hh b/modules/seq/base/src/impl/sequence_impl.hh index 5ca99493ae90c1bd461fb8796bc3c2d1a378c77e..033bf50bf5f331a419b23068b6997d6cdc53c3eb 100644 --- a/modules/seq/base/src/impl/sequence_impl.hh +++ b/modules/seq/base/src/impl/sequence_impl.hh @@ -77,6 +77,9 @@ public: /// \brief Set sequence String void SetString(const String& seq); + /// \brief replace substring starting from start to end + void Replace(const String& str,int start, int end); + /// \brief Get sequence as String ignoring gaps String GetGaplessString() const;