19 #define _USE_MATH_DEFINES
33 #include <basic/options/option.hh>
35 #include <basic/Tracer.hh>
39 #include <numeric/xyzMatrix.hh>
40 #include <numeric/xyzVector.hh>
41 #include <numeric/xyz.functions.hh>
42 #include <numeric/xyzVector.io.hh>
43 #include <numeric/statistics.functions.hh>
44 #include <numeric/fourier/FFT.hh>
49 #include <basic/options/keys/edensity.OptionKeys.gen.hh>
50 #include <basic/options/keys/patterson.OptionKeys.gen.hh>
52 #include <basic/resource_manager/ResourceManager.hh>
53 #include <basic/resource_manager/util.hh>
56 #include <utility/string_util.hh>
65 #include <utility/vector1.hh>
66 #include <utility/excn/Exceptions.hh>
76 namespace electron_density {
83 basic::Tracer
TR(
"core.scoring.electron_density.ElectronDensity");
87 pthread_mutex_t density_map_db_mut_ = PTHREAD_MUTEX_INITIALIZER;
91 using namespace basic::options;
101 inline float d2r(
float d) {
return (d*M_PI/180.0); }
102 inline double d2r(
double d) {
return (d*M_PI/180.0); }
103 inline float square(
float x) {
return (x*x); }
104 inline double square(
double x) {
return (x*x); }
109 int r=x%y;
if (r<-y/2) r+=y;
if (r>=y/2) r-=y;
113 float r=std::fmod(x,y);
if (r<-0.5*y) r+=y;
if (r>=0.5*y) r-=y;
117 double r=std::fmod(x,y);
if (r<-0.5*y) r+=y;
if (r>=0.5*y) r-=y;
125 if ( X.length() >= 1500 ) {
134 int *data = (
int *) v;
137 for (i=0; i<ndata; i++) {
139 *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) | ((*N>>8)&0xff00) | ((*N&0xff00)<<8));
148 if(basic::resource_manager::ResourceManager::get_instance()->
149 has_resource_with_description(
"electron_density")){
152 basic::resource_manager::get_resource< ElectronDensity >(
153 "electron_density"));
155 return *electron_density;
166 pthread_mutex_lock(&density_map_db_mut_);
171 TR <<
"Loading Density Map" << std::endl;
172 if (!basic::options::option[ basic::options::OptionKeys::edensity::mapfile ].user()) {
173 TR.Warning <<
"[ Warning ] No density map specified." << std::endl;
177 std::string mapfile = basic::options::option[ basic::options::OptionKeys::edensity::mapfile ]();
178 core::Real mapreso = basic::options::option[ basic::options::OptionKeys::edensity::mapreso ]();
179 core::Real mapsampling = basic::options::option[ basic::options::OptionKeys::edensity::grid_spacing ]();
182 bool map_loaded = theDensityMap.
readMRCandResize( mapfile , mapreso , mapsampling );
185 TR <<
"[ ERROR ] Error loading density map named '" << mapfile <<
"'" << std::endl;
193 pthread_mutex_unlock(&density_map_db_mut_);
197 return theDensityMap;
221 for (
int i=1 ; i<=nres; ++i) {
225 for (
int j=1 ; j<=nheavyatoms; ++j) {
229 d_min = d_max = xyz_ij;
232 d_min[0] = std::min(d_min[0],xyz_ij[0]); d_min[1] = std::min(d_min[1],xyz_ij[1]); d_min[2] = std::min(d_min[2],xyz_ij[2]);
233 d_max[0] = std::max(d_max[0],xyz_ij[0]); d_max[1] = std::max(d_max[1],xyz_ij[1]); d_max[2] = std::max(d_max[2],xyz_ij[2]);
244 real_apix[0] = ( (d_max[0] - d_min[0]) + 2*FLUFF) / ((
core::Real)grid[0]);
245 real_apix[1] = ( (d_max[1] - d_min[1]) + 2*FLUFF) / ((
core::Real)grid[1]);
246 real_apix[2] = ( (d_max[2] - d_min[2]) + 2*FLUFF) / ((
core::Real)grid[2]);
249 cellAngles[0] = cellAngles[1] = cellAngles[2] = 90;
250 cellDimensions[0] = grid[0]*real_apix[0];
251 cellDimensions[1] = grid[1]*real_apix[1];
252 cellDimensions[2] = grid[2]*real_apix[2];
253 computeCrystParams();
254 TR <<
" celldim: " << cellDimensions[0] <<
" x " << cellDimensions[1] <<
" x " << cellDimensions[2] << std::endl;
255 TR <<
" cellangles: " << cellAngles[0] <<
" x " << cellAngles[1] <<
" x " << cellAngles[2] << std::endl;
259 origin[0] = std::floor(frac_dmin[0]*grid[0]);
260 origin[1] = std::floor(frac_dmin[1]*grid[1]);
261 origin[2] = std::floor(frac_dmin[2]*grid[2]);
266 core::Real mask_min = 2.0 * sqrt( 2.0 / cscat.
k(PattersonB,reso/2) );
267 TR.Warning <<
"ATOM_MASK: " << mask_min << std::endl;
268 ATOM_MASK = mask_min;
271 density.dimension(grid[0],grid[1],grid[2]);
272 for (
int i=0; i<density.u1()*density.u2()*density.u3(); ++i) density[i]=0.0;
276 for (
Size n=1; n<=nposes; ++n) {
279 for (
int i=1 ; i<=nres; ++i) {
284 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
286 for (
int j=1 ; j<=nheavyatoms; ++j) {
289 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
291 core::Real k = sig_j.
k( PattersonB, std::max( apix, reso/2 ) );
295 if ( C < 1e-6 )
continue;
297 cartX = atom_i.xyz() - getTransform();
299 atm_i[0] =
pos_mod (fracX[0]*grid[0] - origin[0] + 1 , (
double)grid[0]);
300 atm_i[1] =
pos_mod (fracX[1]*grid[1] - origin[1] + 1 , (
double)grid[1]);
301 atm_i[2] =
pos_mod (fracX[2]*grid[2] - origin[2] + 1 , (
double)grid[2]);
303 for (
int z=1; z<=density.u3(); ++z) {
305 del_ij[2] = (atm_i[2] - atm_j[2]) / grid[2];
307 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
308 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
310 del_ij[0] = del_ij[1] = 0.0;
311 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
313 for (
int y=1; y<=density.u2(); ++y) {
317 del_ij[1] = (atm_i[1] - atm_j[1]) / grid[1] ;
319 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
320 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
322 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
324 for (
int x=1; x<=density.u1(); ++x) {
328 del_ij[0] = (atm_i[0] - atm_j[0]) / grid[0];
330 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
331 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
334 core::Real d2 = (cart_del_ij).length_squared();
336 if (d2 <= (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING)) {
338 density(x,y,z) += atm;
358 reso = basic::options::option[ basic::options::OptionKeys::edensity::mapreso ]();
359 ATOM_MASK = basic::options::option[ basic::options::OptionKeys::edensity::atom_mask ]();
360 CA_MASK = basic::options::option[ basic::options::OptionKeys::edensity::ca_mask ]();
361 WINDOW_ = basic::options::option[ basic::options::OptionKeys::edensity::sliding_window ]();
362 score_window_context_ = basic::options::option[ basic::options::OptionKeys::edensity::score_sliding_window_context ]();
363 remap_symm_ = basic::options::option[ basic::options::OptionKeys::edensity::score_symm_complex ]();
364 force_apix_ = basic::options::option[ basic::options::OptionKeys::edensity::force_apix ]();
367 DensScoreInMinimizer =
true;
368 ExactDerivatives = basic::options::option[ basic::options::OptionKeys::edensity::debug_derivatives ]();
370 PattersonB = basic::options::option[ basic::options::OptionKeys::patterson::model_B ]();
372 PattersonMaxR = 20.0;
373 if (basic::options::option[ basic::options::OptionKeys::patterson::radius_cutoffs ].user() ) {
375 if (radius_cuts.size() == 1) {
376 PattersonMinR = radius_cuts[1];
377 }
else if (radius_cuts.size() >= 2) {
378 PattersonMinR = std::min( radius_cuts[1] , radius_cuts[2] );
379 PattersonMaxR = std::max( radius_cuts[1] , radius_cuts[2] );
388 NUM_DERIV_H_CEN = NUM_DERIV_H;
411 TR <<
"[ ERROR ] ElectronDensity::matchPose called but no map is loaded!\n";
415 core::Size axis_Z = 2, axis_X = 0, axis_Y = 1;
417 axis_Z = 0; axis_X = 1; axis_Y = 2;
420 axis_Z = 1; axis_X = 2; axis_Y = 0;
423 rho_calc.dimension(density.u1() , density.u2() , density.u3());
424 for (
int i=0; i<density.u1()*density.u2()*density.u3(); ++i) rho_calc[i]=0.0;
429 core::Real SC_scaling = basic::options::option[ basic::options::OptionKeys::edensity::sc_scaling ]();
437 for (
int i=1 ; i<=nres; ++i) {
441 for (
int j=1 ; j<=nheavyatoms; ++j) {
444 poseCoM = poseCoM + xyz_ij;
448 poseCoM /= sum_atoms;
451 for (
int i=1 ; i<=nres; ++i) {
456 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
459 for (
int j=1 ; j<=nheavyatoms; ++j) {
462 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
464 core::Real k = sig_j.
k( PattersonB, max_del_grid );
467 if ( (
Size) j > rsd_i.last_backbone_atom())
470 if ( C < 1e-6 )
continue;
473 core::Real thisH = (atm_i.xyz()[axis_Z] - poseCoM[axis_Z]);
474 minHeight = std::min( minHeight , thisH );
475 maxHeight = std::max( maxHeight , thisH );
477 core::Real thisR2 =
square(atm_i.xyz()[axis_X] - poseCoM[axis_X]) +
square(atm_i.xyz()[axis_Y] - poseCoM[axis_Y]);
478 maxRadius = std::max( maxRadius , thisR2 );
480 cartX = atm_i.xyz() - getTransform();
482 atm_idx_ij[0] =
pos_mod (fracX[0]*grid[0] - origin[0] + 1 , (
double)grid[0]);
483 atm_idx_ij[1] =
pos_mod (fracX[1]*grid[1] - origin[1] + 1 , (
double)grid[1]);
484 atm_idx_ij[2] =
pos_mod (fracX[2]*grid[2] - origin[2] + 1 , (
double)grid[2]);
486 for (
int z=1; z<=density.u3(); ++z) {
488 del_ij[2] = (atm_idx_ij[2] - atm_j[2]) / grid[2];
489 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
490 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
492 del_ij[0] = del_ij[1] = 0.0;
493 if ((f2c*del_ij).length_squared() > (ATOM_MASK+1)*(ATOM_MASK+1))
continue;
495 for (
int y=1; y<=density.u2(); ++y) {
498 del_ij[1] = (atm_idx_ij[1] - atm_j[1]) / grid[1] ;
499 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
500 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
502 if ((f2c*del_ij).length_squared() > (ATOM_MASK+1)*(ATOM_MASK+1))
continue;
504 for (
int x=1; x<=density.u1(); ++x) {
506 del_ij[0] = (atm_idx_ij[0] - atm_j[0]) / grid[0];
507 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
508 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
511 core::Real d2 = (cart_del_ij).length_squared();
512 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
514 rho_calc(x,y,z) += atm;
521 maxRadius = sqrt( maxRadius );
532 core::Real height_spacing = (maxHeight-minHeight) / (height_samples-1);
534 core::Real radial_spacing = 2*M_PI/radial_samples;
535 TR <<
"Realignment with max radius = " << maxRadius << std::endl;
536 TR <<
" #shells = " << nshells <<
" ( spacing = " << shell_spacing <<
")" << std::endl;
537 TR <<
" #hsteps = " << height_samples <<
" ( spacing = " << height_spacing <<
")" << std::endl;
538 TR <<
" #sampls = " << radial_samples <<
" ( spacing = " << radial_spacing*180/M_PI <<
"deg )" << std::endl;
542 for (
int r=0; r<(
int)nshells ; ++r ) {
543 for (
int h=0; h<(
int)height_samples ; ++h ) {
544 rho_o_cyl[r*height_samples+h+1].dimension( radial_samples );
545 rho_c_cyl[r*height_samples+h+1].dimension( radial_samples );
553 for (
int r=0; r<(
int)nshells ; ++r ){
554 Rwt = 2*M_PI*(r+1)*shell_spacing;
556 for (
int h=0; h<(
int)height_samples ; ++h ){
557 cartX[axis_Z] = poseCoM[axis_Z] + minHeight + h*height_spacing;
559 for (
int theta=0; theta<(
int)radial_samples ; ++theta ){
560 cartX[axis_X] = poseCoM[axis_X] + (r+1)*shell_spacing*cos(theta*radial_spacing);
561 cartX[axis_Y] = poseCoM[axis_Y] + (r+1)*shell_spacing*sin(theta*radial_spacing);
564 atm_idx_ij[0] =
pos_mod (fracX[0]*grid[0] - origin[0] + 1 , (
double)grid[0]);
565 atm_idx_ij[1] =
pos_mod (fracX[1]*grid[1] - origin[1] + 1 , (
double)grid[1]);
566 atm_idx_ij[2] =
pos_mod (fracX[2]*grid[2] - origin[2] + 1 , (
double)grid[2]);
570 rho_o_cyl[r*height_samples+h+1][theta] = thisRhoO;
571 rho_c_cyl[r*height_samples+h+1][theta] = thisRhoC;
575 sumRhoC += Rwt*thisRhoC;
576 sumRhoO += Rwt*thisRhoO;
577 sumRho2C += Rwt*thisRhoC*thisRhoC;
578 sumRho2O += Rwt*thisRhoO*thisRhoO;
584 sumRho2C = std::sqrt( sumRho2C/sumN - sumRhoC*sumRhoC );
585 sumRho2O = std::sqrt( sumRho2O/sumN - sumRhoO*sumRhoO );
592 ObjexxFCL::FArray1D< double > correl_sum, correl_flip_sum, correl_i;
593 ObjexxFCL::FArray1D< std::complex<double> > FrhoO, FrhoC, Fcorrel_i;
595 correl_sum.dimension( radial_samples, 0.0 );
596 correl_flip_sum.dimension( radial_samples, 0.0 );
599 for (
int r=0; r<(
int)nshells ; ++r ) {
600 for (
int h=0; h<(
int)height_samples ; ++h ){
601 for (
int theta=0; theta<(
int)radial_samples ; ++theta ){
602 rho_o_cyl[r*height_samples+h+1][theta] = (rho_o_cyl[r*height_samples+h+1][theta]-sumRhoO)/sumRho2O;
603 rho_c_cyl[r*height_samples+h+1][theta] = (rho_c_cyl[r*height_samples+h+1][theta]-sumRhoC)/sumRho2C;
608 Fcorrel_i.dimension( radial_samples );
609 for (
int r=0; r<(
int)nshells ; ++r ) {
610 Rwt = 2*M_PI*(r+1)*shell_spacing;
612 for (
int h=0; h<(
int)height_samples ; ++h ){
615 numeric::fourier::fft(rho_o_cyl[r*height_samples+h+1], FrhoO);
616 numeric::fourier::fft(rho_c_cyl[r*height_samples+h+1], FrhoC);
619 for (
int theta=0; theta<(
int)radial_samples ; ++theta )
620 Fcorrel_i[theta] = FrhoO[theta] * std::conj( FrhoC[theta] );
622 numeric::fourier::ifft(Fcorrel_i, correl_i);
624 for (
int theta=0; theta<(
int)radial_samples ; ++theta )
625 correl_sum[theta] += Rwt*correl_i[theta];
629 numeric::fourier::fft(rho_c_cyl[r*height_samples+(height_samples-h)], FrhoC);
632 for (
int theta=0; theta<(
int)radial_samples ; ++theta )
633 Fcorrel_i[theta] = FrhoO[theta] * FrhoC[theta];
635 numeric::fourier::ifft(Fcorrel_i, correl_i);
637 for (
int theta=0; theta<(
int)radial_samples ; ++theta )
638 correl_flip_sum[theta] += Rwt*correl_i[theta];
645 for (
int theta=0; theta<(
int)radial_samples ; ++theta ) {
646 if (correl_sum[theta] > maxCC) {
647 maxCC = correl_sum[theta];
651 if (correl_flip_sum[theta] > maxCC) {
652 maxCC = correl_flip_sum[theta];
657 TR <<
"Best alignment at theta = " << maxTheta*radial_spacing*180/M_PI << std::endl;
658 TR <<
" flip = " << flipped << std::endl;
659 TR <<
" cc = " << maxCC/sumN <<
" ( " << maxCC <<
" / " << sumN <<
" ) " << std::endl;
663 rotation(axis_Z+1,axis_X+1) = 0; rotation(axis_Z+1,axis_Y+1) = 0;
664 rotation(axis_X+1,axis_Z+1) = 0; rotation(axis_Y+1,axis_Z+1) = 0;
665 rotation(axis_Z+1,axis_Z+1) = flipped;
667 rotation(axis_X+1,axis_X+1) = cos(maxTheta*radial_spacing);
668 rotation(axis_X+1,axis_Y+1) = -flipped*sin(maxTheta*radial_spacing);
669 rotation(axis_Y+1,axis_X+1) = sin(maxTheta*radial_spacing);
670 rotation(axis_Y+1,axis_Y+1) = flipped*cos(maxTheta*radial_spacing);
685 using namespace numeric::statistics;
689 TR <<
"[ ERROR ] ElectronDensity::matchCentroidPose called but no map is loaded!\n";
693 if (!DensScoreInMinimizer) cacheCCs =
false;
696 ObjexxFCL::FArray3D< double > inv_rho_mask;
697 rho_calc.dimension(density.u1() , density.u2() , density.u3());
698 inv_rho_mask.dimension(density.u1() , density.u2() , density.u3());
699 for (
int i=0; i<density.u1()*density.u2()*density.u3(); ++i) {
709 core::Real effReso = std::max( 2.4+0.8*reso , reso );
721 bool isSymm = (symmInfo.get() != NULL);
722 bool remapSymm = basic::options::option[ basic::options::OptionKeys::edensity::score_symm_complex ]();
727 for (
int i=1 ; i<=nres; ++i) {
732 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
735 if (isSymm && !symmInfo->bb_is_independent(i) && !remapSymm) {
744 cartX = atm_i.
xyz() - getTransform();
746 atm_idx[i][0] =
pos_mod (fracX[0]*grid[0] - origin[0] + 1 , (
double)grid[0]);
747 atm_idx[i][1] =
pos_mod (fracX[1]*grid[1] - origin[1] + 1 , (
double)grid[1]);
748 atm_idx[i][2] =
pos_mod (fracX[2]*grid[2] - origin[2] + 1 , (
double)grid[2]);
751 for (
int z=1; z<=density.u3(); ++z) {
753 del_ij[2] = (atm_idx[i][2] - atm_j[2]) / grid[2];
755 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
756 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
758 del_ij[0] = del_ij[1] = 0.0;
759 if ((f2c*del_ij).length_squared() > (CA_MASK+ATOM_MASK_PADDING)*(CA_MASK+ATOM_MASK_PADDING))
continue;
761 for (
int y=1; y<=density.u2(); ++y) {
765 del_ij[1] = (atm_idx[i][1] - atm_j[1]) / grid[1] ;
767 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
768 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
770 if ((f2c*del_ij).length_squared() > (CA_MASK+ATOM_MASK_PADDING)*(CA_MASK+ATOM_MASK_PADDING))
continue;
772 for (
int x=1; x<=density.u1(); ++x) {
776 del_ij[0] = (atm_idx[i][0] - atm_j[0]) / grid[0];
778 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
779 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
782 core::Real d2 = (cart_del_ij).length_squared();
784 if (d2 <= (CA_MASK+ATOM_MASK_PADDING)*(CA_MASK+ATOM_MASK_PADDING)) {
786 core::Real sigmoid_msk = exp( d2 - (ATOM_MASK)*(ATOM_MASK) );
789 rho_calc(x,y,z) += atm;
790 inv_rho_mask(x,y,z) *= (1 - inv_msk);
793 int idx = (z-1)*density.u2()*density.u1() + (y-1)*density.u1() + x-1;
794 rho_dx_pt[i].push_back ( idx );
795 rho_dx_atm[i].push_back ( (-2*k*atm)*cart_del_ij );
799 inv_eps_i = sigmoid_msk;
803 rho_dx_mask[i].push_back( (-2*sigmoid_msk*inv_msk*inv_msk*inv_eps_i)*cart_del_ij );
813 core::Real sumC_i=0, sumO_i=0, sumCO_i=0, vol_i=0, CC_i=0;
814 core::Real sumO2_i=0.0, sumC2_i=0.0, varC_i=0, varO_i=0;
817 for (
int x=0; x<density.u1()*density.u2()*density.u3(); ++x) {
821 eps_x = 1-inv_rho_mask[x];
824 sumCO_i += eps_x*clc_x*obs_x;
825 sumO_i += eps_x*obs_x;
826 sumO2_i += eps_x*obs_x*obs_x;
827 sumC_i += eps_x*clc_x;
828 sumC2_i += eps_x*clc_x*clc_x;
831 varC_i = (sumC2_i - sumC_i*sumC_i / vol_i );
832 varO_i = (sumO2_i - sumO_i*sumO_i / vol_i ) ;
833 if (varC_i == 0 || varO_i == 0)
836 CC_i = (sumCO_i - sumC_i*sumO_i/ vol_i) / sqrt( varC_i * varO_i );
844 if (isSymm && remapSymm && cacheCCs) {
845 compute_symm_rotations( pose, symmInfo );
851 std::map< core::Size , numeric::xyzMatrix< core::Real > > symmRots;
852 for (
int i=1 ; i<=nres; ++i) {
853 if (isSymm && !symmInfo->bb_is_independent(i) && !remapSymm) {
861 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
863 numeric::xyzVector< core::Real > dVdx_ij(0,0,0), dOdx_ij(0,0,0), dO2dx_ij(0,0,0), dCOdx_ij(0,0,0), dC2dx_ij(0,0,0);
872 int npoints = rho_dx_pt_ij.size();
873 for (
int n=1; n<=npoints; ++n) {
874 const int x(rho_dx_pt_ij[n]);
883 dOdx_ij += del_mask*obs_x;
884 dO2dx_ij += del_mask*obs_x*obs_x;
885 dCOdx_ij += del_rhoc*obs_x;
886 dC2dx_ij += 2.0*del_rhoc*clc_x;
890 core::Real f = ( sumCO_i - sumC_i*sumO_i / vol_i );
895 sqrt(varO_i)/sqrt(varC_i) * ( dC2dx_ij + ( sumC_i*sumC_i*dVdx_ij/(vol_i*vol_i) ) ) +
896 sqrt(varC_i)/sqrt(varO_i) * ( dO2dx_ij - ( 1/(vol_i*vol_i) * ( 2*vol_i*sumO_i*dOdx_ij - sumO_i*sumO_i*dVdx_ij ) ) ) );
898 dCCdxs_cen[i] = (g*fprime - f*gprime) / (g*g);
920 using namespace numeric::statistics;
924 TR <<
"[ ERROR ] ElectronDensity::matchPose called but no map is loaded!\n";
928 if (!DensScoreInMinimizer) cacheCCs =
false;
931 ObjexxFCL::FArray3D< double > inv_rho_mask;
932 rho_calc.dimension(density.u1() , density.u2() , density.u3());
933 inv_rho_mask.dimension(density.u1() , density.u2() , density.u3());
934 for (
int i=0; i<density.u1()*density.u2()*density.u3(); ++i) {
943 core::Real SC_scaling = basic::options::option[ basic::options::OptionKeys::edensity::sc_scaling ]();
951 bool isSymm = (symmInfo.get() != NULL);
952 bool remapSymm = basic::options::option[ basic::options::OptionKeys::edensity::score_symm_complex ]();
957 for (
int i=1 ; i<=nres; ++i) {
962 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
965 if (isSymm && !symmInfo->bb_is_independent(i) && !remapSymm) {
972 atm_idx[i].resize(nheavyatoms);
973 rho_dx_pt[i].resize(nheavyatoms);
974 rho_dx_mask[i].resize(nheavyatoms);
975 rho_dx_atm[i].resize(nheavyatoms);
977 for (
int j=1 ; j<=nheavyatoms; ++j) {
981 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
983 core::Real k = sig_j.
k( PattersonB, max_del_grid );
987 if ( (
Size) j > rsd_i.last_backbone_atom())
994 if ( C < 1e-6 )
continue;
996 cartX = atm_i.xyz() - getTransform();
998 atm_idx[i][j][0] =
pos_mod (fracX[0]*grid[0] - origin[0] + 1 , (
double)grid[0]);
999 atm_idx[i][j][1] =
pos_mod (fracX[1]*grid[1] - origin[1] + 1 , (
double)grid[1]);
1000 atm_idx[i][j][2] =
pos_mod (fracX[2]*grid[2] - origin[2] + 1 , (
double)grid[2]);
1003 for (
int z=1; z<=density.u3(); ++z) {
1005 del_ij[2] = (atm_idx[i][j][2] - atm_j[2]) / grid[2];
1007 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
1008 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
1010 del_ij[0] = del_ij[1] = 0.0;
1011 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
1013 for (
int y=1; y<=density.u2(); ++y) {
1017 del_ij[1] = (atm_idx[i][j][1] - atm_j[1]) / grid[1] ;
1019 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
1020 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
1022 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
1024 for (
int x=1; x<=density.u1(); ++x) {
1028 del_ij[0] = (atm_idx[i][j][0] - atm_j[0]) / grid[0];
1030 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
1031 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
1034 core::Real d2 = (cart_del_ij).length_squared();
1036 if (d2 <= (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING)) {
1044 core::Real sigmoid_msk = exp( d2 - (ATOM_MASK)*(ATOM_MASK) );
1047 rho_calc(x,y,z) += atm;
1048 inv_rho_mask(x,y,z) *= (1 - inv_msk);
1051 int idx = (z-1)*density.u2()*density.u1() + (y-1)*density.u1() + x-1;
1055 inv_eps_i = sigmoid_msk;
1057 inv_eps_i = 1/eps_i;
1059 rho_dx_pt[i][j].push_back ( idx );
1060 rho_dx_atm[i][j].push_back ( (-2*k*atm)*cart_del_ij );
1061 rho_dx_mask[i][j].push_back( (-2*sigmoid_msk*inv_msk*inv_msk*inv_eps_i)*cart_del_ij );
1072 core::Real sumC_i=0, sumO_i=0, sumCO_i=0, vol_i=0, CC_i=0;
1073 core::Real sumO2_i=0.0, sumC2_i=0.0, varC_i=0, varO_i=0;
1076 for (
int x=0; x<density.u1()*density.u2()*density.u3(); ++x) {
1078 clc_x = rho_calc[x];
1080 eps_x = 1-inv_rho_mask[x];
1083 sumCO_i += eps_x*clc_x*obs_x;
1084 sumO_i += eps_x*obs_x;
1085 sumO2_i += eps_x*obs_x*obs_x;
1086 sumC_i += eps_x*clc_x;
1087 sumC2_i += eps_x*clc_x*clc_x;
1090 varC_i = (sumC2_i - sumC_i*sumC_i / vol_i );
1091 varO_i = (sumO2_i - sumO_i*sumO_i / vol_i ) ;
1092 if (varC_i == 0 || varO_i == 0)
1095 CC_i = (sumCO_i - sumC_i*sumO_i/ vol_i) / sqrt( varC_i * varO_i );
1103 if (isSymm && remapSymm && cacheCCs) {
1104 compute_symm_rotations( pose, symmInfo );
1111 std::map< core::Size , numeric::xyzMatrix< core::Real > > symmRots;
1112 for (
int i=1 ; i<=nres; ++i) {
1113 if (isSymm && !symmInfo->bb_is_independent(i) && !remapSymm) {
1120 if ( scoring_mask_.find(i) != scoring_mask_.end() )
continue;
1122 int nheavyatoms = atm_idx[i].size();
1125 for (
int j=1 ; j<=nheavyatoms; ++j) {
1126 numeric::xyzVector< core::Real > dVdx_ij(0,0,0), dOdx_ij(0,0,0), dO2dx_ij(0,0,0), dCOdx_ij(0,0,0), dC2dx_ij(0,0,0);
1132 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
1138 int npoints = rho_dx_pt_ij.size();
1139 for (
int n=1; n<=npoints; ++n) {
1140 const int x(rho_dx_pt_ij[n]);
1141 clc_x = rho_calc[x];
1148 dVdx_ij += del_mask;
1149 dOdx_ij += del_mask*obs_x;
1150 dO2dx_ij += del_mask*obs_x*obs_x;
1151 dCOdx_ij += del_rhoc*obs_x;
1152 dC2dx_ij += 2.0*del_rhoc*clc_x;
1156 core::Real f = ( sumCO_i - sumC_i*sumO_i / vol_i );
1161 sqrt(varO_i)/sqrt(varC_i) * ( dC2dx_ij + ( sumC_i*sumC_i*dVdx_ij/(vol_i*vol_i) ) ) +
1162 sqrt(varC_i)/sqrt(varO_i) * ( dO2dx_ij - ( 1/(vol_i*vol_i) * ( 2*vol_i*sumO_i*dOdx_ij - sumO_i*sumO_i*dVdx_ij ) ) ) );
1164 dCCdxs_aacen[i][j] = (g*fprime - f*gprime) / (g*g);
1182 for (
Size i=0; i<3; ++i) {
1183 while (delt_fracX[i] > 0.5) delt_fracX[i]-=1.0;
1184 while (delt_fracX[i] < -0.5) delt_fracX[i]+=1.0;
1186 delt_cart = f2c*delt_fracX;
1208 bool searching(
true);
1214 for (shift[0] = -1; shift[0] < 1.1; shift[0] += 1) {
1215 for (shift[1] = -1; shift[1] < 1.1; shift[1] += 1) {
1216 for (shift[2] = -1; shift[2] < 1.1; shift[2] += 1) {
1217 if (shift.length_squared() < 0.1)
continue;
1224 cartX_out = cartX_copy;
1225 distance_squared = cartX_copy.distance_squared(cartX_ref);
1238 for (
Size i=0; i<3; ++i) {
1239 while (fracX[i] > 0.5) fracX[i]-=1.0;
1240 while (fracX[i] < -0.5) fracX[i]+=1.0;
1255 std::map< int,ObjexxFCL::FArray3D< std::complex<double> > >::const_iterator itx = Fdrhoc_dx.find( atmid );
1257 if (itx == Fdrhoc_dx.end()) {
1258 ObjexxFCL::FArray3D<double> drhoc_dx,drhoc_dy,drhoc_dz;
1264 drhoc_dx.dimension(p_grid[0], p_grid[1], p_grid[2]);
1265 drhoc_dy.dimension(p_grid[0], p_grid[1], p_grid[2]);
1266 drhoc_dz.dimension(p_grid[0], p_grid[1], p_grid[2]);
1267 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1268 if (z < (
int)p_grid[2]/2)
1271 del_ij[2] = (((
core::Real)z - p_grid[2] - 1.0)) / grid[2];
1272 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1273 if (y < (
int)p_grid[1]/2)
1274 del_ij[1] = ((
core::Real)y - 1.0) / grid[1] ;
1276 del_ij[1] = (((
core::Real)y - p_grid[1] - 1.0)) / grid[1];
1277 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1278 if (x < (
int)p_grid[0]/2)
1281 del_ij[0] = (((
core::Real)x - p_grid[0] - 1.0)) / grid[0];
1284 core::Real d2 = (cart_del_ij).length_squared();
1286 drhoc_dx(x,y,z) = cart_del_ij[0] * 4*C*k*exp( -k*d2 );
1287 drhoc_dy(x,y,z) = cart_del_ij[1] * 4*C*k*exp( -k*d2 );
1288 drhoc_dz(x,y,z) = cart_del_ij[2] * 4*C*k*exp( -k*d2 );
1294 Fdrhoc_dx[atmid] = ObjexxFCL::FArray3D< std::complex<double> >();
1295 Fdrhoc_dy[atmid] = ObjexxFCL::FArray3D< std::complex<double> >();
1296 Fdrhoc_dz[atmid] = ObjexxFCL::FArray3D< std::complex<double> >();
1298 numeric::fourier::fft3(drhoc_dx, Fdrhoc_dx[atmid]);
1299 numeric::fourier::fft3(drhoc_dy, Fdrhoc_dy[atmid]);
1300 numeric::fourier::fft3(drhoc_dz, Fdrhoc_dz[atmid]);
1304 retval.push_back( &Fdrhoc_dx[atmid] );
1305 retval.push_back( &Fdrhoc_dy[atmid] );
1306 retval.push_back( &Fdrhoc_dz[atmid] );
1316 ObjexxFCL::FArray3D< double > rho_obs_oversample;
1322 fastorigin[0] = fastgrid[0]*origin[0] / ((
core::Real)grid[0]);
1323 fastorigin[1] = fastgrid[1]*origin[1] / ((
core::Real)grid[1]);
1324 fastorigin[2] = fastgrid[2]*origin[2] / ((
core::Real)grid[2]);
1326 resample( density, rho_obs_oversample, fastgrid );
1327 TR <<
"Resizing " << density.u1() <<
"x" << density.u2() <<
"x" << density.u3() <<
" to "
1328 << rho_obs_oversample.u1() <<
"x" << rho_obs_oversample.u2() <<
"x" << rho_obs_oversample.u3() << std::endl;
1331 ObjexxFCL::FArray3D< double > rhoc, drhoc_dx, drhoc_dy, drhoc_dz;
1348 rhoc.dimension(fastgrid[0], fastgrid[1], fastgrid[2]);
1349 drhoc_dx.dimension(fastgrid[0], fastgrid[1], fastgrid[2]);
1350 drhoc_dy.dimension(fastgrid[0], fastgrid[1], fastgrid[2]);
1351 drhoc_dz.dimension(fastgrid[0], fastgrid[1], fastgrid[2]);
1352 for (
int z=1; z<=(
int)fastgrid[2]; ++z) {
1353 if (z < (
int)fastgrid[2]/2)
1354 del_ij[2] = ((
core::Real)z - 1.0) / fastgrid[2];
1356 del_ij[2] = (((
core::Real)z - fastgrid[2] - 1.0)) / fastgrid[2];
1357 for (
int y=1; y<=(
int)fastgrid[1]; ++y) {
1358 if (y < (
int)fastgrid[1]/2)
1359 del_ij[1] = ((
core::Real)y - 1.0) / fastgrid[1] ;
1361 del_ij[1] = (((
core::Real)y - fastgrid[1] - 1.0)) / fastgrid[1];
1362 for (
int x=1; x<=(
int)fastgrid[0]; ++x) {
1363 if (x < (
int)fastgrid[0]/2)
1364 del_ij[0] = ((
core::Real)x - 1.0) / fastgrid[0];
1366 del_ij[0] = (((
core::Real)x - fastgrid[0] - 1.0)) / fastgrid[0];
1369 core::Real d2 = (cart_del_ij).length_squared();
1371 rhoc(x,y,z) = exp(-k*d2);
1372 drhoc_dx(x,y,z) = -cart_del_ij[0] * 2*k*exp( -k*d2 );
1373 drhoc_dy(x,y,z) = -cart_del_ij[1] * 2*k*exp( -k*d2 );
1374 drhoc_dz(x,y,z) = -cart_del_ij[2] * 2*k*exp( -k*d2 );
1379 ObjexxFCL::FArray3D< std::complex<double> > Frhoo, Frhoc, Fdrhoc_dx, Fdrhoc_dy, Fdrhoc_dz;
1382 numeric::fourier::fft3(rho_obs_oversample, Frhoo);
1383 numeric::fourier::fft3(rhoc, Frhoc);
1384 numeric::fourier::fft3(drhoc_dx, Fdrhoc_dx);
1385 numeric::fourier::fft3(drhoc_dy, Fdrhoc_dy);
1386 numeric::fourier::fft3(drhoc_dz, Fdrhoc_dz);
1389 for (
int i=1; i<=rho_obs_oversample.u1(); i++)
1390 for (
int j=1; j<=rho_obs_oversample.u2(); j++)
1391 for (
int k=1; k<=rho_obs_oversample.u3(); k++) {
1392 Frhoc(i,j,k) *= ( Frhoo(i,j,k) );
1393 Fdrhoc_dx(i,j,k) *= ( Frhoo(i,j,k) );
1394 Fdrhoc_dy(i,j,k) *= ( Frhoo(i,j,k) );
1395 Fdrhoc_dz(i,j,k) *= ( Frhoo(i,j,k) );
1398 numeric::fourier::ifft3( Frhoc , fastdens_score );
1399 numeric::fourier::ifft3( Fdrhoc_dx , fastdens_dscoredx );
1400 numeric::fourier::ifft3( Fdrhoc_dy , fastdens_dscoredy );
1401 numeric::fourier::ifft3( Fdrhoc_dz , fastdens_dscoredz );
1405 core::Real valMin=1e30, valMax=-1e30, mu, sigma;
1406 for (
int i=1; i<=rho_obs_oversample.u1(); i++)
1407 for (
int j=1; j<=rho_obs_oversample.u2(); j++)
1408 for (
int k=1; k<=rho_obs_oversample.u3(); k++) {
1409 valMin = std::min(valMin,fastdens_score(i,j,k));
1410 valMax = std::max(valMax,fastdens_score(i,j,k));
1412 sigma = 0.5*(natms/nres)*(valMax-valMin);
1413 mu = 0.5*(valMin+valMax);
1414 for (
int i=1; i<=rho_obs_oversample.u1(); i++)
1415 for (
int j=1; j<=rho_obs_oversample.u2(); j++)
1416 for (
int k=1; k<=rho_obs_oversample.u3(); k++) {
1417 fastdens_score(i,j,k) = ( fastdens_score(i,j,k) - mu ) / sigma;
1418 fastdens_dscoredx(i,j,k) = ( fastdens_dscoredx(i,j,k) ) / sigma;
1419 fastdens_dscoredy(i,j,k) = ( fastdens_dscoredy(i,j,k) ) / sigma;
1420 fastdens_dscoredz(i,j,k) = ( fastdens_dscoredz(i,j,k) ) / sigma;
1432 ObjexxFCL::FArray3D< double > temp_coeffs;
1433 spline_coeffs( fastdens_score, temp_coeffs); fastdens_score = temp_coeffs;
1434 spline_coeffs( fastdens_dscoredx, temp_coeffs); fastdens_dscoredx = temp_coeffs;
1435 spline_coeffs( fastdens_dscoredy, temp_coeffs); fastdens_dscoredy = temp_coeffs;
1436 spline_coeffs( fastdens_dscoredz, temp_coeffs); fastdens_dscoredz = temp_coeffs;
1451 for (
int i=1 ; i<=nres; ++i) {
1453 if ( (rsd_i.aa() ==
core::chemical::aa_vrt) || (scoring_mask_.find(i) != scoring_mask_.end()) )
continue;
1455 for (
int j=1 ; j<=nheavyatoms; ++j) {
1459 d_min = d_max = xyz_ij;
1462 d_min[0] = std::min(d_min[0],xyz_ij[0]);
1463 d_min[1] = std::min(d_min[1],xyz_ij[1]);
1464 d_min[2] = std::min(d_min[2],xyz_ij[2]);
1465 d_max[0] = std::max(d_max[0],xyz_ij[0]);
1466 d_max[1] = std::max(d_max[1],xyz_ij[1]);
1467 d_max[2] = std::max(d_max[2],xyz_ij[2]);
1477 p_extent = d_max - d_min + PattersonMaxR + 2*FLUFF;
1484 p_grid[0] =
findSampling5(f_extent[0]*grid[0] , MINMULT[0]);
1485 p_grid[1] =
findSampling5(f_extent[1]*grid[1] , MINMULT[1]);
1486 p_grid[2] =
findSampling5(f_extent[2]*grid[2] , MINMULT[2]);
1489 f_extent = c2f*(d_min-FLUFF-PattersonMaxR/2.0);
1490 p_origin[0] = std::floor(f_extent[0]*grid[0]);
1491 p_origin[1] = std::floor(f_extent[1]*grid[1]);
1492 p_origin[2] = std::floor(f_extent[2]*grid[2]);
1495 d_min = d_min-FLUFF;
1496 d_max = d_max+FLUFF;
1501 TR <<
"Setting up patterson map grid " << p_grid[0] <<
"x" << p_grid[1] <<
"x" << p_grid[2] << std::endl;
1502 TR <<
" origin " << p_origin[0] <<
"x" << p_origin[1] <<
"x" << p_origin[2] << std::endl;
1503 TR <<
" d_min " << d_min[0] <<
"x" << d_min[1] <<
"x" << d_min[2] << std::endl;
1504 TR <<
" d_max " << d_max[0] <<
"x" << d_max[1] <<
"x" << d_max[2] << std::endl;
1511 if (nsymmrot > 1 && !basic::options::option[ basic::options::OptionKeys::patterson::dont_use_symm_in_pcalc ]() ) {
1512 TR <<
"... precomputing " << nsymmrot <<
" rotations" << std::endl;
1513 symm_ptrs.resize(nsymmrot);
1516 for (
int i=1; i<= (
int)nsymmrot; ++i) {
1517 symm_ptrs[i].dimension(p_grid[0], p_grid[1], p_grid[2]);
1521 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1522 if (z < (
int)p_grid[2]/2) frac_xyz[2] = ((
core::Real)z - 1.0) / grid[2];
1523 else frac_xyz[2] = (((
core::Real)z - p_grid[2] - 1.0)) / grid[2];
1524 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1525 if (y < (
int)p_grid[1]/2) frac_xyz[1] = ((
core::Real)y - 1.0) / grid[1] ;
1526 else frac_xyz[1] = (((
core::Real)y - p_grid[1] - 1.0)) / grid[1];
1527 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1528 if (x < (
int)p_grid[0]/2) frac_xyz[0] = ((
core::Real)x - 1.0) / grid[0];
1529 else frac_xyz[0] = (((
core::Real)x - p_grid[0] - 1.0)) / grid[0];
1530 for (
int i=1; i<= (
int)nsymmrot; ++i) {
1535 pos_mod( (
int)std::floor(symm_i_xyz[0]*grid[0]+0.5), p_grid[0] ),
1536 pos_mod( (
int)std::floor(symm_i_xyz[1]*grid[1]+0.5), p_grid[1] ),
1537 pos_mod( (
int)std::floor(symm_i_xyz[2]*grid[2]+0.5), p_grid[2] ) );
1538 symm_ptrs[i](x,y,z) = symm_i_idx[2]*p_grid[1]*p_grid[0] + symm_i_idx[1]*p_grid[0] + symm_i_idx[0];
1547 PattersonEpsilon.dimension(p_grid[0], p_grid[1], p_grid[2]);
1548 F_s2.dimension(p_grid[0], p_grid[1], p_grid[2]);
1552 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1553 H = (z < (
int)p_grid[2]/2) ? z-1 : z-p_grid[2] - 1;
1554 if (z < (
int)p_grid[2]/2)
1557 del_ij[2] = (((
core::Real)z - p_grid[2] - 1.0)) / grid[2];
1558 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1559 K = (y < (
int)p_grid[1]/2) ? y-1 : y-p_grid[1]-1;
1560 if (y < (
int)p_grid[1]/2)
1561 del_ij[1] = ((
core::Real)y - 1.0) / grid[1] ;
1563 del_ij[1] = (((
core::Real)y - p_grid[1] - 1.0)) / grid[1];
1564 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1565 L = (x < (
int)p_grid[0]/2) ? x-1 : x-p_grid[0]-1;
1566 if (x < (
int)p_grid[0]/2)
1569 del_ij[0] = (((
core::Real)x - p_grid[0] - 1.0)) / grid[0];
1572 core::Real d2 = (cart_del_ij).length_squared();
1574 if (PattersonMinR <= 0) {
1575 PattersonEpsilon(x,y,z) = 1/(1+exp( d2 - PattersonMaxR*PattersonMaxR));
1577 PattersonEpsilon(x,y,z) = 1/(1+exp( d2 - PattersonMaxR*PattersonMaxR))
1578 * 1/(1+exp( PattersonMinR*PattersonMinR - d2));
1580 eps_sum += PattersonEpsilon(x,y,z);
1581 F_s2(x,y,z) = sqrt(S2(H,K,L));
1582 minS = std::min( minS, F_s2(x,y,z));
1583 maxS = std::max( maxS, F_s2(x,y,z));
1591 p_o.dimension( p_grid[0], p_grid[1], p_grid[2] );
1592 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1594 if (z > (
int)p_grid[2]/2) dens_z = (
int)grid[2] - (
int)p_grid[2] + z;
1595 if (dens_z<=0 || dens_z > grid[2]) {
1598 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1600 if (y>(
int)p_grid[1]/2) dens_y = (
int)grid[1] - (
int)p_grid[1] + y;
1601 if (dens_y<=0 || dens_y > grid[1]) {
1604 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1606 if (x>(
int)p_grid[0]/2) dens_x = (
int)grid[0] - (
int)p_grid[0] + x;
1607 if (dens_x<=0 || dens_x > grid[0]) {
1610 p_o(x,y,z) = density(dens_x,dens_y,dens_z);
1624 if (basic::options::option[ basic::options::OptionKeys::patterson::resolution_cutoffs ].user() ) {
1626 if (rescut_in.size() == 1)
1627 hires_cut = rescut_in[1];
1628 if (rescut_in.size() >= 2) {
1629 hires_cut = std::min(rescut_in[1],rescut_in[2]);
1630 lowres_cut = std::max(rescut_in[1],rescut_in[2]);
1635 core::Size nbuckets = basic::options::option[ basic::options::OptionKeys::patterson::nshells ]();
1636 core::Real max_S3 = std::pow( std::min( 1/hires_cut , maxS) , 3.0);
1637 core::Real min_S3 = std::pow( 1/lowres_cut , 3.0);
1641 bucket_id.dimension( p_grid[0], p_grid[1], p_grid[2] );
1642 for (
int i=0; i< (
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1644 int bucket_i = 1+(
int)std::floor( nbuckets*( std::pow( F_s2[i], 3.0 ) - min_S3 ) / (max_S3 - min_S3) );
1646 if ( bucket_i <= 0 || bucket_i > (
int)nbuckets )
1652 if ( !basic::options::option[ basic::options::OptionKeys::patterson::no_ecalc ]() ) {
1658 ObjexxFCL::FArray3D< std::complex<double> > Fp_o;
1659 numeric::fourier::fft3(p_o, Fp_o);
1660 bucket_counts.resize(nbuckets,0);
1662 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1663 if (bucket_id[i] > 0) {
1664 F2[ bucket_id[i] ] += std::abs(Fp_o[i]);
1665 bucket_counts[ bucket_id[i] ]++;
1670 for (
int i=1; i<=(
int)nbuckets; ++i) {
1671 F2[i] /= bucket_counts[ i ];
1675 core::Real rmsd = basic::options::option[ basic::options::OptionKeys::patterson::rmsd ]();
1676 core::Real fsol = basic::options::option[ basic::options::OptionKeys::patterson::Fsol ]();
1677 core::Real bsol = basic::options::option[ basic::options::OptionKeys::patterson::Bsol ]();
1678 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1679 if (bucket_id[i] > 0) {
1681 core::Real sigmaa_i = sqrt( (1-fsol*std::exp(-bsol*S2_i))*std::exp(-8*(M_PI*M_PI/3)*rmsd*rmsd*S2_i) );
1682 Fp_o[i] = sigmaa_i * (std::abs(Fp_o[i]) / F2[ bucket_id[i] ]);
1689 numeric::fourier::ifft3(Fp_o, p_o);
1714 for (
int i=1 ; i<=nres; ++i) {
1716 if ( (rsd_i.aa() ==
core::chemical::aa_vrt) || (scoring_mask_.find(i) != scoring_mask_.end()) )
continue;
1717 for (
int j=1 ; j<=(
int)rsd_i.nheavyatoms(); ++j) {
1719 getFdrhoc(
get_A( rsd_i.atom_type_set()[ rsd_i.atom_type_index( j ) ].element() ) );
1730 using namespace numeric::statistics;
1734 TR <<
"[ ERROR ] ElectronDensity::matchPose called but no map is loaded!\n";
1742 core::Real SC_scaling = basic::options::option[ basic::options::OptionKeys::patterson::sc_scaling ]();
1779 bool needToSetup = (p_extent.length_squared() == 0);
1787 setup_patterson_first_time(pose);
1791 rho_calc.dimension(p_grid[0], p_grid[1], p_grid[2]);
1793 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]); ++i) {
1800 rho_calc_atms.resize(nres);
1801 rho_calc_as.resize(nres);
1803 for (
int i=1 ; i<=nres; ++i) {
1807 if ( (rsd_i.aa() ==
core::chemical::aa_vrt) || (scoring_mask_.find(i) != scoring_mask_.end()) )
continue;
1810 rho_calc_atms[i].resize(nheavyatoms);
1811 rho_calc_as[i].resize(nheavyatoms);
1813 for (
int j=1 ; j<=nheavyatoms; ++j) {
1816 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
1818 core::Real k = sig_j.
k( PattersonB, max_del_grid );
1821 if ( (
Size) j > rsd_i.last_backbone_atom()+1)
1824 rho_calc_atms[i][j] = atm_i.xyz()-CoM;
1825 rho_calc_as[i][j] = sig_j;
1833 cartX = atm_i.xyz()-CoM;
1838 atm_idx_ij[0] =
pos_mod (fracX[0]*p_grid[0] - p_origin[0] + 1 , (
double)p_grid[0]);
1839 atm_idx_ij[1] =
pos_mod (fracX[1]*p_grid[1] - p_origin[1] + 1 , (
double)p_grid[1]);
1840 atm_idx_ij[2] =
pos_mod (fracX[2]*p_grid[2] - p_origin[2] + 1 , (
double)p_grid[2]);
1842 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1843 del_ij[2] = (atm_idx_ij[2] - z) / grid[2];
1844 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
1845 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
1846 del_ij[0] = del_ij[1] = 0.0;
1847 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
1848 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1849 del_ij[1] = (atm_idx_ij[1] - y) / grid[1] ;
1850 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
1851 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
1853 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
1854 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1855 del_ij[0] = (atm_idx_ij[0] - x) / grid[0];
1856 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
1857 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
1860 core::Real d2 = (cart_del_ij).length_squared();
1861 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
1863 rho_calc(x,y,z) += atm;
1873 for (
int i=0; i< (
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1874 rho_calc[i] /= rho_calc_sum;
1876 numeric::fourier::fft3(rho_calc, Frho_calc);
1878 ObjexxFCL::FArray3D< std::complex<double> > Fcalc2;
1879 Fcalc2.dimension( p_grid[0],p_grid[1],p_grid[2] );
1881 if ( !basic::options::option[ basic::options::OptionKeys::patterson::no_ecalc ]() ) {
1883 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i)
1884 if (bucket_id[i] > 0) {
1885 Fcalc2[i] = std::norm(Frho_calc[i]);
1889 numeric::fourier::ifft3(Fcalc2, Pcalc);
1898 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1899 if (bucket_id[i] > 0)
1900 F2[ bucket_id[i] ] += std::norm(Frho_calc[i]);
1902 for (
int i=1; i<=(
int)bucket_counts.size(); ++i) {
1903 F2[i] /= bucket_counts[ i ];
1907 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1908 if (bucket_id[i] > 0) {
1909 Fcalc2[i] = std::norm(Frho_calc[i]) / F2[ bucket_id[i] ];
1910 Frho_calc[i] = Frho_calc[i] / F2[ bucket_id[i] ];
1917 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1918 if (bucket_id[i] > 0) {
1919 Fcalc2[i] = std::norm(Frho_calc[i]);
1927 numeric::fourier::ifft3(Fcalc2, Pcalc);
1930 if (symm_ptrs.size() > 1 && !basic::options::option[ basic::options::OptionKeys::patterson::dont_use_symm_in_pcalc ]() ) {
1931 ObjexxFCL::FArray3D< double > Pcalcmonomer = Pcalc;
1932 for (
int i=0; i< (
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
1933 for (
int j=2; j<=(
int)symm_ptrs.size(); ++j) {
1934 Pcalc[i] += Pcalcmonomer[ symm_ptrs[j][i] ];
1940 core::Real sumC=0.0, sumC2=0.0, sumO=0.0, sumO2=0.0, sumCO=0.0, vol=0.0;
1944 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
1945 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
1946 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
1948 if (eps_x < 1e-6)
continue;
1956 sumCO += eps_x*clc_x*obs_x;
1957 sumO += eps_x*obs_x;
1958 sumO2 += eps_x*obs_x*obs_x;
1959 sumC += eps_x*clc_x;
1960 sumC2 += eps_x*clc_x*clc_x;
1965 core::Real varC = (sumC2 - sumC*sumC / vol );
1966 core::Real varO = (sumO2 - sumO*sumO / vol ) ;
1978 p_sumC = sumC; p_sumC2 = sumC2;
1979 p_sumO = sumO; p_sumO2 = sumO2;
1980 p_sumCO = sumCO; p_vol = vol;
1982 ObjexxFCL::FArray3D< double > dpcc_dx, dpcc_dy, dpcc_dz;
1984 for (
int i=1 ; i<=nres; ++i) {
1986 dCCdxs_pat[i].resize( rsd_i.nheavyatoms() );
1990 core::Real f = (p_sumCO - p_sumC*p_sumO/p_vol);
1995 for (std::map<
int,ObjexxFCL::FArray3D< std::complex<double> > >::const_iterator it = Fdrhoc_dx.begin();
1996 it != Fdrhoc_dx.end(); ++it) {
1997 ObjexxFCL::FArray3D< std::complex< double > > &Fdrhoc_dx_i = Fdrhoc_dx[ it->first ];
1998 ObjexxFCL::FArray3D< std::complex< double > > &Fdrhoc_dy_i = Fdrhoc_dy[ it->first ];
1999 ObjexxFCL::FArray3D< std::complex< double > > &Fdrhoc_dz_i = Fdrhoc_dz[ it->first ];
2009 ObjexxFCL::FArray3D< std::complex<double> > Fdpcc_dx, Fdpcc_dy, Fdpcc_dz;
2010 dpcc_dx.dimension(p_grid[0],p_grid[1],p_grid[2]);
2011 for (
int i=0; i<(
int)(p_grid[2]*p_grid[1]*p_grid[0]); ++i) {
2012 dpcc_dx[i] = PattersonEpsilon[i] *
2013 ( (p_o[i]-po_bar)/sqrt(g) - f * varO * (Pcalc[i]-pc_bar) / std::pow(g,1.5) );
2016 numeric::fourier::fft3(dpcc_dx, Fdpcc_dx);
2017 Fdpcc_dy = Fdpcc_dx;
2018 Fdpcc_dz = Fdpcc_dx;
2020 for (
int i=0; i<(
int)(p_grid[2]*p_grid[1]*p_grid[0]); ++i) {
2021 Fdpcc_dx[i] = 1.0/rho_calc_sum * Fdpcc_dx[i] * Frho_calc[i] * std::conj(Fdrhoc_dx_i[i]);
2022 Fdpcc_dy[i] = 1.0/rho_calc_sum * Fdpcc_dy[i] * Frho_calc[i] * std::conj(Fdrhoc_dy_i[i]);
2023 Fdpcc_dz[i] = 1.0/rho_calc_sum * Fdpcc_dz[i] * Frho_calc[i] * std::conj(Fdrhoc_dz_i[i]);
2029 numeric::fourier::ifft3(Fdpcc_dx, dpcc_dx);
2030 numeric::fourier::ifft3(Fdpcc_dy, dpcc_dy);
2031 numeric::fourier::ifft3(Fdpcc_dz, dpcc_dz);
2041 ObjexxFCL::FArray3D< double > dpcc_dx_coeffs, dpcc_dy_coeffs, dpcc_dz_coeffs;
2042 if ( basic::options::option[ basic::options::OptionKeys::patterson::use_spline_interpolation ]()) {
2049 for (
int i=1 ; i<=nres; ++i) {
2051 if ( rho_calc_as[i].
size() == 0 )
continue;
2053 for (
int j=1 ; j<=(
int)rsd_i.nheavyatoms(); ++j) {
2054 if (rho_calc_as[i][j].a() != it->first)
continue;
2056 cartX = rsd_i.
atom(j).
xyz()-CoM;
2059 atm_idx_ij[0] = fracX[0]*grid[0] - p_origin[0] + 1;
2060 atm_idx_ij[1] = fracX[1]*grid[1] - p_origin[1] + 1;
2061 atm_idx_ij[2] = fracX[2]*grid[2] - p_origin[2] + 1;
2065 if ( basic::options::option[ basic::options::OptionKeys::patterson::use_spline_interpolation ]()) {
2074 dCCdxs_pat[i][j] = dpcc;
2078 if (symm_ptrs.size() > 1 && !basic::options::option[ basic::options::OptionKeys::patterson::dont_use_symm_in_pcalc ]()) {
2079 dCCdxs_pat[i][j] *= symm_ptrs.size();
2082 sum_dcc += dCCdxs_pat[i][j];
2088 TR.Debug <<
"sum(grad) = " << sum_dcc << std::endl;
2091 for (
int i=1 ; i<=nres; ++i) {
2093 if ( rho_calc_as[i].
size() == 0 )
continue;
2094 for (
int j=1 ; j<=(
int)rsd_i.nheavyatoms(); ++j) {
2095 dCCdxs_pat[i][j] -= sum_dcc;
2113 return ( (sumCO - sumC*sumO/vol) / sqrt( varC * varO ) );
2122 int resid = rsd.
seqpos();
2129 ObjexxFCL::FArray3D< double > rho_calc_copy = rho_calc;
2132 int nheavyatoms_old = rho_calc_atms[resid].size();
2133 for (
int j=1 ; j<=nheavyatoms_old; ++j) {
2135 core::Real k = sig_j.
k( PattersonB, max_del_grid );
2139 if ( C < 1e-6 )
continue;
2141 cartX = rho_calc_atms[resid][j];
2143 atm_idx_ij[0] = fracX[0]*grid[0] - p_origin[0] + 1;
2144 atm_idx_ij[1] = fracX[1]*grid[1] - p_origin[1] + 1;
2145 atm_idx_ij[2] = fracX[2]*grid[2] - p_origin[2] + 1;
2147 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
2148 del_ij[2] = (atm_idx_ij[2] - z) / grid[2];
2149 del_ij[0] = del_ij[1] = 0.0;
2150 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2151 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
2152 del_ij[1] = (atm_idx_ij[1] - y) / grid[1] ;
2154 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2155 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
2156 del_ij[0] = (atm_idx_ij[0] - x) / grid[0];
2159 core::Real d2 = (cart_del_ij).length_squared();
2160 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
2162 rho_calc_copy(x,y,z) -= atm/rho_calc_sum;
2181 for (
int j=1 ; j<=nheavyatoms_new; ++j) {
2187 core::Real k = sig_j.
k( PattersonB, max_del_grid );
2193 cartX = atm_i.xyz() - p_CoM;
2195 atm_idx_ij[0] = fracX[0]*grid[0] - p_origin[0] + 1;
2196 atm_idx_ij[1] = fracX[1]*grid[1] - p_origin[1] + 1;
2197 atm_idx_ij[2] = fracX[2]*grid[2] - p_origin[2] + 1;
2199 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
2200 del_ij[2] = (atm_idx_ij[2] - z) / grid[2];
2201 del_ij[0] = del_ij[1] = 0.0;
2202 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2203 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
2204 del_ij[1] = (atm_idx_ij[1] - y) / grid[1] ;
2206 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2207 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
2208 del_ij[0] = (atm_idx_ij[0] - x) / grid[0];
2211 core::Real d2 = (cart_del_ij).length_squared();
2212 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
2214 rho_calc_copy(x,y,z) += atm/rho_calc_sum;
2222 ObjexxFCL::FArray3D< std::complex<double> > Fcalc2;
2223 ObjexxFCL::FArray3D< double > Pcalc_copy;
2225 numeric::fourier::fft3(rho_calc_copy, Fcalc2);
2228 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
2229 if (bucket_id[i] > 0)
2230 F2[ bucket_id[i] ] += std::norm(Fcalc2[i]);
2232 for (
int i=1; i<=(
int)bucket_counts.size(); ++i) {
2233 F2[i] /= bucket_counts[ i ];
2236 Fcalc2.dimension( p_grid[0],p_grid[1],p_grid[2] );
2237 for (
int i=0; i<(
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
2238 if (bucket_id[i] > 0) {
2239 Fcalc2[i] = std::norm(Fcalc2[i]) / F2[ bucket_id[i] ];
2245 numeric::fourier::ifft3(Fcalc2, Pcalc_copy);
2248 if (symm_ptrs.size() > 1 && !basic::options::option[ basic::options::OptionKeys::patterson::dont_use_symm_in_pcalc ]() ) {
2249 ObjexxFCL::FArray3D< double > Pcalcmonomer = Pcalc_copy;
2250 for (
int i=0; i< (
int)(p_grid[0]*p_grid[1]*p_grid[2]) ; ++i) {
2251 for (
int j=2; j<=(
int)symm_ptrs.size(); ++j) {
2252 Pcalc_copy[i] += Pcalcmonomer[ symm_ptrs[j][i] ];
2258 core::Real sumC=0.0, sumC2=0.0, sumO=0.0, sumO2=0.0, sumCO=0.0, vol=0.0;
2262 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
2263 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
2264 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
2266 if (eps_x < 1e-6)
continue;
2274 sumCO += eps_x*clc_x*obs_x;
2275 sumO += eps_x*obs_x;
2276 sumO2 += eps_x*obs_x*obs_x;
2277 sumC += eps_x*clc_x;
2278 sumC2 += eps_x*clc_x*clc_x;
2283 core::Real varC = (sumC2 - sumC*sumC / vol );
2284 core::Real varO = (sumO2 - sumO*sumO / vol ) ;
2285 return ( (sumCO - sumC*sumO/vol) / sqrt( varC * varO ) );
2292 int resid = rsd.
seqpos();
2299 int nheavyatoms_old = rho_calc_atms[resid].size();
2300 for (
int j=1 ; j<=nheavyatoms_old; ++j) {
2302 core::Real k = sig_j.
k( PattersonB, max_del_grid );
2306 if ( C < 1e-6 )
continue;
2308 cartX = rho_calc_atms[resid][j];
2310 atm_idx_ij[0] = fracX[0]*grid[0] - p_origin[0] + 1;
2311 atm_idx_ij[1] = fracX[1]*grid[1] - p_origin[1] + 1;
2312 atm_idx_ij[2] = fracX[2]*grid[2] - p_origin[2] + 1;
2314 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
2315 del_ij[2] = (atm_idx_ij[2] - z) / grid[2];
2316 del_ij[0] = del_ij[1] = 0.0;
2317 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2318 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
2319 del_ij[1] = (atm_idx_ij[1] - y) / grid[1] ;
2321 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2322 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
2323 del_ij[0] = (atm_idx_ij[0] - x) / grid[0];
2326 core::Real d2 = (cart_del_ij).length_squared();
2327 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
2329 rho_calc(x,y,z) -= atm;
2338 rho_calc_atms[resid].resize(nheavyatoms_new);
2339 rho_calc_as[resid].resize(nheavyatoms_new);
2340 for (
int j=1 ; j<=nheavyatoms_new; ++j) {
2346 core::Real k = sig_j.
k( PattersonB, max_del_grid );
2349 rho_calc_atms[resid][j] = atm_i.xyz()-p_CoM;
2350 rho_calc_as[resid][j] = sig_j;
2358 cartX = atm_i.xyz();
2360 atm_idx_ij[0] = fracX[0]*grid[0] - p_origin[0] + 1;
2361 atm_idx_ij[1] = fracX[1]*grid[1] - p_origin[1] + 1;
2362 atm_idx_ij[2] = fracX[2]*grid[2] - p_origin[2] + 1;
2364 for (
int z=1; z<=(
int)p_grid[2]; ++z) {
2365 del_ij[2] = (atm_idx_ij[2] - z) / grid[2];
2366 del_ij[0] = del_ij[1] = 0.0;
2367 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2368 for (
int y=1; y<=(
int)p_grid[1]; ++y) {
2369 del_ij[1] = (atm_idx_ij[1] - y) / grid[1] ;
2371 if ((f2c*del_ij).length_squared() >
square(ATOM_MASK+1))
continue;
2372 for (
int x=1; x<=(
int)p_grid[0]; ++x) {
2373 del_ij[0] = (atm_idx_ij[0] - x) / grid[0];
2376 core::Real d2 = (cart_del_ij).length_squared();
2377 if (d2 <= (ATOM_MASK+1)*(ATOM_MASK+1)) {
2379 rho_calc(x,y,z) += atm;
2397 bool isSymm = (symmInfo.get() != NULL);
2398 bool remapSymm = basic::options::option[ basic::options::OptionKeys::edensity::score_symm_complex ]();
2400 if (!isSymm || !remapSymm)
return;
2402 int nsubunits = symmInfo->subunits();
2403 int nres_per = symmInfo->num_independent_residues();
2407 for (
int subunit_i=1 ; subunit_i<=nsubunits; ++subunit_i) {
2409 int startRes = (subunit_i-1)*nres_per+1;
2410 int source_subunit = subunit_i;
2413 if (!symmInfo->bb_is_independent(startRes)) {
2414 core::Size sourceRes = symmInfo->bb_follows( startRes );
2415 source_subunit = symmInfo->subunit_index( sourceRes );
2416 R_i = numeric::alignVectorSets(
2425 mapping_i[ subunit_i ] = source_subunit;
2426 symmap[ -subunit_i ] = make_pair( mapping_i, R_i );
2435 int vrtStart = nres_per*nsubunits;
2436 int nvrts = nres - vrtStart;
2438 bool fully_mapped =
false;
2439 while ( !fully_mapped ) {
2440 fully_mapped =
true;
2441 for (
int i=1 ; i<=nvrts; ++i) {
2442 int resid = i+vrtStart;
2443 if (vrts_mapped[i]) {
2447 int nchildren = edges_i.size();
2449 if (nchildren == 0) {
2451 symmap[ resid ] = make_pair(
utility::vector1<int>(nsubunits,0),
numeric::xyzMatrix<core::Real>::rows(1,0,0, 0,1,0, 0,0,1) );
2452 vrts_mapped[i] =
true;
2453 }
else if ( nchildren == 1) {
2455 int downstream = edges_i[1].stop();
2456 if ( downstream <= vrtStart || vrts_mapped[downstream-vrtStart] ) {
2457 if ( downstream <= vrtStart ) {
2458 symmap[ resid ] = symmap[ -symmInfo->subunit_index( downstream ) ];
2460 symmap[ resid ] = symmap[ downstream ];
2462 vrts_mapped[i] =
true;
2464 fully_mapped =
false;
2468 bool allChildrenMapped =
true;
2469 for (
int j=1; j<=nchildren; ++j) {
2470 int downstream = edges_i[j].stop();
2471 if (downstream <= vrtStart) {
2472 TR.Error <<
"[ Error ] VRT (" << resid <<
") contains multiple jumps to subunits! Exiting." << std::endl;
2475 allChildrenMapped &= vrts_mapped[ downstream-vrtStart ];
2478 if ( allChildrenMapped ) {
2479 int firstChild = edges_i[1].stop();
2488 for (
int j=2; j<=nchildren; ++j) {
2490 for (
int k=1; k<=nsubunits; ++k) {
2491 if (mapping_j[k] == 0)
continue;
2497 for (
int l=1; l<=nsubunits; ++l) {
2499 core::Real thisErr = R_diff.col_x().length_squared() + R_diff.col_y().length_squared() + R_diff.col_z().length_squared();
2500 if (thisErr < bestFit) {
2506 mapping_i[ k ] = bestL;
2510 symmap[ resid ] = make_pair( mapping_i, R_i );
2511 vrts_mapped[i] =
true;
2513 fully_mapped =
false;
2527 dCCdxs_res[i].resize( nAtms );
2546 TR <<
"[ ERROR ] ElectronDensity::matchRes called but no map is loaded!\n";
2550 if ( scoring_mask_.find(resid) != scoring_mask_.end() )
return 0.0;
2553 bool isSymm = (symmInfo.get() != NULL);
2554 bool remapSymm = basic::options::option[ basic::options::OptionKeys::edensity::score_symm_complex ]();
2557 if (isSymm && !symmInfo->bb_is_independent(resid) && !remapSymm)
return 0.0;
2568 std::set< core::Size > neighborResids;
2570 Size HALFWINDOW = WINDOW_/2;
2571 Size win_start= resid-HALFWINDOW, win_stop = resid+HALFWINDOW;
2572 for (
int i=HALFWINDOW-1; i>=0; --i) {
2576 win_start = std::max(1, (
int)win_start);
2577 win_stop = std::min((
int)win_stop, nres);
2581 for (
Size i=win_start; i<=win_stop; ++i) {
2585 if ( score_window_context_ ) {
2587 iru = energy_graph.get_node(i)->const_edge_list_begin(),
2589 iru != irue; ++iru ) {
2590 EnergyEdge const * edge( static_cast< EnergyEdge const *> (*iru) );
2593 Size const j = (e1==i) ? e2 : e1;
2594 if (j<win_start || j>win_stop) {
2595 neighborResids.insert( j );
2600 if (i==(
Size)resid)
continue;
2601 if (!rsd_i.is_polymer())
continue;
2606 for (
core::Size j=1; j<=rsd_i.last_backbone_atom(); ++j ) {
2607 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
2609 contextAtoms.push_back( rsd_i.atom( j ) );
2610 contextAtomIds.push_back( std::pair<core::Size,core::Size>(i,j) );
2611 contextAtomAs.push_back( sig_j );
2614 for (
core::Size j=rsd_i.last_backbone_atom()+1; j<=rsd_i.nheavyatoms(); ++j ) {
2615 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
2617 neighborAtoms.push_back( rsd_i.atom( j ) );
2618 neighborAtomIds.push_back( std::pair<core::Size,core::Size>(i,j) );
2619 neighborAtomAs.push_back( sig_j );
2625 for (std::set< core::Size >::iterator it=neighborResids.begin(); it!=neighborResids.end(); it++) {
2627 if (!rsd_i.is_polymer())
continue;
2629 for (
core::Size j=1; j<=rsd_i.nheavyatoms(); ++j ) {
2630 std::string elt_i = atom_type_set[ rsd_i.atom_type_index( j ) ].element();
2632 neighborAtoms.push_back( rsd_i.atom( j ) );
2633 neighborAtomIds.push_back( std::pair<core::Size,core::Size>(*it,j) );
2634 neighborAtomAs.push_back( sig_j );
2638 int nResAtms = rsd.
nheavyatoms(), nContextAtms=contextAtoms.size(), nNeighborAtoms=neighborAtoms.size();
2639 int nTotalAtms = nResAtms+nContextAtms;
2648 for (
int j=1; j<=nTotalAtms; ++j ) {
2654 cartX = atom.xyz() - getTransform();
2657 fracX[1]*grid[1] - origin[1] + 1 ,
2658 fracX[2]*grid[2] - origin[2] + 1 );
2659 atmList.push_back( idxX );
2661 fracX = c2f*( cartX-(ATOM_MASK+2*ATOM_MASK_PADDING) );
2663 fracX[1]*grid[1] - origin[1] + 1 ,
2664 fracX[2]*grid[2] - origin[2] + 1 );
2665 idxX_low[0] = std::min(idxX[0],idxX_low[0]);
2666 idxX_low[1] = std::min(idxX[1],idxX_low[1]);
2667 idxX_low[2] = std::min(idxX[2],idxX_low[2]);
2669 fracX = c2f*( cartX+(ATOM_MASK+2*ATOM_MASK_PADDING) );
2671 fracX[1]*grid[1] - origin[1] + 1 ,
2672 fracX[2]*grid[2] - origin[2] + 1 );
2673 idxX_high[0] = std::max(idxX[0],idxX_high[0]);
2674 idxX_high[1] = std::max(idxX[1],idxX_high[1]);
2675 idxX_high[2] = std::max(idxX[2],idxX_high[2]);
2677 int lastMaskedAtom = atmList.size();
2681 for (
int j=1; j<=nNeighborAtoms; ++j ) {
2685 cartX = atom.
xyz() - getTransform();
2688 fracX[1]*grid[1] - origin[1] + 1 ,
2689 fracX[2]*grid[2] - origin[2] + 1 );
2690 atmList.push_back( idxX );
2694 bbox_min[0] = (
int)floor(idxX_low[0])-1; bbox_max[0] = (
int)ceil(idxX_high[0]); bbox_dims[0] = bbox_max[0]-bbox_min[0];
2695 bbox_min[1] = (
int)floor(idxX_low[1])-1; bbox_max[1] = (
int)ceil(idxX_high[1]); bbox_dims[1] = bbox_max[1]-bbox_min[1];
2696 bbox_min[2] = (
int)floor(idxX_low[2])-1; bbox_max[2] = (
int)ceil(idxX_high[2]); bbox_dims[2] = bbox_max[2]-bbox_min[2];
2698 ObjexxFCL::FArray3D< double > rho_obs, inv_rho_mask, rho_calc_fg, rho_calc_bg;
2699 rho_obs.dimension(bbox_dims[0],bbox_dims[1],bbox_dims[2]);
2700 rho_calc_fg.dimension(bbox_dims[0],bbox_dims[1],bbox_dims[2]);
2701 rho_calc_bg.dimension(bbox_dims[0],bbox_dims[1],bbox_dims[2]);
2702 inv_rho_mask.dimension(bbox_dims[0],bbox_dims[1],bbox_dims[2]);
2704 for (
int x=0; x<bbox_dims[0]*bbox_dims[1]*bbox_dims[2]; ++x) {
2706 rho_calc_fg[x] = 0.0;
2707 rho_calc_bg[x] = 0.0;
2708 inv_rho_mask[x] = 1.0;
2721 for (
int i=1; i<=(
int)atmList.size(); ++i) {
2723 atm_i[0] -= bbox_min[0];
2724 atm_i[1] -= bbox_min[1];
2725 atm_i[2] -= bbox_min[2];
2730 if ( i <= nResAtms) {
2733 k = sig_j.
k( PattersonB, max_del_grid );
2735 }
else if (i<= lastMaskedAtom) {
2737 k = sig_j.
k( PattersonB, max_del_grid );
2741 k = sig_j.
k( PattersonB, max_del_grid );
2745 for (
int z=1; z<=bbox_dims[2]; ++z) {
2747 del_ij[2] = (atm_i[2] - atm_j[2]) / grid[2];
2749 if (del_ij[2] > 0.5) del_ij[2]-=1.0;
2750 if (del_ij[2] < -0.5) del_ij[2]+=1.0;
2752 del_ij[0] = del_ij[1] = 0.0;
2753 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
2755 mapZ = (z+bbox_min[2]) % grid[2];
2756 if (mapZ <= 0) mapZ += grid[2];
2757 if (mapZ > density.u3())
continue;
2759 for (
int y=1; y<=bbox_dims[1]; ++y) {
2763 del_ij[1] = (atm_i[1] - atm_j[1]) / grid[1] ;
2765 if (del_ij[1] > 0.5) del_ij[1]-=1.0;
2766 if (del_ij[1] < -0.5) del_ij[1]+=1.0;
2768 if ((f2c*del_ij).length_squared() > (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING))
continue;
2770 mapY = (y+bbox_min[1]) % grid[1];
2771 if (mapY <= 0) mapY += grid[1];
2772 if (mapY > density.u2())
continue;
2774 for (
int x=1; x<=bbox_dims[0]; ++x) {
2778 del_ij[0] = (atm_i[0] - atm_j[0]) / grid[0];
2780 if (del_ij[0] > 0.5) del_ij[0]-=1.0;
2781 if (del_ij[0] < -0.5) del_ij[0]+=1.0;
2783 mapX = (x+bbox_min[0]) % grid[0];
2784 if (mapX <= 0) mapX += grid[0];
2785 if (mapX > density.u1())
continue;
2788 core::Real d2 = (cart_del_ij).length_squared();
2789 if (d2 <= (ATOM_MASK+ATOM_MASK_PADDING)*(ATOM_MASK+ATOM_MASK_PADDING)) {
2791 core::Real sigmoid_msk = exp( d2 - (ATOM_MASK)*(ATOM_MASK) );
2794 rho_obs(x,y,z) = density(mapX,mapY,mapZ);
2795 if (i<=lastMaskedAtom) {
2796 rho_calc_fg(x,y,z) += atm;
2797 inv_rho_mask(x,y,z) *= (1 - inv_msk);
2799 int idx = (z-1)*rho_calc_fg.u2()*rho_calc_fg.u1() + (y-1)*rho_calc_fg.u1() + x-1;
2803 inv_eps_i = sigmoid_msk;
2805 inv_eps_i = 1/eps_i;
2807 rho_dx_pt[i].push_back ( idx );
2808 rho_dx_atm[i].push_back ( (-2*k*atm)*cart_del_ij );
2809 rho_dx_mask[i].push_back( (-2*sigmoid_msk*inv_msk*inv_msk*inv_eps_i)*cart_del_ij );
2812 rho_calc_bg(x,y,z) += atm;
2829 core::Real sumC_i=0.0, sumO_i=0.0, sumCO_i=0.0, vol_i=0.0, CC_i=0.0;
2830 core::Real sumO2_i=0.0, sumC2_i=0.0, varC_i=0.0, varO_i=0.0;
2832 for (
int x=0; x<bbox_dims[0]*bbox_dims[1]*bbox_dims[2]; ++x) {
2834 clc_x = rho_calc_bg[x] + rho_calc_fg[x];
2840 sumC2_i += wt*clc_x*clc_x;
2842 sumO2_i += wt*obs_x*obs_x;
2843 sumCO_i += wt*clc_x*obs_x;
2845 varC_i = (sumC2_i - sumC_i*sumC_i / vol_i );
2846 varO_i = (sumO2_i - sumO_i*sumO_i / vol_i ) ;
2847 if (varC_i == 0 || varO_i == 0)
2850 CC_i = (sumCO_i - sumC_i*sumO_i/ vol_i) / sqrt( varC_i * varO_i );
2859 for (
int j=1 ; j<=(
int)lastMaskedAtom; ++j) {
2864 numeric::xyzVector< core::Real > dVdx_ij(0,0,0), dOdx_ij(0,0,0), dO2dx_ij(0,0,0), dCOdx_ij(0,0,0), dC2dx_ij(0,0,0), dCdx_ij(0,0,0);
2876 int npoints = rho_dx_pt_ij.size();
2877 for (
int n=1; n<=npoints; ++n) {
2878 const int x(rho_dx_pt_ij[n]);
2879 clc_x = rho_calc_bg[x] + rho_calc_fg[x];
2887 dVdx_ij += del_mask;
2889 dCdx_ij += del_mask*clc_x + del_rhoc*eps_x;
2890 dOdx_ij += del_mask*obs_x;
2891 dO2dx_ij += del_mask*obs_x*obs_x;
2892 dC2dx_ij += clc_x*(del_mask*clc_x + 2.0*del_rhoc*eps_x);
2893 dCOdx_ij += obs_x*(del_mask*clc_x + del_rhoc*eps_x);
2897 core::Real f = ( sumCO_i - sumC_i*sumO_i / vol_i );
2901 (dOdx_ij*sumC_i + dCdx_ij*sumO_i)*vol_i - sumO_i*sumC_i*dVdx_ij);
2903 sqrt(varO_i)/sqrt(varC_i) * ( dC2dx_ij - ( 1/(vol_i*vol_i) * ( 2*vol_i*sumC_i*dCdx_ij - sumC_i*sumC_i*dVdx_ij ) ) ) +
2904 sqrt(varC_i)/sqrt(varO_i) * ( dO2dx_ij - ( 1/(vol_i*vol_i) * ( 2*vol_i*sumO_i*dOdx_ij - sumO_i*sumO_i*dVdx_ij ) ) ) );
2906 std::pair<core::Size,core::Size>
const &atomid (j<=nResAtms?
2907 std::pair<core::Size,core::Size>(resid,j) : contextAtomIds[j-nResAtms]);
2908 dCCdxs_res[atomid.first][atomid.second] += (g*fprime - f*gprime) / (g*g);
2926 TR <<
"[ ERROR ] ElectronDensity::matchResFast called but no map is loaded!\n";
2930 if ( fastdens_score.u1()*fastdens_score.u2()*fastdens_score.u3() == 0 )
2931 setup_fastscoring_first_time(pose);
2933 if ( scoring_mask_.find(resid) != scoring_mask_.end() )
return 0.0;
2936 bool isSymm = (symmInfo.get() != NULL);
2937 bool remapSymm = remap_symm_;
2940 if (isSymm && !symmInfo->bb_is_independent(resid) && !remapSymm)
return 0.0;
2945 fracX = c2f*rsd.
atom(i).
xyz();
2947 fracX[1]*fastgrid[1] - fastorigin[1] + 1,
2948 fracX[2]*fastgrid[2] - fastorigin[2] + 1);
2958 int atmid,
int resid,
2966 TR <<
"[ ERROR ] ElectronDensity::dCCdx_fastRes called but no map is loaded!\n";
2970 if ( fastdens_score.u1()*fastdens_score.u2()*fastdens_score.u3() == 0 )
2971 setup_fastscoring_first_time(pose);
2973 dCCdX[0] = dCCdX[1] = dCCdX[2] = 0;
2975 if ( scoring_mask_.find(resid) != scoring_mask_.end() )
return;
2980 fracX[0]*fastgrid[0] - fastorigin[0] + 1,
2981 fracX[1]*fastgrid[1] - fastorigin[1] + 1,
2982 fracX[2]*fastgrid[2] - fastorigin[2] + 1);
2987 if (ExactDerivatives) {
3013 dCCdX[0] = (CC_px-CC_mx)/(2*NUM_DERIV_H_CEN);
3014 dCCdX[1] = (CC_py-CC_my)/(2*NUM_DERIV_H_CEN);
3015 dCCdX[2] = (CC_pz-CC_mz)/(2*NUM_DERIV_H_CEN);
3017 TR <<
" " << dCCdX<<
" ; " << dCCdX1 << std::endl;
3034 TR <<
"[ ERROR ] ElectronDensity::dCCdx_res called but no map is loaded!\n";
3039 static bool warned=
false;
3040 if (!DensScoreInMinimizer) {
3042 TR <<
"[ WARNING ] dCCdx_res called but DensityScoreInMinimizer = false ... returning 0" << std::endl;
3051 if ( (
int)dCCdxs_res[resid].
size() < atmid ) {
3057 if (! ExactDerivatives ) {
3058 dCCdX = dCCdxs_res[resid][atmid];
3086 dCCdX[0] = (CC_px-CC_mx)/(2*NUM_DERIV_H_CEN);
3087 dCCdX[1] = (CC_py-CC_my)/(2*NUM_DERIV_H_CEN);
3088 dCCdX[2] = (CC_pz-CC_mz)/(2*NUM_DERIV_H_CEN);
3093 TR <<
" " << dCCdX<<
" ; " << dCCdX1 << std::endl;
3106 TR <<
"[ ERROR ] ElectronDensity::dCCdx_cen called but no map is loaded!\n";
3112 TR <<
"[ ERROR ] ElectronDensity::dCCdx_cen called but no map is loaded!\n";
3117 static bool warned=
false;
3118 if (!DensScoreInMinimizer) {
3120 TR <<
"[ WARNING ] dCCdx_cen called but DensityScoreInMinimizer = false ... returning 0" << std::endl;
3126 if (! ExactDerivatives ) {
3127 dCCdX = dCCdxs_cen[resid];
3154 dCCdX[0] = (CC_px-CC_mx)/(2*NUM_DERIV_H_CEN);
3155 dCCdX[1] = (CC_py-CC_my)/(2*NUM_DERIV_H_CEN);
3156 dCCdX[2] = (CC_pz-CC_mz)/(2*NUM_DERIV_H_CEN);
3160 TR <<
" " << dCCdX<<
" ; " << dCCdX1 << std::endl;
3173 TR <<
"[ ERROR ] ElectronDensity::dCCdx_aacen called but no map is loaded!\n";
3178 static bool warned=
false;
3179 if (!DensScoreInMinimizer) {
3181 TR <<
"[ WARNING ] dCCdx_aacen called but DensityScoreInMinimizer = false ... returning 0" << std::endl;
3190 if ( (
int)dCCdxs_aacen[resid].
size() < atmid ) {
3195 if (! ExactDerivatives ) {
3196 dCCdX = dCCdxs_aacen[resid][atmid];
3223 dCCdX[0] = (CC_px-CC_mx)/(2*NUM_DERIV_H_CEN);
3224 dCCdX[1] = (CC_py-CC_my)/(2*NUM_DERIV_H_CEN);
3225 dCCdX[2] = (CC_pz-CC_mz)/(2*NUM_DERIV_H_CEN);
3230 TR <<
" " << dCCdX<<
" ; " << dCCdX1 << std::endl;
3242 TR <<
"[ ERROR ] ElectronDensity::dCCdx_aacen called but no map is loaded!\n";
3246 static bool warned=
false;
3247 if (!DensScoreInMinimizer) {
3249 TR <<
"[ WARNING ] dCCdx_pat called but DensityScoreInMinimizer = false ... returning 0" << std::endl;
3258 if ( (
int)dCCdxs_pat[resid].
size() < atmid ) {
3263 if (! ExactDerivatives ) {
3264 dCCdX = dCCdxs_pat[resid][atmid];
3291 dCCdX[0] = (CC_px-CC_mx)/(2*NUM_DERIV_H_CEN);
3292 dCCdX[1] = (CC_py-CC_my)/(2*NUM_DERIV_H_CEN);
3293 dCCdX[2] = (CC_pz-CC_mz)/(2*NUM_DERIV_H_CEN);
3298 TR << resid <<
" " << atmid <<
" :: " << dCCdX <<
" :: " << dCCdX1 << std::endl;
3311 std::ifstream mapin(mapfile.c_str() , std::ios::binary | std::ios::in );
3312 bool isLoaded(readMRCandResize(mapin, mapfile, reso, gridSpacing));
3323 std::istream & mapin,
3331 char mapString[4], symData[81];
3333 int crs2xyz[3], extent[3], mode, symBytes, grid[3], origin[3];
3334 int xyz2crs[3], vol_xsize, vol_ysize, vol_zsize;
3335 int xIndex, yIndex, zIndex, vol_xySize, coord[3];
3336 long dataOffset, filesize;
3342 TR <<
"[ ERROR ] Error opening MRC map " << mapfile <<
". Not loading map." << std::endl;
3346 if ( !mapin.read(reinterpret_cast <char*> (extent), 3*
sizeof(
int))
3347 || !mapin.read(reinterpret_cast <char*> (&mode), 1*
sizeof(
int))
3348 || !mapin.read(reinterpret_cast <char*> (&origin[0]), 3*
sizeof(
int))
3349 || !mapin.read(reinterpret_cast <char*> (&grid[0]), 3*
sizeof(
int))
3350 || !mapin.read(reinterpret_cast <char*> (&cellDimensions[0]), 3*
sizeof(
float))
3351 || !mapin.read(reinterpret_cast <char*> (&cellAngles[0]), 3*
sizeof(
float))
3352 || !mapin.read(reinterpret_cast <char*> (crs2xyz), 3*
sizeof(
int)) ) {
3353 TR <<
"[ ERROR ] Improperly formatted line in MRC map. Not loading map." << std::endl;
3358 mapin.seekg(92, std::ios::beg);
3359 if ( !mapin.read(reinterpret_cast <char*> (&symBytes), 1*
sizeof(
int)) ) {
3360 TR <<
"[ ERROR ] Failed reading symmetry bytes record. Not loading map." <<
"\n";
3367 mapin.seekg(196, std::ios::beg);
3368 if ( !mapin.read(reinterpret_cast <char*> (altorigin), 3*
sizeof(
float)) ) {
3369 TR <<
"[ ERROR ] Improperly formatted line in MRC map. Not loading map." << std::endl;
3374 mapin.seekg(208, std::ios::beg);
3375 mapString[3] =
'\0';
3376 if ( !mapin.read(mapString, 3) || (
std::string(mapString) !=
"MAP")) {
3377 TR <<
"[ ERROR ] 'MAP' string missing, not a valid MRC map. Not loading map." << std::endl;
3384 TR <<
"[ ERROR ] Non-real (32-bit float) data types are unsupported. Not loading map." << std::endl;
3403 TR <<
" Setting resolution to " << reso <<
"A" << std::endl;
3404 TR <<
" atom mask to " << ATOM_MASK <<
"A" << std::endl;
3405 TR <<
" CA mask to " << CA_MASK <<
"A" << std::endl;
3406 TR <<
" Read density map'" << mapfile <<
"'" << std::endl;
3407 TR <<
" extent: " << extent[0] <<
" x " << extent[1] <<
" x " << extent[2] << std::endl;
3408 TR <<
" origin: " << origin[0] <<
" x " << origin[1] <<
" x " << origin[2] << std::endl;
3409 TR <<
" altorigin: " << altorigin[0] <<
" x " << altorigin[1] <<
" x " << altorigin[2] << std::endl;
3410 TR <<
" grid: " << grid[0] <<
" x " << grid[1] <<
" x " << grid[2] << std::endl;
3411 TR <<
" celldim: " << cellDimensions[0] <<
" x " << cellDimensions[1] <<
" x " << cellDimensions[2] << std::endl;
3412 TR <<
" cellangles: " << cellAngles[0] <<
" x " << cellAngles[1] <<
" x " << cellAngles[2] << std::endl;
3413 TR <<
" crs2xyz: " << crs2xyz[0] <<
" x " << crs2xyz[1] <<
" x " << crs2xyz[2] << std::endl;
3414 TR <<
" symBytes: " << symBytes <<
"\n";
3419 filesize = mapin.tellg();
3420 dataOffset = filesize - 4*(extent[0]*extent[1]*extent[2]);
3424 TR <<
"[ WARNING ] File contains bogus symmetry record. Continuing." << std::endl;
3427 TR <<
"[ ERROR ] File appears truncated and doesn't match header. Not loading map." << std::endl;
3429 }
else if ((dataOffset >
CCP4HDSIZE) && (dataOffset < (1024*1024))) {
3433 TR <<
"[ WARNING ] File is larger than expected and doesn't match header. Reading anyway." << std::endl;
3435 TR <<
"[ ERROR ] File is MUCH larger than expected and doesn't match header. Not loading map." << std::endl;
3443 if (symBytes != 0) {
3444 TR <<
"Symmetry records found:" << std::endl;
3446 for (
int i = 0; i < symBytes/80; i++) {
3447 mapin.read(symData, 80);
3448 symList.push_back(symData);
3449 TR << symData << std::endl;
3453 symList.push_back(
"X, Y, Z");
3455 initializeSymmOps( symList );
3458 if (grid[0] == 0 && extent[0] > 0) {
3459 grid[0] = extent[0] - 1;
3460 TR <<
"[ WARNING ] Fixed X interval count. Continuing." << std::endl;
3462 if (grid[1] == 0 && extent[1] > 0) {
3463 grid[1] = extent[1] - 1;
3464 TR <<
"[ WARNING ] Fixed Y interval count. Continuing." << std::endl;
3466 if (grid[2] == 0 && extent[2] > 0) {
3467 grid[2] = extent[2] - 1;
3468 TR <<
"[ WARNING ] Fixed Z interval count. Continuing." << std::endl;
3472 if (crs2xyz[0] == 0 && crs2xyz[1] == 0 && crs2xyz[2] == 0) {
3473 TR <<
"[ WARNING ] All crs2xyz records are zero." << std::endl;
3474 TR <<
"[ WARNING ] Setting crs2xyz to 1, 2, 3 and continuing." << std::endl;
3475 crs2xyz[0] = 1; crs2xyz[1] = 2; crs2xyz[2] = 3;
3478 xyz2crs[crs2xyz[0]-1] = 0; xyz2crs[crs2xyz[1]-1] = 1; xyz2crs[crs2xyz[2]-1] = 2;
3479 xIndex = xyz2crs[0]; yIndex = xyz2crs[1]; zIndex = xyz2crs[2];
3481 vol_xsize = extent[xIndex];
3482 vol_ysize = extent[yIndex];
3483 vol_zsize = extent[zIndex];
3484 vol_xySize = vol_xsize * vol_ysize;
3488 rowdata =
new float[extent[0]];
3489 mapin.seekg(dataOffset, std::ios::beg);
3492 density.dimension( vol_xsize,vol_ysize,vol_zsize );
3494 for (coord[2] = 1; coord[2] <= extent[2]; coord[2]++) {
3495 for (coord[1] = 1; coord[1] <= extent[1]; coord[1]++) {
3498 if ( mapin.eof() ) {
3499 TR <<
"[ ERROR ] Unexpected end-of-file. Not loading map." << std::endl;
3502 if ( mapin.fail() ) {
3503 TR <<
"[ ERROR ] Problem reading the file. Not loading map." << std::endl;
3506 if ( !mapin.read( reinterpret_cast< char* >(rowdata),
sizeof(
float)*extent[0]) ) {
3507 TR <<
"[ ERROR ] Error reading data row. Not loading map." << std::endl;
3511 for (coord[0] = 1; coord[0] <= extent[0]; coord[0]++) {
3512 density( coord[xyz2crs[0]], coord[xyz2crs[1]], coord[xyz2crs[2]]) = rowdata[coord[0]-1];
3521 this->origin[0] = origin[xyz2crs[0]];
3522 this->origin[1] = origin[xyz2crs[1]];
3523 this->origin[2] = origin[xyz2crs[2]];
3526 this->grid[0] = grid[0];
3527 this->grid[1] = grid[1];
3528 this->grid[2] = grid[2];
3532 if (force_apix_ > 0) {
3533 ori_scale[0] = (force_apix_ * this->grid[0]) / cellDimensions[0];
3534 ori_scale[1] = (force_apix_ * this->grid[0]) / cellDimensions[1];
3535 ori_scale[2] = (force_apix_ * this->grid[0]) / cellDimensions[2];
3536 cellDimensions[0] = force_apix_ * this->grid[0];
3537 cellDimensions[1] = force_apix_ * this->grid[1];
3538 cellDimensions[2] = force_apix_ * this->grid[2];
3539 TR <<
"Forcing apix to " << force_apix_ << std::endl;
3545 this->computeCrystParams();
3548 if ( altorigin[0]!=0 && altorigin[0]!=0 && altorigin[0]!=0 &&
3549 ( altorigin[0] > -10000 && altorigin[0] < 10000) &&
3550 ( altorigin[1] > -10000 && altorigin[1] < 10000) &&
3551 ( altorigin[2] > -10000 && altorigin[2] < 10000)
3553 this->origin[0] = altorigin[xyz2crs[0]];
3554 this->origin[1] = altorigin[xyz2crs[1]];
3555 this->origin[2] = altorigin[xyz2crs[2]];
3559 TR <<
"Using ALTERNATE origin\n";
3560 TR <<
" origin =" << this->origin[0] <<
" x " << this->origin[1] <<
" x " << this->origin[2] << std::endl;
3564 if (force_apix_ > 0) {
3566 this->origin[0]*ori_scale[0] ,
3567 this->origin[1]*ori_scale[1] ,
3568 this->origin[2]*ori_scale[2] );
3570 TR <<
"Force apix repositioning the origin:\n";
3571 TR <<
" origin =" << this->origin[0] <<
" x " << this->origin[1] <<
" x " << this->origin[2] << std::endl;
3574 this->efforigin = this->origin;
3575 this->expandToUnitCell();
3578 if (gridSpacing > 0) this->resize( gridSpacing );
3581 max_del_grid = std::max( cellDimensions[0]/((
double)this->grid[0]) , cellDimensions[1]/((
double)this->grid[1]) );
3582 max_del_grid = std::max( max_del_grid , cellDimensions[2]/((
double)this->grid[2]) );
3585 if (reso/2 > max_del_grid)
3586 max_del_grid = reso/2;
3588 TR <<
" max_del_grid =" << max_del_grid << std::endl;
3595 core::Real mask_min = 2.0 * sqrt( 2.0 / cscat.
k(PattersonB,max_del_grid) );
3596 if (ATOM_MASK < mask_min) {
3597 TR.Warning <<
"OVERIDING ATOM MASK SETTING (was " << ATOM_MASK <<
", now " << mask_min <<
")" << std::endl;
3598 ATOM_MASK = mask_min;
3600 if (CA_MASK < mask_min) {
3601 TR.Warning <<
"OVERIDING CA MASK SETTING (was " << CA_MASK <<
", now " << mask_min <<
")" << std::endl;
3607 numeric::fourier::fft3(density, Fdensity);
3610 this->computeStats();
3611 this->computeGradients();
3628 if ( symList.size() == 0 ) {
3633 MINMULT[0] = MINMULT[1] = MINMULT[2] = 2;
3634 for (
int i=1; i<=(
int)symList.size(); ++i) {
3637 if ( rows.size() != 3 ) {
3638 TR.Error <<
"[ ERROR ] invalid symmop in map file" << std::endl;
3639 TR.Error << line << std::endl;
3640 TR.Error <<
"Setting symmetry to P1 and continuing!" << line << std::endl;
3654 for (
int j=1; j<=3; ++j) {
3655 k = rows[j].find(
'/');
3656 if (k != (
int)std::string::npos) {
3658 int startNum = rows[j].find_last_not_of(
"0123456789",k-1) + 1;
3659 int startDenom = k+1;
3660 float denom = std::atof( &rows[j][startDenom]);
3664 while ( std::fmod(MINMULT[j-1] , denom) > 1e-6 ) MINMULT[j-1] += oldMinMult;
3666 trans[j-1] = std::atof( &rows[j][startNum]) / denom;
3671 if (rows[j].find(
"-X") != std::string::npos)
3673 else if (rows[j].find(
"X") != std::string::npos)
3676 if (rows[j].find(
"-Y") != std::string::npos)
3678 else if (rows[j].find(
"Y") != std::string::npos)
3681 if (rows[j].find(
"-Z") != std::string::npos)
3683 else if (rows[j].find(
"Z") != std::string::npos)
3687 symmOps.push_back( RT( rot, trans ) );
3693 for (
int i=1; i<=(
int)symmRotOps.size(); ++i) {
3695 if ( (
rot(1,1) == R_i(1,1) &&
rot(1,2) == R_i(1,2) &&
rot(1,3) == R_i(1,3)
3696 &&
rot(2,1) == R_i(2,1) &&
rot(2,2) == R_i(2,2) &&
rot(2,3) == R_i(2,3)
3697 &&
rot(3,1) == R_i(3,1) &&
rot(3,2) == R_i(3,2) &&
rot(3,3) == R_i(3,3) ) ||
3698 (
rot(1,1) == -R_i(1,1) &&
rot(1,2) == -R_i(1,2) &&
rot(1,3) == -R_i(1,3)
3699 &&
rot(2,1) == -R_i(2,1) &&
rot(2,2) == -R_i(2,2) &&
rot(2,3) == -R_i(2,3)
3700 &&
rot(3,1) == -R_i(3,1) &&
rot(3,2) == -R_i(3,2) &&
rot(3,3) == -R_i(3,3) ) ) {
3710 symmRotOps.push_back( rot );
3714 TR <<
"MINMULT: " << MINMULT[0] <<
" " << MINMULT[1] <<
" " << MINMULT[2] << std::endl;
3725 if ( grid[0] == extent[0] && grid[1] == extent[1] && grid[2] == extent[2] )
3728 ObjexxFCL::FArray3D< float > newDensity( grid[0],grid[1],grid[2], 0.0 );
3731 int limX=std::min(extent[0],grid[0]),
3732 limY=std::min(extent[1],grid[1]),
3733 limZ=std::min(extent[2],grid[2]);
3734 for (
int x=1; x<=limX; ++x)
3735 for (
int y=1; y<=limY; ++y)
3736 for (
int z=1; z<=limZ; ++z) {
3737 newDensity( x,y,z ) = density( x,y,z );
3742 for (
int x=grid[0]; x>=1; --x)
3743 for (
int y=grid[1]; y>=1; --y)
3744 for (
int z=grid[2]; z>=1; --z) {
3745 if (x <= limX && y <= limY && z <= limZ)
3751 ( (
core::Real)z + origin[2] - 1 ) / grid[2] );
3753 for (
int symm_idx=1; symm_idx<=(
int)symmOps.size(); symm_idx++) {
3755 symmOps[symm_idx].get_rotation() * fracX + symmOps[symm_idx].get_translation();
3758 int Sx =
pos_mod((
int)floor(SfracX[0]*grid[0]+0.5 - origin[0]) , grid[0]) + 1;
3759 int Sy =
pos_mod((
int)floor(SfracX[1]*grid[1]+0.5 - origin[1]) , grid[1]) + 1 ;
3760 int Sz =
pos_mod((
int)floor(SfracX[2]*grid[2]+0.5 - origin[2]) , grid[2]) + 1 ;
3762 if (Sx <= limX && Sy <= limY && Sz <= limZ) {
3763 newDensity( x,y,z ) = density(Sx,Sy,Sz);
3774 density = newDensity;
3779 for (
int i=1; i<=(
int)reses.size(); ++i ) {
3780 TR <<
" " << reses[i] <<
": " << CCs[reses[i]] << std::endl;
3787 using namespace std;
3789 string outfile = filestem +
".mat";
3793 out.open(outfile.c_str(), ios::out);
3799 "MATLAB 5.0 MAT-file, Platform: GLNX86 "
3804 out.write((
char*)&buff_s, 2);
3806 out.write((
char*)&buff_s, 2);
3809 buff_l = 0x0000000E;
3810 out.write((
char*)&buff_l, 4);
3811 buff_l = 4*dims[0]*dims[1]*dims[2] + 64;
3812 out.write((
char*)&buff_l, 4);
3815 buff_l = 0x00000006;
3816 out.write((
char*)&buff_l, 4);
3817 buff_l = 0x00000008;
3818 out.write((
char*)&buff_l, 4);
3819 buff_l = 0x00000007;
3820 out.write((
char*)&buff_l, 4);
3821 buff_l = 0x00000000;
3822 out.write((
char*)&buff_l, 4);
3825 buff_l = 0x00000005;
3826 out.write((
char*)&buff_l, 4);
3827 buff_l = 0x0000000C;
3828 out.write((
char*)&buff_l, 4);
3829 out.write((
char*)&dims[0], 12);
3830 buff_l = 0x00000000;
3831 out.write((
char*)&buff_l, 4);
3835 out.write((
char*)&buff_l, 4);
3837 out.write((
char*)&buff_l, 4);
3838 out.write(
"match ", 8);
3841 buff_l = 0x00000007;
3842 out.write((
char*)&buff_l, 4);
3843 buff_l = 4*dims[0]*dims[1]*dims[2];
3844 out.write((
char*)&buff_l, 4);
3846 for (
int k=1; k<=dims[2]; k++) {
3847 for (
int j=1; j<=dims[1]; j++) {
3848 for (
int i=1; i<=dims[0]; i++) {
3849 float buff_f = (float) density(i,j,k);
3850 out.write((
char*)&buff_f, 4);
3863 std::fstream outx( (mapfilename).c_str() , std::ios::binary | std::ios::out );
3872 TR.Error <<
"[ ERROR ] Error opening MRC map for writing." << std::endl;
3877 buff_vi[0] = density.u1(); buff_vi[1] = density.u2(); buff_vi[2] = density.u3();
3878 outx.write(reinterpret_cast <char*>(buff_vi),
sizeof(
int)*3);
3882 outx.write(reinterpret_cast <char*>(&buff_i),
sizeof(
int));
3886 ori_int[0] = (
int)std::floor( origin[0] );
3887 ori_int[1] = (
int)std::floor( origin[1] );
3888 ori_int[2] = (
int)std::floor( origin[2] );
3889 outx.write(reinterpret_cast <char*>(ori_int),
sizeof(
int)*3);
3892 outx.write(reinterpret_cast <char*>(&grid[0]),
sizeof(
int)*3);
3895 outx.write(reinterpret_cast <char*>(&cellDimensions),
sizeof(
float)*3);
3896 outx.write(reinterpret_cast <char*>(&cellAngles),
sizeof(
float)*3);
3899 buff_vi[0] = 1; buff_vi[1] = 2; buff_vi[2] = 3;
3900 outx.write(reinterpret_cast <char*>(buff_vi),
sizeof(
int)*3);
3903 buff_vf[0] = -100.0; buff_vf[1] = 100.0; buff_vf[2] = 0.0;
3904 outx.write(reinterpret_cast <char*>(buff_vf),
sizeof(
float)*3);
3908 outx.write(reinterpret_cast <char*>(&buff_i),
sizeof(
int));
3911 outx.write(reinterpret_cast <char*>(&symBytes),
sizeof(
int));
3915 for (
int i=0; i<25; ++i) {
3916 outx.write(reinterpret_cast <char*>(&buff_i),
sizeof(
int));
3923 ori_float[0] = (float)( origin_realspace[0] );
3924 ori_float[1] = (float)( origin_realspace[1] );
3925 ori_float[2] = (float)( origin_realspace[2] );
3926 outx.write(reinterpret_cast <char*>(ori_float),
sizeof(
float)*3);
3929 char buff_s[80]; strcpy(buff_s,
"MAP DD");
3930 outx.write(reinterpret_cast <char*>(buff_s), 8);
3935 for (
int i=0; i<nJunkWords; ++i) {
3936 outx.write(reinterpret_cast <char*>(&buff_i),
sizeof(
int));
3941 for (coord[2] = 1; coord[2] <= density.u3(); coord[2]++) {
3942 for (coord[1] = 1; coord[1] <= density.u2(); coord[1]++) {
3943 for (coord[0] = 1; coord[0] <= density.u1(); coord[0]++) {
3944 buff_f = (float) density(coord[0],coord[1],coord[2]);
3945 outx.write(reinterpret_cast <char*>(&buff_f),
sizeof(
float));
3958 if ( grid[0] != density.u1() || grid[1] != density.u2() || grid[2] != density.u3() ){
3959 TR <<
"[ ERROR ] resize() not supported for maps not covering the entire unit cell."<< std::endl;
3960 TR <<
" " << grid[0] <<
" != " << density.u1()
3961 <<
" || " << grid[1] <<
" != " << density.u2()
3962 <<
" || " << grid[2] <<
" != " << density.u3() << std::endl;
3971 newDims[0] =
findSampling( cellDimensions[0] / approxGridSpacing , MINMULT[0] );
3972 newDims[1] =
findSampling( cellDimensions[1] / approxGridSpacing , MINMULT[1] );
3973 newDims[2] =
findSampling( cellDimensions[2] / approxGridSpacing , MINMULT[2] );
3975 newOri[0] = newDims[0]*origin[0] / ((
core::Real)grid[0]);
3976 newOri[1] = newDims[1]*origin[1] / ((
core::Real)grid[1]);
3977 newOri[2] = newDims[2]*origin[2] / ((
core::Real)grid[2]);
3980 ObjexxFCL::FArray3D< double > newDensity;
3982 resample( density, newDensity, newDims );
3983 TR <<
"Resizing " << density.u1() <<
"x" << density.u2() <<
"x" << density.u3() <<
" to "
3984 << newDensity.u1() <<
"x" << newDensity.u2() <<
"x" << newDensity.u3() << std::endl;
3987 density.dimension( newDims[0], newDims[1], newDims[2] );
3988 for (
int i=0; i< newDims[0]*newDims[1]*newDims[2] ; ++i)
3989 density[i] = (
float)newDensity[i];
3990 this->grid = newGrid;
3991 this->efforigin = origin = newOri;
3993 TR <<
" new extent: " << density.u1() <<
" x " << density.u2() <<
" x " << density.u3() << std::endl;
3994 TR <<
" new origin: " << origin[0] <<
" x " << origin[1] <<
" x " << origin[2] << std::endl;
3995 TR <<
" new grid: " << grid[0] <<
" x " << grid[1] <<
" x " << grid[2] << std::endl;
4006 ObjexxFCL::FArray3D< float > grad_x, grad_y, grad_z;
4007 grad_x.dimension( dims[0] , dims[1] , dims[2] ); grad_x = 0;
4008 grad_y.dimension( dims[0] , dims[1] , dims[2] ); grad_y = 0;
4009 grad_z.dimension( dims[0] , dims[1] , dims[2] ); grad_z = 0;
4011 for (
int x=2; x<dims[0]; ++x) {
4012 for (
int y=2; y<dims[1]; ++y) {
4013 for (
int z=2; z<dims[2]; ++z) {
4014 grad_x(x,y,z) = 0.5*(density(x+1,y,z) - density(x-1,y,z));
4015 grad_x(x,y,z) = 0.125*(density(x+1,y+1,z) - density(x-1,y+1,z));
4016 grad_x(x,y,z) = 0.125*(density(x+1,y-1,z) - density(x-1,y-1,z));
4017 grad_x(x,y,z) = 0.125*(density(x+1,y,z+1) - density(x-1,y,z+1));
4018 grad_x(x,y,z) = 0.125*(density(x+1,y,z-1) - density(x-1,y,z-1));
4020 grad_y(x,y,z) = 0.5*(density(x,y+1,z) - density(x,y-1,z));
4021 grad_y(x,y,z) = 0.125*(density(x+1,y+1,z) - density(x+1,y-1,z));
4022 grad_y(x,y,z) = 0.125*(density(x-1,y+1,z) - density(x-1,y-1,z));
4023 grad_y(x,y,z) = 0.125*(density(x,y+1,z+1) - density(x,y-1,z+1));
4024 grad_y(x,y,z) = 0.125*(density(x,y+1,z-1) - density(x,y-1,z-1));
4026 grad_z(x,y,z) = 0.5*(density(x,y,z+1) - density(x,y,z-1));
4027 grad_z(x,y,z) = 0.125*(density(x+1,y,z+1) - density(x+1,y,z-1));
4028 grad_z(x,y,z) = 0.125*(density(x-1,y,z+1) - density(x-1,y,z-1));
4029 grad_z(x,y,z) = 0.125*(density(x,y+1,z+1) - density(x,y+1,z-1));
4030 grad_z(x,y,z) = 0.125*(density(x,y-1,z+1) - density(x,y-1,z-1));
4039 TR <<
"Finished computing gradient maps" << std::endl;
4048 dens_max = -std::numeric_limits< core::Real >::max();
4049 dens_min = std::numeric_limits< core::Real >::max();
4052 int N = density.u1()*density.u2()*density.u3();
4055 for (
int i=1; i<=density.u1(); i++)
4056 for (
int j=1; j<=density.u2(); j++)
4057 for (
int k=1; k<=density.u3(); k++) {
4058 sum += density(i,j,k);
4059 sum2 += density(i,j,k)*density(i,j,k);
4060 dens_max = std::max(dens_max, (
core::Real)density(i,j,k));
4061 dens_min = std::min(dens_min, (
core::Real)density(i,j,k));
4064 dens_stdev = sqrt( sum2/N-dens_mean*dens_mean );
4066 for (
int i=1; i<=density.u1(); i++)
4067 for (
int j=1; j<=density.u2(); j++)
4068 for (
int k=1; k<=density.u3(); k++) {
4070 if (density(i,j,k) > 0) {
4071 centerOfMass[0] += i*density(i,j,k);
4072 centerOfMass[1] += j*density(i,j,k);
4073 centerOfMass[2] += k*density(i,j,k);
4074 sumCoM += density(i,j,k);
4077 centerOfMass /= sumCoM;
4079 TR <<
"Density map stats:" << std::endl;
4080 TR <<
" min = " << dens_min << std::endl;
4081 TR <<
" max = " << dens_max << std::endl;
4082 TR <<
" mean = " << dens_mean << std::endl;
4083 TR <<
" stdev = " << dens_stdev << std::endl;
4084 TR <<
" CoM = " << centerOfMass[0] <<
" , " << centerOfMass[1] <<
" , " << centerOfMass[2] << std::endl;
4086 TR <<
" xform = " << trans[0] <<
" , " << trans[1] <<
" , " << trans[2] << std::endl;
4087 TR <<
" efforig = " << efforigin[0] <<
" , " << efforigin[1] <<
" , " << efforigin[2] << std::endl;
4095 core::Real ca = cos(
d2r(cellAngles[0])), cb = cos(
d2r(cellAngles[1])), cg = cos(
d2r(cellAngles[2]));
4096 core::Real sa = sin(
d2r(cellAngles[0])), sb = sin(
d2r(cellAngles[1])), sg = sin(
d2r(cellAngles[2]));
4100 cellDimensions[0] , cellDimensions[1] * cg, cellDimensions[2] * cb,
4101 0.0, cellDimensions[1] * sg, cellDimensions[2] * (ca - cb*cg) / sg,
4102 0.0, 0.0 , cellDimensions[2] * sb * sqrt(1.0 -
square((cb*cg - ca)/(sb*sg))) );
4105 TR <<
"[ WARNING ] Invalid crystal cell dimensions." << std::endl;
4110 (f2c(2,2)*f2c(3,3)-f2c(2,3)*f2c(3,2))/D,
4111 -(f2c(1,2)*f2c(3,3)-f2c(1,3)*f2c(3,2))/D,
4112 (f2c(1,2)*f2c(2,3)-f2c(1,3)*f2c(2,2))/D,
4113 -(f2c(2,1)*f2c(3,3)-f2c(3,1)*f2c(2,3))/D,
4114 (f2c(1,1)*f2c(3,3)-f2c(1,3)*f2c(3,1))/D,
4115 -(f2c(1,1)*f2c(2,3)-f2c(1,3)*f2c(2,1))/D,
4116 (f2c(2,1)*f2c(3,2)-f2c(3,1)*f2c(2,2))/D,
4117 -(f2c(1,1)*f2c(3,2)-f2c(1,2)*f2c(3,1))/D,
4118 (f2c(1,1)*f2c(2,2)-f2c(1,2)*f2c(2,1))/D );
4119 this->V = cellDimensions[0]*cellDimensions[1]*cellDimensions[2]* sqrt(1-
square(ca)-
square(cb)-
square(cg)+2*ca*cb*cg);
4122 this->RcellDimensions[0] = cellDimensions[1]*cellDimensions[2]*sa/V;
4123 this->RcellDimensions[1] = cellDimensions[0]*cellDimensions[2]*sb/V;
4124 this->RcellDimensions[2] = cellDimensions[0]*cellDimensions[1]*sg/V;
4125 this->cosRcellAngles[0] = cos( asin( std::min( std::max( V/(cellDimensions[0]*cellDimensions[1]*cellDimensions[2]*sb*sg) , -1.0) , 1.0) ) );
4126 this->cosRcellAngles[1] = cos( asin( std::min( std::max( V/(cellDimensions[0]*cellDimensions[1]*cellDimensions[2]*sa*sg) , -1.0) , 1.0) ) );
4127 this->cosRcellAngles[2] = cos( asin( std::min( std::max( V/(cellDimensions[0]*cellDimensions[1]*cellDimensions[2]*sa*sb) , -1.0) , 1.0) ) );