Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
util.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 protocols for folding into density
12 /// @detailed
13 /// @author Frank DiMaio
14 
18 
19 
20 #include <core/id/AtomID.hh>
25 #include <core/kinematics/Jump.hh>
27 
28 // Symmetry
31 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
32 
35 
36 
37 #include <core/pose/Pose.hh>
38 // AUTO-REMOVED #include <core/pose/util.hh>
39 
42 
43 #include <basic/options/option.hh>
44 
45 // option key includes
46 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
47 
48 //
49 #include <basic/Tracer.hh>
50 
51 #include <protocols/loops/Loop.hh>
52 #include <protocols/loops/Loops.hh>
53 
54 #include <utility/vector1.hh>
55 #include <numeric/xyz.functions.hh>
56 
57 using basic::T;
58 using basic::Error;
59 using basic::Warning;
60 
61 
62 namespace protocols {
63 namespace electron_density {
64 
65 static basic::Tracer TR("protocols.electron_density.util");
66 
67 using namespace protocols;
68 using namespace core;
69 
70 // find stratch of residues worst agreeing with patterson map
71 // for each possible segment, remove and rescore
73  int nres = pose.total_residue();
74  while (!pose.residue(nres).is_protein()) nres--;
75 
76  runtime_assert( nres > (int)N );
77 
78  utility::vector1< core::Real > scores(nres, -1);
79  int start_res = allow_termini? 1 : 6;
80  int stop_res = allow_termini? nres : nres-5;
81 
82  // SLOW
83  for (int i=start_res+1; i<= stop_res-(int)N; i++) {
84  // check for cutpoints in this segment
85  bool contains_cut = false;
86  for (int j=i; j<i+(int)N; ++j)
87  contains_cut |= pose.fold_tree().is_cutpoint( j );
88  if (contains_cut) continue;
89 
91 
92  // mask i->i+N-1
93  for (int j=i; j<i+(int)N; ++j)
95 
96  // score
98  //std::cerr << "res " << i << " to " << i+N-1 << " --- " << scores[i] << std::endl;
99  }
100 
102  for (int i=0; i<(int)nloops; ++i) {
103  core::Real worst_match = -1;
104  int worst_match_idx = -1;
105  for (int j=0; j<nres; ++j) {
106  if (scores[j] > worst_match) {
107  worst_match = scores[j];
108  worst_match_idx = j;
109  }
110  }
111 
112  retval.push_back( protocols::loops::Loop( worst_match_idx, worst_match_idx+N-1 ) );
113  for (int j=worst_match_idx; j<worst_match_idx+(int)N; ++j)
114  scores[j] = -1;
115  }
116 
117  return ( retval );
118 }
119 
120 
121 protocols::loops::Loops findLoopFromDensity( core::pose::Pose & pose, core::Real frac, int max_helix_melt, int max_strand_melt ) {
122  int nres = pose.total_residue();
123  while (!pose.residue(nres).is_polymer()) nres--;
124 
125  // get dssp parse
126  core::scoring::dssp::Dssp secstruct( pose );
127  ObjexxFCL::FArray1D< char > dssp_pose( nres );
128  secstruct.dssp_reduced (dssp_pose);
129  utility::vector1< core::Real > perResCC( nres ), smoothPerResCC( nres );
130 
131  // align to map
134  dockindens->apply( pose );
135 
136  // per-res score
138 
139  //////////////////////
140  // now do the matching!
141  for (int r=1; r<=nres; ++r) {
142  // check for missing density ... how? look for atoms > 40A apart
143  bool isMissingDens = false;
144  for (int j=1; j<(int)pose.residue(r).natoms(); ++j) {
145  for (int i=j+1; j<=(int)pose.residue(r).natoms(); ++j) {
146  if ( (pose.residue(r).atom(i).xyz() - pose.residue(r).atom(j).xyz()).length() > 40 ) {
147  isMissingDens = true;
148  break;
149  }
150  }
151  }
152 
153  if (isMissingDens) {
154  perResCC[r] = 0.0;
155  } else {
156  perResCC[r] =
157  std::max(
158  core::scoring::electron_density::getDensityMap().matchRes( r , pose.residue(r), pose, NULL , false),
159  0.001);
160  }
161  }
162 
163  // sort by filtered smoothed CC
164  utility::vector1< bool > loopMarker( nres, false );
165 
166  // smooth CCs
167  smoothPerResCC[1] = 0.67*perResCC[1] + 0.33*perResCC[2];
168  for (int r=2; r<=nres-1; ++r) {
169  smoothPerResCC[r] = 0.25*perResCC[r+1] + 0.5*perResCC[r] + 0.25*perResCC[r];
170  }
171  smoothPerResCC[nres] = 0.67*perResCC[nres] + 0.33*perResCC[nres-1];
172 
173  // missing dens
174  for (int r=1; r<=nres; ++r) {
175  if (perResCC[r] == 0) smoothPerResCC[r] = 0.0;
176  if (r != 1 && perResCC[r-1] == 0) smoothPerResCC[r] = 0.0;
177  if (r != nres && perResCC[r+1] == 0) smoothPerResCC[r] = 0.0;
178  }
179 
180  // don't eat into sec struct elements too much
181  // filter by setting their CCs artificially high
182  for (int r=1; r<=nres; ++r) {
183  bool in_strand = (max_strand_melt >= 0), in_helix = (max_helix_melt >= 0);
184  //bool in_strand = true, in_helix = true;
185  for (int i=std::max(1,r-max_strand_melt), i_end=std::min(nres,r+max_strand_melt); i<= i_end; ++i) {
186  in_strand &= (dssp_pose(i) == 'E');
187  }
188  for (int i=std::max(1,r-max_helix_melt), i_end=std::min(nres,r+max_helix_melt); i<= i_end; ++i) {
189  in_helix &= (dssp_pose(i) == 'H');
190  }
191  if ( in_strand || in_helix ) {
192  if ( smoothPerResCC[ r ] > 0.0 ) // missing dens
193  smoothPerResCC[ r ] = 2;
194  }
195  }
196 
197  utility::vector1< core::Real > sortPerResCC = smoothPerResCC;
198  std::sort( sortPerResCC.begin(), sortPerResCC.end() );
199  core::Real CCcutoff = sortPerResCC[ (int)std::floor(frac*nres + 0.5) ];
200  for (int r=1; r<=nres; ++r) {
201  loopMarker[r] = (smoothPerResCC[r] < CCcutoff);
202  }
203 
204  // remove singletons
205  for (int r=2; r<=nres-1; ++r) {
206  if ( loopMarker[r+1] && loopMarker[r-1] ) {
207  loopMarker[r] = true;
208  }
209  if ( !loopMarker[r+1] && !loopMarker[r-1] ) {
210  if ( perResCC[r] > 0 ) {
211  loopMarker[r] = false;
212  } else {
213  loopMarker[r+1] = loopMarker[r-1] = true; // r is missing density; force rebuild
214  }
215  }
216  }
217 
218  // fix termini
219  // if _ANY_ of the four terminal residues should be rebuilt, build them all
221  for (int i=1; i<=(int)cuts.size(); ++i) {
222  int j = cuts[i];
223  if (j <= nres-4 && (loopMarker[j+4] || loopMarker[j+3] || loopMarker[j+2] || loopMarker[j+1] ) ) {
224  loopMarker[j+4] = loopMarker[j+3] = loopMarker[j+2] = loopMarker[j+1] = true;
225  }
226  if (j >= 3 && (loopMarker[j] || loopMarker[j-3] || loopMarker[j-2] || loopMarker[j-1]) ) {
227  loopMarker[j] = loopMarker[j-3] = loopMarker[j-2] = loopMarker[j-1] = true;
228  }
229  }
230 
231  // finally ... write the loopfile
233  core::Size loop_start=0, loop_end=0;
234  bool inloop=false;
235  for (int r=1; r<=nres; ++r) {
236  if ( loopMarker[r] && !inloop ) {
237  loop_start = r;
238  loop_end = r;
239  inloop = true;
240  } else if ( loopMarker[r] && inloop ) {
241  loop_end = r;
242  } else if ( !loopMarker[r] && inloop ) {
243  //out << "LOOP " << loop_start << " " << loop_end << " 0 0" << std::endl;
244  retval.push_back( protocols::loops::Loop( loop_start, loop_end ) );
245  inloop = false;
246  }
247 
248  // force loop to end at cutpoint
249  if (pose.fold_tree().is_cutpoint( r ) && inloop) {
250  // above cases handle singletons
251  retval.push_back( protocols::loops::Loop( loop_start, loop_end ) );
252  inloop = false;
253  }
254  }
255 
256  if ( inloop ) {
257  retval.push_back( protocols::loops::Loop( loop_start, loop_end ) );
258  }
259 
260  return retval;
261 }
262 
263 
264 //
265 // dock pose into a density map
266 // respect recentering flags
267 // should we ensure we are set up for density scoring?????
269  using namespace basic::options;
270 
271  std::string align = align_in;
272  if (align.length() == 0)
273  align = option[ OptionKeys::edensity::realign ]();
274 
275  // minimization
278  scorefxn_dens = new core::scoring::symmetry::SymmetricScoreFunction( scorefxn_dens );
280 
282  core::Real dens_patt = scorefxn_input->get_weight( core::scoring::patterson_cc );
283  core::Real dens_wind = scorefxn_input->get_weight( core::scoring::elec_dens_window );
284  core::Real dens_allca = scorefxn_input->get_weight( core::scoring::elec_dens_whole_structure_ca );
285  core::Real dens_allatom = scorefxn_input->get_weight( core::scoring::elec_dens_whole_structure_allatom );
286  core::Real dens_fast = scorefxn_input->get_weight( core::scoring::elec_dens_fast );
287 
288  if (dens_patt>0) scorefxn_dens->set_weight( core::scoring::patterson_cc, dens_patt );
289  if (dens_wind>0) scorefxn_dens->set_weight( core::scoring::elec_dens_window, dens_wind );
290  if (dens_allca>0) scorefxn_dens->set_weight( core::scoring::elec_dens_whole_structure_ca, dens_allca );
291  if (dens_allatom>0) scorefxn_dens->set_weight( core::scoring::elec_dens_whole_structure_allatom, dens_allatom );
292  if (dens_fast>0) scorefxn_dens->set_weight( core::scoring::elec_dens_fast, dens_fast );
293 
294  // make sure at least 1 density term is on
295  core::Real dens_score_sum =
296  scorefxn_dens->get_weight( core::scoring::patterson_cc ) +
297  scorefxn_dens->get_weight( core::scoring::elec_dens_window ) +
298  scorefxn_dens->get_weight( core::scoring::elec_dens_whole_structure_ca ) +
299  scorefxn_dens->get_weight( core::scoring::elec_dens_whole_structure_allatom );
300  scorefxn_dens->get_weight( core::scoring::elec_dens_fast );
301 
302  if (align != "no" && align != "random" && dens_score_sum==0 ) {
303  scorefxn_dens->set_weight( core::scoring::elec_dens_fast, 1.0 );
304  }
305 
306  core::Real dens_score = 0.0;
307 
308  if (align == "no") {
309  //dens_score = (*scorefxn_dens)( pose );
310  return dens_score; // do nothing
311  }
312  if (align == "random") {
313  // get jump index of root jump
314  int root = pose.fold_tree().root();
317  for (int i=1; i<=(int)root_edges.size(); ++i) {
318  core::kinematics::Jump flexible_jump = pose.jump( i );
319  flexible_jump.set_rotation( rot * flexible_jump.get_rotation() );
320  pose.set_jump( i, flexible_jump );
321  }
322  dens_score = (*scorefxn_dens)( pose );
323  return dens_score;
324  }
325 
326  /////
327  // initial alignment
328  if ( align.substr(0,8) == "membrane") {
329  // align centers of mass
330  fastTransAlignPose( pose );
331 
332  // rotation
333  fast2DRotAlignPose( pose, option[ OptionKeys::edensity::membrane_axis ]());
334  }
335 
336  /////
337  // minimization
338  // special case for symmetric poses
339  if ( align.length() >= 3 && align.substr( align.length()-3 ) == "min" ) {
340  bool isSymm = core::pose::symmetry::is_symmetric(pose);
341 
342  // get jump index of root jump
343  int root = pose.fold_tree().root();
345 
347  rbmm->set_bb( false ); rbmm->set_chi( false );
348  // TODO? a flag which toggles minimization of:
349  // a) all rigid-body DOFs
350  // b) all symmetric DOFs
351  // HOWEVER, if this is done then fa_rep / vdw should be turned on
352  TR << "RBminimizing pose into density alongs jump(s)";
353  for (core::Size i=1; i<=root_edges.size(); ++i) {
354  TR << " " << root_edges[i].label();
355  rbmm->set_jump ( root_edges[i].label() , true );
356  }
357  TR << std::endl;
358 
359  if (isSymm) {
361 
363  moves::MoverOP min_mover = new simple_moves::symmetry::SymMinMover( rbmm, symmscorefxn_dens, "dfpmin_armijo_nonmonotone", 1e-5, true );
364 
367  min_mover->apply( pose );
369 
370  symmscorefxn_dens->show( TR, pose ); TR<<std::endl;
371  dens_score = (*symmscorefxn_dens)( pose );
372  } else {
373  moves::MoverOP min_mover = new protocols::simple_moves::MinMover( rbmm, scorefxn_dens, "dfpmin_armijo_nonmonotone", 1e-5, true );
374 
377  min_mover->apply( pose );
379  dens_score = (*scorefxn_dens)( pose );
380  }
381  }
382  return dens_score;
383 }
384 
385 
386 //
387 // align pose CoM to density CoM
389  // align CoM of map and fragment
390  int nres( pose.total_residue() ), nAtms = 0;
391  numeric::xyzVector<core::Real> massSum(0,0,0), poseCoM, mapCoM, mapOri;
392  for ( int i=1; i<= nres; ++i ) {
393  conformation::Residue const & rsd( pose.residue(i) );
394  if (rsd.aa() == core::chemical::aa_vrt) continue;
395 
396  for ( Size j=1; j<= rsd.nheavyatoms(); ++j ) {
397  conformation::Atom const & atom( rsd.atom(j) );
398  massSum += atom.xyz();
399  nAtms++;
400  }
401  }
402  poseCoM = massSum / (core::Real)nAtms;
403 
405  //mapOri = core::scoring::electron_density::getDensityMap().getOrigin();
406 
407  // grid coords -> cart coords
410 
411  numeric::xyzVector<core::Real> translation = mapCoMxyz-poseCoM;
412  //TR << "Aligning inital pose to density ... " << std::endl;
413  //TR << " pdb center-of-mass = " << poseCoM << std::endl;
414  //TR << " map center-of-mass = " << mapCoM << std::endl;
415  //TR << " translation (structure -> map) = " << translation << std::endl;
416 
417  // apply translation to each residue in the pose
418  for ( int i=1; i<= nres; ++i ) {
419  conformation::Residue const & rsd( pose.residue(i) );
420  if (rsd.type().aa() == core::chemical::aa_vrt)
421  continue;
422  for ( Size j=1; j<= rsd.natoms(); ++j ) {
423  numeric::xyzVector<core::Real> atom_ij = pose.xyz( id::AtomID(j,i) );
424  pose.set_xyz( id::AtomID(j,i) , (atom_ij+translation) );
425  }
426  }
427  return 0.0;
428 }
429 
431  if (axis != "X" && axis != "Y" && axis != "Z") {
432  TR.Error << "Unrecognized membrane-normal axis '" << axis << "'" << std::endl;
433  TR.Error << "Not aligning!" << std::endl;
434  return 0.0;
435  }
436 
437  int nres( pose.total_residue() ), nAtms = 0;
438  numeric::xyzVector<core::Real> massSum(0,0,0), poseCoM, mapCoM, mapOri;
439  for ( int i=1; i<= nres; ++i ) {
440  conformation::Residue const & rsd( pose.residue(i) );
441  if (rsd.aa() == core::chemical::aa_vrt) continue;
442  for ( Size j=1; j<= rsd.nheavyatoms(); ++j ) {
443  conformation::Atom const & atom( rsd.atom(j) );
444  massSum += atom.xyz();
445  nAtms++;
446  }
447  }
448  poseCoM = massSum / (core::Real)nAtms;
449 
452 
453  // apply translation to each residue in the pose
454  for ( int i=1; i<= nres; ++i ) {
455  conformation::Residue const & rsd( pose.residue(i) );
456  if (rsd.type().aa() == core::chemical::aa_vrt) continue;
457  for ( Size j=1; j<= rsd.natoms(); ++j ) {
458  numeric::xyzVector<core::Real> atom_ij = pose.xyz( id::AtomID(j,i) );
459  pose.set_xyz( id::AtomID(j,i) , R*(atom_ij-poseCoM)+poseCoM );
460  }
461  }
462  return 0.0;
463 }
464 
465 
466 }
467 }
468