Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ElectronDensity.hh
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 core/scoring/methods/electron_density/ElectronDensity.hh
11 /// @brief Scoring a structure against an electron density map
12 /// @author Frank DiMaio
13 
14 #ifndef INCLUDED_core_scoring_electron_density_ElectronDensity_hh
15 #define INCLUDED_core_scoring_electron_density_ElectronDensity_hh
16 
17 // Project headers
18 #include <core/types.hh>
19 #include <core/pose/Pose.fwd.hh>
24 
25 // Utility headers
26 #include <utility/exit.hh>
27 
28 // ObjexxFCL Headers
29 #include <ObjexxFCL/FArray3D.hh>
30 
31 // C++ headers
32 #include <string>
33 #include <map>
34 #include <complex>
35 
36 #include <core/kinematics/RT.hh>
37 #include <utility/vector1.hh>
38 #include <utility/pointer/ReferenceCount.hh>
39 
40 
41 namespace core {
42 namespace scoring {
43 namespace electron_density {
44 
45 const core::Real MAX_FLT = 1e37;
46 
47 float pos_mod(float x,float y);
48 
50 public:
51  ///@brief Automatically generated virtual destructor for class deriving directly from ReferenceCount
52  virtual ~ElectronDensity();
53  /// @brief constructor
55 
56  /// @brief calulated density from a vector of poses
58 
59  /// @brief constructor from an FArray3D (debugging only)
60  template<class T>
61  ElectronDensity( ObjexxFCL::FArray3D< T > const &map,
62  core::Real apix = 1.0,
64  bool fftshift=false) {
65  init();
66 
67  isLoaded = true;
68  efforigin = origin = new_origin;
69  grid = numeric::xyzVector< int >(map.u1(),map.u2(),map.u3());
70  cellDimensions = numeric::xyzVector< float >(apix*map.u1(),apix*map.u2(),apix*map.u3());
72  density.dimension( map.u1(),map.u2(),map.u3() );
73  if (fftshift) origin -= grid/2;
74  for (int i=1; i<=(int)map.u1(); ++i) {
75  int fi = (int)(fftshift ? pos_mod( i-(map.u1()/2)-1 , map.u1())+1 : i);
76  for (int j=1; j<=(int)map.u2(); ++j) {
77  int fj = (int)(fftshift ? pos_mod( j-(map.u2()/2)-1 , map.u2())+1 : j);
78  for (int k=1; k<=(int)map.u3(); ++k) {
79  int fk = (int)(fftshift ? pos_mod( k-(map.u3()/2)-1 , map.u3())+1 : k);
80  density(fi,fj,fk) = (float)map(i,j,k);
81  }
82  }
83  }
84  }
85 
86  void
87  init();
88 
89  /// @brief Load an MRC (="new-CCP4") density map
90  bool
92  std::string mapfile,
93  core::Real reso=5.0,
94  core::Real gridSpacing=0.0);
95 
96  /// @brief Load an MRC (="new-CCP4") density map
97  bool readMRCandResize(
98  std::istream & mapin,
99  std::string mapfile, // just used as information about the map
100  core::Real reso=5.0,
101  core::Real gridSpacing=0.0);
102 
103  /// @brief (debugging) Write MRC mapfile
104  bool writeMRC(std::string mapfilestem);
105 
106  /// @brief (debugging) Write MATLAB v5 mapfile
107  bool writeMAT(std::string mapfilestem);
108 
109  /// @brief Align a pose about a 2D rotation axis
111 
112  /// @brief Quickly matches a centroid pose into a low-resolution density map
113  /// by placing a single Gaussian at each CA
114  core::Real
116  core::pose::Pose const &pose,
118  bool cacheCCs=false
119  );
120 
121  /// @brief Quickly matches a centroid pose into a low-resolution density map
122  /// by placing a single Gaussian at each atom
123  core::Real
124  matchPose(
125  core::pose::Pose const &pose,
127  bool cacheCCs=false
128  );
129 
130  /// @brief Match a pose to a patterson map
131  core::Real matchPoseToPatterson( core::pose::Pose const &pose, bool cacheCCs=false );
132 
133  /// @brief Rematch the pose to a patterson map, using previous rho_calc with only rsd changed
135 
136  /// @brief Update cached rho_calc by changing residue 'rsd'
138 
139  /// @brief Match a residue's conformation to the density map.
140  /// Backbone atoms from adjacent residues are also used for scoring.
141  /// Returns the correlation coefficient between map and pose
142  /// Internally stores per-res CCs, per-atom dCC/dxs
143  core::Real
144  matchRes(
145  int resid,
146  core::conformation::Residue const &rsd,
147  core::pose::Pose const &pose,
149  bool cacheCCs=false
150  );
151 
152  /// @brief Match a residue's conformation to the density map.
153  /// Same as matchRes, but using a fast approximation to the match function
154  core::Real
155  matchResFast( int resid,
156  core::conformation::Residue const &rsd,
157  core::pose::Pose const &pose,
159  );
160 
161  /// @brief Computes the symmatric rotation matrices
162  void
164  core::pose::Pose const &pose,
166  );
167 
168  /// @brief Return the gradient of CC w.r.t. atom X's movement
169  /// Uses information stored from the previous call to matchRes with this resid
170  void dCCdx_res(
171  int atmid,
172  int resid,
174  core::conformation::Residue const &rsd,
175  core::pose::Pose const &pose,
177  );
178 
179  /// @brief Return the gradient of "fast CC" w.r.t. atom X's movement
180  /// Uses information stored from the previous call to matchRes with this resid
181  void
183  int atmid,
184  int resid,
186  core::conformation::Residue const &rsd,
187  core::pose::Pose const &pose,
189  );
190 
191  /// @brief Return the gradient of CC w.r.t. res X's CA's movement
192  /// Centroid-mode analogue of dCCdx
193  void
194  dCCdx_cen(
195  int resid,
197  core::pose::Pose const &pose,
199  );
200 
201  /// @brief Return the gradient of whole-structure-CC w.r.t. atom X's movement
202  /// non-sliding-window analogue of dCCdx
203  void
204  dCCdx_aacen(
205  int atmid,
206  int resid,
208  core::pose::Pose const &pose,
210  );
211 
212  /// @brief Return the gradient of patterson-CC w.r.t. atom X's movement
213  void
214  dCCdx_pat(
215  int atmid,
216  int resid,
218  core::pose::Pose const &pose,
220  );
221 
222  /// @brief Resets the counters used for derivative computation in
223  /// sliding-window/fast scoring
224  void clear_dCCdx_res_cache( core::pose::Pose const &pose );
225 
226  /// @brief Get the transformation from indices to Cartesian coords using 'real' origin
228  numeric::xyzVector<core::Real> idxX( grid[0]-origin[0]+1 , grid[1]-origin[1]+1 , grid[2]-origin[2]+1 ) , cartX;
229  idx2cart( idxX , cartX );
230  return cartX;
231  }
232 
233  /// @brief set # of residues
234  void set_nres(int nres) {
235  if ( (int) CCs.size() != nres ) {
236  CCs.resize(nres, 0.0);
237  dCCdxs_res.resize(nres);
238  dCCdxs_pat.resize(nres);
239  dCCdxs_cen.resize(nres);
240  dCCdxs_aacen.resize(nres);
241  symmap.clear(); // reset if #residues changes
242  }
243  }
244 
245  /// @brief Print cached CCs
246  void showCachedScores( utility::vector1< int > const &reses );
248  runtime_assert( resid <= CCs.size() );
249  return CCs[resid];
250  }
251 
252  //////////////////////////////////
253  // property getters and setters
254  inline void setUseDensityInMinimizer( bool newVal ) { DensScoreInMinimizer = newVal; }
255  inline bool getUseDensityInMinimizer() const { return DensScoreInMinimizer; }
256 
257  inline void setUseExactDerivatives( bool newVal ) { ExactDerivatives = newVal; }
258  inline bool getUseExactDerivatives() const { return ExactDerivatives; }
259 
260  inline void setWindow( core::Size window_in ) { WINDOW_ = window_in; }
261  inline core::Size getWindow( ) { return WINDOW_; }
262 
263  inline void setScoreWindowContext( bool newVal ) { score_window_context_ = newVal; }
264  inline bool getScoreWindowContext() const { return score_window_context_; }
265 
266  //////////////////////////////////
267  // map properties
268  inline bool isMapLoaded() const { return this->isLoaded; };
269  inline core::Real getNumDerivH() const { return NUM_DERIV_H; }
270  inline core::Real getMean() const { return dens_mean; }
271  inline core::Real getMin() const { return dens_min; }
272  inline core::Real getMax() const { return dens_max; }
273  inline core::Real getStdev() const { return dens_stdev; }
274  inline core::Real getResolution( ) const { return this->reso; }
279 
280  void maskResidues( int scoring_mask ) {
281  scoring_mask_[ scoring_mask ] = 1;
282  }
283  void maskResidues( utility::vector1< int > const & scoring_mask ) {
284  for (core::Size i=1; i<= scoring_mask.size(); ++i)
285  scoring_mask_[ scoring_mask[i] ] = 1;
286  }
287  void clearMask( ) {
288  scoring_mask_.clear();
289  }
290 
291 
292  //////////////////////////////////
293  //////////////////////////////////
294  // raw data pointer
295  inline ObjexxFCL::FArray3D< float > const & data() const { return density; };
296 
297 
298  //////////////////////////////////
299  //////////////////////////////////
300  // helper functions to convert between indices and cartesian coords
301  inline void cart2idx( numeric::xyzVector<core::Real> const & cartX , numeric::xyzVector<core::Real> &idxX ) const {
302  numeric::xyzVector<core::Real> fracX = c2f*cartX;
303  idxX = numeric::xyzVector<core::Real>( fracX[0]*grid[0] - efforigin[0] + 1,
304  fracX[1]*grid[1] - efforigin[1] + 1,
305  fracX[2]*grid[2] - efforigin[2] + 1);
306  }
307 
308  template<class Q>
309  void idx2cart( numeric::xyzVector<Q> const & idxX , numeric::xyzVector<core::Real> &cartX ) const {
310  numeric::xyzVector<core::Real> fracX( (idxX[0] + efforigin[0] -1 ) / grid[0],
311  (idxX[1] + efforigin[1] -1 ) / grid[1],
312  (idxX[2] + efforigin[2] -1 ) / grid[2] );
313  cartX = f2c*fracX;
314  }
315 
316  template<class Q>
318  numeric::xyzVector<core::Real> fracX( ( (core::Real) idxX[0] ) / grid[0],
319  ( (core::Real) idxX[1] ) / grid[1],
320  ( (core::Real) idxX[2] ) / grid[2] );
321  cartX = f2c*fracX;
322  }
323 
324  //////////////////////////////////
325  //////////////////////////////////
326  // helper functions to convert between fractional and cartesian coords
327  inline void cart2frac( numeric::xyzVector<core::Real> const & cartX , numeric::xyzVector<core::Real> & fracX ) const {
328  fracX = c2f*(cartX);
329  }
330  inline void frac2cart( numeric::xyzVector<core::Real> const & fracX , numeric::xyzVector<core::Real> &cartX ) const {
331  cartX = f2c*fracX;
332  }
333 
337 
338 
340 
341  /// resize the map via FFT
342  void resize( core::Real approxGridSpacing );
343 
344  //// access cached data from last scored pose
346  runtime_assert( symmap.find( vrtid ) != symmap.end() );
347  X_map = symmap[ vrtid ].first;
348  R = symmap[ vrtid ].second;
349  }
350 
351  // gets rotation vactor for subunit 'subunit' in last-scored pose (Rosetta symmetry)
352  void get_R(int subunit, numeric::xyzMatrix<core::Real> &R) {
353  runtime_assert( symmap.find( -subunit ) != symmap.end() );
354  R = symmap[ -subunit ].second;
355  }
356 
357 
358 
359 ///////////
360 // PRIVATE MEMBER FUNCTIONS
361 ///////////
362 private:
363  // helper functions for map statistics
364  void computeGradients();
365  void computeStats();
366  int suggestRadius();
367 
368  // helper functions for symmetry
369  void initializeSymmOps( utility::vector1< std::string > const & symList );
370  void computeCrystParams();
371  void expandToUnitCell();
372 
373  // setup patterson map scoring data
375 
376  // setup fast density scoring data
378 
379  // get Fdrho_d(xyz)
380  // compute if not already computed
382 
383  // get S2 (reciprocal space dist^2)
384  double S2(int h, int k, int l) {
385  return ( h*h*RcellDimensions[0]*RcellDimensions[0]
386  + k*k*RcellDimensions[1]*RcellDimensions[1]
387  + l*l*RcellDimensions[2]*RcellDimensions[2]
391  }
392 
393 ///////////
394 // DATA
395 ///////////
396 private:
397  // do we have a map loaded?
398  bool isLoaded;
399 
400  // the density data array
401  ObjexxFCL::FArray3D< float > density;
402 
403  // fft of density
404  ObjexxFCL::FArray3D< std::complex<double> > Fdensity;
405 
406  // Controllable parameters
407  std::map< core::Size, bool > scoring_mask_;
411 
414  ObjexxFCL::FArray3D< float > PattersonEpsilon;
415 
416  // (patterson only) map resamped on p_calc grid
417  ObjexxFCL::FArray3D< double > p_o;
418  double po_bar;
419 
420  // (fast scoring) precomputed rhocrhoo, d_rhocrhoo
421  ObjexxFCL::FArray3D< double > fastdens_score;
422  ObjexxFCL::FArray3D< double > fastdens_dscoredx, fastdens_dscoredy, fastdens_dscoredz;
425 
426  ///////////////////
427  /// TONS OF CACHED STUFF
428  ///////////////////
429  // previously scored computed density map, fft(rho_calc), and patterson map
430  ObjexxFCL::FArray3D< double > rho_calc;
432  ObjexxFCL::FArray3D< std::complex<double> > Frho_calc;
434  ObjexxFCL::FArray3D< core::Size > bucket_id;
436  ObjexxFCL::FArray3D< double > F_s2;
437  ObjexxFCL::FArray3D< double > Pcalc;
439 
440  // symm pointer matrices
442 
443  // (precomputed)
444  // FFT of gradient of rho_calc with respec to an atom at the origin's movement in x/y/z
445  // computed for each scatterer
446  std::map< int , ObjexxFCL::FArray3D< std::complex<double> > > Fdrhoc_dx;
447  std::map< int , ObjexxFCL::FArray3D< std::complex<double> > > Fdrhoc_dy;
448  std::map< int , ObjexxFCL::FArray3D< std::complex<double> > > Fdrhoc_dz;
449 
450  // atoms, scattering used to calculate density map rho_calc
453 
454  // cached patterson map statistics
456 
457  // patterson map is calculated in P1, in an alternate (padded) grid to avoid self peaks
458  numeric::xyzVector< core::Real > d_min,d_max; // (remember bounding coords)
462 
463  // map info
464  core::Real max_del_grid; // max dist between grid pts
467 
468  // cache scoring-related statistics
475 
476  ///////////////////
477  /// SYMMETRY (Rosetta's symmetry, not necessarily crystal symmetry)
478  ///////////////////
479  // map vrtid -> subunit mapping, rotation
480  // if (vrtid < 0) then it refers to the mapping from a non-vrt in subunit# -vrtid
481  std::map< int , std::pair< utility::vector1<int> , numeric::xyzMatrix<core::Real> > > symmap;
482 
483  ///////////////////
484  /// VISUALIZATION-SPECIFIC
485  ///////////////////
486  // gradients, used for displaying isocontoured surface
487  // ... mutable for the viewer to access
488  // in non-graphics builds this never gets initialized
489  mutable ObjexxFCL::FArray3D< double > coeff_grad_x, coeff_grad_y, coeff_grad_z;
490 
491  ///////////////////
492  /// CRYSTAL INFO
493  ///////////////////
494  // TO DO --- put all this in a self-contained class
495  // converting fractional to cartesian coords
497 
498  // unit cell, reciprocal unit cell parameters, volume
502 
503  // symmetric transforms (in frac. coords)
504  // this is only used to expand the density data outside the ASU
505  // and is unrelated Rosetta's symmetric modelling
508 
509  // min multiples in each dim
511 
512  // map statistics
515 };
516 
517 /// @brief The EDM instance
519 
520 /// @brief The EDM instance
522 
523 
524 // x mod y, returns z in [0,y-1]
525 inline int pos_mod(int x,int y) {
526  int r=x%y; if (r<0) r+=y;
527  return r;
528 }
529 inline float pos_mod(float x,float y) {
530  float r=std::fmod(x,y); if (r<0) r+=y;
531  return r;
532 }
533 inline double pos_mod(double x,double y) {
534  double r=std::fmod(x,y); if (r<0) r+=y;
535  return r;
536 }
537 
538 }
539 }
540 }
541 
542 
543 #endif
544