Skip to content
Snippets Groups Projects
Select Git revision
  • 0a7bad63f988a59bf9a42f690474edcda43e77d4
  • 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

query_state.cc

Blame
  • user avatar
    Marco Biasini authored
    the default atom properties for each element are shared. Upon changing
    one of the properties, the properties are copied and stored locally
    for that atom. That way, we have the advantage of low memory consumption
    while still keeping the previous flexibility.
    a0970ace
    History
    query_state.cc 13.60 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
    //------------------------------------------------------------------------------
    /*
     Author: Marco Biasini
     */
    #include <ost/mol/query_state.hh>
    #include <ost/mol/mol.hh>
    #include <ost/mol/impl/entity_impl.hh>
    #include <ost/mol/impl/chain_impl.hh>
    #include <ost/mol/impl/residue_impl.hh>
    #include <ost/mol/impl/atom_impl.hh>
    #include <ost/mol/impl/query_impl.hh>
    
    namespace ost { namespace mol {
    
    struct LazilyBoundRef {
      LazilyBoundRef& operator=(const LazilyBoundRef& rhs);
      //EntityView for now, will be generalized to a point cloud later on.
      EntityView  view;
    };
      
    struct LazilyBoundData {
      std::vector<LazilyBoundRef> refs;
    };
    
    
        
    using namespace impl;
    
    bool cmp_string(CompOP op,const String& lhs, const String& rhs) {
      switch (op) {
        case COP_EQ:
          return lhs == rhs;
        case COP_NEQ:
          return lhs != rhs;
        default:
          assert(0 && "should be checked during ast generation");
          return false;
      }
    }
    
    bool QueryState::do_within(const geom::Vec3& pos, const impl::WithinParam& p, 
                               CompOP op) 
    {
      if (!p.HasValidRef()) {
        geom::Vec3 d=pos-p.GetCenter();
        if (op==COP_LE)
          return geom::Dot(d, d) <= p.GetRadiusSquare();
        else
          return geom::Dot(d, d) > p.GetRadiusSquare();
      } else {
        const LazilyBoundRef& r=this->GetBoundObject(p.GetRef());
        for (AtomViewIter i=r.view.AtomsBegin(), e=r.view.AtomsEnd(); i!=e; ++i) {
          geom::Vec3 d=pos-(*i).GetPos();
          if (op==COP_LE) {
            if (geom::Dot(d, d) <= p.GetRadiusSquare()) {
              return true;
            }
          } else if (geom::Dot(d, d) > p.GetRadiusSquare()) {
            return false;
          }
        }
        return op!=COP_LE;
      }
    }
    
    
    template <typename T>
    bool cmp_num(CompOP op, T lhs, T rhs) 
    {
      switch (op) {
        case COP_EQ:
          return lhs == rhs;
        case COP_NEQ:
          return lhs != rhs;
        case COP_GE:
          return lhs >= rhs;
        case COP_LE:
          return lhs <= rhs;
        case COP_LT:
          return lhs < rhs;
        case COP_GT:
          return lhs > rhs;
      }
      return true;
    }
    
    QueryState::~QueryState()
    {
    }
    
    QueryState::QueryState(const QueryImpl& query, const EntityHandle& ref)
      : q_(query) {
      s_.resize(query.sel_values_.size(),boost::logic::indeterminate);
      if (query.bracketed_expr_.size()>0) {
        r_.reset(new LazilyBoundData);
        r_->refs.resize(query.bracketed_expr_.size());
        for (size_t i=0;i<query.bracketed_expr_.size(); ++i) {
          r_->refs[i].view=ref.Select(Query(query.bracketed_expr_[i]));
        }    
      }
    
    }
    
    LazilyBoundRef& LazilyBoundRef::operator=(const LazilyBoundRef& rhs) {
      view=rhs.view;
      return *this;
    }
    
    QueryState::QueryState(const QueryImpl& query, const EntityView& ref)
      : q_(query) {
      s_.resize(query.sel_values_.size(),boost::logic::indeterminate);
      if (query.bracketed_expr_.size()>0) {
        r_.reset(new LazilyBoundData);
        r_->refs.resize(query.bracketed_expr_.size());
        for (size_t i=0;i<query.bracketed_expr_.size(); ++i) {
          r_->refs[i].view=ref.Select(Query(query.bracketed_expr_[i]));
        }    
      }
    }
    
    const LazilyBoundRef& QueryState::GetBoundObject(int i) const {
      return r_->refs[i];
    }
    
    
    
    
    boost::logic::tribool QueryState::EvalChain(const impl::ChainImplPtr& c) {
      if (q_.empty_optimize_)
        return true;
      const std::set<size_t>& indices = q_.indices_[(int)Prop::CHAIN];
      std::set<size_t>::const_iterator i = indices.begin();
      for (; i != indices.end(); ++i) {
        const SelStmt& ss = q_.sel_values_[*i];
        String value;
        float float_value;
        switch (ss.sel_id) {
          case Prop::CNAME:
            value = c->GetName();
            s_[*i] = cmp_string(ss.comp_op,
                                boost::get<String>(ss.param),value);
            continue;
          default:
            if (ss.sel_id>=Prop::CUSTOM) {
              int index=ss.sel_id-Prop::CUSTOM;
              GenProp gen_prop=q_.gen_prop_list_[index];
              if (gen_prop.has_default) {
                float_value=gen_prop.mapper.Get(c, gen_prop.default_val);
              } else {
                float_value=gen_prop.mapper.Get(c);
              }
              s_[*i]=cmp_num<Real>(ss.comp_op, float_value,
                                   boost::get<float>(ss.param));
            } else {
              assert(0 && "not implemented" );
            }
        }
      }  
      return this->EvalStack(Prop::CHAIN);
    }
    
    boost::logic::tribool QueryState::EvalResidue(const impl::ResidueImplPtr& r) {
      if (q_.empty_optimize_)
        return true;
      const std::set<size_t>& indices = q_.indices_[(int)Prop::RESIDUE];
      std::set<size_t>::const_iterator i = indices.begin();
      String str_value;
      int int_value;
      String p;  
      for (; i != indices.end(); ++i) {
        const SelStmt& ss = q_.sel_values_[*i];
        Real float_value;
        switch (ss.sel_id) {
          case Prop::RNAME:
            str_value = r->GetKey();
            s_[*i] = cmp_string(ss.comp_op,str_value,
                                boost::get<String>(ss.param));
            continue;
          case Prop::RNUM:
            int_value=r->GetNumber().GetNum();
            s_[*i]=cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));        
            break;
          case Prop::PEPTIDE:
            int_value=r->GetChemClass().IsPeptideLinking();
            s_[*i] = cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));        
            break;        
          case Prop::RBFAC:
            // This is ugly! Outcome is the same for a prefiltered view as it is for
            // as for the full entity, even though the residue view might not have
            // all the atoms included.
            float_value=r->GetAverageBFactor();
            s_[*i] = cmp_num<Real>(ss.comp_op, float_value,
                                     boost::get<float>(ss.param));        
            break;
          case Prop::PROTEIN:
            int_value=r->IsProtein();
            s_[*i]=cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));
            break;
          case Prop::WATER:
            int_value=r->GetChemClass().IsWater();
            s_[*i]=cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));
            break;
          case Prop::RTYPE:
            p=boost::get<String>(ss.param);
            if (p.length()>1) {
              bool b=false;
              if (p=="helix") {
                b=r->GetSecStructure().IsHelical();
              } else if (p=="ext" || p=="strand") {
                b=r->GetSecStructure().IsExtended();
              } else if (p=="coil") {
                b=r->GetSecStructure().IsCoil();
              } else if (p=="*") {
                b=true;
              }
              s_[*i]=ss.comp_op==COP_EQ ? b : !b;          
            } else {
              str_value= String(1, (char)r->GetSecStructure());
              s_[*i]=cmp_string(ss.comp_op,str_value,
                                boost::get<String>(ss.param));          
            }
            break;
          case Prop::RINDEX:
            int_value=r->GetIndex();
            s_[*i]=cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));
            break;
          default:
            if (ss.sel_id>=Prop::CUSTOM) {
              int index=ss.sel_id-Prop::CUSTOM;
              GenProp gen_prop=q_.gen_prop_list_[index];
              if (gen_prop.has_default) {
                float_value=gen_prop.mapper.Get(r, gen_prop.default_val);
              } else {
                float_value=gen_prop.mapper.Get(r);
              }
              s_[*i]=cmp_num<Real>(ss.comp_op, float_value,
                                   boost::get<float>(ss.param));
            } else {
              assert(0 && "not implemented" );
            }
        }
      }
      return this->EvalStack(Prop::RESIDUE);  
    }
    
    boost::logic::tribool QueryState::EvalStack(Prop::Level level) {
      const SelStack& stack = q_.sel_stacks_[(int)level];
      SelStack::const_reverse_iterator i = stack.rbegin();
      std::vector<boost::logic::tribool> value_stack;
    
      while (i!=stack.rend()) {
        const SelItem& si = *i;
        if (si.type==VALUE) {
          value_stack.push_back(s_[si.value]);
          ++i;
          continue;
        } else {
          boost::logic::tribool lhs = value_stack.back();
          value_stack.pop_back();
          boost::logic::tribool rhs = value_stack.back();
          value_stack.pop_back();      
          LogicOP lop = (LogicOP)si.value;
          boost::logic::tribool result;
          switch(lop) {
            case LOP_AND:
              result = lhs && rhs;
              break;
            case LOP_OR:
              result = lhs || rhs;
              break;              
          }      
          value_stack.push_back(result);
          ++i;
        }
      }
      assert(value_stack.size()==1);
      return value_stack.back();
    }
    
    namespace {
    // silences a warning for VS90
    QueryImpl dummy_query_impl;
    }
    QueryState::QueryState()
      : s_(), q_(dummy_query_impl) {
    }
    
    boost::logic::tribool QueryState::EvalAtom(const impl::AtomImplPtr& a) {
      if (q_.empty_optimize_)
        return true;  
      const std::set<size_t>& indices = q_.indices_[(int)Prop::ATOM];
      std::set<size_t>::const_iterator i = indices.begin();
      for (; i != indices.end(); ++i) {
        const SelStmt& ss = q_.sel_values_[*i];
        String str_value;
        Real float_value;
        int int_value;
        switch (ss.sel_id) {
          case Prop::ANAME:
            str_value = a->GetName();
            s_[*i] = cmp_string(ss.comp_op,str_value,
              boost::get<String>(ss.param));                  
            break;
          case Prop::AX:
            float_value=(a->GetPos())[0];
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                   boost::get<float>(ss.param));
            break;
          case Prop::AY:
            float_value=(a->GetPos())[1];
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                   boost::get<float>(ss.param));
            break;
          case Prop::AZ:
            float_value=(a->GetPos())[2];
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                   boost::get<float>(ss.param));
            break;                
          case Prop::OCC:
            float_value=a->GetOccupancy();
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                   boost::get<float>(ss.param));
            break;                        
          case Prop::ELE:
            str_value = a->GetElement();
            s_[*i] = cmp_string(ss.comp_op,str_value,
              boost::get<String>(ss.param));                          
            break;
          case Prop::ABFAC:
            float_value=a->GetBFactor();
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                  boost::get<float>(ss.param));
            break;
          case Prop::WITHIN:
            s_[*i]= this->do_within(a->GetPos(), 
                                    boost::get<WithinParam>(ss.param),
                                    ss.comp_op);
            break;
          case Prop::ISHETATM:
            int_value = a->IsHetAtom();
            s_[*i] = cmp_num<int>(ss.comp_op,int_value,boost::get<int>(ss.param));
            break;
          case Prop::ACHARGE:
            float_value=a->GetCharge();
            s_[*i]=cmp_num<Real>(ss.comp_op, float_value, 
                                  boost::get<float>(ss.param));
            break;
          default:
            if (ss.sel_id>=Prop::CUSTOM) {
              int index=ss.sel_id-Prop::CUSTOM;
              GenProp gen_prop=q_.gen_prop_list_[index];
              if (gen_prop.has_default) {
                float_value=gen_prop.mapper.Get(a, gen_prop.default_val);
              } else {
                float_value=gen_prop.mapper.Get(a);
              }
              s_[*i]=cmp_num<Real>(ss.comp_op, float_value,
                                   boost::get<float>(ss.param));
            } else {
              assert(0 && "not implemented" );
            }
        }    
      }
      return this->EvalStack(Prop::ATOM);
    }
    
    void QueryState::Reset(Prop::Level level) {
      if (q_.empty_optimize_)
        return;
      const std::set<size_t>& indices = q_.indices_[(int)level];
      std::set<size_t>::const_iterator i = indices.begin();
      for (; i != indices.end(); ++i) {
        s_[*i] = boost::logic::indeterminate;
      }
    }
    
    bool QueryState::IsAtomSelected(const AtomHandle& h)
    {
      boost::logic::tribool ret = this->EvalChain(h.GetResidue().GetChain().Impl());
      if(ret==false) return false;
      ret = this->EvalResidue(h.GetResidue().Impl());
      if(ret==false) return false;
      return this->EvalAtom(h.Impl());
    }
    
    bool QueryState::IsResidueSelected(const ResidueHandle& r)
    {
      boost::logic::tribool ret = this->EvalChain(r.GetChain().Impl());
      if(ret==false) return false;
      ret = this->EvalResidue(r.Impl());
      if(ret==false) return false;
      AtomHandleList atoms=r.GetAtomList();
      for (AtomHandleList::iterator i=atoms.begin(), e=atoms.end(); i!=e; ++i) {
        if (this->EvalAtom((*i).Impl())==true)
          return true;
      }
      return false;
    }
    
    bool QueryState::IsChainSelected(const ChainHandle& chain)
    {
      boost::logic::tribool ret = this->EvalChain(chain.Impl());
      if(ret==false) return false;
      ResidueHandleList res=chain.GetResidueList();
      for (ResidueHandleList::iterator j=res.begin(), k=res.end(); j!=k; ++j) {
        ResidueHandle r=*j;
        ret = this->EvalResidue(r.Impl());
        if(ret==false)
          continue;
        AtomHandleList atoms=r.GetAtomList();
        for (AtomHandleList::iterator i=atoms.begin(), e=atoms.end(); i!=e; ++i) {
          if (this->EvalAtom((*i).Impl())==true)
            return true;
        }    
      }
      return false;
    }
    
    
    }} // ns