Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef ESBTL_ATOM_CLASSIFIER_H
00035 #define ESBTL_ATOM_CLASSIFIER_H
00036
00037 #include <boost/unordered_map.hpp>
00038 #include<boost/lexical_cast.hpp>
00039 #include <boost/algorithm/string.hpp>
00040 #include <iostream>
00041 #include <sstream>
00042 #include <fstream>
00043
00044
00045 namespace ESBTL{
00046
00093 template <class NT,class Atom>
00094 class Radius_of_atom{
00095 private:
00096 typedef Radius_of_atom<NT,Atom> Self;
00097 NT radius_;
00098 unsigned index_;
00099
00100 public:
00102 typedef Atom Query_type;
00104 typedef std::string Key_type;
00106 typedef NT Value_type;
00107
00108
00114
00115 Radius_of_atom(const NT& radius,const unsigned& index):radius_(radius),index_(index){}
00116 NT value() const {return radius_;}
00117
00124
00125 Radius_of_atom(std::stringstream& ss,unsigned index):index_(index){
00126 ss >> radius_;
00127 }
00128
00137 template <class Dictionary,class Vector_properties>
00138 static unsigned default_loader(Dictionary& dict,Vector_properties& vect)
00139 {
00141 #include <ESBTL/properties/Tsai_jmb_99_radii.h>
00143 }
00144
00149 static std::string make_key(const Atom& atom)
00150 {
00151 return atom.residue_name()+atom.atom_name();
00152 }
00153
00161 template <class Dictionary>
00162 static
00163 unsigned add_classification(std::stringstream& ss,Dictionary& dict){
00164 std::string resname,atmname;
00165 ss >> resname;
00166 ss >> atmname;
00167 unsigned prop;
00168 ss >> prop;
00169 dict[resname+atmname]=prop;
00170 return prop;
00171 }
00172
00177 static void handle_extra(std::stringstream&){}
00178
00183 static
00184 int& index_of_default(){
00185 static int index_of_default=-1;
00186 return index_of_default;
00187 }
00188
00189 };
00190
00192 template <class NT,class Atom>
00193 NT get_radius(const Radius_of_atom<NT,Atom>& property){
00194 return property.value();
00195 }
00196
00197
00202 template <class NT,class Atom>
00203 class Name_and_radius_of_atom{
00204 private:
00205 typedef Name_and_radius_of_atom<NT,Atom> Self;
00207
00208 static
00209 unsigned& water_index(){
00210 static unsigned index=9;
00211 return index;
00212 }
00213
00215 static
00216 std::string water_name(){
00217 static std::string water_name="Owat";
00218 return water_name;
00219 }
00220
00221 public:
00222
00223 typedef Atom Query_type;
00224 typedef std::string Key_type;
00225
00226
00227 Name_and_radius_of_atom(const std::string& name_,const NT& radius_,const unsigned& index_):name(name_),index(index_),radius(radius_)
00228 {}
00229
00230 std::string name;
00231 unsigned index;
00232 NT radius;
00233
00234 bool is_water() const {
00235 assert(index!=water_index() || name==water_name());
00236 return index==water_index();
00237 }
00238
00239 template <class Dictionary,class Vector_properties>
00240 static unsigned default_loader(Dictionary& dict,Vector_properties& vect)
00241 {
00243 #include <ESBTL/properties/default_atom_properties.h>
00245 }
00246
00247 static std::string make_key(const Atom& atom)
00248 {
00249 return atom.residue_name()+atom.atom_name();
00250 }
00251
00252 static
00253 int& index_of_default(){
00254 static int index_of_default=-1;
00255 return index_of_default;
00256 }
00257
00258 };
00259
00265 class Name_of_pair{
00266 private:
00267 typedef Name_of_pair Self;
00268
00269
00270 public:
00271
00272
00273 static
00274 int& index_of_default(){
00275 static int index_of_default=-1;
00276 return index_of_default;
00277 }
00278
00279
00280
00281 typedef std::string Key_type;
00282 typedef std::pair<unsigned,unsigned> Query_type;
00283
00284 Name_of_pair(const std::string& name_,const unsigned& index_):name(name_),index(index_){}
00285 std::string name;
00286 unsigned index;
00287
00288 template <class Dictionary,class Vector_properties>
00289 static unsigned default_loader(Dictionary& dict,Vector_properties& vect)
00290 {
00292 #include <ESBTL/properties/default_pair_properties.h>
00294 }
00295
00296 static Key_type make_key(const Query_type& indices)
00297 {
00298 unsigned i0=indices.first;
00299 unsigned i1=indices.second;
00300 if (i0<i1)
00301 return boost::lexical_cast<std::string>(i0)+
00302 boost::lexical_cast<std::string>(i1);
00303
00304
00305 return boost::lexical_cast<std::string>(i1)+
00306 boost::lexical_cast<std::string>(i0);
00307 }
00308 };
00309
00310
00311
00317 template<class Properties_>
00318 struct Generic_classifier{
00319 typedef Properties_ Properties;
00320 typedef typename Properties_::Key_type Key_type;
00321 typedef typename Properties_::Query_type Query_type;
00322 typedef typename std::vector<Properties_>::iterator Properties_iterator;
00323 typedef typename std::vector<Properties_>::const_iterator Properties_const_iterator;
00324 private:
00325 typedef boost::unordered_map<Key_type, unsigned> Internal_map_type;
00326 typedef std::vector<Properties_> Internal_vector_type;
00327
00328 Internal_map_type hmap_;
00329 Internal_vector_type properties_;
00330 unsigned max_index_;
00331
00332 public:
00333
00337 Generic_classifier(){
00338 max_index_=Properties_::default_loader(hmap_,properties_);
00339 assert(max_index_==properties_.size());
00340 }
00341
00343 Generic_classifier(std::string filename,int){
00344
00345
00346 }
00347
00379 Generic_classifier(const std::string& filename){
00380 enum Read_state {PROPERTIES, CLASSIFICATION, END, EXTRA,DEFAULT};
00381
00382 std::ifstream input(filename.c_str());
00383
00384 if (!input){
00385 std::cerr << "Cannot open file " << filename << std::endl;
00386 exit( EXIT_FAILURE);
00387 }
00388
00389 std::string buffer;
00390 Read_state state=END;
00391
00392 std::map<unsigned,Properties> properties_map;
00393 unsigned max_property=0;
00394
00395
00396 while(input){
00397 std::getline(input,buffer);
00398
00399 if (!input) {
00400 if (input.eof()) break;
00401 std::cerr << "Fatal error: Error while reading file "<< filename <<"\n";
00402 exit( EXIT_FAILURE );
00403 }
00404
00405 boost::trim(buffer);
00406 if (buffer.empty() || buffer[0] == '#') continue;
00407
00408 switch (state){
00409 case END:
00410 if (buffer == "PROPERTIES") {state=PROPERTIES; break;}
00411 if (buffer == "CLASSIFICATION") {state=CLASSIFICATION; break;}
00412 if (buffer == "EXTRA") {state=EXTRA; break;}
00413 if (buffer == "DEFAULT") {state=DEFAULT; break;}
00414 std::cerr << "Fatal error: Error while reading file "<< filename;
00415 std::cerr << ", unexpected <|" << buffer << "|> found.\n";
00416 exit( EXIT_FAILURE );
00417 case CLASSIFICATION:
00418 {
00419 if (buffer=="END") {state=END; break;}
00420 std::stringstream ss (std::stringstream::in | std::stringstream::out);
00421 ss << buffer;
00422
00423 unsigned index=Properties::add_classification(ss,hmap_);
00424 if (max_property < index) max_property=index;
00425 break;
00426 }
00427 case PROPERTIES:
00428 {
00429 if (buffer=="END") {state=END; break;}
00430 std::stringstream ss (std::stringstream::in | std::stringstream::out);
00431 ss << buffer;
00432 unsigned index;
00433 ss >> index;
00434
00435 assert(properties_map.find(index)==properties_map.end());
00436 properties_map.insert(std::make_pair(index,Properties(ss,index)));
00437 break;
00438 }
00439 case DEFAULT:
00440 {
00441 if (buffer=="END") {state=END; break;}
00442 unsigned i;
00443 std::stringstream ss (std::stringstream::in | std::stringstream::out);
00444 ss << buffer;
00445 ss >> i;
00446 if ( max_property<i ) max_property=i;
00447 Properties::index_of_default()=i;
00448 break;
00449 }
00450 case EXTRA:
00451 {
00452 if (buffer=="END") {state=END; break;}
00453
00454 std::stringstream ss (std::stringstream::in | std::stringstream::out);
00455 ss << buffer;
00456 Properties::handle_extra(ss);
00457 break;
00458 }
00459 };
00460 }
00461
00462
00463 unsigned i=0;
00464 for (typename std::map<unsigned,Properties>::const_iterator it=properties_map.begin();it!=properties_map.end();++it){
00465 if (i++ != it->first){
00466 std::cerr << "Fatal error: properties number " << i-1 << " could not be found in file " << filename <<"\n";
00467 exit( EXIT_FAILURE );
00468 }
00469 properties_.push_back(it->second);
00470 }
00471
00472 if (i <= max_property){
00473 std::cerr << "Fatal error: Up to " << max_property+1 << " properties are used, but only " << i << " are declared.\n";
00474 exit( EXIT_FAILURE );
00475 }
00476
00477 max_index_=i;
00478
00479 }
00480
00484 const Properties& get_properties(unsigned i) const{
00485 assert(i <= max_index_);
00486 return properties_[i];
00487 }
00488
00492 const Properties& get_properties(const Query_type& query) const{
00493 typename Internal_map_type::const_iterator it=hmap_.find( Properties_::make_key(query) );
00494 if ( it==hmap_.end() ){
00495 if (Properties::index_of_default()!=-1)
00496 return properties_[Properties::index_of_default()];
00497 std::cerr << "Fatal error: Could not find an entry for " << Properties_::make_key(query);
00498 std::cerr << " and no default have been defined.\n";
00499 exit( EXIT_FAILURE );
00500 }
00501 return properties_[it->second];
00502 }
00503
00505 unsigned number_of_properties() const {return max_index_;}
00506
00508 Properties_iterator properties_begin(){ return properties_.begin();}
00510 Properties_const_iterator properties_begin() const { return properties_.begin();}
00512 Properties_iterator properties_end(){ return properties_.end(); }
00514 Properties_const_iterator properties_end() const { return properties_.end(); }
00515
00516 };
00517
00518
00523 template <class Atom_classifier>
00524 struct Weight_of_atoms{
00525
00527 Weight_of_atoms(const Atom_classifier* atom_classifier):atom_classifier_(atom_classifier){}
00528
00533 typename Atom_classifier::Properties::Value_type
00534 operator()(const typename Atom_classifier::Query_type& atom) const {
00535 typename Atom_classifier::Properties::Value_type value=get_radius(atom_classifier_->get_properties(atom));
00536 return value*value;
00537 }
00538 private:
00539 const Atom_classifier* atom_classifier_;
00540 };
00541
00542 }
00543
00544 #endif //ESBTL_ATOM_CLASSIFIER_H