line_selectors.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_LINE_SELECTORS_H
00036 #define ESBTL_LINE_SELECTORS_H
00037 
00038 #include <ESBTL/global_functions.h>
00039 #include <ESBTL/PDB.h>
00040 #include <map>
00041 
00042 namespace ESBTL{
00043 
00069 class PDB_line_selector{
00070   public:
00071   int discarded;
00072   
00073   PDB_line_selector():discarded(0){}
00074   
00075   //return the system pattern that matches the line: 0 remark, 1...n coordinates, -1 to discard
00076   template <class Line_format,class Occupancy_handler>
00077   int keep(const Line_format& line_format,const std::string& line,Occupancy_handler& occupancy){
00078     if (line_format.record_type()==PDB::ATOM || line_format.record_type()==PDB::HETATM)
00079       return occupancy.add_or_postpone(line_format,line,1);
00080     
00081     if (line_format.record_type()==PDB::MODEL)
00082       return RMK;
00083     ++discarded;
00084     return DISCARD;
00085   }
00086   
00087   unsigned max_nb_systems() const {return 1;}
00088   
00089 };
00090 
00096 class PDB_line_selector_two_systems{
00097   public:
00098   
00099   //return the system pattern that matches the line: 0 remark, 1...n coordinates, -1 to discard
00100   template <class Line_format,class Occupancy_handler>
00101   int keep(const Line_format& line_format,const std::string& line,Occupancy_handler& occupancy){
00102     
00103     if (line_format.record_type()==PDB::ATOM || line_format.record_type()==PDB::HETATM){
00104       if (is_hydrogen(std::make_pair(line_format,line)) )  return DISCARD;
00105       if ( is_water(std::make_pair(line_format,line)) ) return occupancy.add_or_postpone(line_format,line,2);
00106       return occupancy.add_or_postpone(line_format,line,1);
00107     }
00108 
00109     if (line_format.record_type()==PDB::MODEL)
00110       return RMK;
00111     return DISCARD;
00112   }
00113   
00114   unsigned max_nb_systems() const {return 2;}
00115   
00116 };
00117 
00118 
00122 class PDB_line_selector_chain{
00123   typedef std::map<char,int> System_indices;
00124   System_indices system_index_map_;
00125   bool keep_hydrogen_;
00126   bool keep_water_;
00127   bool keep_remaining_chains_;
00128   double Water_Bfactorlim_;
00129   int max_chain_index;
00130   
00131   unsigned nb_atm_htm_seen_;
00132   
00133   public:
00134   int discarded;
00135 
00136   const unsigned& nb_atm_htm_seen() const {
00137     return nb_atm_htm_seen_;
00138   }
00139   
00140   //TODO enable_if only for string
00141   //all characters of one string belong to the same system
00153   template<class Str_iterator>
00154   PDB_line_selector_chain
00155   (const Str_iterator& begin,const Str_iterator& end,
00156    bool keep_water=true,bool keep_remaining_chains=false,
00157    double Water_Bfactorlim=200,bool keep_hydrogen=false):
00158     keep_hydrogen_(keep_hydrogen),keep_water_(keep_water),keep_remaining_chains_(keep_remaining_chains),
00159     Water_Bfactorlim_(Water_Bfactorlim),max_chain_index(0),nb_atm_htm_seen_(0),discarded(0)
00160   {
00161     for (Str_iterator it=begin;it!=end;++it){
00162       const std::string& str=*it;
00163       ++max_chain_index;
00164       for (int i=0;i!= (int) str.size();++i)
00165         system_index_map_.insert(std::make_pair(str[i],max_chain_index));
00166     }
00167   }
00168   
00169   
00170   //return the system pattern that matches the line: 0 remark, 1...n coordinates, -1 to discard
00171   template <class Line_format,class Occupancy_handler>
00172   int keep(const Line_format& line_format,const std::string& line,Occupancy_handler& occupancy){
00173     if (line_format.record_type()==PDB::ATOM || line_format.record_type()==PDB::HETATM){
00174       
00175       System_indices::iterator it=system_index_map_.find(line_format.get_chain_identifier(line));
00176       ++nb_atm_htm_seen_;
00177       
00178       //Filter hydrogen
00179       if (!keep_hydrogen_ && is_hydrogen(std::make_pair(line_format,line)) )
00180         return DISCARD;
00181       
00182 
00183       //Filter water
00184       if ( is_water(std::make_pair(line_format,line)) ){
00185         //Filter Temperature factor too high
00186         if ( !keep_water_ || line_format.get_temperature_factor(line) > Water_Bfactorlim_)
00187           return DISCARD;
00188         else
00189           return occupancy.add_or_postpone(line_format,line,max_chain_index+1);
00190       }
00191 
00192       if ( it==system_index_map_.end() ){
00193         if (keep_remaining_chains_)
00194           return occupancy.add_or_postpone(line_format,line,max_chain_index+(keep_water_?2:1));
00195         return DISCARD;
00196       }
00197       return occupancy.add_or_postpone(line_format,line,it->second);
00198     }
00199 
00200     if (line_format.record_type()==PDB::MODEL)
00201       return RMK;
00202     ++discarded;
00203     return DISCARD;
00204   }
00205   
00206   unsigned max_nb_systems() const {return max_chain_index+(keep_water_?1:0)+(keep_remaining_chains_?1:0); }
00207 };
00208 
00209 
00210 //generic line selector
00211 //---------------------------------------
00216 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00217 
00219 #define GENERIC_LINE_SELECTOR_COMMON_PART \
00220   public: \
00221   \
00222   template <class Line_format,class Occupancy_handler> \
00223   int keep(const Line_format& line_format,const std::string& line,Occupancy_handler& occupancy) const{ \
00224   \
00225     if (line_format.record_type()==PDB::ATOM || line_format.record_type()==PDB::HETATM){ \
00226       int ret=operator()(std::make_pair(line_format,line)); \
00227       if (ret!=-1) \
00228         return occupancy.add_or_postpone(line_format,line,ret);\
00229       return DISCARD;  \
00230     }\
00231   \
00232     if (line_format.record_type()==PDB::MODEL)\
00233       return RMK;\
00234     return DISCARD;\
00235   }\
00236   \
00237   static unsigned max_nb_systems() { return nb_system;}
00238 
00239 template <class T1,class T2=void,class T3=void,class T4=void,class T5=void,class T6=void,class T7=void, class T8=void,class T9=void,class T10=void>
00240 class Generic_line_selector;
00241 
00242 
00243 template <class T1>
00244 class Generic_line_selector<T1>
00245 {
00246   T1 t1_;
00247   static const unsigned nb_system=1;
00248 public:
00249   Generic_line_selector(){};  
00250   Generic_line_selector(const T1& t1):t1_(t1){}
00251 protected:    
00252   template <class Line_format>
00253   int operator()(const std::pair<Line_format,std::string>& p) const 
00254   {
00255     if (t1_(p))
00256       return 1;
00257     return -1;
00258   }
00259   
00260   GENERIC_LINE_SELECTOR_COMMON_PART
00261 };
00262 
00263 template <class T1,class T2>
00264 class Generic_line_selector<T1,T2>
00265 {
00266   T1 t1_;
00267   T2 t2_;
00268 public:
00269   Generic_line_selector(){};  
00270   Generic_line_selector(const T1& t1,const T2& t2):t1_(t1),t2_(t2){}
00271 protected:    
00272   static const unsigned nb_system=2;  
00273   template <class Line_format>
00274   int operator()(const std::pair<Line_format,std::string>& p) const 
00275   {
00276     if (t1_(p))
00277       return 1;
00278     if (t2_(p))    
00279       return 2;
00280     return -1;
00281   }
00282     
00283   GENERIC_LINE_SELECTOR_COMMON_PART
00284 };
00285 
00286 
00287 template <class T1,class T2, class T3>
00288 class Generic_line_selector<T1,T2,T3>: public Generic_line_selector<T2,T3>
00289 {
00290   T1 t1_;
00291 public:
00292   Generic_line_selector(){};
00293   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3):t1_(t1),Generic_line_selector<T2,T3>(t2,t3){}
00294 protected:    
00295   static const unsigned nb_system=Generic_line_selector<T2,T3>::nb_system + 1;  
00296   template <class Line_format>
00297   int operator()(const std::pair<Line_format,std::string>& p) const 
00298   {
00299     if (t1_(p))
00300       return 1;
00301     int ret=Generic_line_selector<T2,T3>::operator()(p);
00302     if (ret!=-1)
00303       return 1+ret;
00304     return -1;
00305   }
00306 
00307   GENERIC_LINE_SELECTOR_COMMON_PART  
00308 };
00309 
00310 template <class T1,class T2, class T3,class T4>
00311 class Generic_line_selector<T1,T2,T3,T4>: public Generic_line_selector<T2,T3,T4>
00312 {
00313   T1 t1_;
00314 public:
00315   Generic_line_selector(){};
00316   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4):
00317     t1_(t1),Generic_line_selector<T2,T3,T4>(t2,t3,t4){}
00318 protected:    
00319   static const unsigned nb_system=Generic_line_selector<T2,T3,T4>::nb_system + 1;
00320   template <class Line_format>
00321   int operator()(const std::pair<Line_format,std::string>& p) const 
00322   {
00323     if (t1_(p))
00324       return 1;
00325     int ret=Generic_line_selector<T2,T3,T4>::operator()(p);
00326     if (ret!=-1)
00327       return 1+ret;
00328     return -1;
00329   }
00330 
00331   GENERIC_LINE_SELECTOR_COMMON_PART  
00332 };
00333 
00334 template <class T1,class T2, class T3,class T4,class T5>
00335 class Generic_line_selector<T1,T2,T3,T4,T5>: public Generic_line_selector<T2,T3,T4,T5>
00336 {
00337   T1 t1_;
00338 public:
00339   Generic_line_selector(){};
00340   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5):
00341     t1_(t1),Generic_line_selector<T2,T3,T4,T5>(t2,t3,t4,t5){}
00342 protected:    
00343   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5>::nb_system + 1;
00344   template <class Line_format>
00345   int operator()(const std::pair<Line_format,std::string>& p) const 
00346   {
00347     if (t1_(p))
00348       return 1;
00349     int ret=Generic_line_selector<T2,T3,T4,T5>::operator()(p);
00350     if (ret!=-1)
00351       return 1+ret;
00352     return -1;
00353   }
00354 
00355   GENERIC_LINE_SELECTOR_COMMON_PART  
00356 };
00357 
00358 template <class T1,class T2, class T3,class T4,class T5, class T6>
00359 class Generic_line_selector<T1,T2,T3,T4,T5,T6>: public Generic_line_selector<T2,T3,T4,T5,T6>
00360 {
00361   T1 t1_;
00362 public:
00363   Generic_line_selector(){};
00364   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5,const T6& t6):
00365     t1_(t1),Generic_line_selector<T2,T3,T4,T5,T6>(t2,t3,t4,t5,t6){}
00366 protected:    
00367   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5,T6>::nb_system + 1;
00368   template <class Line_format>
00369   int operator()(const std::pair<Line_format,std::string>& p) const 
00370   {
00371     if (t1_(p))
00372       return 1;
00373     int ret=Generic_line_selector<T2,T3,T4,T5,T6>::operator()(p);
00374     if (ret!=-1)
00375       return 1+ret;
00376     return -1;
00377   }
00378 
00379   GENERIC_LINE_SELECTOR_COMMON_PART  
00380 };
00381 
00382 
00383 template <class T1,class T2, class T3,class T4,class T5, class T6,class T7>
00384 class Generic_line_selector<T1,T2,T3,T4,T5,T6,T7>: public Generic_line_selector<T2,T3,T4,T5,T6,T7>
00385 {
00386   T1 t1_;
00387 public:
00388   Generic_line_selector(){};
00389   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5,const T6& t6,const T7& t7):
00390     t1_(t1),Generic_line_selector<T2,T3,T4,T5,T6,T7>(t2,t3,t4,t5,t6,t7){}
00391 protected:    
00392   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5,T6,T7>::nb_system + 1;
00393   template <class Line_format>
00394   int operator()(const std::pair<Line_format,std::string>& p) const 
00395   {
00396     if (t1_(p))
00397       return 1;
00398     int ret=Generic_line_selector<T2,T3,T4,T5,T6,T7>::operator()(p);
00399     if (ret!=-1)
00400       return 1+ret;
00401     return -1;
00402   }
00403 
00404   GENERIC_LINE_SELECTOR_COMMON_PART  
00405 };
00406 
00407 template <class T1,class T2, class T3,class T4,class T5, class T6,class T7,class T8>
00408 class Generic_line_selector<T1,T2,T3,T4,T5,T6,T7,T8>: public Generic_line_selector<T2,T3,T4,T5,T6,T7,T8>
00409 {
00410   T1 t1_;
00411 public:
00412   Generic_line_selector(){};
00413   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5,const T6& t6,const T7& t7,const T8& t8):
00414     t1_(t1),Generic_line_selector<T2,T3,T4,T5,T6,T7,T8>(t2,t3,t4,t5,t6,t7,t8){}
00415 protected:    
00416   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8>::nb_system + 1;
00417   template <class Line_format>
00418   int operator()(const std::pair<Line_format,std::string>& p) const 
00419   {
00420     if (t1_(p))
00421       return 1;
00422     int ret=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8>::operator()(p);
00423     if (ret!=-1)
00424       return 1+ret;
00425     return -1;
00426   }
00427 
00428   GENERIC_LINE_SELECTOR_COMMON_PART  
00429 };
00430 
00431 template <class T1,class T2, class T3,class T4,class T5, class T6,class T7,class T8, class T9>
00432 class Generic_line_selector<T1,T2,T3,T4,T5,T6,T7,T8,T9>: public Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9>
00433 {
00434   T1 t1_;
00435 public:
00436   Generic_line_selector(){};
00437   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5,const T6& t6,const T7& t7,const T8& t8,const T9& t9):
00438     t1_(t1),Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9>(t2,t3,t4,t5,t6,t7,t8,t9){}
00439 protected:    
00440   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9>::nb_system + 1;
00441   template <class Line_format>
00442   int operator()(const std::pair<Line_format,std::string>& p) const 
00443   {
00444     if (t1_(p))
00445       return 1;
00446     int ret=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9>::operator()(p);
00447     if (ret!=-1)
00448       return 1+ret;
00449     return -1;
00450   }
00451 
00452   GENERIC_LINE_SELECTOR_COMMON_PART  
00453 };
00454 
00464 template <class T1,class T2, class T3,class T4,class T5, class T6,class T7,class T8, class T9,class T10>
00465 class Generic_line_selector: public Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9,T10>
00466 {
00467   T1 t1_;
00468 public:
00469   Generic_line_selector(){};
00470   Generic_line_selector(const T1& t1,const T2& t2,const T3& t3,const T4& t4,const T5& t5,const T6& t6,const T7& t7,const T8& t8,const T9& t9,const T10& t10):
00471     t1_(t1),Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9,T10>(t2,t3,t4,t5,t6,t7,t8,t9,t10){}
00472 protected:    
00473   static const unsigned nb_system=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9,T10>::nb_system + 1;
00474   template <class Line_format>
00475   int operator()(const std::pair<Line_format,std::string>& p) const 
00476   {
00477     if (t1_(p))
00478       return 1;
00479     int ret=Generic_line_selector<T2,T3,T4,T5,T6,T7,T8,T9,T10>::operator()(p);
00480     if (ret!=-1)
00481       return 1+ret;
00482     return -1;
00483   }
00484 
00485   GENERIC_LINE_SELECTOR_COMMON_PART  
00486 };
00487 
00488 
00489 #else
00490 
00491 namespace internal{
00492 template <class ... T>
00493 struct Generic_line_selector_base;
00494 
00495 template <class T0,class ... T>
00496 struct Generic_line_selector_base<T0,T...>: public Generic_line_selector_base<T...>{
00497   static const unsigned nb_system=Generic_line_selector_base<T...>::nb_system + 1;
00498   T0 t0_;
00499 
00500   Generic_line_selector_base(){}
00501   Generic_line_selector_base(const T0& t0,const T& ... ts):Generic_line_selector_base<T...>(ts...),t0_(t0){}
00502   
00503   template <class Line_format>
00504   int operator()(const std::pair<Line_format,std::string>& p) const
00505   {
00506     if (t0_(p))
00507       return 1;
00508     int ret=Generic_line_selector_base<T...>::operator()(p);
00509     if (ret!=-1) return ret+1;
00510     return -1;
00511   }
00512 };
00513 
00514 template <class T0>
00515 struct Generic_line_selector_base<T0>{
00516   static const unsigned nb_system=1;
00517   T0 t0_;
00518   
00519   Generic_line_selector_base() {}
00520   Generic_line_selector_base(const T0& t0):t0_(t0) {}
00521   
00522   template <class Line_format>
00523   int operator()(const std::pair<Line_format,std::string>& p) const {
00524     if (t0_(p))
00525       return 1;
00526     return -1;
00527   }
00528 };
00529 
00530 } //namespace internal
00531 
00532 
00533 template <class ... T>
00534 class Generic_line_selector: public internal::Generic_line_selector_base<T ... >{
00535   public:
00536   
00537   Generic_line_selector(){}
00538   Generic_line_selector(const T& ... ts):internal::Generic_line_selector_base<T...>(ts...){}
00539   
00540   //return the system pattern that matches the line: 0 remark, 1...n coordinates, -1 to discard
00541   template <class Line_format,class Occupancy_handler>
00542   int keep(const Line_format& line_format,const std::string& line,Occupancy_handler& occupancy){
00543     
00544     if (line_format.record_type()==PDB::ATOM || line_format.record_type()==PDB::HETATM){
00545       int ret=internal::Generic_line_selector_base<T ... >::operator()(std::make_pair(line_format,line));
00546       if (ret!=-1)
00547         return occupancy.add_or_postpone(line_format,line,ret);
00548       return DISCARD;  
00549     }
00550 
00551     if (line_format.record_type()==PDB::MODEL)
00552       return RMK;
00553     return DISCARD;
00554   }
00555   
00556   static unsigned max_nb_systems() {
00557     return internal::Generic_line_selector_base<T ... >::nb_system;
00558   }
00559   
00560 };
00562 #endif
00563 
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 }// namespace ESBTL 
00576 
00577 #endif //ESBTL_LINE_SELECTORS_H