Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
density_tools.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
11 /// @brief
12 
13 #include <protocols/viewer/viewers.hh>
14 
15 #include <protocols/moves/MonteCarlo.hh>
16 #include <protocols/moves/Mover.hh>
17 
18 #include <core/types.hh>
19 
20 #include <core/chemical/AA.hh>
21 #include <core/chemical/ChemicalManager.hh>
22 #include <core/chemical/ResidueTypeSet.fwd.hh>
23 #include <core/scoring/ScoreFunction.hh>
24 #include <core/scoring/ScoreFunctionFactory.hh>
25 #include <core/pose/Pose.hh>
26 #include <core/pose/PDBInfo.hh>
27 #include <core/scoring/electron_density/ElectronDensity.hh>
28 #include <core/import_pose/import_pose.hh>
29 #include <protocols/electron_density/util.hh>
30 #include <protocols/electron_density/SetupForDensityScoringMover.hh>
31 
32 #include <basic/options/util.hh>
33 #include <devel/init.hh>
34 
35 
36 #include <utility/vector1.hh>
37 
38 #include <numeric/xyzVector.hh>
39 #include <numeric/random/random.hh>
40 #include <numeric/constants.hh>
41 
43 #include <core/kinematics/Jump.hh>
44 
45 #include <basic/options/option.hh>
48 #include <basic/options/keys/in.OptionKeys.gen.hh>
49 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
50 
51 // C++ headers
52 #include <iostream>
53 #include <fstream>
54 #include <string>
55 
56 
57 using namespace core;
58 using namespace basic;
59 using namespace utility;
60 using namespace protocols;
61 
62 
63 OPT_1GRP_KEY(File, edensity, alt_mapfile)
64 OPT_1GRP_KEY(Integer, denstools, nresbins)
65 OPT_1GRP_KEY(Integer, denstools, rscc_wdw)
66 OPT_1GRP_KEY(Real, denstools, lowres)
67 OPT_1GRP_KEY(Real, denstools, hires)
68 OPT_1GRP_KEY(Real, denstools, truncate_lowres)
69 OPT_1GRP_KEY(Real, denstools, truncate_hires)
70 OPT_1GRP_KEY(Boolean, denstools, truncate_map)
71 OPT_1GRP_KEY(Boolean, denstools, verbose)
72 OPT_1GRP_KEY(Boolean, denstools, super_verbose)
73 OPT_1GRP_KEY(Boolean, denstools, dump_map_and_mask)
74 OPT_1GRP_KEY(Boolean, denstools, mask)
75 OPT_1GRP_KEY(Boolean, denstools, mask_modelmap)
76 OPT_1GRP_KEY(Real, denstools, mask_radius)
77 OPT_1GRP_KEY(Boolean, denstools, perres)
78 OPT_1GRP_KEY(Boolean, denstools, bin_squared)
79 
80 
81 using core::scoring::electron_density::poseCoords;
82 using core::scoring::electron_density::poseCoord;
83 
84 // map atom names to elements
85 // loosely based on openbabel logic
86 std::string
87 name2elt( std::string line ) {
88  std::string atmid = line.substr(12,4);
89  while ( !atmid.empty() && atmid[0] == ' ' ) atmid = atmid.substr(1,atmid.size()-1);
90  while ( !atmid.empty() && atmid[atmid.size()-1] == ' ' ) atmid = atmid.substr(0,atmid.size()-1);
91  std::string resname = line.substr(17,3);
92  while ( !resname.empty() && resname[0] == ' ' ) resname = resname.substr(1,resname.size()-1);
93  while ( !resname.empty() && resname[resname.size()-1] == ' ' ) resname = resname.substr(0,resname.size()-1);
94 
95  std::string type;
96 
97  if ( line.substr(0,4) == "ATOM" ) {
98  type = atmid.substr(0,2);
99  if ( isdigit(type[0]) ) {
100  // sometimes non-standard files have, e.g 11HH
101  if ( !isdigit(type[1]) ) type = atmid.substr(1,1);
102  else type = atmid.substr(2,1);
103  } else if ( (line[12] == ' ' && type!="Zn" && type!="Fe" && type!="ZN" && type!="FE")
104  || isdigit(type[1]) ) {
105  type = atmid.substr(0,1); // one-character element
106  }
107 
108  if ( resname.substr(0,2) == "AS" || resname[0] == 'N' ) {
109  if ( atmid == "AD1" ) type = "O";
110  if ( atmid == "AD2" ) type = "N";
111  }
112  if ( resname.substr(0,3) == "HIS" || resname[0] == 'H' ) {
113  if ( atmid == "AD1" || atmid == "AE2" ) type = "N";
114  if ( atmid == "AE1" || atmid == "AD2" ) type = "C";
115  }
116  if ( resname.substr(0,2) == "GL" || resname[0] == 'Q' ) {
117  if ( atmid == "AE1" ) type = "O";
118  if ( atmid == "AE2" ) type = "N";
119  }
120  if ( atmid.substr(0,2) == "HH" ) { // ARG
121  type = "H";
122  }
123  if ( atmid.substr(0,2) == "HD" || atmid.substr(0,2) == "HE" || atmid.substr(0,2) == "HG" ) {
124  type = "H";
125  }
126  } else {
127  if ( isalpha(atmid[0]) ) {
128  if ( atmid.size() > 2 && (atmid[2] == '\0' || atmid[2] == ' ') ) {
129  type = atmid.substr(0,2);
130  } else if ( atmid[0] == 'A' ) { // alpha prefix
131  type = atmid.substr(1, atmid.size() - 1);
132  } else {
133  type = atmid.substr(0,1);
134  }
135  } else if ( atmid[0] == ' ' ) {
136  type = atmid.substr(1,1); // one char element
137  } else {
138  type = atmid.substr(1,2);
139  }
140 
141  if ( atmid == resname ) {
142  type = atmid;
143  if ( type.size() == 2 ) type[1] = toupper(type[1]);
144  } else if ( resname == "ADR" || resname == "COA" || resname == "FAD" ||
145  resname == "GPG" || resname == "NAD" || resname == "NAL" ||
146  resname == "NDP" || resname == "ABA" ) {
147  if ( type.size() > 1 ) type = type.substr(0,1);
148  } else if ( isdigit(type[0]) ) {
149  type = type.substr(1,1);
150  } else if ( type.size() > 1 && isdigit(type[1]) ) {
151  type = type.substr(0,1);
152  } else if ( type.size() > 1 && isalpha(type[1]) ) {
153  if ( type[0] == 'O' && type[1] == 'H' ) {
154  type = type.substr(0,1); // no "Oh" element (e.g. 1MBN)
155  } else if ( islower(type[1]) ) {
156  type[1] = toupper(type[1]);
157  }
158  }
159  }
160  return type;
161 }
162 
163 
164 // quick and dirty PDB read where we only care about heavyatom locations and atom ids
165 void
166 readPDBcoords(std::string filename, poseCoords &atmlist) {
167  std::ifstream inpdb(filename.c_str());
168  std::string buf;
169 
170  while ( std::getline(inpdb, buf ) ) {
171  if ( buf.substr(0,4)!="ATOM" && buf.substr(0,6)!="HETATM" ) continue;
172  poseCoord atom_i;
173 
174  atom_i.x_[0] = atof(buf.substr(30,8).c_str());
175  atom_i.x_[1] = atof(buf.substr(38,8).c_str());
176  atom_i.x_[2] = atof(buf.substr(46,8).c_str());
177  atom_i.B_ = atof(buf.substr(60,6).c_str());
178 
179  atom_i.elt_ = name2elt( buf ); // horrible hacky logic mapping name->elt (could use PDB fields 76-77 if on by default)
180  if ( atom_i.elt_ == "H" ) continue;
181 
182  atmlist.push_back( atom_i );
183  }
184 }
185 
186 
187 ///////////////////////////////////////////////////////////////////////////////
188 void
190 {
191  using namespace protocols::moves;
192  using namespace scoring;
193  using namespace basic::options;
194  using namespace basic::options::OptionKeys;
195 
196  // outputs
197  Size nresobins = option[ denstools::nresbins ]();
198  bool bin_squared = option[ denstools::bin_squared ]();
199  utility::vector1< core::Real > resobins, mapI, maskedmapI, modelI, maskI;
200  utility::vector1< core::Size > resobin_counts;
202 
203  utility::vector1< core::Real > mapmapFSC, maskedMapMapFSC;
204  utility::vector1< core::Real > modelmapFSC, maskedModelMapFSC;
205 
206  // resolution limits for analysis
207  core::Real hires = option[ denstools::hires ]();
208  core::Real lowres = option[ denstools::lowres ]();
209  core::Real truncate_hires = option[ denstools::truncate_hires ]();
210  core::Real truncate_lowres = option[ denstools::truncate_lowres ]();
211  core::Real mask_radius = option[ denstools::mask_radius ]();
212  bool perres =option[ denstools::perres ]();
213 
214  ObjexxFCL::FArray3D< double > rhoC, rhoMask, rhoOmask, rhoO2mask;
215  ObjexxFCL::FArray3D< std::complex<double> > FrhoC, FrhoMask, FrhoCmask, FrhoOmask, FrhoO2mask;
217 
218  if ( hires == 0.0 ) hires = core::scoring::electron_density::getDensityMap().maxNominalRes();
219  if ( truncate_hires == 0.0 ) truncate_hires = core::scoring::electron_density::getDensityMap().maxNominalRes();
220 
221  runtime_assert( lowres > hires );
222  runtime_assert( truncate_lowres > truncate_hires );
223 
224  hires = 1.0/hires;
225  lowres = 1.0/lowres;
226  truncate_lowres = 1.0/truncate_lowres;
227  truncate_hires = 1.0/truncate_hires;
228 
229  // fft
230  std::cout << "Stage 1: FFT rho_obs" << std::endl;
231  numeric::fourier::fft3(core::scoring::electron_density::getDensityMap().data(), FrhoO);
232  core::scoring::electron_density::getDensityMap().getIntensities(FrhoO, nresobins, lowres, hires, mapI, bin_squared);
233 
234  // load model, mask density
235  std::cout << "Stage 2: model processing" << std::endl;
236  bool userpose = (option[ in::file::s ].user());
237 
238  poseCoords pose;
239  core::pose::Pose fullpose; // needed for per-residue stats (if requested)
240  std::string pdbfile;
241  if ( userpose && !option[ denstools::truncate_map ] ) {
244 
245  std::cout << " : calc rho_c + FFT" << std::endl;
246  core::scoring::electron_density::getDensityMap().calcRhoC( pose, mask_radius, rhoC, rhoMask );
247  numeric::fourier::fft3(rhoC, FrhoC);
248  numeric::fourier::fft3(rhoMask, FrhoMask);
249 
250  // apply mask
251  std::cout << " : mask map" << std::endl;
252  rhoOmask = rhoMask;
253  for ( int i=0; i<rhoC.u1()*rhoC.u2()*rhoC.u3(); ++i ) {
254  rhoOmask[i] *= core::scoring::electron_density::getDensityMap().data()[i];
255  }
256  numeric::fourier::fft3(rhoOmask, FrhoOmask);
257 
258  // intensities
259  std::cout << " : get intensities" << std::endl;
260  core::scoring::electron_density::getDensityMap().getIntensities(FrhoC, nresobins, lowres, hires, modelI, bin_squared);
261  core::scoring::electron_density::getDensityMap().getIntensities(FrhoMask, nresobins, lowres, hires, maskI, bin_squared);
262  core::scoring::electron_density::getDensityMap().getIntensities(FrhoOmask, nresobins, lowres, hires, maskedmapI, bin_squared);
263  }
264 
265  core::scoring::electron_density::getDensityMap().getResolutionBins(nresobins, lowres, hires, resobins, resobin_counts, bin_squared);
266 
267  // rescale
268  if ( option[ denstools::truncate_map ] ) {
269  utility::vector1< core::Real > trunc = mapI;
270  for ( int i=1; i<=(int)mapI.size(); ++i ) {
271  if ( resobins[i] <= truncate_lowres || resobins[i] >= truncate_hires ) {
272  trunc[i] = 0;
273  } else {
274  trunc[i] = 1;
275  }
276  }
277 
278  core::scoring::electron_density::getDensityMap().scaleIntensities( trunc, lowres, hires, bin_squared );
279  core::scoring::electron_density::getDensityMap().writeMRC( "map_trunc.mrc" );
280  std::cout << "Wrote truncated map" << std::endl;
281  return;
282  }
283 
284  // map vs map stats
285  std::cout << "Stage 3: map vs map" << std::endl;
286  core::scoring::electron_density::ElectronDensity mapAlt;
287  bool usermap = option[ edensity::alt_mapfile ].user();
288  if ( usermap ) {
289  std::string mapfile = option[ edensity::alt_mapfile ];
290  core::Real mapreso = option[ edensity::mapreso ]();
291  core::Real mapsampling = option[ edensity::grid_spacing ]();
292  std::cout << " : load alt_map + FFT" << std::endl;
293  mapAlt.readMRCandResize( mapfile , mapreso , mapsampling );
294  numeric::fourier::fft3(mapAlt.data(), FrhoO2);
295 
296  if ( userpose ) {
297  std::cout << " : mask alt_map" << std::endl;
298  rhoO2mask = rhoMask;
299  for ( int i=0; i<rhoC.u1()*rhoC.u2()*rhoC.u3(); ++i ) {
300  rhoO2mask[i] *= mapAlt.data()[i];
301  }
302  numeric::fourier::fft3(rhoO2mask, FrhoO2mask);
303  }
304 
305  // unmasked
306  std::cout << " : get FSCs" << std::endl;
307  core::scoring::electron_density::getDensityMap().getFSC(FrhoO, FrhoO2, nresobins, lowres, hires, mapmapFSC, bin_squared);
308 
309  // masked
310  if ( userpose ) {
311  core::scoring::electron_density::getDensityMap().getFSC(FrhoOmask, FrhoO2mask, nresobins, lowres, hires, mapmapFSC, bin_squared);
312  }
313  }
314 
315  // [3] model-map stats (intensity + model v map FSC + RSCC + per-res corrleations)
316  Real modelMapFSCsum=0, maskedModelMapFSCsum=0, RSCC=0;
317 
318  std::cout << "Stage 4: model vs map" << std::endl;
319  if ( userpose ) {
320  if ( perres ) {
321  std::cout << " : per-res" << std::endl;
322  core::chemical::ResidueTypeSetCAP rsd_set;
323  rsd_set = core::chemical::ChemicalManager::get_instance()->residue_type_set( "fa_standard" );
324  core::import_pose::pose_from_pdb( fullpose, pdbfile );
325 
326  core::Size nres = fullpose.total_residue();
327  perResCC.resize( nres, 0.0 );
328 
329  protocols::electron_density::SetupForDensityScoringMoverOP dockindens( new protocols::electron_density::SetupForDensityScoringMover );
330  dockindens->apply( fullpose );
331 
332  core::scoring::electron_density::getDensityMap().set_nres( nres );
333  core::scoring::electron_density::getDensityMap().setScoreWindowContext( true );
334  core::scoring::electron_density::getDensityMap().setWindow( option[ denstools::rscc_wdw ]() );
335 
336  core::scoring::ScoreFunctionOP scorefxn = core::scoring::get_score_function();
337  scorefxn->set_weight( core::scoring::elec_dens_window, 1.0 );
338  (*scorefxn)(fullpose);
339 
340  for ( core::uint r = 1; r <= nres; ++r ) {
341  perResCC[r] = core::scoring::electron_density::getDensityMap().matchRes( r , fullpose.residue(r), fullpose, NULL , false);
342  }
343  }
344 
345  std::cout << " : FSCs" << std::endl;
346  core::scoring::electron_density::getDensityMap().getFSC(FrhoO, FrhoC, nresobins, lowres, hires, modelmapFSC, bin_squared);
347  core::scoring::electron_density::getDensityMap().getFSC(FrhoOmask, FrhoC, nresobins, lowres, hires, maskedModelMapFSC, bin_squared);
348 
349  std::cout << " : RSCC" << std::endl;
350  RSCC = core::scoring::electron_density::getDensityMap().getRSCC( rhoC, rhoMask );
351 
352  // sum FSC over reso bins
353  for ( Size i=1; i<=resobins.size(); ++i ) {
354  modelMapFSCsum += modelmapFSC[i];
355  maskedModelMapFSCsum += maskedModelMapFSC[i];
356  }
357  modelMapFSCsum /= resobins.size();
358  maskedModelMapFSCsum /= resobins.size();
359  }
360 
361  // verbose
362  if ( option[ denstools::verbose ]() ) {
363  std::cerr << "res count";
364  if ( mapI.size() ) std::cerr << " I_map";
365  if ( maskedmapI.size() ) std::cerr << " I_map_masked";
366  if ( modelI.size() ) std::cerr << " I_model" ;
367  if ( maskI.size() ) std::cerr << " I_mask" ;
368  if ( mapmapFSC.size() ) std::cerr << " FSC_mapmap";
369  if ( modelmapFSC.size() ) std::cerr << " FSC_modelmap";
370  if ( maskedModelMapFSC.size() ) std::cerr << " FSC_maskedmodelmap";
371  std::cerr << std::endl;
372  for ( Size i=1; i<=resobins.size(); ++i ) {
373  std::cerr << resobins[i] << " " << resobin_counts[i];
374  if ( mapI.size() ) std::cerr << " " << mapI[i];
375  if ( maskedmapI.size() ) std::cerr << " " << maskedmapI[i];
376  if ( modelI.size() ) std::cerr << " " << modelI[i];
377  if ( maskI.size() ) std::cerr << " " << maskI[i];
378  if ( mapmapFSC.size() ) std::cerr << " " << mapmapFSC[i];
379  if ( modelmapFSC.size() ) std::cerr << " " << modelmapFSC[i];
380  if ( maskedModelMapFSC.size() ) std::cerr << " " << maskedModelMapFSC[i];
381  std::cerr << std::endl;
382  }
383  }
384 
385  // dump
386  if ( userpose && option[ denstools::dump_map_and_mask ]() ) {
387  core::scoring::electron_density::getDensityMap().set_data(rhoOmask);
388  core::scoring::electron_density::getDensityMap().writeMRC( "map_masked.mrc" );
389 
390  core::scoring::electron_density::getDensityMap().set_data(rhoC);
391  core::scoring::electron_density::getDensityMap().writeMRC( "model_dens.mrc" );
392 
393  core::scoring::electron_density::getDensityMap().set_data(rhoMask);
394  core::scoring::electron_density::getDensityMap().writeMRC( "model_mask.mrc" );
395  }
396 
397  if ( userpose && option[ denstools::perres ]() ) {
398  for ( core::uint r = 1; r <= perResCC.size(); ++r ) {
399  std::cerr << "PERRESCC residue " << r << " " << perResCC[r] << std::endl;
400  }
401  }
402 
403  // compact
404  if ( userpose ) {
405  std::cerr << pdbfile << "RSCC/FSC/FSCmask: " << RSCC << " " << modelMapFSCsum << " " << maskedModelMapFSCsum;
406  std::cerr << std::endl;
407  }
408 }
409 
410 
411 ///////////////////////////////////////////////////////////////////////////////
412 
413 int
414 main( int argc, char * argv [] )
415 {
416  try {
417  // options, random initialization
418  NEW_OPT(denstools::lowres, "low res limit", 1000.0);
419  NEW_OPT(denstools::hires, "high res limit", 0.0);
420  NEW_OPT(edensity::alt_mapfile, "alt mapfile", "");
421  NEW_OPT(denstools::nresbins, "# resolution bins for statistics", 200);
422  NEW_OPT(denstools::truncate_map, "dump map with map I scaled to to model I?", false);
423  NEW_OPT(denstools::truncate_lowres, "low res truncation", 1000.0);
424  NEW_OPT(denstools::truncate_hires, "high res truncation", 0.0);
425  NEW_OPT(denstools::dump_map_and_mask, "dump mrc of rho_calc and eps_calc", false);
426  NEW_OPT(denstools::mask, "mask all calcs", false);
427  NEW_OPT(denstools::mask_modelmap, "mask model-map calcs only", false);
428  NEW_OPT(denstools::mask_radius, "radius for masking", 0.0);
429  NEW_OPT(denstools::perres, "output per-residue stats", false);
430  NEW_OPT(denstools::verbose, "dump extra output", false);
431  NEW_OPT(denstools::super_verbose, "dump a lot of extra output", false);
432  NEW_OPT(denstools::bin_squared, "bin uniformly in 1/res^2 (default bins 1/res)", false);
433  NEW_OPT(denstools::rscc_wdw, "sliding window to calculate rscc", 3);
434 
435  devel::init( argc, argv );
436  densityTools();
437  } catch ( utility::excn::EXCN_Base const & e ) {
438  std::cout << "caught exception " << e.msg() << std::endl;
439  return -1;
440  }
441  return 0;
442 }
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
virtual std::string const msg() const
Definition: EXCN_Base.hh:70
std::istream & getline(std::istream &stream, Fstring &s)
Get Line from Stream.
Definition: Fstring.cc:1610
void init(int argc, char *argv[])
Command line init() version.
Definition: init.cc:23
core::pose::Pose Pose
Definition: supercharge.cc:101
#define runtime_assert(_Expression)
Assert that the condition holds. Evaluated for both debug and release builds.
Definition: exit.hh:63
Random number generator system.
std::string start_file()
kind of like the old -s – just one file
Definition: util.cc:41
void fft3(ObjexxFCL::FArray3D< std::complex< double > > const &X, ObjexxFCL::FArray3D< std::complex< double > > &fX)
3D fft c->c double
Definition: FFT.cc:152
tuple scorefxn
Definition: PyMOL_demo.py:63
basic::options::OptionKeys collection
void readPDBcoords(std::string filename, poseCoords &atmlist)
rule< Scanner, options_closure::context_t > options
Definition: Tag.cc:377
double Real
Definition: types.hh:39
int main(int argc, char *argv[])
static char * line
Definition: Svm.cc:2683
#define NEW_OPT(akey, help, adef)
ocstream cout(std::cout)
Wrapper around std::cout.
Definition: ocstream.hh:287
vector1: std::vector with 1-based indexing
void densityTools()
std::string name2elt(std::string line)
std::size_t uint
Definition: types.hh:39
Common numeric constants in varying precisions.
#define OPT_1GRP_KEY(type, grp, key)
Program options global and initialization function.
Fast (x,y,z)-coordinate numeric vector.
platform::Size Size
Definition: random.fwd.hh:30
int const verbose
rule< Scanner, option_closure::context_t > option
Definition: Tag.cc:378
FArray3D: Fortran-Compatible 3D Array.
Definition: FArray3.hh:27