Something went wrong on our end
-
marco authored
specifically, remove LOGN_* macros and introduce new logging levels. We now have ERROR, WARNING, INFO, VERBOSE, DEBUG and TRACE. DEBUG and TRACE are turned off under NDEBUG and expand to an empty macro. new default verbosity level displays ERROR/WARNING/INFO git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2709 5a81b35b-ba03-0410-adc8-b2c5c5119f08
marco authoredspecifically, remove LOGN_* macros and introduce new logging levels. We now have ERROR, WARNING, INFO, VERBOSE, DEBUG and TRACE. DEBUG and TRACE are turned off under NDEBUG and expand to an empty macro. new default verbosity level displays ERROR/WARNING/INFO git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2709 5a81b35b-ba03-0410-adc8-b2c5c5119f08
chain_impl.cc 12.08 KiB
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#include <ost/log.hh>
#include "chain_impl.hh"
#include "residue_impl.hh"
#include "entity_impl.hh"
#include <ost/mol/impl/atom_impl.hh>
#include <ost/mol/entity_visitor.hh>
#include <boost/bind.hpp>
#include <algorithm>
#include <numeric>
using boost::bind;
using std::accumulate;
namespace ost { namespace mol { namespace impl {
ChainImpl::ChainImpl(const EntityImplPtr& e, const String& name):
ent_(e),
name_(name),
residue_list_(),
in_sequence_(true)
{}
String ChainImpl::GetName() const
{
return name_;
}
struct ResNumComp {
bool operator()(const ResNum& a,
const ResidueImplPtr& b) {
return a<b->GetNumber();
}
bool operator()(const ResidueImplPtr& a,
const ResNum& b) {
return a->GetNumber()<b;
}
};
bool ChainImpl::InSequence() const {
return in_sequence_;
}
ResidueImplPtr ChainImpl::AppendResidue(const ResidueImplPtr& res)
{
ResidueImplPtr dst_res=this->AppendResidue(res->GetKey(), res->GetNumber());
dst_res->Assign(*res.get());
dst_res->SetOneLetterCode(res->GetOneLetterCode());
dst_res->SetSecStructure(res->GetSecStructure());
dst_res->SetChemClass(res->GetChemClass());
return dst_res;
}
ResidueImplPtr ChainImpl::InsertResidueBefore(int index,
const ResNum& num2,
const ResidueKey& key) {
ResNum num=num2;
if (index>=static_cast<int>(residue_list_.size()) || index<0) {
return ResidueImplPtr();
}
// check if we break the InSequence property
if (in_sequence_) {
ResNum next=residue_list_[index]->GetNumber();
if (next<=num2 || (index>0 && residue_list_[index-1]->GetNumber()>=num))
in_sequence_=false;
}
ResidueImplPtr rp = ent_.lock()->CreateResidue(shared_from_this(), num, key);
residue_list_.insert(residue_list_.begin()+index, rp);
if (in_sequence_) {
this->UpdateShifts();
}
return rp;
}
ResidueImplPtr ChainImpl::InsertResidueAfter(int index,
const ResNum& num2,
const ResidueKey& key) {
ResNum num=num2;
if (index>=static_cast<int>(residue_list_.size()) || index<0) {
return ResidueImplPtr();
}
// check if we break the InSequence property
if (in_sequence_) {
ResNum prev=residue_list_[index]->GetNumber();
if (prev>=num || (index<static_cast<int>(residue_list_.size())-1 &&
residue_list_[index+1]->GetNumber()<=num)) {
in_sequence_=false;
}
}
ResidueImplPtr rp = ent_.lock()->CreateResidue(shared_from_this(), num, key);
residue_list_.insert(residue_list_.begin()+index+1, rp);
if (in_sequence_) {
this->UpdateShifts();
}
return rp;
}
void ChainImpl::UpdateShifts()
{
shifts_.clear();
ResidueImplList::iterator i=residue_list_.begin();
ResNum last(0);
for (int count=0; i!=residue_list_.end(); ++i, ++count) {
const ResNum& next=(*i)->GetNumber();
if (last.GetNum()==next.GetNum()) {
// introduce negative shift, due to inserted residue. We should do
// something more clever here, since it is very likely that there are
// more than one consecutively inserted residues.
Shift s;
s.start=count;
s.shift=-1;
last=next;
shifts_.push_back(s);
continue;
} else if (last.GetNum()+1==next.GetNum()) {
last=next;
continue;
}
Shift s;
s.start=count;
s.shift=next.GetNum()-last.GetNum()-1;
last=next;
shifts_.push_back(s);
}
}
void ChainImpl::DeleteAllResidues() {
ResidueImplList::iterator i=residue_list_.begin();
for (; i!=residue_list_.end(); ++i) {
(*i)->DeleteAllAtoms();
}
residue_list_.clear();
this->UpdateShifts();
}
void ChainImpl::DeleteResidue(const ResNum& number) {
int index=this->GetIndex(number);
if (index>=0) {
ResidueImplPtr r=residue_list_[index];
r->DeleteAllAtoms();
residue_list_.erase(residue_list_.begin()+index);
this->UpdateShifts();
}
}
void ChainImpl::DeleteResidue(const ResidueImplPtr& residue) {
if (residue->GetChain().get()!=this)
return;
this->DeleteResidue(residue->GetNumber());
}
ResidueImplPtr ChainImpl::AppendResidue(const ResidueKey& key,
const ResNum& num)
{
ResidueImplPtr rp = ent_.lock()->CreateResidue(shared_from_this(), num, key);
if (residue_list_.empty()) {
if (num!=ResNum(1)) {
// insert shift here...
Shift s;
s.start=std::min(rp->GetNumber().GetNum()-1, 0);
s.shift=rp->GetNumber().GetNum()-1;
shifts_.push_back(s);
}
} else {
if (residue_list_.back()->GetNumber()>=num) {
in_sequence_=false;
}
if (in_sequence_) {
LOG_DEBUG("appending residue " << num);
// update is only needed if we introduce a new gap.
if (residue_list_.back()->GetNumber().GetNum()+1<num.GetNum()) {
Shift s;
s.start=residue_list_.size();
s.shift=num.GetNum()-residue_list_.back()->GetNumber().GetNum()-1;
shifts_.push_back(s);
} else if (residue_list_.back()->GetNumber().GetNum()==num.GetNum()) {
Shift s;
s.start=residue_list_.size();
s.shift=-1;
shifts_.push_back(s);
}
}
}
residue_list_.push_back(rp);
return rp;
}
ResidueImplPtr ChainImpl::AppendResidue(const ResidueKey& key)
{
ResNum num(1);
if(!residue_list_.empty()) {
num=residue_list_.back()->GetNumber()+1;
}
ResidueImplPtr rp = ent_.lock()->CreateResidue(shared_from_this(),num,key);
residue_list_.push_back(rp);
return rp;
}
ResidueImplPtr ChainImpl::GetPrev(const ResidueImplPtr& r) const
{
if (!r)
return ResidueImplPtr();
int index=this->GetIndex(r->GetNumber())-1;
if (index>-1 && index<static_cast<int>(residue_list_.size())-1) {
return residue_list_[index];
}
return ResidueImplPtr();
}
int ChainImpl::GetResidueCount() const {
return static_cast<int>(residue_list_.size());
}
int ChainImpl::GetAtomCount() const {
int count=0;
ResidueImplList::const_iterator it=residue_list_.begin();
while(it!=residue_list_.end()) {
count+=(*it)->GetAtomCount();
++it;
}
return count;
}
int ChainImpl::GetBondCount() const {
int count=0;
ResidueImplList::const_iterator it=residue_list_.begin();
while(it!=residue_list_.end()) {
count+=(*it)->GetBondCount();
++it;
}
return count;
}
ResidueImplPtr ChainImpl::GetNext(const ResidueImplPtr& r) const
{
if (!r)
return ResidueImplPtr();
int index=this->GetIndex(r->GetNumber())+1;
if (index>0 && index<=static_cast<int>(residue_list_.size())-1) {
return residue_list_[index];
}
return ResidueImplPtr();
}
const ResidueImplList& ChainImpl::GetResidueList() const
{
return residue_list_;
}
void ChainImpl::Apply(EntityVisitor& v)
{
LOG_TRACE("visitor @" << &v << " visiting chain impl @" << this);
if (v.VisitChain(ChainHandle(shared_from_this()))) {
for (ResidueImplList::iterator it=residue_list_.begin();
it!=residue_list_.end();++it) {
(*it)->Apply(v);
}
}
}
ResidueImplPtr ChainImpl::FindResidue(const ResNum& number) const
{
int index=this->GetIndex(number);
bool invalid=index<0 || index>static_cast<int>(residue_list_.size())-1;
return invalid ? ResidueImplPtr() : residue_list_[index];
}
AtomImplPtr ChainImpl::FindAtom(const ResNum& num,
const String& atom_name) const
{
ResidueImplPtr r=this->FindResidue(num);
if (r) {
return r->FindAtom(atom_name);
}
return AtomImplPtr();
}
EntityImplPtr ChainImpl::GetEntity() const
{
return ent_.lock();
}
int ChainImpl::GetIndex(const ResNum& number) const
{
if (in_sequence_) {
int pos=number.GetNum()-1;
std::list<Shift>::const_iterator i;
for (i=shifts_.begin(); i!=shifts_.end(); ++i) {
const Shift& s=*i;
if (pos<s.start) {
break;
} else if (pos<s.start+s.shift) {
return -1;
}
pos-=s.shift;
}
while (pos>=0 && pos<static_cast<int>(residue_list_.size()) &&
residue_list_[pos]->GetNumber()<number) {
pos++;
}
if (pos<0 || pos>=static_cast<int>(residue_list_.size())) {
return -1;
}
assert(residue_list_[pos]->GetNumber()==number);
return pos;
} else {
ResidueImplList::const_iterator k;
k=std::find_if(residue_list_.begin(),
residue_list_.end(),
bind(&ResidueImpl::GetNumber, _1)==number);
if (k==residue_list_.end())
return -1;
int pos=std::distance(residue_list_.begin(), k);
assert(residue_list_[pos]->GetNumber()==number);
return pos;
}
}
void ChainImpl::AssignSecondaryStructure(SecStructure ss,
const ResNum& start,
const ResNum& end)
{
int i=this->GetIndex(start);
int j=this->GetIndex(end);
if (i>=0 && j>=0 && i<=j && j<static_cast<int>(residue_list_.size())) {
std::for_each(residue_list_.begin()+i, residue_list_.begin()+j+1,
bind(&ResidueImpl::SetSecStructure, _1, ss));
}
}
Real ChainImpl::GetMass() const
{
Real mass = 0;
for (ResidueImplList::const_iterator i=residue_list_.begin();
i!=residue_list_.end(); ++i) {
ResidueImplPtr r=*i;
for (AtomImplList::iterator j=r->GetAtomList().begin();
j!=r->GetAtomList().end(); ++j) {
mass+=(*j)->GetAtomProps().mass;
}
}
return mass;
}
geom::AlignedCuboid ChainImpl::GetBounds() const
{
geom::Vec3 mmin( std::numeric_limits<Real>::infinity());
geom::Vec3 mmax(-std::numeric_limits<Real>::infinity());
bool atoms=false;
for (ResidueImplList::const_iterator i=residue_list_.begin();
i!=residue_list_.end(); ++i) {
ResidueImplPtr r=*i;
for (AtomImplList::iterator j=r->GetAtomList().begin();
j!=r->GetAtomList().end(); ++j) {
mmin=geom::Min(mmin, (*j)->GetPos());
mmax=geom::Max(mmax, (*j)->GetPos());
atoms=true;
}
}
if (!atoms) {
return geom::AlignedCuboid(geom::Vec3(), geom::Vec3());
}
return geom::AlignedCuboid(mmin, mmax);
}
geom::Vec3 ChainImpl::GetCenterOfAtoms() const
{
geom::Vec3 sum;
if(this->GetAtomCount() > 0) {
for (ResidueImplList::const_iterator i=residue_list_.begin();
i!=residue_list_.end(); ++i) {
ResidueImplPtr r=*i;
for (AtomImplList::iterator j=r->GetAtomList().begin();
j!=r->GetAtomList().end(); ++j) {
sum+=(*j)->GetPos();
}
}
sum/=this->GetAtomCount();
}
return sum;
}
geom::Vec3 ChainImpl::GetCenterOfMass() const
{
geom::Vec3 center;
Real mass = this->GetMass();
if(this->GetAtomCount() > 0 && mass > 0) {
for (ResidueImplList::const_iterator i=residue_list_.begin();
i!=residue_list_.end(); ++i) {
ResidueImplPtr r=*i;
for (AtomImplList::iterator j=r->GetAtomList().begin();
j!=r->GetAtomList().end(); ++j) {
center+=(*j)->GetPos() * (*j)->GetAtomProps().mass;
}
}
center/=mass;
}
return center;
}
void ChainImpl::SetName(const String& new_name)
{
name_=new_name;
}
}}} // ns