Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FunGroupTK.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 // This file is part of the Rosetta software suite and is made available under license.
5 // The Rosetta software is developed by the contributing members of the Rosetta Commons consortium.
6 // (C) 199x-2009 Rosetta Commons participating institutions and developers.
7 // For more information, see http://www.rosettacommons.org/.
8 
9 /// @file /src/apps/pilat/will/genmatch.cc
10 /// @brief ???
11 
13 
14 #include <basic/Tracer.hh>
17 // AUTO-REMOVED #include <core/chemical/util.hh>
20 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
21 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
22 // AUTO-REMOVED #include <core/kinematics/MoveMap.hh>
23 #include <core/kinematics/Stub.hh>
24 #include <core/pose/Pose.hh>
25 #include <core/pose/util.hh>
26 #include <numeric/constants.hh>
27 #include <numeric/xyz.functions.hh>
28 // AUTO-REMOVED #include <numeric/xyz.io.hh>
29 // AUTO-REMOVED #include <ObjexxFCL/FArray2D.hh>
30 #include <ObjexxFCL/format.hh>
31 #include <ObjexxFCL/string.functions.hh>
33 #include <sstream>
34 // AUTO-REMOVED #include <utility/io/izstream.hh>
35 // AUTO-REMOVED #include <utility/io/ozstream.hh>
36 
37 #include <utility/vector1.hh>
38 
39 //Auto Headers
42 
43 
44 
45 static basic::Tracer TR("protocols.kinmatchFunGroupTK");
46 
47 namespace protocols {
48 namespace kinmatch {
49 
50 /// @details Auto-generated virtual destructor
52 
55 using core::Real;
56 using core::Size;
57 using core::pose::Pose;
58 using core::pose::PoseOP;
60 using core::id::AtomID;
65 using std::string;
66 using utility::vector1;
67 using numeric::min;
68 using numeric::min;
69 using numeric::max;
70 using numeric::constants::d::pi;
71 using numeric::conversions::degrees;
72 using utility::io::ozstream;
73 using ObjexxFCL::fmt::I;
74 using ObjexxFCL::fmt::F;
75 
81 
82 template< typename T >
83 inline
85 str( T const & t )
86 {
87  return ObjexxFCL::string_of(t);
88 }
89 
90 template< typename T >
91 inline
94  T const & t,
95  int const w // Minimum width
96 )
97 {
98  return ObjexxFCL::lead_zero_string_of(t,w);
99 }
100 
101 
102 
103 
104  inline Real sqr(Real const r) { return r*r; }
105 
106  inline Vec xyz(Pose const & p, Size const & ia, Size const & ir) {
107  return p.xyz(AtomID(ia,ir));
108  }
109 
110  PoseOP alapose(Pose const & pose_in) {
111  PoseOP rpose = new Pose(pose_in);
112  Pose & pose(*rpose);
113  for(Size i=1; i<=pose.n_residue(); ++i) {
115  }
116  return rpose;
117  }
118 
120  if( v.size()==0 ) {
121  v.resize(n);
122  for(Size i = 1; i <=n; ++i) v[i] = i;
123  }
124  return(v);
125  }
126 
127 
128  void dumpcgo(Vec v, string l) {
129  std::cerr << "cmd.load_cgo(Vec( " << v.x() << "," << v.y() << "," << v.z() << ").cgo(), '"+l+"')" << std::endl;
130  }
131 
132  void xform_rsd_gl2(Stub const & s, Residue & rsd) {
133  for(Size i = 1; i <= rsd.natoms(); ++i) rsd.set_xyz(i, s.global2local(rsd.xyz(i)) );
134  }
135 
136 
137 KRSQuery::KRSQuery(KRSQueryType typ ) : type(typ),cen(0,0,0),axs(1,0,0),ori(0,1,0),disth(0.5),angth(0.0175),clash( 2.8) {}
138 KRSQuery::KRSQuery(KRSQueryType typ, Vec c, Vec a, Vec o, Real dt, Real at, Real clsh ) : type(typ),cen( c ),axs( a ),ori( o ),disth( dt),angth( at ),clash(clsh) {}
139 KRSQuery::KRSQuery(KRSQueryType typ, Vec c, Vec a, Real dt, Real at, Real clsh ) : type(typ),cen( c ),axs( a ),ori(0,0,0),disth( dt),angth( at ),clash(clsh) {}
140 
141 
143  Pose & p_in,
144  vector1<Size> & pos
145  )
146  : pose_(alapose(p_in)), pos_(allifnone(pos,pose_->n_residue()))
147 {
148  ifc_ = new ImplicitFastClashCheck(*pose_,2.2);
150  vector1<string> res_types;
151  res_types.push_back("ASP");
152  res_types.push_back("CYS");
153  res_types.push_back("HIS");
154  for(vector1<string>::const_iterator it = res_types.begin(); it != res_types.end(); ++it) {
155  rsd_[*it].resize(pose_->n_residue());
156  for(vector1<Size>::const_iterator i=pos_.begin(); i!=pos_.end(); ++i) {
157  ResidueOP rsd = core::conformation::ResidueFactory::create_residue(frs_->name_map(*it),pose_->residue(*i),pose_->conformation());
158  stb_[*it].push_back(Stub(rsd->xyz(5),rsd->xyz(2),rsd->xyz(1)));
159  rsd_[*it][*i] = rsd;
160  }
161  }
162 }
163 
166  return *ifc_;
167 }
168 
170 
171 void
173  KRSQuery const & q,
174  Residue const & qrsd,
176  ) const
177 {
178  vector1<Size>::const_iterator ip = pos_.begin();
179  vector1<Stub> const & stb(stb_.find("CYS")->second);
180  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
181  Real cbd2 = q.cen.distance_squared(is->v);
182  if(*ip==qrsd.seqpos()) continue;
183  if( cbd2 > 14.0 ) continue;
184  ResidueOP bestrsd;
185  Real bestsc = 9e9;
186  ResidueOP rsd = rsd_.find("CYS")->second[*ip];
187  rsd->set_xyz(11, rsd->xyz("SG") + 2.1*(rsd->xyz("HG")-rsd->xyz("SG")).normalized() );
188  for(Real ch1 = 0; ch1 <= 360; ch1+=3.0) {
189  rsd->set_chi(1,ch1);
190  Vec sg = rsd->xyz("SG");
191  if( sg.distance_squared(q.cen) > 8.0 ) continue;
192  for(Real ch2 = 0; ch2 <= 360; ch2+=3.0) {
193  rsd->set_chi(2,ch2);
194  Vec hg = rsd->xyz("HG");
195  Vec cen = sg+2.1*((hg-sg).normalized());
196  Real const dsq = cen.distance_squared(q.cen);
197  if( dsq > q.disth*q.disth) continue;
198  Vec axs = ((sg-q.cen).normalized());
199  Real const da = numeric::angle_radians( axs, Vec(0,0,0), q.axs);
200 
201  // Vec qc = is->global2local(q.cen);
202  // qc = qc * 2.911171 / qc.length();
203  // ozstream out("test_"+str(qc.x())+"_"+lzs(qrsd.seqpos(),3)+"_"+lzs(*ip,3)+"_"+lzs((Size)ch1,3)+"_"+lzs((Size)ch2,3)+".pdb");
204  // Size ano=0;
205  // core::io::pdb::dump_pdb_residue(*rsd,ano,out);
206  // out.close();
207 
208  if( fabs(da-q.ori.x()) > q.angth ) continue;
209  bool clash = false;
210  for(Size ia = 6; ia <= rsd->nheavyatoms(); ++ia) {
211  if(!ifc().clash_check(rsd->xyz(ia),*ip) ) { clash = true; break; }
212  for(Size ja = 1; ja <= qrsd.nheavyatoms(); ++ja) if( qrsd.xyz(ja).distance_squared(rsd->xyz(ia)) < q.clash ) { clash = true; break; }
213  if(clash) break;
214  }
215  if(clash) continue;
216  if( da < bestsc ) {
217  //TR << da << " " << q.ori.x() << " " << q.angth << std::endl;
218  bestrsd = rsd->clone();
219  bestsc = da;
220  }
221  }
222  }
223  if(bestsc < 9e8) {
224  hits.push_back(bestrsd);
225  }
226  }
227 }
228 
229 void
231  KRSQuery const & q,
232  Residue const & qrsd,
234  ) const
235 {
236  vector1<Size>::const_iterator ip = pos_.begin();
237  vector1<Stub> const & stb(stb_.find("HIS")->second);
238  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
239  Real cbd2 = q.cen.distance_squared(is->v);
240  if(*ip==qrsd.seqpos()) continue;
241  if( cbd2 > 14.0 ) continue;
242  ResidueOP bestrsd;
243  Real bestsc = 9e9;
244  ResidueOP rsd = rsd_.find("HIS")->second[*ip];
245  rsd->set_xyz(11, rsd->xyz("SG") + 2.1*(rsd->xyz("HG")-rsd->xyz("SG")).normalized() );
246  for(Real ch1 = 0; ch1 <= 360; ch1+=3.0) {
247  rsd->set_chi(1,ch1);
248  Vec sg = rsd->xyz("SG");
249  if( sg.distance_squared(q.cen) > 8.0 ) continue;
250  for(Real ch2 = 0; ch2 <= 360; ch2+=3.0) {
251  rsd->set_chi(2,ch2);
252  Vec hg = rsd->xyz("HG");
253  Vec cen = sg+2.1*((hg-sg).normalized());
254  Real const dsq = cen.distance_squared(q.cen);
255  if( dsq > q.disth*q.disth) continue;
256  Vec axs = ((sg-q.cen).normalized());
257  Real const da = numeric::angle_radians( axs, Vec(0,0,0), q.axs);
258 
259  // Vec qc = is->global2local(q.cen);
260  // qc = qc * 2.911171 / qc.length();
261  // ozstream out("test_"+str(qc.x())+"_"+lzs(qrsd.seqpos(),3)+"_"+lzs(*ip,3)+"_"+lzs((Size)ch1,3)+"_"+lzs((Size)ch2,3)+".pdb");
262  // Size ano=0;
263  // core::io::pdb::dump_pdb_residue(*rsd,ano,out);
264  // out.close();
265 
266  if( fabs(da-q.ori.x()) > q.angth ) continue;
267  bool clash = false;
268  for(Size ia = 6; ia <= rsd->nheavyatoms(); ++ia) {
269  if(!ifc().clash_check(rsd->xyz(ia),*ip) ) { clash = true; break; }
270  for(Size ja = 1; ja <= qrsd.nheavyatoms(); ++ja) if( qrsd.xyz(ja).distance_squared(rsd->xyz(ia)) < q.clash ) { clash = true; break; }
271  if(clash) break;
272  }
273  if(clash) continue;
274  if( da < bestsc ) {
275  //TR << da << " " << q.ori.x() << " " << q.angth << std::endl;
276  bestrsd = rsd->clone();
277  bestsc = da;
278  }
279  }
280  }
281  if(bestsc < 9e8) {
282  hits.push_back(bestrsd);
283  }
284  }
285 }
286 
287 void
289  KRSQuery const & q,
290  Residue const & qrsd,
292  ) const
293 {
294  vector1<Size>::const_iterator ip = pos_.begin();
295  vector1<Stub> const & stb(stb_.find("ASP")->second);
296  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
297  Real cbd2 = q.cen.distance_squared(is->v);
298  if(*ip==qrsd.seqpos()) continue;
299  if( cbd2 > 36.0 ) continue;
300  ResidueOP bestrsd;
301  Real bestsc = 9e9;
302  ResidueOP rsd = rsd_.find("ASP")->second[*ip];
303  Vec cb = rsd->xyz("CB");
304  for(Real ch1 = 0; ch1 <= 360; ch1+=3.0) {
305  rsd->set_chi(1,ch1);
306  Vec cg = rsd->xyz("CG");
307  if( cg.distance_squared(q.cen) > 25.0 ) continue;
308  for(Real ch2 = 0; ch2 <= 360; ch2+=3.0) {
309  rsd->set_chi(2,ch2);
310  Vec od1 = rsd->xyz("OD1");
311  Vec od2 = rsd->xyz("OD2");
312  for(int od12 = 0; od12 <= 1; ++od12) {
313  //int od12 = 0;
314  for(int prpp = 0; prpp <= 1; ++prpp) {
315  Vec const oda(od12?od1:od2);
316  Vec const odb(od12?od2:od1);
317  Vec const axs( ((prpp?(cg-cb):(oda-odb)).normalized()) );
318  Vec const cen = oda + 1.8 * axs;
319  Real const dsq = cen.distance_squared(q.cen);
320  if( dsq > q.disth*q.disth) continue;
321  Real const dt( axs.dot(q.axs) );
322  if( dt < q.angth ) continue; // dot, not ang
323  bool clash = false;
324  for(Size ia = 6; ia <= rsd->nheavyatoms()-2; ++ia) {
325  if(!ifc().clash_check(rsd->xyz(ia),*ip) ) { clash = true; break; }
326  for(Size ja = 1; ja <= qrsd.nheavyatoms(); ++ja) if( qrsd.xyz(ja).distance_squared(rsd->xyz(ia)) < q.clash ) { clash = true; break; }
327  if(clash) break;
328  }
329  if(clash) continue;
330  Real const da = dsq - 5*dt;
331  if( da < bestsc ) {
332  //TR << da << " " << q.ori.x() << " " << q.angth << std::endl;
333  bestrsd = rsd->clone();
334  bestsc = da;
335  }
336  }
337  }
338  }
339  }
340  if(bestsc < 9e8) {
341  hits.push_back(bestrsd);
342  }
343  }
344 }
345 
346 
348  Pose & p_in,
349  vector1<Size> pos )
350  : FunGroupTK(p_in,pos) {}
351 
352 void
354  KRSQuery const & q,
355  Residue const & qrsd,
357  ) const
358 {
359 #define CYS_CB_HG_DIS 2.911171 // 3.388379 // 2.771698
360 #define CYS_SG_CB_H 0.7494478 // height of SG "above" CB
361 #define CYS_HG_SG_PRJLEN 2.088496 //1.818653 // sin(CB-SG-HG)*len(HG-SG)
362 #define CYS_1oSIN_CB_SG_HG 1.092026 //
363 #define CYS_HG_SG_X_DROP 0.0998 // h drop due measured, 2.1*tan((90-84.011803)/180*pi)*tan((90-65.522644)/180*pi)
364 #define CYS_CB_SG_PERP 1.646237
365  if( fabs(q.axs.length()-1.0) > 0.0000001 ) utility_exit_with_message("place_c query axs not kormalized()!");
366  Real const r3o2 = sqrt(3.0)/2.0;
367  Real const dis2ub = sqr( CYS_CB_HG_DIS+q.disth );
368  Real const dis2lb = sqr(max(0.0,CYS_CB_HG_DIS-q.disth));
369  vector1<Size>::const_iterator ip = pos_.begin();
370  vector1<Stub> const & stb(stb_.find("CYS")->second);
371  vector1<ResidueOP> const & rsdlst(rsd_.find("CYS")->second);
372  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
373  if(*ip==qrsd.seqpos()) continue;
374  core::conformation::ResidueOP rtmp = rsdlst[*ip];;
375  Real const cbd2 = q.cen.distance_squared(is->v);
376  if( dis2ub < cbd2 || cbd2 < dis2lb ) continue;
377  Vec const qcen0(is->global2local(q.cen));
378  Real const pdis = sqrt(sqr(q.disth)-sqr(sqrt(cbd2)-CYS_CB_HG_DIS)) * qcen0.length() / CYS_CB_HG_DIS;
379  Size const NPOS = (pdis > 0.2) ? 7 : 1;
380  Vec const Y = Vec(0,1,0).cross(qcen0).normalized();
381  Vec const Z = Y.cross(qcen0).normalized();
383  for(int flp = -1; flp <= 1; flp+=2) {
384  Real best_angerr = 9e9, best_ch1=0.0, best_ch2=0.0, mn_ang=9e9, mx_ang=-9e9;
385  for(Size ipos = 0; ipos < NPOS; ++ipos) {
386  Real y=0,z=0;
387  if (ipos==1) { y = 1.0; z = 0.0; }
388  else if(ipos==2) { y = 0.5; z = r3o2; }
389  else if(ipos==3) { y = -0.5; z = r3o2; }
390  else if(ipos==4) { y = -1.0; z = 0.0; }
391  else if(ipos==5) { y = -0.5; z = -r3o2; }
392  else if(ipos==6) { y = 0.5; z = -r3o2; }
393  Vec const qcen = qcen0 + y*Y*pdis + z*Z*pdis;
394  // calc chi2
395  Real const lqcen = qcen.length();
396  Real const qcenxsphere = qcen.x() * CYS_CB_HG_DIS / lqcen;
397  Real const h = ( qcenxsphere - CYS_SG_CB_H) * CYS_1oSIN_CB_SG_HG - CYS_HG_SG_X_DROP;
398  if( CYS_HG_SG_PRJLEN < fabs(h) ) continue;
399  Real const ch2_0 = acos( h/CYS_HG_SG_PRJLEN ); // chi2 = pi +- ch2_0
400  //calc chi1
401  Real const lqcenpx = sqrt(qcen.y()*qcen.y()+qcen.z()*qcen.z());
402  Real const ch1_0 = (qcen.y()>0)? asin(qcen.z()/lqcenpx) : pi-asin(qcen.z()/lqcenpx);
403  Real const hgz = sin(pi-ch2_0)*CYS_HG_SG_PRJLEN;
404  Real const hgdzy = lqcenpx * CYS_CB_HG_DIS / lqcen;
405  Real const ch1_ofst = asin( hgz/hgdzy );
406  Real const ch1 = ch1_0 + flp*ch1_ofst;
407  Real const ch2 = pi + flp*ch2_0 ;
408  // check angle
409  Vec const sg = is->local2global(Vec(CYS_SG_CB_H, cos(ch1)*CYS_CB_SG_PERP, sin(ch1)*CYS_CB_SG_PERP));
410  if(!ifc().clash_check(sg,*ip) ) continue;
411 
412  Real const bang = acos( (sg-q.cen).normalized().dot(q.axs) );
413  // // make rsd
414  // core::conformation::ResidueOP rtmp = core::conformation::ResidueFactory::create_residue(frs_->name_map("CYS"),pose_.residue(*ip),pose_.conformation());
415  // rtmp->set_xyz(11, rtmp->xyz(6) + 2.1*(rtmp->xyz(11)-rtmp->xyz(6)).normalized() );
416  // rtmp->set_chi(1,degrees(ch1));
417  // rtmp->set_chi(2,degrees(ch2));
418  // // ResidueOP hrsd = qrsd.clone();
419  // // xform_rsd_gl2(*is,*rtmp);
420  // // xform_rsd_gl2(*is,*hrsd);
421  // //hrsd->set_xyz("HE2", hrsd->xyz("HE2") * CYS_CB_HG_DIS / hrsd->xyz("HE2").length() );
422  // Size tmp = 1;
423  // ozstream out1("cys_"+lzs(*ip,3)+"_"+str(ipos)+"_"+str(flp+1)+".pdb");
424  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
425  // //core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
426  // out1.close();
427  // // utility_exit_with_message(str(degrees(bang)));
428  mn_ang = min(bang,mn_ang);
429  mx_ang = max(bang,mx_ang);
430  Real const angerr = fabs( bang - q.ori.x() );
431  if( angerr < best_angerr ) {
432  best_angerr = angerr;
433  best_ch1 = ch1;
434  best_ch2 = ch2;
435  }
436  }
437  if( q.ori.x() < mn_ang-q.angth || mx_ang+q.angth < q.ori.x() ) continue;
438 
439  // position rsd
440  rtmp->set_chi(1,degrees(best_ch1));
441  rtmp->set_chi(2,degrees(best_ch2));
442 
443  // if( hits.size() == 1 ) {
444  // Real tmp = fabs( acos((hits[1]->xyz("SG")-q.cen).normalized().dot(q.axs)) - q.ori.x() );
445  // if( tmp < best_angerr ) hits[1] = rtmp;
446  // } else {
447  hits.push_back(rtmp->clone());
448  // }
449  //if(hits.size()) TR << *ip << " " << hits.size() << std::endl;
450 
451  // ResidueOP hrsd = qrsd.clone();
452  // xform_rsd_gl2(*is,*rtmp);
453  // xform_rsd_gl2(*is,*hrsd);
454  // hrsd->set_xyz("HE2", hrsd->xyz("HE2") * CYS_CB_HG_DIS / hrsd->xyz("HE2").length() );
455  // Size tmp = 1;
456  // ozstream out1("cys"+str(ipos)+"_"+str(flp+1)+".pdb");
457  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
458  // core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
459  // out1.close();
460 
461  }
462  hits_out.insert(hits_out.end(),hits.begin(),hits.end());
463  }
464 }
465 
466 void
468  KRSQuery const & q,
469  Residue const & qrsd,
471  ) const
472 {
473 #define HIS_CB_HG_DIS 5.6570235
474 #define HIS_CB_HG_PAR 3.946279
475 #define HIS_CG_CB_H 0.6019999
476 #define HIS_HE2_CG_PRJLEN 1.5392682574
477 #define HIS_1oSIN_CA_CB_CG 1.092026358 // 1/sina(ca-cb-cg)
478 #define HIS_HE2_CG_X_DROP (2.4821480185 - 0.087) // 5.6570235*math.tan((90-66.309441 )*math.pi/180)
479 #define HIS_CB_CG_PERP 1.371000
480 
481  if( fabs(q.axs.length()-1.0) > 0.0000001 ) utility_exit_with_message("place_h query axs not kormalized()!");
482  Real const r3o2 = sqrt(3.0)/2.0;
483  Real const dis2ub = sqr( HIS_CB_HG_DIS+q.disth );
484  Real const dis2lb = sqr(max(0.0,HIS_CB_HG_DIS-q.disth));
485  vector1<Size>::const_iterator ip = pos_.begin();
486  vector1<Stub> const & stb(stb_.find("HIS")->second);
487  vector1<ResidueOP> const & rsdlst(rsd_.find("HIS")->second);
488  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
489  if(*ip==qrsd.seqpos()) continue;
490  core::conformation::ResidueOP rtmp = rsdlst[*ip];
491 
492  // xform_rsd_gl2(*is,*rtmp);
493  // rtmp->set_xyz("HE2", rtmp->xyz("NE2") + 2.1*(rtmp->xyz("HE2")-rtmp->xyz("NE2")).normalized() );
494  // Size tmp = 1;
495  // ozstream out1("his_"+ObjexxFCL::string_of(*ip,3)+".pdb");
496  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
497  // out1.close();
498  // utility_exit_with_message("his test");
499 
500  Real const cbd2 = q.cen.distance_squared(is->v);
501  if( dis2ub < cbd2 || cbd2 < dis2lb ) continue;
502  Vec const qcen0(is->global2local(q.cen));
503  Real const pdis = sqrt(sqr(q.disth)-sqr(sqrt(cbd2)-HIS_CB_HG_DIS)) * qcen0.length() / HIS_CB_HG_DIS;
504  Size const NPOS = (pdis > 0.2) ? 7 : 1;
505  Vec const Y = Vec(0,1,0).cross(qcen0).normalized();
506  Vec const Z = Y.cross(qcen0).normalized();
508  for(int flp = -1; flp <= 1; flp+=2) {
509  Real best_angerr = 9e9, best_ch1=0.0, best_ch2=0.0, mn_ang=9e9, mx_ang=-9e9;
510  for(Size ipos = 0; ipos < NPOS; ++ipos) {
511  Real y=0,z=0;
512  if (ipos==1) { y = 1.0; z = 0.0; }
513  else if(ipos==2) { y = 0.5; z = r3o2; }
514  else if(ipos==3) { y = -0.5; z = r3o2; }
515  else if(ipos==4) { y = -1.0; z = 0.0; }
516  else if(ipos==5) { y = -0.5; z = -r3o2; }
517  else if(ipos==6) { y = 0.5; z = -r3o2; }
518  Vec const qcen = qcen0 + y*Y*pdis + z*Z*pdis;
519  // calc chi2
520  Real const lqcen = qcen.length();
521  Real const qcenxsphere = qcen.x() * HIS_CB_HG_DIS / lqcen;
522  Real const h = ( qcenxsphere ) * HIS_1oSIN_CA_CB_CG - HIS_HE2_CG_X_DROP;
523  if( h < -HIS_HE2_CG_PRJLEN || HIS_HE2_CG_PRJLEN < h ) continue;
524  Real const ch2_0 = (h>0) ? acos( -h/HIS_HE2_CG_PRJLEN ) : 2*pi-acos( -h/HIS_HE2_CG_PRJLEN ); // chi2 = pi +- ch2_0
525  //calc chi1
526  Real const lqcenpx = sqrt(qcen.y()*qcen.y()+qcen.z()*qcen.z());
527  Real const ch1_0 = (qcen.y()>0)? asin(qcen.z()/lqcenpx) : pi-asin(qcen.z()/lqcenpx);
528  Real const hgz = sin(pi-ch2_0)*HIS_HE2_CG_PRJLEN;
529  Real const hgdzy = lqcenpx * HIS_CB_HG_DIS / lqcen;
530  Real const ch1_ofst = asin( hgz/hgdzy );
531  Real const ch1 = ch1_0 - flp*ch1_ofst;
532  Real const ch2 = pi + flp*ch2_0 ;
533  // check angle
534  Vec const ne2 = is->local2global(rotation_matrix(Vec(1,0,0),ch1)*rotation_matrix(Vec(0.602000, 1.371000, 0.000000),ch2) * Vec(1.884000, 3.152000, -0.001000));
535  //Vec const ne2 = is->local2global(Vec(HIS_CG_CB_H, cos(ch1)*HIS_CB_CG_PERP, sin(ch1)*HIS_CB_CG_PERP));
536  if(!ifc().clash_check(ne2,*ip) ) continue;
537 
538  Real const bang = acos( (ne2-q.cen).normalized().dot(q.axs) );
539 
540  // // make rsd
541  // core::conformation::ResidueOP rtmp = core::conformation::ResidueFactory::create_residue(frs_->name_map("HIS"),pose_->residue(*ip),pose_->conformation());
542  // rtmp->set_xyz("HE2", rtmp->xyz("NE2") + 2.1*(rtmp->xyz("HE2")-rtmp->xyz("NE2")).normalized() );
543  // rtmp->set_chi(1,degrees(ch1));
544  // rtmp->set_chi(2,degrees(ch2));
545 
546  // // dumpcgo(ne2,"rast");
547  // TR << (rtmp->xyz("NE2") - ne2 ).length() << " " << degrees(bang) << " " << angle_degrees(rtmp->xyz("NE2"),q.cen,q.cen+q.axs) << std::endl;
548 
549  // ResidueOP hrsd = qrsd.clone();
550  // xform_rsd_gl2(*is,*rtmp);
551  // xform_rsd_gl2(*is,*hrsd);
552  // hrsd->set_xyz("HE2", hrsd->xyz("HE2") * HIS_CB_HG_DIS / hrsd->xyz("HE2").length() );
553  // Size tmp = 1;
554  // ozstream out1("his_"+lzs(qrsd.seqpos(),3)+"_"+lzs(q.ori.z(),3)+"_"+lzs(*ip,3)+"_"+str(ipos)+"_"+str(flp+1)+".pdb");
555  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
556  // core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
557  // out1.close();
558  // TR << h << std::endl;
559  // TR << lqcenpx << std::endl;
560  // TR << qcen.z() << std::endl;
561  // TR << degrees(ch1_ofst) << std::endl;
562  // TR << degrees(ch1_0) << std::endl;
563  // TR << degrees(ch2_0) << std::endl;
564  // TR << degrees(ch2_0) << std::endl;
565  // utility_exit_with_message("aoirstne");
566  mn_ang = min(bang,mn_ang);
567  mx_ang = max(bang,mx_ang);
568  Real const angerr = fabs( bang - q.ori.x() );
569  if( angerr < best_angerr ) {
570  best_angerr = angerr;
571  best_ch1 = ch1;
572  best_ch2 = ch2;
573  }
574  }
575  if( q.ori.x() < mn_ang-q.angth || mx_ang+q.angth < q.ori.x() ) continue;
576 
577  // position rsd
578  rtmp->set_chi(1,degrees(best_ch1));
579  rtmp->set_chi(2,degrees(best_ch2));
580 
581  // if( hits.size() == 1 ) {
582  // Real tmp = fabs( acos((hits[1]->xyz("NE2")-q.cen).normalized().dot(q.axs)) - q.ori.x() );
583  // if( tmp < best_angerr ) hits[1] = rtmp;
584  // } else {
585  hits.push_back(rtmp->clone());
586  // }
587  //if(hits.size()) TR << *ip << " " << hits.size() << std::endl;
588 
589  // ResidueOP hrsd = qrsd.clone();
590  // xform_rsd_gl2(*is,*rtmp);
591  // xform_rsd_gl2(*is,*hrsd);
592  // hrsd->set_xyz("HE2", hrsd->xyz("HE2") * HIS_CB_HG_DIS / hrsd->xyz("HE2").length() );
593  // Size tmp = 1;
594  // ozstream out1("his"+str(ipos)+"_"+str(flp+1)+".pdb");
595  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
596  // core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
597  // out1.close();
598 
599  }
600  hits_out.insert(hits_out.end(),hits.begin(),hits.end());
601  // if(hits.size()) utility_exit_with_message("aoirstne");
602  }
603 }
604 
605 
606 void
608  KRSQuery const & q,
609  Residue const & qrsd,
611  ) const
612 {
613 #define HIS_CB_HG_DIS 5.6570235
614 #define HIS_CB_HG_PAR 3.946279
615 #define HIS_CG_CB_H 0.6019999
616 #define HIS_HE2_CG_PRJLEN 1.5392682574
617 #define HIS_1oSIN_CA_CB_CG 1.092026358 // 1/sina(ca-cb-cg)
618 #define HIS_HE2_CG_X_DROP (2.4821480185 - 0.087) // 5.6570235*math.tan((90-66.309441 )*math.pi/180)
619 #define HIS_CB_CG_PERP 1.371000
620 
621  if( fabs(q.axs.length()-1.0) > 0.0000001 ) utility_exit_with_message("place_h query axs not kormalized()!");
622  Real const r3o2 = sqrt(3.0)/2.0;
623  Real const dis2ub = sqr( HIS_CB_HG_DIS+q.disth );
624  Real const dis2lb = sqr(max(0.0,HIS_CB_HG_DIS-q.disth));
625  vector1<Size>::const_iterator ip = pos_.begin();
626  vector1<Stub> const & stb(stb_.find("HIS")->second);
627  vector1<ResidueOP> const & rsdlst(rsd_.find("HIS")->second);
628  for(vector1<Stub>::const_iterator is = stb.begin(); is!=stb.end(); ++is,++ip) {
629  if(*ip==qrsd.seqpos()) continue;
630  core::conformation::ResidueOP rtmp = rsdlst[*ip];
631 
632  // xform_rsd_gl2(*is,*rtmp);
633  // rtmp->set_xyz("HE2", rtmp->xyz("NE2") + 2.1*(rtmp->xyz("HE2")-rtmp->xyz("NE2")).normalized() );
634  // Size tmp = 1;
635  // ozstream out1("his_"+ObjexxFCL::string_of(*ip,3)+".pdb");
636  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
637  // out1.close();
638  // utility_exit_with_message("his test");
639 
640  Real const cbd2 = q.cen.distance_squared(is->v);
641  if( dis2ub < cbd2 || cbd2 < dis2lb ) continue;
642  Vec const qcen0(is->global2local(q.cen));
643  Real const pdis = sqrt(sqr(q.disth)-sqr(sqrt(cbd2)-HIS_CB_HG_DIS)) * qcen0.length() / HIS_CB_HG_DIS;
644  Size const NPOS = (pdis > 0.2) ? 7 : 1;
645  Vec const Y = Vec(0,1,0).cross(qcen0).normalized();
646  Vec const Z = Y.cross(qcen0).normalized();
648  for(int flp = -1; flp <= 1; flp+=2) {
649  Real best_angerr = 9e9, best_ch1=0.0, best_ch2=0.0, mn_ang=9e9, mx_ang=-9e9;
650  for(Size ipos = 0; ipos < NPOS; ++ipos) {
651  Real y=0,z=0;
652  if (ipos==1) { y = 1.0; z = 0.0; }
653  else if(ipos==2) { y = 0.5; z = r3o2; }
654  else if(ipos==3) { y = -0.5; z = r3o2; }
655  else if(ipos==4) { y = -1.0; z = 0.0; }
656  else if(ipos==5) { y = -0.5; z = -r3o2; }
657  else if(ipos==6) { y = 0.5; z = -r3o2; }
658  Vec const qcen = qcen0 + y*Y*pdis + z*Z*pdis;
659  // calc chi2
660  Real const lqcen = qcen.length();
661  Real const qcenxsphere = qcen.x() * HIS_CB_HG_DIS / lqcen;
662  Real const h = ( qcenxsphere ) * HIS_1oSIN_CA_CB_CG - HIS_HE2_CG_X_DROP;
663  if( h < -HIS_HE2_CG_PRJLEN || HIS_HE2_CG_PRJLEN < h ) continue;
664  Real const ch2_0 = (h>0) ? acos( -h/HIS_HE2_CG_PRJLEN ) : 2*pi-acos( -h/HIS_HE2_CG_PRJLEN ); // chi2 = pi +- ch2_0
665  //calc chi1
666  Real const lqcenpx = sqrt(qcen.y()*qcen.y()+qcen.z()*qcen.z());
667  Real const ch1_0 = (qcen.y()>0)? asin(qcen.z()/lqcenpx) : pi-asin(qcen.z()/lqcenpx);
668  Real const hgz = sin(pi-ch2_0)*HIS_HE2_CG_PRJLEN;
669  Real const hgdzy = lqcenpx * HIS_CB_HG_DIS / lqcen;
670  Real const ch1_ofst = asin( hgz/hgdzy );
671  Real const ch1 = ch1_0 - flp*ch1_ofst;
672  Real const ch2 = pi + flp*ch2_0 ;
673  // check angle
674  Vec const ne2 = is->local2global(rotation_matrix(Vec(1,0,0),ch1)*rotation_matrix(Vec(0.602000, 1.371000, 0.000000),ch2) * Vec(1.884000, 3.152000, -0.001000));
675  //Vec const ne2 = is->local2global(Vec(HIS_CG_CB_H, cos(ch1)*HIS_CB_CG_PERP, sin(ch1)*HIS_CB_CG_PERP));
676  if(!ifc().clash_check(ne2,*ip) ) continue;
677 
678  Real const bang = acos( (ne2-q.cen).normalized().dot(q.axs) );
679 
680  // // make rsd
681  // core::conformation::ResidueOP rtmp = core::conformation::ResidueFactory::create_residue(frs_->name_map("HIS"),pose_->residue(*ip),pose_->conformation());
682  // rtmp->set_xyz("HE2", rtmp->xyz("NE2") + 2.1*(rtmp->xyz("HE2")-rtmp->xyz("NE2")).normalized() );
683  // rtmp->set_chi(1,degrees(ch1));
684  // rtmp->set_chi(2,degrees(ch2));
685 
686  // // dumpcgo(ne2,"rast");
687  // TR << (rtmp->xyz("NE2") - ne2 ).length() << " " << degrees(bang) << " " << angle_degrees(rtmp->xyz("NE2"),q.cen,q.cen+q.axs) << std::endl;
688 
689  // ResidueOP hrsd = qrsd.clone();
690  // xform_rsd_gl2(*is,*rtmp);
691  // xform_rsd_gl2(*is,*hrsd);
692  // hrsd->set_xyz("HE2", hrsd->xyz("HE2") * HIS_CB_HG_DIS / hrsd->xyz("HE2").length() );
693  // Size tmp = 1;
694  // ozstream out1("his_"+lzs(qrsd.seqpos(),3)+"_"+lzs(q.ori.z(),3)+"_"+lzs(*ip,3)+"_"+str(ipos)+"_"+str(flp+1)+".pdb");
695  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
696  // core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
697  // out1.close();
698  // TR << h << std::endl;
699  // TR << lqcenpx << std::endl;
700  // TR << qcen.z() << std::endl;
701  // TR << degrees(ch1_ofst) << std::endl;
702  // TR << degrees(ch1_0) << std::endl;
703  // TR << degrees(ch2_0) << std::endl;
704  // TR << degrees(ch2_0) << std::endl;
705  // utility_exit_with_message("aoirstne");
706  mn_ang = min(bang,mn_ang);
707  mx_ang = max(bang,mx_ang);
708  Real const angerr = fabs( bang - q.ori.x() );
709  if( angerr < best_angerr ) {
710  best_angerr = angerr;
711  best_ch1 = ch1;
712  best_ch2 = ch2;
713  }
714  }
715  if( q.ori.x() < mn_ang-q.angth || mx_ang+q.angth < q.ori.x() ) continue;
716 
717  // position rsd
718  rtmp->set_chi(1,degrees(best_ch1));
719  rtmp->set_chi(2,degrees(best_ch2));
720 
721  // if( hits.size() == 1 ) {
722  // Real tmp = fabs( acos((hits[1]->xyz("NE2")-q.cen).normalized().dot(q.axs)) - q.ori.x() );
723  // if( tmp < best_angerr ) hits[1] = rtmp;
724  // } else {
725  hits.push_back(rtmp->clone());
726  // }
727  //if(hits.size()) TR << *ip << " " << hits.size() << std::endl;
728 
729  // ResidueOP hrsd = qrsd.clone();
730  // xform_rsd_gl2(*is,*rtmp);
731  // xform_rsd_gl2(*is,*hrsd);
732  // hrsd->set_xyz("HE2", hrsd->xyz("HE2") * HIS_CB_HG_DIS / hrsd->xyz("HE2").length() );
733  // Size tmp = 1;
734  // ozstream out1("his"+str(ipos)+"_"+str(flp+1)+".pdb");
735  // core::io::pdb::dump_pdb_residue(*rtmp,tmp,out1);
736  // core::io::pdb::dump_pdb_residue(*hrsd,tmp,out1);
737  // out1.close();
738 
739  }
740  hits_out.insert(hits_out.end(),hits.begin(),hits.end());
741  // if(hits.size()) utility_exit_with_message("aoirstne");
742  }
743 }
744 
745 
746 } // namespace kinmatch
747 } // namespace protocols
748 
749