Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Fingerprint.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file protocols/pockets/Fingerprint.cc
11 /// @brief protocols::pockets::Fingerprint functions
12 /// @author Ragul Gowthaman
13 
14 // Protocol Headers
15 #include <numeric/constants.hh>
18 
19 // Core Headers
20 #include <core/pose/Pose.hh>
21 #include <core/id/AtomID_Map.hh>
25 #include <core/types.hh>
26 #include <numeric/xyz.functions.hh>
27 #include <numeric/xyzMatrix.hh>
28 #include <numeric/conversions.hh>
29 #include <utility/io/ozstream.hh>
30 
31 // Utility Headers
32 #include <basic/options/option.hh>
33 #include <basic/options/keys/OptionKeys.hh>
34 #include <basic/options/keys/fingerprint.OptionKeys.gen.hh>
35 #include <basic/database/open.hh>
36 
37 #include <iostream>
38 #include <iomanip>
39 #include <fstream>
40 #include <ostream>
41 #include <string>
42 #include <sstream>
43 #include <cmath>
44 #include <map>
45 
46 #include <utility/vector1.hh>
47 
48 //Auto Headers
49 #include <numeric/random/random.fwd.hh>
50 
51 using namespace core;
52 using namespace core::scoring;
53 using namespace std;
54 
55 
56 namespace protocols {
57 namespace pockets {
58 
59 FingerprintBase::FingerprintBase () :
60  ReferenceCount()
61 {
62  origin_.zero();
63  CoM_.zero();
64 }
65 
66 /// @details Auto-generated virtual destructor
68 
69 void FingerprintBase::print_to_file(std::string const & output_filename) const {
70 
71  utility::io::ozstream out_stream;
72  out_stream.open(output_filename, std::ios::out);
73  out_stream<<"/ORI/"<<std::fixed<<std::setprecision(2)<< origin_.x() << "\t" <<std::fixed<<std::setprecision(2)<< origin_.y() << "\t"<<std::fixed<<std::setprecision(3)<< origin_.z() <<std::endl;
74  out_stream<<"/COM/"<<std::fixed<<std::setprecision(2)<< CoM_.x() << "\t" <<std::fixed<<std::setprecision(2)<< CoM_.y() << "\t"<<std::fixed<<std::setprecision(3)<< CoM_.z() <<std::endl;
75  for (std::list<spherical_coor_triplet>::const_iterator fi = triplet_fingerprint_data_.begin(); fi != triplet_fingerprint_data_.end(); ++fi) {
76  out_stream<<std::fixed<<std::setprecision(2)<< fi->phi << "\t" <<std::fixed<<std::setprecision(2)<<fi->psi << "\t"<<std::fixed<<std::setprecision(3)<< fi->rho <<std::endl;
77  }
78  out_stream.close();
79  out_stream.clear();
80 
81  return;
82 }
83 
84 void FingerprintBase::print_to_pdb(std::string const & output_pdbname) const {
85  numeric::xyzVector<core::Real> no_translation(0.);
86  print_to_pdb( output_pdbname, no_translation );
87 }
88 
89 void FingerprintBase::print_to_pdb(std::string const & output_pdbname, numeric::xyzVector<core::Real> const & translation) const {
90 
91  utility::io::ozstream out_stream;
92  out_stream.open(output_pdbname, std::ios::out);
93 
94  out_stream<<"HETATM "<<std::setw(2)<<1<<" C ORI X 0 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.x()+translation.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.y()+translation.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.z()+translation.z()<<std::endl;
95  out_stream<<"HETATM "<<std::setw(2)<<1<<" C COM X 0 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.x()+translation.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.y()+translation.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.z()+translation.z()<<std::endl;
96  for (std::list<spherical_coor_triplet>::const_iterator pd = triplet_fingerprint_data_.begin(); pd != triplet_fingerprint_data_.end(); ++pd) {
99  new_coor += origin_;
100  out_stream<<"HETATM "<<std::setw(2)<<1<<" C MAP A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.x()+translation.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.y()+translation.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.z()+translation.z()<<std::endl;
101  }
102 
103  out_stream.close();
104  out_stream.clear();
105 
106  return;
107 }
108 
110  origin_ = pfp.origin();
112  std::copy (pfp.triplet_fingerprint_data().begin(),pfp.triplet_fingerprint_data().end(), triplet_fingerprint_data_.begin());
113  return;
114 }
115 
116 //use same grid for both egg and ext shell
117 void NonPlaidFingerprint::setup_from_PocketGrid( core::pose::Pose const & protein_pose, PocketGrid const & pocket_grid ) {
118 
119  PocketGrid grid_for_extshell = pocket_grid;
120  setup_from_PocketGrid(protein_pose, pocket_grid, grid_for_extshell);
121 
122  return;
123 }
124 
125 void NonPlaidFingerprint::setup_from_PocketGrid( core::pose::Pose const & protein_pose, PocketGrid const & pocket_grid, PocketGrid const & grid_for_extshell ) {
126  EggshellGrid egg_sg(pocket_grid);
128  EggshellGrid ext_sg(grid_for_extshell, eggshell_list_);
129  extshell_list_ = ext_sg.extra_coord_list();
130 
131  //combine eggshell & extra coord list into a single list
132  egg_and_ext_list_.clear();
134 
135  //set CoM_ to the eggshell CoM
136  CoM_ = egg_sg.eggshell_CoM_;
137 
138  //set origin
139  set_origin( protein_pose, egg_and_ext_list_);
140 
142 
143  return;
144 }
145 
146 void NonPlaidFingerprint::write_eggshell_to_pdb_file( std::string const & output_eggshell_name ) const {
147 
148  utility::io::ozstream outPDB_stream;
149  outPDB_stream.open(output_eggshell_name, std::ios::out);
150  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C ORI A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.z()<<std::endl;
151  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C COM A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.z()<<std::endl;
152  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = eggshell_list_.begin(); pd != eggshell_list_.end(); ++pd) {
153  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C EGG A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->z()<<std::endl;
154  }
155  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = extshell_list_.begin(); pd != extshell_list_.end(); ++pd) {
156  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" O EXT B 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->z()<<std::endl;
157  }
158  outPDB_stream.close();
159  outPDB_stream.clear();
160 
161 }
162 
163 void NonPlaidFingerprint::set_origin( core::pose::Pose const & protein_pose, std::list< numeric::xyzVector<core::Real> > const & egg_and_extra_shell ) {
164  using namespace basic::options;
165  int origin_option = option[ OptionKeys::fingerprint::set_origin ];
166  Size best_origin_option(0);
167  if (origin_option == 0){
168  //choose best origin by finding the lowest R (ruggedness) value from different origin position
169  core::Real best_R(999.);
170  for(Size set_origin_option = 1; set_origin_option < 4; ++set_origin_option){
171  core::Real new_R = get_Rvalue( protein_pose, egg_and_extra_shell, set_origin_option );
172  //std::cout << "set_origin_option " << set_origin_option << " new_Rvalue " << new_R << std::endl;
173  if ( new_R < best_R ) {
174  best_R = new_R;
175  best_origin_option = set_origin_option;
176  }
177  }
178  //std::cout << "best_origin_option " << best_origin_option << " best_Rvalue " << best_R << std::endl;
179  } else {
180  best_origin_option = origin_option;
181  }
182  set_origin_from_option_( protein_pose, egg_and_extra_shell, best_origin_option );
183 
184 }
185 
186 core::Real NonPlaidFingerprint::get_Rvalue( core::pose::Pose const & protein_pose, std::list< numeric::xyzVector<core::Real> > const & egg_and_extra_shell, Size const & set_origin_option ) {
187 
188  set_origin_from_option_( protein_pose, egg_and_extra_shell, set_origin_option );
189 
190  core::Real min_rho_difference(0.);
191  core::Size num_points(0);
192  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pt1 = egg_and_extra_shell.begin(); pt1 != egg_and_extra_shell.end(); ++pt1) {
193  numeric::xyzVector< core::Real > eggshell_point1 = *pt1 - origin_;
194  spherical_coor_triplet triplet1;
195  convert_cartesian_to_spherical_coor_triplet( eggshell_point1, triplet1 );
196  core::Real min_angle(999.);
197  spherical_coor_triplet triplet2;
198  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pt2 = egg_and_extra_shell.begin(); pt2 != egg_and_extra_shell.end(); ++pt2) {
199  if ( pt1 == pt2 ) continue;
200  core::Real const curr_angle = std::abs(cos_of( *pt1, *pt2 ));
201  if(curr_angle < min_angle){
202  min_angle = curr_angle;
203  numeric::xyzVector< core::Real > eggshell_point2 = *pt2 - origin_;
204  convert_cartesian_to_spherical_coor_triplet( eggshell_point2, triplet2 );
205  }
206  }
207  min_rho_difference += std::abs( triplet1.rho - triplet2.rho );
208  num_points++;
209  }
210  return min_rho_difference / num_points;
211 }
212 
213 void NonPlaidFingerprint::set_origin_from_option_( core::pose::Pose const & protein_pose, std::list< numeric::xyzVector<core::Real> > const & egg_and_extra_shell, Size const & set_origin_option ) {
214 
215  if (set_origin_option == 1){
217  //std::cout<< " ORIGIN1 "<<origin_.x()<<" "<<origin_.y()<<" "<<origin_.z()<<std::endl;
218  } else if (set_origin_option == 2){
219  set_origin_away_from_eggshell(egg_and_extra_shell, protein_pose);
220  //std::cout<< " ORIGIN2 "<<origin_.x()<<" "<<origin_.y()<<" "<<origin_.z()<<std::endl;
221  } else if (set_origin_option == 3){
222  set_origin_away_from_eggshell_plane(egg_and_extra_shell, protein_pose, set_origin_option);
223  //std::cout<< " ORIGIN3 "<<origin_.x()<<" "<<origin_.y()<<" "<<origin_.z()<<std::endl;
224  } else if (set_origin_option == 4){
225  set_origin_away_from_eggshell_plane(egg_and_extra_shell, protein_pose, set_origin_option);
226  //std::cout<< " ORIGIN4 "<<origin_.x()<<" "<<origin_.y()<<" "<<origin_.z()<<std::endl;
227  } else {
228  std::cout<<"Error, wrong option for set_origin" << std::endl;
229  exit(1);
230  }
231  return;
232 }
233 
235 
236  // convert from cartesian eggshell to spherical coors
238  spherical_coor_triplet new_triplet;
239 
240  Size num_int_points = 0;//This is only used when gpu is enabled
241  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = eggshell_list_.begin(); pd != eggshell_list_.end(); ++pd) {
243  triplet_fingerprint_data_.push_back(new_triplet);
244  num_int_points=num_int_points+1;
245  }
246 
247  Size num_ext_points = 0;//This is only used when gpu is enabled
248  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = extshell_list_.begin(); pd != extshell_list_.end(); ++pd) {
250  new_triplet.rho = 0.;
251  triplet_fingerprint_data_.push_back(new_triplet);
252  num_ext_points=num_ext_points+1;
253  }
254 
255 #ifdef USEOPENCL
256  gpu_num_rays_ = num_int_points + num_ext_points;
257  setup_gpu_rays();
258 #endif
259 
260  /*
261  std::list< spherical_coor_triplet > temp_egg_triplet;
262 
263  spherical_coor_triplet new_triplet;
264  numeric::xyzVector<core::Real> new_coord;
265  temp_egg_triplet.clear();
266 
267 
268  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = eggshell_grid.eggshell_coord_list().begin(); pd != eggshell_grid.eggshell_coord_list().end(); ++pd) {
269  convert_cartesian_to_spherical_coor_triplet( *pd - origin_, new_triplet );
270  temp_egg_triplet.push_back(new_triplet);
271  }
272  std::list< spherical_coor_triplet > temp_ext_triplet = temp_egg_triplet;
273  temp_ext_triplet.clear();
274  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = eggshell_grid.extra_coord_list().begin(); pd != eggshell_grid.extra_coord_list().end(); ++pd) {
275  convert_cartesian_to_spherical_coor_triplet( *pd - origin_, new_triplet );
276  temp_ext_triplet.push_back(new_triplet);
277  }
278 
279  //filter phi psi
280  for (std::list<spherical_coor_triplet>::const_iterator aa = temp_egg_triplet.begin(); aa != temp_egg_triplet.end(); ++aa) {
281  for (std::list<spherical_coor_triplet>::iterator bb = temp_ext_triplet.begin(); bb != temp_ext_triplet.end();) {
282  if( (aa->phi == bb->phi) && (aa->psi == bb->psi) ) {
283  std::cout<<"found "<<std::endl;
284  bb = temp_ext_triplet.erase(bb);
285  }
286  else {
287  ++bb;
288  }
289  }
290  }
291 
292  eggshell_list_.clear();
293  extshell_list_.clear();
294  for (std::list<spherical_coor_triplet>::iterator aa = temp_egg_triplet.begin(); aa != temp_egg_triplet.end(); ++aa) {
295  convert_spherical_coor_triplet_to_cartesian( *aa, new_coord );
296  eggshell_list_.push_back(new_coord+origin_);
297  }
298  for (std::list<spherical_coor_triplet>::iterator bb = temp_ext_triplet.begin(); bb != temp_ext_triplet.end(); ++bb) {
299  convert_spherical_coor_triplet_to_cartesian( *bb, new_coord );
300  extshell_list_.push_back(new_coord+origin_);
301  }
302  triplet_fingerprint_data_.clear();
303  triplet_fingerprint_data_ = temp_egg_triplet;
304  for (std::list<spherical_coor_triplet>::iterator bb = temp_ext_triplet.begin(); bb != temp_ext_triplet.end(); ++bb) {
305  bb->rho = 0.;
306  triplet_fingerprint_data_.push_back(*bb);
307  }
308  */
309 
310  return;
311 }
312 
313 #ifdef USEOPENCL
314 void NonPlaidFingerprint::setup_gpu( core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight, int & num_particles, PlaidFingerprint & pf ) {
315  // GPU Initalization
316  if(gpu_.use()) {
317 
318  float weights[4];
319  weights[0] = missing_point_weight;
320  weights[1] = steric_weight;
321  weights[2] = extra_point_weight;
322  weights[3] = num_particles;
323  // Allocate persistent memory for rays
324  gpu_weights_ = gpu_.AllocateMemory(sizeof(*weights) * 4);
325  // Copy ray data to GPU memory
326  gpu_.WriteData(gpu_weights_, weights, sizeof(*weights) * 4);
327 
328  gpu_atoms_ = gpu_.AllocateMemory(sizeof(*atom_) * ATOMS_ARRAY);
329 
330  if(!gpu_ray_scores_) {
331  // Allocate GPU memory for distances (results)
332  gpu_ray_scores_ = gpu_.AllocateMemory(sizeof(*ray_scores_) * RAY_SCORE_ARRAY);
333  }
334 
335  if(!gpu_particle_scores_) {
336  // Allocate GPU memory for distances (results)
337  gpu_particle_scores_ = gpu_.AllocateMemory(sizeof(*particle_scores_) * NUMBER_OF_PARTICLES);
338  }
339 
340  std::string fn = basic::database::full_name("gpu/DARC_PSO.cl");
341  if(!gpu_.RegisterProgram(fn.c_str())) {
342  std::cout << "Failed to load CL kernel." << std::endl;
343  exit(1);
344  }
345 
346  gpu_num_atoms_ = pf.compute_ligand_natoms();
347  gpu_num_particles_ = num_particles;
348 
349  cl_kernel kernel1 = gpu_.BuildKernel("Check_for_intersection");
350  gpu_.setKernelArg(kernel1, 0, sizeof(gpu_rays_), &gpu_rays_);
351  gpu_.setKernelArg(kernel1, 1, sizeof(gpu_atoms_), &gpu_atoms_);
352  gpu_.setKernelArg(kernel1, 2, sizeof(gpu_ray_scores_), &gpu_ray_scores_);
353  gpu_.setKernelArg(kernel1, 3, sizeof(gpu_num_atoms_), &gpu_num_atoms_);
354  gpu_.setKernelArg(kernel1, 4, sizeof(gpu_weights_), &gpu_weights_);
355  gpu_.setKernelArg(kernel1, 5, sizeof(gpu_num_rays_), &gpu_num_rays_);
356 
357  cl_kernel kernel2 = gpu_.BuildKernel("Get_scores");
358  gpu_.setKernelArg(kernel2, 0, sizeof(gpu_ray_scores_), &gpu_ray_scores_);
359  gpu_.setKernelArg(kernel2, 1, sizeof(gpu_particle_scores_), &gpu_particle_scores_);
360  gpu_.setKernelArg(kernel2, 2, sizeof(gpu_num_rays_), &gpu_num_rays_);
361  gpu_.setKernelArg(kernel2, 3, sizeof(gpu_num_particles_), &gpu_num_particles_);
362 
363  }
364 }
365 
366 void NonPlaidFingerprint::free_gpu(){
367  if(gpu_.use()) {
368  if(gpu_rays_) gpu_.Free(gpu_rays_);
369  if(gpu_atoms_) gpu_.Free(gpu_atoms_);
370  if(gpu_ray_scores_) gpu_.Free(gpu_ray_scores_);
371  if(gpu_particle_scores_) gpu_.Free(gpu_particle_scores_);
372  if(gpu_weights_) gpu_.Free(gpu_weights_);
373  }
374 }
375 
376 void NonPlaidFingerprint::setup_gpu_rays() {
377 
378  if(gpu_.use()) {
379  if(gpu_num_rays_>MAX_NUM_RAYS){
380  std::cout << "Too many pocket points" << std::endl;
381  exit(2);
382  }
383 
384  gpu_rays_ = NULL;
385  gpu_atoms_ = NULL;
386  gpu_ray_scores_ = NULL;
387  gpu_particle_scores_ = NULL;
388  gpu_weights_ = NULL;
389  gpu_.profiling(0);
390  gpu_.Init();
391 
392  basic::gpu::float4 rays[MAX_NUM_RAYS];
393 
394  Size i = 0;
395  for (std::list<spherical_coor_triplet>::const_iterator fi = triplet_fingerprint_data_.begin(); fi != triplet_fingerprint_data_.end(); ++fi) {
396  rays[i].x = fi->phi;
397  rays[i].y = fi->psi;
398  rays[i].z = fi->rho;
399  ++i;
400  }
401 
402  // Allocate persistent memory for rays
403  gpu_rays_ = gpu_.AllocateMemory(sizeof(*rays) * MAX_NUM_RAYS);
404 
405  // Copy ray data to GPU memory
406  gpu_.WriteData(gpu_rays_, rays, sizeof(*rays) * gpu_num_rays_);
407  }
408 
409  return;
410 }
411 #endif
412 
414 
415  ifstream inFile(input_filename.c_str());
416  if (!inFile) {
417  std::cout<< "Can't open input file " << input_filename << std::endl;
418  exit(1);
419  }
420 
421  std::list< numeric::xyzVector<core::Real> > temp_eggshell_coord_list;
422  std::list< numeric::xyzVector<core::Real> > temp_extra_coord_list;
423  std::list< numeric::xyzVector<core::Real> > egg_and_extra_coord_list;
424  temp_eggshell_coord_list.clear();
425  temp_extra_coord_list.clear();
426  egg_and_extra_coord_list.clear();
427 
428  std::string line;
429  std::string name;
431  std::string restype;
432 
433  numeric::xyzVector<core::Real> eggshell_CoM;
434  core::Size comcounter = 0;
435  core::Size oricounter = 0;
436 
437  while (std::getline(inFile, line)) {
438  name = line.substr(0,6);
439  chainID = line.substr(21,1);
440  restype = line.substr(17,3);
441 
443  std::string Xstring, Ystring, Zstring;
444 
445  if (name=="END") break;
446  else if ((name=="HETATM")&&(restype=="ORI"))
447  {
448  Xstring = line.substr(30,8);
449  origin_.x() = atof(Xstring.c_str());
450  Ystring = line.substr(38,8);
451  origin_.y() = atof(Ystring.c_str());
452  Zstring = line.substr(46,8);
453  origin_.z() = atof(Zstring.c_str());
454  oricounter++;
455  }
456  else if ((name=="HETATM")&&(restype=="COM"))
457  {
458  Xstring = line.substr(30,8);
459  CoM_.x() = atof(Xstring.c_str());
460  Ystring = line.substr(38,8);
461  CoM_.y() = atof(Ystring.c_str());
462  Zstring = line.substr(46,8);
463  CoM_.z() = atof(Zstring.c_str());
464  comcounter++;
465  }
466  else if ((name=="HETATM")&&(restype=="EGG"))
467  {
468  Xstring = line.substr(30,8);
469  pdb_coord.x() = atof(Xstring.c_str());
470  Ystring = line.substr(38,8);
471  pdb_coord.y() = atof(Ystring.c_str());
472  Zstring = line.substr(46,8);
473  pdb_coord.z() = atof(Zstring.c_str());
474  temp_eggshell_coord_list.push_back(pdb_coord);
475  }
476  else if ((name=="HETATM")&&(restype=="EXT"))
477  {
478  Xstring = line.substr(30,8);
479  pdb_coord.x() = atof(Xstring.c_str());
480  Ystring = line.substr(38,8);
481  pdb_coord.y() = atof(Ystring.c_str());
482  Zstring = line.substr(46,8);
483  pdb_coord.z() = atof(Zstring.c_str());
484  temp_extra_coord_list.push_back(pdb_coord);
485  }
486  }
487  inFile.close();
488 
489  if ( (oricounter == 0) || (comcounter == 0) ){
490  std::cout<<"Error, No ORIGIN or CoM value specified in input Eggshell file" << std::endl;
491  exit(1);
492  } else if ( (oricounter > 1) || (comcounter >1) ){
493  std::cout<<"Error, More than one ORIGIN or CoM value specified in input Eggshell file" << std::endl;
494  exit(1);
495  }
496 
497  // convert from cartesian_coord to spherical coors
498  spherical_coor_triplet new_triplet;
500 
501  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = temp_eggshell_coord_list.begin(); pd != temp_eggshell_coord_list.end(); ++pd) {
503  triplet_fingerprint_data_.push_back(new_triplet);
504  }
505 
506  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = temp_extra_coord_list.begin(); pd != temp_extra_coord_list.end(); ++pd) {
508  new_triplet.rho = 0.;
509  triplet_fingerprint_data_.push_back(new_triplet);
510  }
511 
512  return;
513 }
514 
516 
517  //input_file should contain a line starting with "/COM/" for CoM values
518  //input_file should contain a line starting with "/ORI/" for ORIGIN values
519  //input_file should contain 3 tab separated columns for the triplet
520 
521  ifstream inFile(input_filename.c_str());
522 
523  if (!inFile) {
524  std::cout<< "Can't open input file " << input_filename << std::endl;
525  exit(1);
526  }
527 
528  std::string lineread;
529  std::string Line;
530  std::string Field;
531 
532  spherical_coor_triplet new_triplet;
534 
535 #ifdef USEOPENCL
536  gpu_num_rays_ = 0;
537 #endif
538 
539  while (std::getline(inFile, lineread)) {
540 
541  std::stringstream sss(lineread);
542  std::string Pock_string_phi, Pock_string_psi, Pock_string_rho;
543  core::Real Pock_real_phi, Pock_real_psi, Pock_real_rho;
544 
545  //parse ORIGIN values from line starting with "/ORI/"
546  if (lineread[0] == '/' && lineread[1] == 'O' && lineread[2] == 'R' && lineread[3] == 'I' && lineread[4] == '/') {
547  lineread.erase(0,5);
548  std::stringstream ori_line(lineread);
549  std::getline(ori_line, Pock_string_phi, '\t');
550  origin_.x() = atof(Pock_string_phi.c_str());
551  std::getline(ori_line, Pock_string_psi, '\t');
552  origin_.y() = atof(Pock_string_psi.c_str());
553  std::getline(ori_line, Pock_string_rho, '\t');
554  origin_.z() = atof(Pock_string_rho.c_str());
555  //std::cout<<"setup from triplet file : "<< " " <<origin_.x()<<" "<<origin_.y()<<" "<<origin_.z()<<std::endl;
556  continue;
557  }
558  //parse CoM values from line starting with "/COM/"
559  if (lineread[0] == '/' && lineread[1] == 'C' && lineread[2] == 'O' && lineread[3] == 'M' && lineread[4] == '/') {
560  lineread.erase(0,5);
561  std::stringstream com_line(lineread);
562  std::getline(com_line, Pock_string_phi, '\t');
563  CoM_.x() = atof(Pock_string_phi.c_str());
564  std::getline(com_line, Pock_string_psi, '\t');
565  CoM_.y() = atof(Pock_string_psi.c_str());
566  std::getline(com_line, Pock_string_rho, '\t');
567  CoM_.z() = atof(Pock_string_rho.c_str());
568  //std::cout<<"setup from triplet file : "<< " " <<CoM_.x()<<" "<<CoM_.y()<<" "<<CoM_.z()<<std::endl;
569  continue;
570  }
571 
572  std::getline(sss, Pock_string_phi, '\t');
573  Pock_real_phi = atof(Pock_string_phi.c_str());
574  std::getline(sss, Pock_string_psi, '\t');
575  Pock_real_psi = atof(Pock_string_psi.c_str());
576  std::getline(sss, Pock_string_rho, '\t');
577  Pock_real_rho = atof(Pock_string_rho.c_str());
578 
579  new_triplet.phi = Pock_real_phi;
580  new_triplet.psi = Pock_real_psi;
581  new_triplet.rho = Pock_real_rho;
582  triplet_fingerprint_data_.push_back(new_triplet);
583 #ifdef USEOPENCL
584  gpu_num_rays_ = gpu_num_rays_ + 1;
585 #endif
586  }
587  inFile.close();
588 
589 #ifdef USEOPENCL
590  setup_gpu_rays();
591 #endif
592 
593  return;
594 }
595 
597 
598  protocols::pockets::PlaidFingerprint known_pf( known_ligand_pose, *this );
599  std::list< spherical_coor_triplet > triplet_trim_data;
600  for (std::list<spherical_coor_triplet>::const_iterator pro = triplet_fingerprint_data_.begin(), lig = known_pf.triplet_fingerprint_data().begin(); pro != triplet_fingerprint_data_.end(), lig != known_pf.triplet_fingerprint_data().end(); ++pro, ++lig) {
601 
602  //jk note: these are no longer necessarily true, since we alter the Plaid one by shifting up/down by 2*pi
603  //these are useful asserts though, it's worth thinking about how to make them valid again...
604  //assert( std::abs( pro->phi - lig->phi ) < 0.001 );
605  //assert( std::abs( pro->psi - lig->psi ) < 0.001 );
606 
607  if ( ( pro->rho > 0.001 ) && ( lig->rho < 0.001 ) ) continue;
608  triplet_trim_data.push_back(*pro);
609 
610  }
612  triplet_fingerprint_data_ = triplet_trim_data;
613 
614  //DUMP TRIMED_EGGSHELL TO A PDB FILE
615  utility::io::ozstream outPDB_stream;
616  outPDB_stream.open("trim_eggshell.pdb", std::ios::out);
617  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C ORI A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.z()<<std::endl;
618  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C COM B 2 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.z()<<std::endl;
619  for (std::list<spherical_coor_triplet>::const_iterator pd = triplet_fingerprint_data_.begin(); pd != triplet_fingerprint_data_.end(); ++pd) {
622  new_coor += origin_;
623  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C EGG C 3 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<new_coor.z()<<std::endl;
624  }
625  outPDB_stream.close();
626  outPDB_stream.clear();
627 
628  return;
629 }
630 
631 void NonPlaidFingerprint::set_origin_away_from_eggshell_plane( std::list< numeric::xyzVector<core::Real> > const & egg_and_extra_shell, core::pose::Pose const & protein_pose, Size const & set_origin_option ) {
632 
633  origin_.zero();
634 
635  core::Real A11(0.), A12(0.), A13(0.), A22(0.), A23(0.), b1(0.), b2(0.), b3(0.);
636  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = egg_and_extra_shell.begin(); pd != egg_and_extra_shell.end(); ++pd) {
637  A11 += pd->x()*pd->x();
638  A12 += pd->x()*pd->y();
639  A13 += pd->x();
640  A22 += pd->y()*pd->y();
641  A23 += pd->y();
642  b1 += pd->x()*pd->z();
643  b2 += pd->y()*pd->z();
644  b3 += pd->z();
645  }
646 
648  A(1,1)=A11;
649  A(1,2)=A12;
650  A(2,1)=A12;
651  A(1,3)=A13;
652  A(3,1)=A13;
653  A(2,2)=A22;
654  A(2,3)=A23;
655  A(3,2)=A23;
656  A(3,3)=egg_and_extra_shell.size();
658  b(1)=b1;
659  b(2)=b2;
660  b(3)=b3;
661 
662  numeric::xyzVector<core::Real> soln = inverse(A) * b;
663  core::Real best_fit_a = soln.x();
664  core::Real best_fit_b = soln.y();
665  core::Real best_fit_c = soln.z();
666 
667  // best fit plane has the equation z = best_fit_a * x + best_fit_b * y + best_fit_c
668 
669  // RAGUL TEST
670  numeric::xyzVector<core::Real> plane_coord;
671  std::list< numeric::xyzVector<core::Real> > plane_coord_list;
672 
673  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pdebug = egg_and_extra_shell.begin(); pdebug != egg_and_extra_shell.end(); ++pdebug) {
674  plane_coord.x() = pdebug->x();
675  plane_coord.y() = pdebug->y();
676  plane_coord.z() = best_fit_a * pdebug->x() + best_fit_b * pdebug->y() + best_fit_c;
677  plane_coord_list.push_back(plane_coord);
678  }
679 
680  //plane_CoM is the same as eggshell_CoM
681  numeric::xyzVector<core::Real> plane_CoM(0.);
682  plane_CoM = CoM_;
683 
684  //cross product of two vectors that lies on the plane gives a vector perpendicular to the plane
685  numeric::xyzVector<core::Real> plane_normal(0.);
686  plane_normal = cross_product( (plane_coord_list.front() - plane_CoM ), (plane_coord_list.back() - plane_CoM ) );
687  // set plane_normal to have length 30 A
688  plane_normal.normalize(30.);
689 
690  numeric::xyzVector<core::Real> temp_origin1 = plane_CoM + plane_normal;
691  numeric::xyzVector<core::Real> temp_origin2 = plane_CoM - plane_normal;
692  numeric::xyzVector<core::Real> closest_origin(0.);
693  numeric::xyzVector<core::Real> distant_origin(0.);
694 
695  //calculate distance b/w protein_CoM and +/- origin and choose the shortest
696  numeric::xyzVector<core::Real> protein_CoM = calculate_protein_CoM(protein_pose);
697  if( protein_CoM.distance(temp_origin1) > protein_CoM.distance(temp_origin2) ) {
698  closest_origin = temp_origin2;
699  distant_origin = temp_origin1;
700  } else {
701  closest_origin = temp_origin1;
702  distant_origin = temp_origin2;
703  }
704 
705  if (set_origin_option == 3){
706  origin_ = closest_origin;
707  } else if (set_origin_option == 4){
708  origin_ = distant_origin;
709  }
710 
711  //DUMP EGGSHELL_GRID(plane) TO A PDB FILE
712  /*
713  utility::io::ozstream outPDB_stream;
714  outPDB_stream.open("plane.pdb", std::ios::out);
715  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = plane_coord_list.begin(); pd != plane_coord_list.end(); ++pd) {
716  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C PLN A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<pd->z()<<std::endl;
717  }
718  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C COM C 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<plane_CoM.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<plane_CoM.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<plane_CoM.z()<<std::endl;
719  //outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C ORA A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin1.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin1.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin1.z()<<std::endl;
720  //outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C ORB B 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin2.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin2.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<temp_origin2.z()<<std::endl;
721  outPDB_stream<<"HETATM "<<std::setw(2)<<1<<" C ORI C 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<origin_.z()<<std::endl;
722  outPDB_stream.close();
723  outPDB_stream.clear();
724  */
725  //END printing plane.pdb
726 
727  return;
728 
729 }
730 
731 void NonPlaidFingerprint::set_origin_away_from_eggshell(std::list< numeric::xyzVector<core::Real> > const & egg_and_extra_shell, core::pose::Pose const & protein_pose ) {
732 
733  // set origin_ 30 A below the eggshell
734  origin_.zero();
735  numeric::xyzVector<core::Real> temp_vec(0.);
736  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = egg_and_extra_shell.begin(); pd != egg_and_extra_shell.end(); ++pd) {
737  temp_vec += (CoM_ - *pd);
738  }
739  temp_vec.normalize(30.);
740 
741  numeric::xyzVector<core::Real> temp_origin1 = CoM_ + temp_vec;
742  numeric::xyzVector<core::Real> temp_origin2 = CoM_ - temp_vec;
743  numeric::xyzVector<core::Real> closest_origin(0.);
744  numeric::xyzVector<core::Real> distant_origin(0.);
745 
746  //calculate distance b/w protein_CoM and +/- origin and choose the shortest
747  numeric::xyzVector<core::Real> protein_CoM = calculate_protein_CoM(protein_pose);
748  if( protein_CoM.distance(temp_origin1) > protein_CoM.distance(temp_origin2) ) {
749  closest_origin = temp_origin2;
750  distant_origin = temp_origin1;
751  } else {
752  closest_origin = temp_origin1;
753  distant_origin = temp_origin2;
754  }
755  origin_ = closest_origin;
756 
757  return;
758 }
759 
760 
762 
763  // set origin_ to the protein CoM, then move origin_ 30Angstrom away from protein center
764  origin_ = calculate_protein_CoM(protein_pose);
765  numeric::xyzVector<core::Real> temp_vec(0.);
766  temp_vec = origin_ - CoM_;
767  temp_vec.normalize(30.);
768  origin_ = temp_vec + CoM_;
769  return;
770 }
771 
773 
774  numeric::xyzVector<core::Real> protein_com(0.);
775  core::Size total_atoms(0);
776  for ( int j = 1, resnum = protein_pose.total_residue(); j <= resnum; ++j ) {
777  core::conformation::Residue const & curr_rsd = protein_pose.residue(j);
778  if ( curr_rsd.is_protein() ) {
779  for(Size i = 1, i_end = curr_rsd.nheavyatoms(); i <= i_end; ++i) {
780  protein_com.x() += curr_rsd.atom(i).xyz()(1);
781  protein_com.y() += curr_rsd.atom(i).xyz()(2);
782  protein_com.z() += curr_rsd.atom(i).xyz()(3);
783  total_atoms++;
784  }
785  }
786  }
787  protein_com /= total_atoms;
788  return protein_com;
789 
790 }
791 
793  FingerprintBase(),
794  pose_(input_pose)
795 {
796 
797  //calculate ligand center of mass
799 
800  // move pose_ such that ligand CoM is at the pocket center of mass
802  I_mat.to_identity();
803  pose_.apply_transform_Rx_plus_v(I_mat, fp.CoM() - ligand_CoM);
804 
805  core::Size const lig_res_num = compute_ligand_resnum();
806  // core::Size const ligand_natoms = compute_ligand_natoms();
808 
809  numeric::xyzVector<core::Real> no_CoM_offset(0.);
810  move_ligand_(fp,no_CoM_offset,0,0,0);
811  update_rhos_(fp, ligand_rsd);
812 }
813 
814 void PlaidFingerprint::apply_rotation_offset_to_pose_( core::pose::Pose & pose, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset ) const {
815 
816  //calculate_ligand_CoM function not working here (const )!!
817  //numeric::xyzVector<core::Real> ligand_CoM = calculate_ligand_CoM(pose);
818 
819  core::Size lig_res_num = compute_ligand_resnum(pose);
820  numeric::xyzVector<core::Real> ligand_CoM(0.);
821  core::conformation::Residue const & curr_rsd = pose.conformation().residue(lig_res_num);
822  core::Size ligand_total_atoms = compute_ligand_natoms(pose);
823  for(Size i = 1, i_end = ligand_total_atoms; i <= i_end; ++i) {
824  ligand_CoM.x() += curr_rsd.atom(i).xyz()(1);
825  ligand_CoM.y() += curr_rsd.atom(i).xyz()(2);
826  ligand_CoM.z() += curr_rsd.atom(i).xyz()(3);
827  }
828  ligand_CoM /= ligand_total_atoms;
829 
830  // move pose such that ligand CoM is at the origin
832  I_mat.to_identity();
833  pose.apply_transform_Rx_plus_v(I_mat, -ligand_CoM);
834 
835  numeric::xyzMatrix<core::Real> x_rot_mat( numeric::x_rotation_matrix_radians(angle1_offset) );
836  numeric::xyzMatrix<core::Real> y_rot_mat( numeric::y_rotation_matrix_radians(angle2_offset) );
837  numeric::xyzMatrix<core::Real> z_rot_mat( numeric::z_rotation_matrix_radians(angle3_offset) );
838  numeric::xyzMatrix<core::Real> tot_rot_mat = z_rot_mat * y_rot_mat * x_rot_mat;
839  core::Vector v(0,0,0);
840  pose.apply_transform_Rx_plus_v(tot_rot_mat, v);
841 
842  // move pose back to original ligand CoM
843  pose.apply_transform_Rx_plus_v(I_mat, ligand_CoM);
844 
845 }
846 
848  core::Size lig_res_num = 0;
849  for ( int j = 1, resnum = pose.total_residue(); j <= resnum; ++j ) {
850  if (!pose.residue(j).is_protein()){
851  lig_res_num = j;
852  break;
853  }
854  }
855  if (lig_res_num == 0){
856  std::cout<<"Error, no ligand for PlaidFingerprint" << std::endl;
857  exit(1);
858  }
859  return lig_res_num;
860 }
861 
863  core::Size lig_res_num = compute_ligand_resnum(pose);
864  core::conformation::Residue const & curr_rsd = pose.conformation().residue(lig_res_num);
865  core::Size ligand_total_atoms;
866  using namespace basic::options;
867  if (option[ OptionKeys::fingerprint::include_hydrogens ]()){
868  ligand_total_atoms = curr_rsd.natoms();
869  } else {
870  ligand_total_atoms = curr_rsd.nheavyatoms();
871  }
872  return ligand_total_atoms;
873 }
874 
875 core::conformation::ResidueCOP PlaidFingerprint::move_ligand_( FingerprintBase & fp, numeric::xyzVector<core::Real> const & CoM_offset, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset ) {
876 
877  core::pose::Pose tmp_pose = pose_;
878 
879  apply_rotation_offset_to_pose_( tmp_pose, angle1_offset, angle2_offset, angle3_offset );
880 
881  // set the fingerprint CoM to be the ligand CoM, then apply offset as needed
882  CoM_ = calculate_ligand_CoM(tmp_pose);
883  // jk note: this next step of setting the origins to match is unnecessary as written, because given current implementation CoM_ and fp.CoM() are the same
884  // jk is there a case when this isn't true, or is this leftover from an old approach??
885  origin_ = fp.origin() + CoM_ - fp.CoM();
886  origin_ += CoM_offset;
887 
888  core::Size const lig_res_num = compute_ligand_resnum(tmp_pose);
889  // core::Size const ligand_natoms = compute_ligand_natoms(tmp_pose);
890  core::conformation::ResidueCOP ligand_rsd = new core::conformation::Residue( tmp_pose.conformation().residue(lig_res_num) );
891 
892  return ligand_rsd;
893 
894 }
895 
896 void PlaidFingerprint::update_rhos_(FingerprintBase & fp, core::conformation::ResidueCOP curr_ligand_rsd, bool const update_derivatives ) {
897 
898  using namespace basic::options;
899  core::Real const radius_scale = option[ OptionKeys::fingerprint::atom_radius_scale ];
900  core::Real const atom_buffer = option[ OptionKeys::fingerprint::atom_radius_buffer ];
901 
903 
904  core::Size const ligand_natoms = compute_ligand_natoms();
905 
906  // compute the max and min possible phi and psi for each atom, store these in 4 arrays
907  // also compute the overall max and min possible for the whole ligand
908  utility::vector1<core::Real> atom_max_phi( ligand_natoms );
909  utility::vector1<core::Real> atom_max_psi( ligand_natoms );
910  utility::vector1<core::Real> atom_min_phi( ligand_natoms );
911  utility::vector1<core::Real> atom_min_psi( ligand_natoms );
912 
913  utility::vector1< core::Real > atomX( ligand_natoms );
914  utility::vector1< core::Real > atomY( ligand_natoms );
915  utility::vector1< core::Real > atomZ( ligand_natoms );
916  utility::vector1<core::Real> atom_radius( ligand_natoms );
917 
918  core::Real max_phi( -999. );
919  core::Real max_psi( -999. );
920  core::Real min_phi( 999. );
921  core::Real min_psi( 999. );
922 
923  for (Size i = 1, i_end = ligand_natoms; i <= i_end; ++i) {
924 
925  numeric::xyzVector<core::Real> this_atomcoors = curr_ligand_rsd->atom(i).xyz() - origin_;
926  core::Real const this_atom_radius = ( curr_ligand_rsd->atom_type(i).lj_radius() - atom_buffer ) * radius_scale;
927 
928  // find the atom center (in spherical coors)
929  spherical_coor_triplet atom_center;
930  convert_cartesian_to_spherical_coor_triplet( this_atomcoors, atom_center );
931 
932  core::Real const tmp_atomx=this_atomcoors.x();
933  core::Real const tmp_atomy=this_atomcoors.y();
934  core::Real const tmp_atomz=this_atomcoors.z();
935 
936  // find the max/min angular phi displacement that will intersect the atom
937  // project atom onto the z-axis (ie. set x and y coors to zero) to calculate this for phi
938  core::Real curr_max_phi( 999 );
939  core::Real curr_min_phi( -999 );
940  if ( std::abs(tmp_atomz) > 0.00001 ) {
941  core::Real const inside_phi_asin = this_atom_radius / tmp_atomz;
942  if ( std::abs(inside_phi_asin) < 1. ) {
943  core::Real const max_angular_displacement_phi = std::abs( asin( inside_phi_asin ) );
944  curr_max_phi = atom_center.phi + max_angular_displacement_phi;
945  curr_min_phi = atom_center.phi - max_angular_displacement_phi;
946  }
947  }
948 
949  // find the max/min angular psi displacement that will intersect the atom
950  // project atom onto the x-y plane (ie. set the z coor to zero) to calculate this for psi
951  core::Real curr_max_psi( 999 );
952  core::Real curr_min_psi( -999 );
953  if ( ( std::abs(tmp_atomx) > 0.00001 ) || ( std::abs(tmp_atomx) > 0.00001 ) ) {
954  core::Real const inside_psi_asin = this_atom_radius / sqrt( (tmp_atomx*tmp_atomx) + (tmp_atomy*tmp_atomy) );
955  if ( std::abs(inside_psi_asin) < 1. ) {
956  core::Real const max_angular_displacement_psi = std::abs( asin( inside_psi_asin ) );
957  curr_max_psi = atom_center.psi + max_angular_displacement_psi;
958  curr_min_psi = atom_center.psi - max_angular_displacement_psi;
959  }
960  }
961 
962  if ( curr_max_phi > max_phi ) max_phi = curr_max_phi;
963  if ( curr_max_psi > max_psi ) max_psi = curr_max_psi;
964  if ( curr_min_phi < min_phi ) min_phi = curr_min_phi;
965  if ( curr_min_psi < min_psi ) min_psi = curr_min_psi;
966  atom_max_phi.at(i) = curr_max_phi;
967  atom_max_psi.at(i) = curr_max_psi;
968  atom_min_phi.at(i) = curr_min_phi;
969  atom_min_psi.at(i) = curr_min_psi;
970  atomX.at(i) = this_atomcoors.x();
971  atomY.at(i) = this_atomcoors.y();
972  atomZ.at(i) = this_atomcoors.z();
973  atom_radius.at(i) = this_atom_radius;
974 
975  }
976 
977  derivs_of_ray_distances_.clear();
978 
979  //float orig_cpu_total_dist = 0.;
980  //Size orig_cpu_total_num = 0;
981  //Size orig_cpu_num_evaluations = 0;
982  for (std::list<spherical_coor_triplet>::const_iterator ni = fp.triplet_fingerprint_data().begin(); ni != fp.triplet_fingerprint_data().end(); ++ni) {
983 
984  core::Real curr_phi = ni->phi;
985  core::Real curr_psi = ni->psi;
986  // if the current phi and/or psi is outside the overall max/min, set best_rho to zero and jumpout (ie. ray misses the ligand)
987  core::Real best_rho_sq(9999.);
988  core::Size best_intersecting_atom(0);
989  for (Size i = 1, i_end = ligand_natoms; i <= i_end; ++i) {
990 
991  if ( atom_radius.at(i) < 0.001 ) continue;
992 
993  while ( curr_phi < atom_min_phi.at(i) ) {
994  curr_phi += numeric::constants::r::pi_2;
995  }
996  while ( curr_phi > atom_max_phi.at(i) ) {
997  curr_phi -= numeric::constants::r::pi_2;
998  }
999  while ( curr_psi < atom_min_psi.at(i) ) {
1000  curr_psi += numeric::constants::r::pi_2;
1001  }
1002  while ( curr_psi > atom_max_psi.at(i) ) {
1003  curr_psi -= numeric::constants::r::pi_2;
1004  }
1005  if ( curr_phi < atom_min_phi.at(i) ) continue;
1006  if ( curr_psi < atom_min_psi.at(i) ) continue;
1007  if ( curr_phi > atom_max_phi.at(i) ) continue;
1008  if ( curr_psi > atom_max_psi.at(i) ) continue;
1009 
1010  core::Real const min_intersect_SQ = Find_Closest_Intersect_SQ(curr_phi,curr_psi,atomX.at(i),atomY.at(i),atomZ.at(i),atom_radius.at(i));
1011  //++orig_cpu_num_evaluations;
1012 
1013  if ( min_intersect_SQ < best_rho_sq ) {
1014  best_rho_sq = min_intersect_SQ;
1015  best_intersecting_atom = i;
1016  }
1017  }
1018 
1019  spherical_coor_triplet new_triplet;
1020  new_triplet.phi = curr_phi;
1021  new_triplet.psi = curr_psi;
1022 
1023  if ( best_rho_sq < 9998. ) {
1024  new_triplet.rho = sqrt(best_rho_sq);
1025  //orig_cpu_total_dist += sqrt(best_rho_sq);
1026  //++orig_cpu_total_num;
1027  } else {
1028  new_triplet.rho = 0.;
1029  }
1030  triplet_fingerprint_data_.push_back(new_triplet);
1031 
1032  if ( update_derivatives ) {
1033  std::cout<<"DARC derivatives are currently commented out...." << std::endl;
1034  exit(1);
1035  }
1036 
1037  /*
1038 
1039  if ( update_derivatives ) {
1040 
1041  ray_distance_derivs new_deriv_set;
1042 
1043  // compute derivatives only if the ray hits both pocket and ligand - otherwise derivative is zero
1044  if ( (ni->rho > 0.001) && (new_triplet.rho > 0.001) ) {
1045 
1046  // (x0,y0,z0) = the coordinates of the "origin" point from which all rays originate, called P0
1047  core::Real const x0 = origin_.x();
1048  core::Real const y0 = origin_.y();
1049  core::Real const z0 = origin_.z();
1050 
1051  // (x2,y2,z2) = the coordinates of the pocket point that intersects the ray whose derivative we are calculating, called P2
1052  numeric::xyzVector<core::Real> fp_coord;
1053  convert_spherical_coor_triplet_to_cartesian( *ni, fp_coord );
1054  fp_coord += origin_;
1055  core::Real const x2 = fp_coord.x();
1056  core::Real const y2 = fp_coord.y();
1057  core::Real const z2 = fp_coord.z();
1058 
1059  // (x3,y3,z3) = the coordinates of the center of the atom that is intersecting the ray, called P3
1060  // note: can't use atomX / atomY / atomZ, since these are relative to the origin
1061  numeric::xyzVector<core::Real> best_atom_coors = curr_rsd.atom(best_intersecting_atom).xyz();
1062  core::Real const x3 = best_atom_coors.x();
1063  core::Real const y3 = best_atom_coors.y();
1064  core::Real const z3 = best_atom_coors.z();
1065 
1066  // (xc,yc,zc) = the coordinates of the center of mass of the ligand BEFORE it has been moved into the current pose, called Pc
1067  // note: before moving ligand, the ligand CoM (in pose_) is at fp.CoM() - this happens in the PlaidFingerprint constructor
1068  core::Real const xc = fp.CoM().x();
1069  core::Real const yc = fp.CoM().y();
1070  core::Real const zc = fp.CoM().z();
1071 
1072  // (xs,ys,zs) = the coordinates of the center of the atom that is intersecting the ray BEFORE it has been moved into the current pose, called Ps
1073  conformation::Residue const & ligand_res_before_rotation = pose_.conformation().residue(lig_res_num);
1074  numeric::xyzVector<core::Real> atom_before_rotation = ligand_res_before_rotation.atom(best_intersecting_atom).xyz();
1075  core::Real const xs = atom_before_rotation.x();
1076  core::Real const ys = atom_before_rotation.y();
1077  core::Real const zs = atom_before_rotation.z();
1078 
1079  // r = the radius of the atom that is intersecting the ray
1080  core::Real const r = atom_radius.at(best_intersecting_atom);
1081 
1082  new_deriv_set.dDist_dv1 = dD_dv1(x0,x2,x3,y0,y2,y3,z0,z2,z3,r);
1083  new_deriv_set.dDist_dv2 = dD_dv2(x0,x2,x3,y0,y2,y3,z0,z2,z3,r);
1084  new_deriv_set.dDist_dv3 = dD_dv3(x0,x2,x3,y0,y2,y3,z0,z2,z3,r);
1085  new_deriv_set.dDist_dv4 = dD_dv4(x0,x2,x3,y0,y2,y3,z0,z2,z3,r,angle1_offset,angle2_offset,angle3_offset,xc,xs,yc,ys,zc,zs);
1086  new_deriv_set.dDist_dv5 = dD_dv5(x0,x2,x3,y0,y2,y3,z0,z2,z3,r,angle1_offset,angle2_offset,angle3_offset,xc,xs,yc,ys,zc,zs);
1087  new_deriv_set.dDist_dv6 = dD_dv6(x0,x2,x3,y0,y2,y3,z0,z2,z3,r,angle1_offset,angle2_offset,angle3_offset,xc,xs,yc,ys,zc,zs);
1088 
1089  } else {
1090 
1091  // set derivatives to zero if there's no intersection with the ligand or pocket
1092  new_deriv_set.dDist_dv1 = 0.;
1093  new_deriv_set.dDist_dv2 = 0.;
1094  new_deriv_set.dDist_dv3 = 0.;
1095  new_deriv_set.dDist_dv4 = 0.;
1096  new_deriv_set.dDist_dv5 = 0.;
1097  new_deriv_set.dDist_dv6 = 0.;
1098 
1099  }
1100 
1101  derivs_of_ray_distances_.push_back(new_deriv_set);
1102 
1103  }
1104  */
1105 
1106  }
1107 
1108  // cout << "ORIG_CPU TOTAL DISTANCE: " << orig_cpu_total_dist << std::endl;
1109  // cout << "ORIG_CPU TOTAL NUM: " << orig_cpu_total_num << std::endl;
1110  // cout << "ORIG_CPU NUM INTERSECTION EVALUATIONS: " << orig_cpu_num_evaluations << std::endl;
1111 
1112 }
1113 
1114 
1115 core::Real PlaidFingerprint::fp_compare( FingerprintBase & fp, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight ) const {
1116 
1117  core::Real Total_score = 0;
1118  core::Size num_rays = 0;
1119  using namespace basic::options;
1120  bool square = option[ OptionKeys::fingerprint::square_score ]();
1121 
1122  for (std::list<spherical_coor_triplet>::const_iterator pi = fp.triplet_fingerprint_data().begin(), li = triplet_fingerprint_data_.begin(); pi != fp.triplet_fingerprint_data().end(), li != triplet_fingerprint_data_.end(); ++pi, ++li) {
1123 
1124  // jk note: these are no longer necessarily true, since we alter the Plaid one by shifting up/down by 2*pi
1125  // these are useful asserts though, it's worth thinking about how to make them valid again...
1126  // assert( std::abs( pi->phi - li->phi ) < 0.001 );
1127  // assert( std::abs( pi->psi - li->psi ) < 0.001 );
1128 
1129  if ( (li->rho < 0.001) && (pi->rho < 0.001) ) {
1130  continue;
1131  } else if (li->rho < 0.001) {
1132  Total_score += missing_point_weight;
1133  } else if (pi->rho < 0.001 ) {
1134  Total_score += extra_point_weight;
1135  } else {
1136  core::Real dist_deviation = std::abs( pi->rho - li->rho );
1137  if (square){
1138  if (li->rho > pi->rho) dist_deviation *= dist_deviation;
1139  if (li->rho < pi->rho) dist_deviation *= (dist_deviation * steric_weight);
1140  }
1141  else if (!square) {
1142  if (li->rho > pi->rho) dist_deviation = dist_deviation;
1143  if (li->rho < pi->rho) dist_deviation = (dist_deviation * steric_weight);
1144  }
1145  Total_score += dist_deviation;
1146  }
1147  num_rays++;
1148  }
1149  // if ( num_rays < 25 ) return 999.;
1150  return (Total_score/num_rays);
1151 }
1152 
1153 void PlaidFingerprint::fp_compare_deriv( FingerprintBase & fp, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight, core::Real & dE_dx, core::Real & dE_dy, core::Real & dE_dz, core::Real & dE_dv4, core::Real & dE_dv5, core::Real & dE_dv6 ) const {
1154 
1155  dE_dx = 0.; dE_dy = 0.; dE_dz = 0.; dE_dv4 = 0.; dE_dv5 = 0.; dE_dv6 = 0.;
1156 
1157  if ( derivs_of_ray_distances_.size() < 2 ) {
1158  std::cout<<"Error, fingerprint derivatives have not been computed" << std::endl;
1159  exit(1);
1160  }
1161  assert( derivs_of_ray_distances_.size() == fp.triplet_fingerprint_data().size() );
1162 
1163  core::Real Total_score = 0;
1164  core::Real Differentiable_score = 0;
1165  core::Size num_rays = 0;
1166  std::list<ray_distance_derivs>::const_iterator di = derivs_of_ray_distances_.begin();
1167  for (std::list<spherical_coor_triplet>::const_iterator pi = fp.triplet_fingerprint_data().begin(), li = triplet_fingerprint_data_.begin(); pi != fp.triplet_fingerprint_data().end(), li != triplet_fingerprint_data_.end(), di != derivs_of_ray_distances_.end(); ++pi, ++li, ++di) {
1168  assert( std::abs( pi->phi - li->phi ) < 0.001 );
1169  assert( std::abs( pi->psi - li->psi ) < 0.001 );
1170 
1171  if ( (li->rho < 0.001) && (pi->rho < 0.001) ) {
1172  continue;
1173  } else if (li->rho < 0.001) {
1174  Total_score += missing_point_weight;
1175  } else if (pi->rho < 0.001 ) {
1176  Total_score += extra_point_weight;
1177  } else {
1178  core::Real dist_deviation = std::abs( pi->rho - li->rho );
1179  // derivative is zero except in the case where the ray hits BOTH ligand and pocket
1180  // (ie. "missing point" and "extra point" scores don't contribute to the derivatives)
1181  if (li->rho > pi->rho) {
1182  dE_dx += di->dDist_dv1;
1183  dE_dy += di->dDist_dv2;
1184  dE_dz += di->dDist_dv3;
1185  dE_dv4 += di->dDist_dv4;
1186  dE_dv5 += di->dDist_dv5;
1187  dE_dv6 += di->dDist_dv6;
1188  } else {
1189  dist_deviation *= steric_weight;
1190  dE_dx += steric_weight * di->dDist_dv1;
1191  dE_dy += steric_weight * di->dDist_dv2;
1192  dE_dz += steric_weight * di->dDist_dv3;
1193  dE_dv4 += steric_weight * di->dDist_dv4;
1194  dE_dv5 += steric_weight * di->dDist_dv5;
1195  dE_dv6 += steric_weight * di->dDist_dv6;
1196  }
1197  Total_score += dist_deviation;
1198  Differentiable_score += dist_deviation;
1199  }
1200 
1201  num_rays++;
1202  }
1203 
1204  dE_dx /= num_rays;
1205  dE_dy /= num_rays;
1206  dE_dz /= num_rays;
1207  dE_dv4 /= num_rays;
1208  dE_dv5 /= num_rays;
1209  dE_dv6 /= num_rays;
1210  Total_score /= num_rays;
1211  Differentiable_score /= num_rays;
1212 
1213  std::cout<<"DARC score while computing derivatives: " << Total_score << std::endl;
1214  // std::cout<<"DARC score while computing derivatives are total: " << Total_score << " and differentiable part " << Differentiable_score << std::endl;
1215  // std::cout<<"Derivatives are " << dE_dx << " , " << dE_dy << " , " << dE_dz << " , " << dE_dv4 << " , " << dE_dv5 << " , " << dE_dv6 << std::endl;
1216 
1217  return;
1218 
1219 }
1220 
1221 core::Real PlaidFingerprint::search_random_poses( FingerprintBase & fp, core::Size const & num_pose_search, core::Real & optimal_angle1, core::Real & optimal_angle2, core::Real & optimal_angle3, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight ) {
1222 
1223  numeric::xyzVector<core::Real> no_CoM_offset(0.);
1224  return search_random_poses( fp, num_pose_search, optimal_angle1, optimal_angle2, optimal_angle3, missing_point_weight, steric_weight, extra_point_weight, no_CoM_offset);
1225 }
1226 
1227 
1228 core::Real PlaidFingerprint::search_random_poses( FingerprintBase & fp, core::Size const & num_pose_search, core::Real & optimal_angle1, core::Real & optimal_angle2, core::Real & optimal_angle3, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight, numeric::xyzVector<core::Real> const & CoM_offset ) {
1229 
1230  core::Real best_score = std::numeric_limits<core::Real>::max();
1231 
1232  for (core::Size j = 0; j < num_pose_search; ++j ){
1233  core::Real curr_angle1 = (int) (numeric::random::uniform() *359.999);
1234  core::Real curr_angle2 = (int) (numeric::random::uniform() *359.999);
1235  core::Real curr_angle3 = (int) (numeric::random::uniform() *359.999);
1236 
1237  move_ligand_and_update_rhos_( fp, CoM_offset, curr_angle1, curr_angle2, curr_angle3 );
1238  core::Real curr_score = fp_compare( fp, missing_point_weight, steric_weight, extra_point_weight );
1239  //std::cout<<"curr_score "<<curr_score<< " " << curr_phi << " " <<curr_psi << std::endl;
1240  if ( curr_score < best_score ) {
1241  best_score = curr_score;
1242  optimal_angle1 = curr_angle1;
1243  optimal_angle2 = curr_angle2;
1244  optimal_angle3 = curr_angle3;
1245  //std::cout<<"best_score "<<curr_score<< " " << curr_phi << " " <<curr_psi << std::endl;
1246  }
1247  }
1248  return best_score;
1249 }
1250 
1251 core::Real PlaidFingerprint::find_optimal_rotation( FingerprintBase & fp, core::Real const & angle_increment, core::Real & optimal_angle1, core::Real & optimal_angle2, core::Real & optimal_angle3, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight ) {
1252  numeric::xyzVector<core::Real> no_CoM_offset(0.);
1253  return find_optimal_rotation( fp, angle_increment, optimal_angle1, optimal_angle2, optimal_angle3, missing_point_weight, steric_weight, extra_point_weight, no_CoM_offset);
1254 }
1255 
1256 core::Real PlaidFingerprint::find_optimal_rotation( FingerprintBase & fp, core::Real const & angle_increment, core::Real & optimal_angle1, core::Real & optimal_angle2, core::Real & optimal_angle3, core::Real const & missing_point_weight, core::Real const & steric_weight, core::Real const & extra_point_weight, numeric::xyzVector<core::Real> const & CoM_offset ) {
1257 
1258  core::Real best_score = std::numeric_limits<core::Real>::max();
1259  core::Size num_steps = core::Size ( 360. / angle_increment );
1260 
1261  core::Real curr_angle1=0.;
1262  for (core::Size i = 0; i < num_steps; ++i ){
1263  core::Real curr_angle2=0.;
1264  for (core::Size j = 0; j < num_steps; ++j ){
1265  core::Real curr_angle3=0.;
1266 
1267  for (core::Size k = 0; k < num_steps; ++k ){
1268  move_ligand_and_update_rhos_( fp, CoM_offset, curr_angle1, curr_angle2, curr_angle3 );
1269  core::Real curr_score = fp_compare( fp, missing_point_weight, steric_weight, extra_point_weight );
1270  // std::cout<<"curr_score "<<curr_score<< " " << curr_phi << " " <<curr_psi << std::endl;
1271  if ( curr_score < best_score ) {
1272  best_score = curr_score;
1273  optimal_angle1 = curr_angle1;
1274  optimal_angle2 = curr_angle2;
1275  optimal_angle3 = curr_angle3;
1276  // std::cout<<"best_score "<<curr_score<< " " << curr_phi << " " <<curr_psi << std::endl;
1277  }
1278  curr_angle3 += angle_increment;
1279  }
1280  curr_angle2 += angle_increment;
1281  }
1282  curr_angle1 += angle_increment;
1283  }
1284 
1285  return best_score;
1286 }
1287 
1288 void PlaidFingerprint::dump_oriented_pose_and_fp_to_pdb( std::string const & pose_filename, std::string const & fp_filename, FingerprintBase & fp, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset ) {
1289 
1290  utility::vector1<core::Real> original_pocket_angle_transform(3, 0.);
1291  numeric::xyzVector<core::Real> no_CoM_offset(0.);
1292  dump_oriented_pose_and_fp_to_pdb(pose_filename, fp_filename, fp, angle1_offset, angle2_offset, angle3_offset, original_pocket_angle_transform, no_CoM_offset );
1293 
1294 }
1295 
1296 void PlaidFingerprint::dump_oriented_pose_and_fp_to_pdb( std::string const & pose_filename, std::string const & fp_filename, FingerprintBase & fp, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset, numeric::xyzVector<core::Real> const & CoM_offset ) {
1297 
1298  utility::vector1<core::Real> original_pocket_angle_transform(3, 0.);
1299  dump_oriented_pose_and_fp_to_pdb(pose_filename, fp_filename, fp, angle1_offset, angle2_offset, angle3_offset, original_pocket_angle_transform, CoM_offset );
1300 
1301 }
1302 
1303 void PlaidFingerprint::dump_oriented_pose_and_fp_to_pdb( std::string const & pose_filename, std::string const & fp_filename, FingerprintBase & fp, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset, utility::vector1<core::Real> const & original_pocket_angle_transform ) {
1304 
1305  numeric::xyzVector<core::Real> no_CoM_offset(0.);
1306  dump_oriented_pose_and_fp_to_pdb(pose_filename, fp_filename, fp, angle1_offset, angle2_offset, angle3_offset, original_pocket_angle_transform, no_CoM_offset );
1307 
1308 }
1309 
1310 
1311 void PlaidFingerprint::dump_oriented_pose_and_fp_to_pdb( std::string const & pose_filename, std::string const & fp_filename, FingerprintBase & fp, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset, utility::vector1<core::Real> const & original_pocket_angle_transform, numeric::xyzVector<core::Real> const & CoM_offset ) {
1312 
1313  move_ligand_and_update_rhos_( fp, CoM_offset, angle1_offset, angle2_offset, angle3_offset);
1314 
1315  core::pose::Pose tmp_pose = pose_;
1316  apply_rotation_offset_to_pose_( tmp_pose, angle1_offset, angle2_offset, angle3_offset );
1317 
1318  numeric::xyzMatrix<core::Real> bestx_rot_mat( numeric::x_rotation_matrix_radians( original_pocket_angle_transform[1] ) );
1319  numeric::xyzMatrix<core::Real> besty_rot_mat( numeric::y_rotation_matrix_radians( original_pocket_angle_transform[2] ) );
1320  numeric::xyzMatrix<core::Real> bestz_rot_mat( numeric::z_rotation_matrix_radians( original_pocket_angle_transform[3] ) );
1321  numeric::xyzMatrix<core::Real> best_mat = bestz_rot_mat * besty_rot_mat * bestx_rot_mat;
1322  numeric::xyzMatrix<core::Real> inverse_best_mat = numeric::inverse(best_mat);
1323  core::Vector v(0,0,0);
1324  tmp_pose.apply_transform_Rx_plus_v(inverse_best_mat, v);
1325 
1326  numeric::xyzVector<core::Real> back_to_FingerprintBase_origin = fp.origin() - origin_;
1327 
1328  print_to_pdb( fp_filename, back_to_FingerprintBase_origin );
1329 
1330  utility::io::ozstream out_stream;
1331  out_stream.open(pose_filename, std::ios::out);
1332 
1333  out_stream<<"HETATM "<<std::setw(2)<<1<<" C ORI X 0 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<fp.origin().x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<fp.origin().y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<fp.origin().z()<<std::endl;
1334  out_stream<<"HETATM "<<std::setw(2)<<1<<" C COM X 0 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.x()+back_to_FingerprintBase_origin.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.y()+back_to_FingerprintBase_origin.y()<<std::setw(8)<<std::fixed<<std::setprecision(3)<<CoM_.z()+back_to_FingerprintBase_origin.z()<<std::endl;
1335 
1336  core::Size lig_res_num = compute_ligand_resnum( tmp_pose );
1337 
1338  core::conformation::Residue const & curr_rsd = tmp_pose.conformation().residue(lig_res_num);
1339  for(Size i = 1, i_end = curr_rsd.natoms(); i <= i_end; ++i) {
1340  //out_stream<<"HETATM "<<std::setw(2)<<1<<" C MAP A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<curr_rsd.atom(i).xyz()(1) <<std::setw(8)<<std::fixed<<std::setprecision(3)<< curr_rsd.atom(i).xyz()(2) <<std::setw(8)<<std::fixed<<std::setprecision(3)<<curr_rsd.atom(i).xyz()(3) <<std::endl;
1341  out_stream<<"HETATM "<<std::setw(2)<<1<<" C MAP A 1 "<<std::setw(8)<<std::fixed<<std::setprecision(3)<<curr_rsd.atom(i).xyz()(1)+back_to_FingerprintBase_origin.x()<<std::setw(8)<<std::fixed<<std::setprecision(3)<< curr_rsd.atom(i).xyz()(2)+back_to_FingerprintBase_origin.y() <<std::setw(8)<<std::fixed<<std::setprecision(3)<<curr_rsd.atom(i).xyz()(3)+back_to_FingerprintBase_origin.z() <<std::endl;
1342  }
1343 
1344  out_stream.close();
1345  out_stream.clear();
1346 
1347 }
1348 
1349 
1350 core::pose::Pose PlaidFingerprint::get_oriented_pose( FingerprintBase &fp , core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset, numeric::xyzVector<core::Real> const & CoM_offset ) {
1351 
1352  utility::vector1<core::Real> original_pocket_angle_transform(3, 0.);
1353  core::pose::Pose oriented_pose = get_oriented_pose( fp, angle1_offset, angle2_offset, angle3_offset, original_pocket_angle_transform, CoM_offset );
1354  return oriented_pose;
1355 }
1356 
1357 core::pose::Pose PlaidFingerprint::get_oriented_pose( FingerprintBase & fp, core::Real const & angle1_offset, core::Real const & angle2_offset, core::Real const & angle3_offset, utility::vector1<core::Real> const & original_pocket_angle_transform, numeric::xyzVector<core::Real> const & CoM_offset ) {
1358 
1359  move_ligand_and_update_rhos_( fp, CoM_offset, angle1_offset, angle2_offset, angle3_offset);
1360 
1361  core::pose::Pose tmp_pose = pose_;
1362  apply_rotation_offset_to_pose_( tmp_pose, angle1_offset, angle2_offset, angle3_offset );
1363 
1364  numeric::xyzMatrix<core::Real> bestx_rot_mat( numeric::x_rotation_matrix_radians( original_pocket_angle_transform[1] ) );
1365  numeric::xyzMatrix<core::Real> besty_rot_mat( numeric::y_rotation_matrix_radians( original_pocket_angle_transform[2] ) );
1366  numeric::xyzMatrix<core::Real> bestz_rot_mat( numeric::z_rotation_matrix_radians( original_pocket_angle_transform[3] ) );
1367  numeric::xyzMatrix<core::Real> best_mat = bestz_rot_mat * besty_rot_mat * bestx_rot_mat;
1368  numeric::xyzMatrix<core::Real> inverse_best_mat = numeric::inverse(best_mat);
1369  core::Vector v(0,0,0);
1370  tmp_pose.apply_transform_Rx_plus_v(inverse_best_mat, v);
1371 
1372 
1373  // move pose such that ligand CoM is at the origin
1375  I_mat.to_identity();
1376  numeric::xyzVector<core::Real> back_to_FingerprintBase_origin = fp.origin() - origin_;
1377  tmp_pose.apply_transform_Rx_plus_v(I_mat, back_to_FingerprintBase_origin);
1378 
1379  return tmp_pose;
1380 
1381 }
1382 
1384 
1385  core::Size lig_res_num = compute_ligand_resnum( ligand_pose );
1386  numeric::xyzVector<core::Real> ligand_com(0.);
1387  core::conformation::Residue const & curr_rsd = ligand_pose.conformation().residue(lig_res_num);
1388  core::Size ligand_total_atoms = compute_ligand_natoms( ligand_pose );
1389  for(Size i = 1, i_end = ligand_total_atoms; i <= i_end; ++i) {
1390  ligand_com.x() += curr_rsd.atom(i).xyz()(1);
1391  ligand_com.y() += curr_rsd.atom(i).xyz()(2);
1392  ligand_com.z() += curr_rsd.atom(i).xyz()(3);
1393  }
1394  ligand_com /= ligand_total_atoms;
1395 
1396  return ligand_com;
1397 }
1398 
1399 core::Real PlaidFingerprint::rmsd(core::pose::Pose const & original_pose, core::pose::Pose const & oriented_pose) {
1400 
1401  core::Size lig_res_num = compute_ligand_resnum( original_pose );
1402 
1403  core::conformation::Residue const & pose1_rsd = original_pose.conformation().residue(lig_res_num);
1404  core::conformation::Residue const & pose2_rsd = oriented_pose.conformation().residue(lig_res_num);
1405 
1406  core::Real rmsd, dist_sum(0.);
1407  for(Size i = 1, i_end = pose1_rsd.nheavyatoms(); i <= i_end; ++i) {
1408  core::Real x_dist = ( (pose1_rsd.atom(i).xyz()(1) - pose2_rsd.atom(i).xyz()(1)) * (pose1_rsd.atom(i).xyz()(1) - pose2_rsd.atom(i).xyz()(1)) );
1409  core::Real y_dist = ( (pose1_rsd.atom(i).xyz()(2) - pose2_rsd.atom(i).xyz()(2)) * (pose1_rsd.atom(i).xyz()(2) - pose2_rsd.atom(i).xyz()(2)) );
1410  core::Real z_dist = ( (pose1_rsd.atom(i).xyz()(3) - pose2_rsd.atom(i).xyz()(3)) * (pose1_rsd.atom(i).xyz()(3) - pose2_rsd.atom(i).xyz()(3)) );
1411  dist_sum += x_dist + y_dist + z_dist;
1412  }
1413  rmsd = sqrt(dist_sum/pose1_rsd.nheavyatoms());
1414  return rmsd;
1415 
1416 }
1417 
1418 
1419 // note: not used
1420 //void PlaidFingerprint::move_origin( numeric::xyzVector<core::Real> const & new_origin ){
1421 // numeric::xyzVector<core::Real> fp_coor;
1422 // for (std::list<spherical_coor_triplet>::iterator pd = triplet_fingerprint_data_.begin(); pd != triplet_fingerprint_data_.end(); ++pd) {
1423 // // find cartesian coors relative to old origin
1424 // convert_spherical_coor_triplet_to_cartesian( *pd, fp_coor );
1425 // // move cartesian coors from old origin to new origin
1426 // fp_coor += origin_ - new_origin;
1427 // // convert from cartesian coors to polar
1428 // convert_cartesian_to_spherical_coor_triplet( fp_coor, *pd );
1429 // }
1430 // origin_ = new_origin;
1431 //}
1432 
1433 
1434 
1435 // note: not used, also deprecated because we now express all angles in radians
1436 //void correct_phi_psi( core::Real & phi, core::Real & psi ){
1437 // while ( phi < 0. ) {
1438 // phi *= -1.;
1439 // psi += 180.;
1440 // }
1441 // while ( phi > 360. ) {
1442 // phi -= 360.;
1443 // }
1444 // while ( phi > 180. ) {
1445 // phi = 360. - phi;
1446 // psi += 180.;
1447 // }
1448 // while ( psi < -180. ) psi += 360.;
1449 // while ( psi > 180. ) psi -= 360.;
1450 //}
1451 
1452 
1453 
1454 /* DEFINITIONS for the following code:
1455  (x0,y0,z0) = the coordinates of the "origin" point from which all rays originate, called P0
1456  (x2,y2,z2) = the coordinates of the pocket point that intersects the ray whose derivative we are calculating, called P2
1457  (x3,y3,z3) = the coordinates of the center of the atom that is intersecting the ray, called P3
1458  (xc,yc,zc) = the coordinates of the center of mass of the ligand BEFORE it has been moved into the current pose, called Pc
1459  (xs,ys,zs) = the coordinates of the center of the atom that is intersecting the ray BEFORE it has been moved into the current pose, called Ps
1460  r = the radius of the atom that is intersecting the ray
1461  v1 = variable that determines how much we translate the ligand's center of mass in the x direction, x component of translation vector called V13
1462  v2 = variable that determines how much we translate the ligand's center of mass in the y direction, y component of translation vector called V13
1463  v3 = variable that determines how much we translate the ligand's center of mass in the z direction, z component of translation vector called V13
1464  v4 = variable that determines the angle of rotation about the x axis, called rotation matrix A4
1465  v5 = variable that determines the angle of rotation about the y axis, called rotation matrix A5
1466  v6 = variable that determines the angle of rotation about the z axis, called rotation matrix A6
1467  (a,b,c) = (x2-x0,y2-y0,z2-z0) is the directional vector for the ray, called Pd = P2 -P0
1468 */
1469 /* ASSUMPTIONS for the following code:
1470  rotations are applied to the starting vector in the order: x first, y second, z third
1471  the coordinate basis has been chosen such that the NEGATIVE BRANCH of the solution for the intersection of the ray with the sphere is ALWAYS the correct one
1472  P0, P2, PC, PS and r are all constants
1473  we calculate P3 from the following equation:
1474  P3 = A6.A5.A4.(Ps-Pc) + Pc + V13
1475  which implies that v1-v6 are the only variables which influence P3
1476  ALL ANGLES ARE IN RADIANS
1477 */
1478 
1479 /* the function dD_dv1 calculates the value of the partial derivative of the distance, D, with respect to the variable v1 */
1480 double dD_dv1(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r){
1481 
1482  double u ; // paremeter that determines the point of intersection between the ray and the sphere
1483  double xI; // x coordinate for the intersection point
1484  double yI; // y coordinate for the intersection point
1485  double zI; // z coordinate for the intersection point
1486  double d ; // current distance between PI and P2
1487 
1488  double du_dx3 ; // derivative of u with respect to x3
1489  double Q ; // constant which multiplies the derivative du_dx3 to obtain dD_dv1
1490 
1491  // calculate directional vector
1492  const double a = x2-x0;
1493  const double b = y2-y0;
1494  const double c = z2-z0;
1495 
1496  // calculate paremter that determines intersection point between the line and the sphere
1497  u =(-(a*x0) + a*x3 - b*y0 + b*y3 - c*z0 - sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3)))/2.0 + c*z3)/(a*a + b*b + c*c);
1498 
1499  // calculate xI, yI and zI
1500  xI = x0+a*u ;
1501  yI = y0+b*u ;
1502  zI = z0+c*u ;
1503 
1504  // calculate current distance
1505  d = sqrt((xI-x2)*(xI-x2)+(yI-y2)*(yI-y2)+(zI-z2)*(zI-z2)) ;
1506 
1507  // claculate Q
1508  Q = (a*(xI-x2)+b*(yI-y2)+c*(zI-z2))/d ;
1509  //cout << "simple version:\n" << (xI-x2)/d << endl ;
1510 
1511  // calculate the derivative du_dx3
1512  du_dx3 = (a + (2.0*(b*b*(-x0 + x3) + a*b*(y0 - y3) + c*(c*(-x0 + x3) + a*(z0 - z3))))/sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3))))/(a*a + b*b + c*c) ;
1513 
1514  // cout << "complex version:\n" << Q*du_dx3 << endl ;
1515  return Q * du_dx3 ;
1516 }
1517 
1518 /* the function dD_dv2 calculates the value of the partial derivative of the distance, D, with respect to the variable v2 */
1519 double dD_dv2(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r){
1520 
1521  double u ; // paremeter that determines the point of intersection between the ray and the sphere
1522  double xI; // x coordinate for the intersection point
1523  double yI; // y coordinate for the intersection point
1524  double zI; // z coordinate for the intersection point
1525  double d ; // current distance between PI and P2
1526 
1527  double du_dy3 ; // derivative of u with respect to y3
1528  double Q ; // constant which multiplies the derivative du_dy3 to obtain dD_dv2
1529 
1530  // calculate directional vector
1531  const double a = x2-x0;
1532  const double b = y2-y0;
1533  const double c = z2-z0;
1534 
1535  // calculate paremter that determines intersection point between the line and the sphere
1536  u = (-(a*x0) + a*x3 - b*y0 + b*y3 - c*z0 - sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3)))/2.0 + c*z3)/(a*a + b*b + c*c);
1537 
1538  // calculate xI, yI and zI
1539  xI = x0+a*u ;
1540  yI = y0+b*u ;
1541  zI = z0+c*u ;
1542 
1543  // calculate current distance
1544  d = sqrt((xI-x2)*(xI-x2)+(yI-y2)*(yI-y2)+(zI-z2)*(zI-z2)) ;
1545 
1546  // claculate Q
1547  Q = (a*(xI-x2)+b*(yI-y2)+c*(zI-z2))/d ;
1548 
1549  // calculate the derivative du_dx3
1550  du_dy3 = (b - (2.0*(a*b*(-x0 + x3) + a*a*(y0 - y3) + c*(c*(y0 - y3) + b*(-z0 + z3))))/sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3))))/(a*a + b*b + c*c) ;
1551 
1552  return Q * du_dy3 ;
1553 }
1554 
1555 /* the function dD_dv3 calculates the value of the partial derivative of the distance, D, with respect to the variable v3 */
1556 double dD_dv3(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r){
1557 
1558  double u ; // paremeter that determines the point of intersection between the ray and the sphere
1559  double xI; // x coordinate for the intersection point
1560  double yI; // y coordinate for the intersection point
1561  double zI; // z coordinate for the intersection point
1562  double d ; // current distance between PI and P2
1563 
1564  double du_dz3 ; // derivative of u with respect to z3
1565  double Q ; // constant which multiplies the derivative du_dz3 to obtain dD_dv3
1566 
1567  // calculate directional vector
1568  const double a = x2-x0;
1569  const double b = y2-y0;
1570  const double c = z2-z0;
1571 
1572  // calculate paremter that determines intersection point between the line and the sphere
1573  u = (-(a*x0) + a*x3 - b*y0 + b*y3 - c*z0 - sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3)))/2.0 + c*z3)/(a*a + b*b + c*c);
1574 
1575  // calculate xI, yI and zI
1576  xI = x0+a*u ;
1577  yI = y0+b*u ;
1578  zI = z0+c*u ;
1579 
1580  // calculate current distance
1581  d = sqrt((xI-x2)*(xI-x2)+(yI-y2)*(yI-y2)+(zI-z2)*(zI-z2)) ;
1582 
1583  // claculate Q
1584  Q = (a*(xI-x2)+b*(yI-y2)+c*(zI-z2))/d ;
1585 
1586  // calculate the derivative du_dx3
1587  du_dz3 = (c + (2.0*(a*c*(x0 - x3) + a*a*(-z0 + z3) + b*(c*(y0 - y3) + b*(-z0 + z3))))/sqrt(4.0*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3))*(a*(x0 - x3) + b*(y0 - y3) + c*(z0 - z3)) - 4.0*(a*a + b*b + c*c)*(-r*r + (x0 - x3)*(x0-x3) + (y0 - y3)*(y0 - y3) + (z0 - z3)*(z0 - z3))))/(a*a + b*b + c*c);
1588 
1589  return Q * du_dz3 ;
1590 }
1591 
1592 /* the function dD_dv4 calculates the value of the partial derivative of the distance, D, with respect to the variable v4 */
1593 double dD_dv4(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r,const double v4,const double v5,const double v6,const double ,const double ,const double yc,const double ys,const double zc,const double zs) {
1594 
1595  double dx3_dv4 ; // derivative of x3 with respect to v4
1596  double dy3_dv4 ; // derivative of y3 with respect to v4
1597  double dz3_dv4 ; // derivative of y3 with respect to v4
1598 
1599  // calculate derivatives for P3
1600  dx3_dv4 = (-zc + zs)*(-(cos(v6)*sin(v4)*sin(v5)) + cos(v4)*sin(v6)) + (-yc + ys)*(cos(v4)*cos(v6)*sin(v5) + sin(v4)*sin(v6));
1601  dy3_dv4 = (-yc + ys)*(-(cos(v6)*sin(v4)) + cos(v4)*sin(v5)*sin(v6)) + (-zc + zs)*(-(cos(v4)*cos(v6)) - sin(v4)*sin(v5)*sin(v6)) ;
1602  dz3_dv4 = (-yc + ys)*cos(v4)*cos(v5) - (-zc + zs)*cos(v5)*sin(v4) ;
1603 
1604  return dD_dv1(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dx3_dv4 + dD_dv2(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dy3_dv4 + dD_dv3(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dz3_dv4 ;
1605 }
1606 
1607 /* the function dD_dv5 calculates the value of the partial derivative of the distance, D, with respect to the variable v5 */
1608 double dD_dv5(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r,const double v4,const double v5,const double v6,const double xc,const double xs,const double yc,const double ys,const double zc,const double zs) {
1609 
1610  double dx3_dv5 ; // derivative of x3 with respect to v5
1611  double dy3_dv5 ; // derivative of y3 with respect to v5
1612  double dz3_dv5 ; // derivative of y3 with respect to v5
1613 
1614  // calculate derivatives for P3
1615  dx3_dv5 = (-zc + zs)*cos(v4)*cos(v5)*cos(v6) + (-yc + ys)*cos(v5)*cos(v6)*sin(v4) - (-xc + xs)*cos(v6)*sin(v5) ;
1616  dy3_dv5 = (-zc + zs)*cos(v4)*cos(v5)*sin(v6) + (-yc + ys)*cos(v5)*sin(v4)*sin(v6) - (-xc + xs)*sin(v5)*sin(v6) ;
1617  dz3_dv5 = (xc - xs)*cos(v5) - (-zc + zs)*cos(v4)*sin(v5) - (-yc + ys)*sin(v4)*sin(v5) ;
1618 
1619  return dD_dv1(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dx3_dv5 + dD_dv2(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dy3_dv5 + dD_dv3(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dz3_dv5 ;
1620 }
1621 
1622 /* the function dD_dv6 calculates the value of the partial derivative of the distance, D, with respect to the variable v6 */
1623 double dD_dv6(const double x0,const double x2,const double x3,const double y0,const double y2,const double y3,const double z0,const double z2,const double z3,const double r,const double v4,const double v5,const double v6,const double xc,const double xs,const double yc,const double ys,const double zc,const double zs) {
1624 
1625  double dx3_dv6 ; // derivative of x3 with respect to v6
1626  double dy3_dv6 ; // derivative of y3 with respect to v6
1627  double dz3_dv6 ; // derivative of y3 with respect to v6
1628 
1629  // calculate derivatives for P3
1630  dx3_dv6 = (xc - xs)*cos(v5)*sin(v6) + (-zc + zs)*(cos(v6)*sin(v4) - cos(v4)*sin(v5)*sin(v6)) + (-yc + ys)*(-(cos(v4)*cos(v6)) - sin(v4)*sin(v5)*sin(v6)) ;
1631  dy3_dv6 = (-xc + xs)*cos(v5)*cos(v6) + (-yc + ys)*(cos(v6)*sin(v4)*sin(v5) - cos(v4)*sin(v6)) + (-zc + zs)*(cos(v4)*cos(v6)*sin(v5) + sin(v4)*sin(v6)) ;
1632  dz3_dv6 = 0.0 ;
1633 
1634  return dD_dv1(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dx3_dv6 + dD_dv2(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dy3_dv6 + dD_dv3(x0,x2,x3,y0,y2,y3,z0,z2,z3,r)*dz3_dv6 ;
1635 }
1636 
1637 
1638 core::Real Find_Closest_Intersect_SQ(core::Real const & phiAngle, core::Real const & psiAngle, core::Real const & atomX, core::Real const & atomY, core::Real const & atomZ, core::Real const & atom_radius){
1639 
1640  // note: phi/psi are in radians
1641 
1642  core::Real const large_dist(999.);
1643  core::Real dirX,dirY,dirZ;
1644  //compute (dirX,dirY,dirZ) from phi/psi with random large_dist, relative to Origin
1645  //Reference: http://paulbourke.net/geometry/sphereline/
1646  dirX = large_dist*sin(phiAngle)*cos(psiAngle);
1647  dirY = large_dist*sin(phiAngle)*sin(psiAngle);
1648  dirZ = large_dist*cos(phiAngle);
1649 
1650  // setup our quadratic equation
1651  core::Real const a = (dirX*dirX) + (dirY*dirY) + (dirZ*dirZ);
1652  core::Real const b = 2.0 * ( (dirX*(-atomX)) + (dirY*(-atomY)) + (dirZ*(-atomZ)) );
1653  core::Real const c = atomX*atomX + atomY*atomY + atomZ*atomZ - (atom_radius * atom_radius);
1654 
1655  // test for intersection
1656  core::Real const inside_sqrt = ( b * b ) - ( 4. * a * c );
1657 
1658  if ( inside_sqrt > 0. ) {
1659  // std::cout << "Line intersects atom\n" << std::endl;
1660  core::Real const inside = sqrt(inside_sqrt);
1661  core::Real const mu1 = -(b-inside) / ( 2. * a);
1662  core::Real const x1 = mu1 * dirX;
1663  core::Real const y1 = mu1 * dirY;
1664  core::Real const z1 = mu1 * dirZ;
1665  core::Real const dist1_sq = x1*x1 + y1*y1 + z1*z1;
1666  core::Real const mu2 = -(b+inside) / ( 2. * a);
1667  core::Real const x2 = mu2 * dirX;
1668  core::Real const y2 = mu2 * dirY;
1669  core::Real const z2 = mu2 * dirZ;
1670  core::Real const dist2_sq = x2*x2 + y2*y2 + z2*z2;
1671  if ( dist2_sq < dist1_sq ) {
1672  return dist2_sq;
1673  }
1674  return dist1_sq;
1675  }
1676  // std::cout <<phiAngle<<" " <<psiAngle<< " " << "No Intersection" << std::endl;
1677  return 9999.;
1678 }
1679 
1680 std::list<numeric::xyzVector<core::Real> > NonPlaidFingerprint::combine_xyz_lists(std::list< numeric::xyzVector<core::Real> > const & xyz_list_1, std::list< numeric::xyzVector<core::Real> > const & xyz_list_2 ) {
1681 
1682  std::list<numeric::xyzVector<core::Real> > combined_list;
1683  combined_list.clear();
1684  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = xyz_list_1.begin(); pd != xyz_list_1.end(); ++pd) {
1685  combined_list.push_back(*pd);
1686  }
1687  for (std::list< numeric::xyzVector<core::Real> >::const_iterator pd = xyz_list_2.begin(); pd != xyz_list_2.end(); ++pd) {
1688  combined_list.push_back(*pd);
1689  }
1690  return combined_list;
1691 }
1692 
1693 } // Pockets
1694 } // protocols