coarse_creators.h
Go to the documentation of this file.
00001 // Copyright (c) 2009-2010  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 //This file is part of ESBTL.
00005 //
00006 //ESBTL is free software: you can redistribute it and/or modify
00007 //it under the terms of the GNU General Public License as published by
00008 //the Free Software Foundation, either version 3 of the License, or
00009 //(at your option) any later version.
00010 //
00011 //ESBTL is distributed in the hope that it will be useful,
00012 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //GNU General Public License for more details.
00015 //
00016 //You should have received a copy of the GNU General Public License
00017 //along with ESBTL.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 //
00020 //Additional permission under GNU GPL version 3 section 7
00021 //
00022 //If you modify this Library, or any covered work, by linking or
00023 //combining it with CGAL (or a modified version of that library), the
00024 //licensors of this Library grant you additional permission to convey
00025 //the resulting work. Corresponding Source for a non-source form of
00026 //such a combination shall include the source code for the parts of CGAL
00027 //used as well as that of the covered work. 
00028 //
00029 //
00030 //
00031 // Author(s)     :  Sébastien Loriot
00032 
00033 
00034 
00035 #ifndef ESBTL_COARSE_CREATORS_H
00036 #define ESBTL_COARSE_CREATORS_H
00037 
00038 #include <limits>
00039 
00040 namespace ESBTL{
00041 
00069 template <class Residue>
00070 class Coarse_creator_two_barycenters{
00071   typedef typename Residue::Coarse_atom         Coarse_atom;
00072   typedef typename Residue::Atom                Atom;
00073   typedef double                                FT;
00074   typedef typename Residue::Atom::Point_3       Point_3;
00075   
00076   static const std::string  info_;
00077 
00078   void update_coordinates(FT* X,const Atom& atom) const{
00079     X[0]+=atom.x();
00080     X[1]+=atom.y();
00081     X[2]+=atom.z();
00082     X[3]+=1;
00083   }
00084   
00085 public:
00086 
00087   static const std::string info(){return info_;}
00088 
00089   //returns the number of atoms created
00090   template <class Output_iterator>
00091   int operator()(const Residue& res,Output_iterator out) const{
00092     Coarse_atom bb(0,res);
00093     Coarse_atom sc(1,res);
00094     FT Xbb[4]={0,0,0,0};
00095     FT Xsc[4]={0,0,0,0};
00096     unsigned tot_res=0;
00097     for(typename Residue::Atoms_const_iterator
00098         at_it=res.atoms_begin();
00099         at_it!=res.atoms_end();
00100         ++at_it)
00101     {
00102       ++tot_res;
00103       if ( is_backbone(*at_it) ){
00104         bb.add(*at_it);
00105         update_coordinates(Xbb,*at_it);
00106       }
00107       else{
00108         sc.add(*at_it);
00109         update_coordinates(Xsc,*at_it);
00110       }
00111     }
00112     if (tot_res==0)
00113       return 0;
00114     unsigned ret=0;
00115     if (Xbb[3]!=0){ //to handle case of a ligand for example.
00116       static_cast<Point_3&>(bb)=Point_3(Xbb[0]/Xbb[3],Xbb[1]/Xbb[3],Xbb[2]/Xbb[3]);
00117       *out++=bb;
00118       ++ret;
00119     }
00120     if (Xsc[3]!=0){
00121       static_cast<Point_3&>(sc)=Point_3(Xsc[0]/Xsc[3],Xsc[1]/Xsc[3],Xsc[2]/Xsc[3]);
00122       *out++=sc;
00123       return ret+1;
00124     }
00125     else{assert(res.residue_name()=="GLY");}
00126     assert(ret==1);
00127     return 1;
00128   }
00129 };
00130 
00131 template<class Residue>
00132 const std::string Coarse_creator_two_barycenters<Residue>::info_="Coarse model using one atom as barycenter of backbone and one atom as barycenter of side chain atoms";
00133 
00134 
00143 template <class Residue,class FT_>
00144 class Coarse_creator_closest_to_barycenter{
00145   typedef typename Residue::Coarse_atom         Coarse_atom;
00146   typedef typename Residue::Atom                Atom;
00147   typedef FT_                                   FT;
00148   
00149   static const std::string  info_;
00150 
00151   void update_coordinates(FT* X,const Atom& atom) const{
00152     X[0]+=atom.x();
00153     X[1]+=atom.y();
00154     X[2]+=atom.z();
00155     X[3]+=1;
00156   }
00157   
00158   static inline FT square(const FT& n){return n*n;}
00159   
00160   template <class Point_3>
00161   static inline FT squared_distance(const Point_3& p1,const Point_3& p2){
00162     return square(p1.x()-p2.x())+square(p1.y()-p2.y())+square(p1.z()-p2.z());
00163   }
00164   
00165 public:
00166 
00167   static const std::string info(){return info_;}
00168 
00169   //returns the number of atoms created
00170   template <class Output_iterator>
00171   int operator()(const Residue& res,Output_iterator out) const {
00172     Coarse_atom c_atm(0,res);
00173     FT X_c_atm[4]={0,0,0,0};
00174     std::list<const Atom*> candidate_list;
00175     for(typename Residue::Atoms_const_iterator
00176         at_it=res.atoms_begin();
00177         at_it!=res.atoms_end();
00178         ++at_it)
00179     {
00180       if ( is_side_chain_or_CA(*at_it) ){
00181         c_atm.add(*at_it);
00182         update_coordinates(X_c_atm,*at_it);
00183         candidate_list.push_back( &(*at_it) );
00184       }
00185     }
00186     assert(X_c_atm[3]!=0);
00187     Atom barycenter=Atom(X_c_atm[0]/X_c_atm[3],X_c_atm[1]/X_c_atm[3],X_c_atm[2]/X_c_atm[3]);
00188     FT min_dist=std::numeric_limits<FT>::max();
00189     
00190     typename std::list<const Atom*>::iterator min_it=candidate_list.end();
00191     for (typename std::list<const Atom*>::iterator it=candidate_list.begin();it!=candidate_list.end();++it){
00192       FT curr_dist=squared_distance(barycenter,*(*it));
00193       if (curr_dist < min_dist){
00194         min_it=it;
00195         min_dist=curr_dist;
00196       }
00197     }
00198     assert(min_it!=candidate_list.end());
00199     static_cast<typename Coarse_atom::Point_3&>(c_atm)=static_cast<const typename Atom::Point_3&>(*(*min_it));
00200 
00201         
00202     *out++=c_atm;
00203     return 1;
00204   }
00205 };
00206 
00207 template<class Residue,class FT_>
00208 const std::string 
00209 Coarse_creator_closest_to_barycenter<Residue,FT_>::info_=
00210 "Coarse model using one pseudo-atom centered at the atom closest to the barycenter of the side-chain and the C-alpha of each residue";
00211 
00212 
00213 
00214 
00215 
00216 } //namespace ESBTL
00217 
00218 #endif //ESBTL_COARSE_CREATORS_H