Skip to content
Snippets Groups Projects
Select Git revision
  • 9425b07a88487b5e909d53ac6659c9969cc4137a
  • master default protected
  • develop protected
  • cmake_boost_refactor
  • ubuntu_ci
  • mmtf
  • non-orthogonal-maps
  • no_boost_filesystem
  • data_viewer
  • 2.11.1
  • 2.11.0
  • 2.10.0
  • 2.9.3
  • 2.9.2
  • 2.9.1
  • 2.9.0
  • 2.8.0
  • 2.7.0
  • 2.6.1
  • 2.6.0
  • 2.6.0-rc4
  • 2.6.0-rc3
  • 2.6.0-rc2
  • 2.6.0-rc
  • 2.5.0
  • 2.5.0-rc2
  • 2.5.0-rc
  • 2.4.0
  • 2.4.0-rc2
29 results

residue_impl.cc

Blame
  • user avatar
    marco authored
    In addition to accessing the properties, say, the radius,  with
    atom.GetProp().radius, it is now possible to call atom.GetRadius().
    
    Also, rename AtomBase::GetProp() to AtomBase::GetAtomProps().
    
    git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2114 5a81b35b-ba03-0410-adc8-b2c5c5119f08
    3de0c3d2
    History
    residue_impl.cc 16.93 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 <ost/mol/entity_visitor.hh>
    
    #include "chain_impl.hh"
    #include "residue_impl.hh"
    #include "atom_impl.hh"
    #include "entity_impl.hh"
    #include <boost/bind.hpp>
    #include <algorithm>
    #include "torsion_impl.hh"
    #include <ost/mol/impl/connector_impl.hh>
    
    using boost::bind;
    
    namespace ost { namespace mol { namespace impl {
    
    ResidueImpl::ResidueImpl(const EntityImplPtr& ent,
                             const ChainImplPtr& ch,
                             const ResNum& num,
                             const ResidueKey& key):
      ent_(ent),
      chain_(ch),
      num_(num),
      key_(key),
      atom_list_(),
      sec_structure_(SecStructure::COIL),
      olc_('?')
    {}
    
    
    AtomImplPtr ResidueImpl::InsertAtom(const String& name,
                                      const geom::Vec3& pos,
                                      const AtomProp& prop)
    {
      AtomImplPtr ap=ent_.lock()->CreateAtom(shared_from_this(),name, pos, prop);
      atom_list_.push_back(ap);
      return ap;
    }
    
    AtomImplPtr ResidueImpl::InsertAtom(const AtomImplPtr& atom)
    {
      AtomImplPtr dst_atom=this->InsertAtom(atom->GetName(), 
                                            atom->GetPos(),
                                            atom->GetAtomProps());
      dst_atom->Assign(*atom.get());
      dst_atom->SetState(atom->GetState());
      return dst_atom;
    }
    
    Real ResidueImpl::GetAverageBFactor() const
    {
      Real sum=0;
      for (AtomImplList::const_iterator i=atom_list_.begin(), 
           e=atom_list_.end(); i!=e; ++i) {
        sum+=(*i)->GetAtomProps().b_factor;
      }
      return atom_list_.size()>0 ? sum/atom_list_.size() : 0.0;
    }
    
    void ResidueImpl::AddAltAtom(const String& group, const AtomImplPtr& atom,
                                 const geom::Vec3& position) {
    
      if (group.length()==0)
       throw Error("alt atom group name can't be empty String");
      AtomEntryGroups::iterator i=alt_groups_.find(group);
      if (i==alt_groups_.end()) {
        std::pair<AtomEntryGroups::iterator, bool> p;
        AtomGroup ag;
        ag.name=group;
        p=alt_groups_.insert(std::make_pair(group, ag));
        i=p.first;
        if (alt_groups_.size()==1) {
          curr_group_=group;
        }
      }
      i->second.atoms.push_back(AtomGroupEntry(atom, position));
    }
    
    geom::Vec3 ResidueImpl::GetAltAtomPos(const AtomImplPtr& atom, 
                                          const String& group) const
    {
      AtomEntryGroups::const_iterator i=alt_groups_.find(group);
      if (i==alt_groups_.end()) {
        throw Error("No alt atom group '"+group+"'");
      }
      const AtomGroup& g=i->second;
      for (AtomGroupEntryList::const_iterator j=g.atoms.begin(), 
           e=g.atoms.end(); j!=e; ++j) {
        if (atom==j->atom.lock()) {
          return j->pos;
        }
      }
      throw Error(atom->GetQualifiedName()+
                  " does not have alternative atom position '"+group+"'");
    }
    
    AtomImplPtr ResidueImpl::InsertAltAtom(const String& name,
                                           const String& alt_group,
                                           const geom::Vec3& pos,
                                           const AtomProp& prop) {
      AtomImplPtr atom=this->InsertAtom(name, pos, prop);
      this->AddAltAtom(alt_group, atom, pos);
      return atom;
    }
    
    void ResidueImpl::Apply(EntityVisitor& v)
    {
      LOGN_TRACE("visitor @" << &v << " visiting residue ; @" << this);
      if(v.VisitResidue(ResidueHandle(shared_from_this()))) {
        for (AtomImplList::iterator it=atom_list_.begin();
             it!=atom_list_.end();++it) {
          (*it)->Apply(v);
        }
      }
    }
    
    SecStructure ResidueImpl::GetSecStructure() const 
    {
      return sec_structure_;
    }
    
    void ResidueImpl::SetSecStructure(SecStructure ss) 
    {
      sec_structure_=ss;
    }
    
    EntityImplPtr ResidueImpl::GetEntity() const
    {
      return ent_.lock();
    }
    
    AtomImplPtr ResidueImpl::GetCentralAtom() const
    {
      if (chem_class_.IsNucleotideLinking()) {
        for (AtomImplList::const_iterator it=atom_list_.begin();
             it!=atom_list_.end();++it) {
          if((*it)->GetName()=="P") return *it;
        }    
      } else if (chem_class_.IsPeptideLinking()) {
        for (AtomImplList::const_iterator it=atom_list_.begin();
             it!=atom_list_.end();++it) {
          if((*it)->GetName()=="CA") return *it;
        }    
      }
    
      return AtomImplPtr();
    }
    
    char ResidueImpl::GetOneLetterCode() const
    {
      return olc_;
    }
    
    void ResidueImpl::SetOneLetterCode(const char olc)  
    {
      olc_=olc;
    }
    
    int ResidueImpl::GetAtomCount() const 
    {
      return static_cast<int>(atom_list_.size());
    }
    
    int ResidueImpl::GetBondCount() const 
    {
      int count=0;
      AtomImplList::const_iterator it=atom_list_.begin();
      while(it!=atom_list_.end()) {
        count+=(AtomHandle(*it)).GetBondCount();
        ++it;
      }
      return count/2;
    }
    
    
    ChainImplPtr ResidueImpl::GetChain() const
    {
      return chain_.lock();
    }
    
    geom::Vec3 ResidueImpl::GetCentralNormal() const
    {
      if (chem_class_.IsPeptideLinking()) {
        AtomImplPtr a1 = FindAtom("C");
        AtomImplPtr a2 = FindAtom("O"); 
        geom::Vec3 nrvo;
        if(a1 && a2) {
          nrvo = geom::Normalize(a1->GetPos()-a2->GetPos());
        } else {
          geom::Vec3 v0=GetCentralAtom()->GetPos();
          nrvo=geom::Cross(geom::Normalize(v0),
                           geom::Normalize(geom::Vec3(-v0[2],v0[0],v0[1])));
          LOGN_VERBOSE("warning: could not find atoms for proper central normal calculation");
        }
        return nrvo;    
      } else if (chem_class_.IsNucleotideLinking()) {
        AtomImplPtr a1 = FindAtom("P");
        AtomImplPtr a2 = FindAtom("OP1");
        AtomImplPtr a3 = FindAtom("OP2");
        geom::Vec3 nrvo;
        if(a1 && a2 && a3) {
          nrvo = geom::Normalize(a1->GetPos()-(a2->GetPos()+a3->GetPos())*.5);
        } else {
          geom::Vec3 v0=GetCentralAtom()->GetPos();
          nrvo=geom::Cross(geom::Normalize(v0),
                           geom::Normalize(geom::Vec3(-v0[2],v0[0],v0[1])));
          LOGN_VERBOSE("warning: could not find atoms for proper central normal calculation");
        }
        return nrvo;
      }
      return geom::Vec3();
    }
    
    
    AtomImplPtr ResidueImpl::FindAtom(const String& aname) const
    {
      for (AtomImplList::const_iterator it=atom_list_.begin();
           it!=atom_list_.end();++it) {
        if ((*it)->GetName()==aname) {
          return *it;
        }
      }
      return AtomImplPtr();
    }
    
    const AtomImplList& ResidueImpl::GetAtomList() const
    {
      return atom_list_;
    }
    
    TorsionImplP ResidueImpl::GetPsiTorsion() const {
      ChainImplPtr chain=this->GetChain();
      ResidueImplPtr self=const_cast<ResidueImpl*>(this)->shared_from_this();
      ResidueImplPtr next=chain->GetNext(self);
      if (!next || !InSequence(self, next))
        return TorsionImplP();
      AtomImplPtr calpha=this->FindAtom("CA");
      AtomImplPtr n=this->FindAtom("N");
      AtomImplPtr c=this->FindAtom("C");
      AtomImplPtr npo=next->FindAtom("N");
      TorsionImplList::const_iterator i=torsion_list_.begin();
      for (;i!=torsion_list_.end(); ++i) {
        TorsionImplP t=*i;
        if (t->Matches(n, calpha, c, npo))
          return t;
      }
    
      LOGN_DUMP("Can't find torsion PSI for " <<
               this->GetKey() << this->GetNumber());
      return TorsionImplP();
    
    }
    
    void  ResidueImpl::AddTorsion(const TorsionImplP& torsion) {
      torsion_list_.push_back(torsion);
    }
    
    TorsionImplP ResidueImpl::FindTorsion(const String& torsion_name) const {
      TorsionImplList::const_iterator i=torsion_list_.begin();
      for (; i!=torsion_list_.end(); ++i) {
        if ((*i)->GetName()==torsion_name) {
          return *i;
        }
      }
      return TorsionImplP();
    }
    
    
    TorsionImplP ResidueImpl::GetOmegaTorsion() const {
      ChainImplPtr chain=this->GetChain();
      ResidueImplPtr self=const_cast<ResidueImpl*>(this)->shared_from_this();
      ResidueImplPtr prev=chain->GetPrev(self);
      if (!prev || !InSequence(prev, self))
        return TorsionImplP();
    
      AtomImplPtr calpha_prev=prev->FindAtom("CA");
      AtomImplPtr c_prev=prev->FindAtom("C");
      AtomImplPtr n=this->FindAtom("N");
      AtomImplPtr calpha=this->FindAtom("CA");
      TorsionImplList::const_iterator i=torsion_list_.begin();
    
      for (;i!=torsion_list_.end(); ++i) {
        TorsionImplP t=*i;
        if (t->Matches(calpha_prev, c_prev, n,  calpha))
          return t;
      }
    
      LOGN_DUMP("Can't find torsion Omega for " <<
               this->GetKey() << this->GetNumber());
      return TorsionImplP();
    }
    
    
    TorsionImplP ResidueImpl::GetPhiTorsion() const {
      ChainImplPtr chain=this->GetChain();
      ResidueImplPtr self=const_cast<ResidueImpl*>(this)->shared_from_this();
      ResidueImplPtr prev=chain->GetPrev(self);
      if (!prev || !InSequence(prev, self))
        return TorsionImplP();
    
      AtomImplPtr cmo=prev->FindAtom("C");
      AtomImplPtr n=this->FindAtom("N");
      AtomImplPtr calpha=this->FindAtom("CA");
      AtomImplPtr c=this->FindAtom("C");
      TorsionImplList::const_iterator i=torsion_list_.begin();
      for (;i!=torsion_list_.end(); ++i) {
        TorsionImplP t=*i;
        if (t->Matches(cmo, n, calpha, c))
          return t;
      }
    
      LOGN_DUMP("Can't find torsion PHI for " <<
               this->GetKey() << this->GetNumber());
      return TorsionImplP();
    }
    
    
    
    void ResidueImpl::DeleteAtom(const AtomImplPtr& atom) {
      AtomImplList::iterator i=atom_list_.begin();
      for (; i!=atom_list_.end(); ++i) {
        if ((*i)==atom) {
          (*i)->DeleteAllTorsions();
          (*i)->DeleteAllConnectors();
          this->RemoveAltPositionsForAtom(atom);
          this->GetEntity()->DeleteAtom(*i);
          atom_list_.erase(i);
          break;
        }
    
      }
    }
    
    void ResidueImpl::DeleteAtoms(const String& atom_name) {
      AtomImplList::iterator i=atom_list_.begin();
      for (; i!=atom_list_.end(); ++i) {
        if ((*i)->GetName()==atom_name) {
          (*i)->DeleteAllTorsions();
          (*i)->DeleteAllConnectors();
          this->GetEntity()->DeleteAtom(*i);
        }
      }
      AtomImplList::iterator new_end;
      new_end=std::remove_if(atom_list_.begin(), atom_list_.end(),
                             bind(&AtomImpl::GetName, _1)==atom_name);
      atom_list_.erase(new_end, atom_list_.end());
    }
    
    void ResidueImpl::DeleteAllAtoms() {
      AtomImplList::iterator i=atom_list_.begin();
      for (; i!=atom_list_.end(); ++i) {
        (*i)->DeleteAllTorsions();
        (*i)->DeleteAllConnectors();
          this->GetEntity()->DeleteAtom(*i);
      }
      atom_list_.clear();
    }
    
    String ResidueImpl::GetQualifiedName() const {
      String chain_name=this->GetChain()->GetName();
      return (chain_name==" " ? "" :  chain_name+".")+
             this->GetKey()+
             this->GetNumber().AsString();
    }
    
    void ResidueImpl::RemoveAltPositionsForAtom(const AtomImplPtr& atom) {
      AtomEntryGroups::iterator i=alt_groups_.begin();
      bool set_name=false, inc=false;
      // we do not increment the iterator in the for loop directly, but do it
      // inside the loop to get our hands on the next iterator in the map
      // before we delete the element
      for (; i!=alt_groups_.end(); ) {
        AtomGroupEntryList::iterator k=i->second.atoms.begin();
        inc=true;
        for (; k!=i->second.atoms.end(); ++k) {
          if (k->atom.lock().get()==atom.get()) {
            i->second.atoms.erase(k);
            if (i->second.atoms.empty()) {
              AtomEntryGroups::iterator to_be_deleted=i;
              if (i->first==curr_group_) {
                set_name=true;
              }      
              ++i;
              inc=false;
              alt_groups_.erase(to_be_deleted);
            }
            break;
          }
        }
        if (inc) {
          ++i;
        }
      }
      if (set_name) {
        if (alt_groups_.size()==0)
          curr_group_="";
        else
          curr_group_=alt_groups_.begin()->first;
      }
    }
    
    Real ResidueImpl::GetMass() const
    {
      Real mass = 0;
      for (AtomImplList::const_iterator i=atom_list_.begin(); 
           i!=atom_list_.end(); ++i) {
        mass+=(*i)->GetAtomProps().mass;
      }
      return mass;
    }
    
    geom::Vec3 ResidueImpl::GetGeometricEnd() const {
      geom::Vec3 maximum(-std::numeric_limits<Real>::infinity(),
                         -std::numeric_limits<Real>::infinity(),
                         -std::numeric_limits<Real>::infinity());
      for (AtomImplList::const_iterator i=atom_list_.begin(); 
           i!=atom_list_.end(); ++i) {
        maximum=geom::Max(maximum,(*i)->GetPos());
      }
      return maximum;
    }
    
    geom::Vec3 ResidueImpl::GetGeometricStart() const {
      geom::Vec3 minimum(std::numeric_limits<Real>::infinity(),
                         std::numeric_limits<Real>::infinity(),
                         std::numeric_limits<Real>::infinity());
      for (AtomImplList::const_iterator i=atom_list_.begin(); 
           i!=atom_list_.end(); ++i) {
        minimum=geom::Min(minimum,(*i)->GetPos());
      }
      return minimum;
    }
    
    geom::Vec3 ResidueImpl::GetGeometricCenter() const
    {
      return (this->GetGeometricStart() + this->GetGeometricEnd())/2;
    }
    
    geom::Vec3 ResidueImpl::GetCenterOfAtoms() const
    {
      geom::Vec3 sum;
      if (!atom_list_.empty()) {
        for (AtomImplList::const_iterator i=atom_list_.begin(); 
            i!=atom_list_.end(); ++i) {
          sum+=(*i)->GetPos();
        }
        sum/=atom_list_.size();
      }
      return sum;
    }
    
    geom::Vec3 ResidueImpl::GetCenterOfMass() const
    {
      geom::Vec3 center;
      Real mass = this->GetMass();
      if (this->GetAtomCount() > 0 && mass > 0) {
        for (AtomImplList::const_iterator i=atom_list_.begin(); 
            i!=atom_list_.end(); ++i) {
          center+=(*i)->GetPos()*(*i)->GetAtomProps().mass;
        }
      }
      return center/mass;
    }
    
    void ResidueImpl::AddAltAtomPos(const String& group,
                                         const AtomImplPtr& atom,
                                         const geom::Vec3& position) {
      // Make sure atom is already registered for having an alternative position.
      // Bail out, if this is not the case.
      AtomEntryGroups::iterator i=alt_groups_.begin();
      bool found=false;
      for (; i!=alt_groups_.end(); ++i) {
        AtomGroupEntryList::iterator k=i->second.atoms.begin();
        for (; k!=i->second.atoms.end(); ++k) {
          AtomGroupEntry& entry=*k;
          if (entry.atom.lock().get()==atom.get()) {
            found=true;
            break;
          }
        }
      }
      if (found)
        this->AddAltAtom(group, atom, position);
      else {
        String m="Definition of alternative position without prior call to "
                 "InsertAltAtom is not allowed";
        throw Error(m);
      }
    }
    
    int ResidueImpl::GetIndex() const {
      return this->GetChain()->GetIndex(this->GetNumber());
    }
    
    bool ResidueImpl::HasAltAtomGroup(const String& group) const {
      return alt_groups_.find(group)!=alt_groups_.end();
    }
    
    std::vector<String> ResidueImpl::GetAltAtomGroupNames() const {
      std::vector<String> names;
      AtomEntryGroups::const_iterator i=alt_groups_.begin();
      for (; i!=alt_groups_.end(); ++i) {
        names.push_back(i->first);
      }
      return names;
    }
    
    
    std::vector<String> ResidueImpl::GetAltAtomGroupNames(const AtomImplPtr& atom) const
    {
      std::vector<String> names;
      AtomEntryGroups::const_iterator i=alt_groups_.begin();
      for (; i!=alt_groups_.end(); ++i) {
        const AtomGroup& g=i->second;
        for (AtomGroupEntryList::const_iterator j=g.atoms.begin(), 
             e=g.atoms.end(); j!=e; ++j) {
          if (atom==j->atom.lock()) {
            names.push_back(i->first);
          }
        }
      }
      return names;
    }
    
    
    bool ResidueImpl::HasAltAtoms() const {
      return !alt_groups_.empty();
    }
    
    bool ResidueImpl::SwitchAtomPos(const String& group) {
      AtomEntryGroups::iterator i=alt_groups_.find(group);
      if (i==alt_groups_.end())
        return false;
      AtomEntryGroups::iterator old=alt_groups_.find(curr_group_);
      if (old!=alt_groups_.end()) {
        AtomGroup& gr=old->second;
        AtomGroupEntryList::iterator k=gr.atoms.begin();
        for (; k!=gr.atoms.end(); ++k) {
          AtomGroupEntry& entry=*k;
          assert(!entry.atom.expired());
          entry.pos=entry.atom.lock()->GetOriginalPos();
        }
      }
      AtomGroup& agr=i->second;
      AtomGroupEntryList::iterator j=agr.atoms.begin();
      for (; j!=agr.atoms.end(); ++j) {
    
        AtomGroupEntry& entry=*j;
        assert(!entry.atom.expired());
        entry.atom.lock()->SetOriginalPos(entry.pos);
        EntityHandle ent = entry.atom.lock()->GetEntity();
        geom::Mat4 transf_matrix = ent.GetTransformationMatrix();
        geom::Vec3 transf_pos = geom::Vec3(transf_matrix*geom::Vec4(entry.pos));
        entry.atom.lock()->SetTransformedPos(transf_pos);
      }
      curr_group_=group;
      return true;
    }
    
    int ResidueImpl::GetIntProperty(Prop::ID prop_id) const
    {
      switch (prop_id) {
        case Prop::RNUM:
          return num_.GetNum();
        default:
          throw PropertyError(prop_id);
      }
    }
    
    Real ResidueImpl::GetFloatProperty(Prop::ID prop_id) const
    {
      switch (prop_id) {
        case Prop::RBFAC:
          return this->GetAverageBFactor();
        default:
          throw PropertyError(prop_id);
      }
    }
    
    String ResidueImpl::GetStringProperty(Prop::ID prop_id) const
    {
      switch (prop_id) {
        case Prop::RNAME:
          return this->GetName();
        default:
          throw PropertyError(prop_id);
      }
    }
    
    }}} // ns