/** * \file SampledDensityMap.cpp * \brief Sampled density map. * * Copyright 2007-2010 IMP Inventors. All rights reserved. * */ #include IMPEM_BEGIN_NAMESPACE SampledDensityMap::SampledDensityMap(const DensityHeader &header): DensityMap(header) { x_key_=IMP::core::XYZ::get_coordinate_key(0); y_key_=IMP::core::XYZ::get_coordinate_key(1); z_key_=IMP::core::XYZ::get_coordinate_key(2); kernel_params_ = KernelParameters(header_.get_resolution()); distance_mask_ = DistanceMask(&header_); } IMP::algebra::BoundingBox3D SampledDensityMap::calculate_particles_bounding_box(const Particles &ps) { IMP_INTERNAL_CHECK(ps.size()>0, "Can not calculate a particles bounding box for zero particles"< > all_points; for(IMP::Particles::const_iterator it = ps.begin(); it != ps.end(); it++ ){ all_points.push_back(IMP::core::XYZ(*it).get_coordinates()); } return IMP::algebra::BoundingBox3D(all_points); } void SampledDensityMap::set_header(const algebra::VectorD<3> &lower_bound, const algebra::VectorD<3> &upper_bound, emreal maxradius, emreal resolution, emreal voxel_size, int sig_cutoff) { //set the map header header_ = DensityHeader(); header_.set_resolution(resolution); header_.Objectpixelsize_=voxel_size; header_.update_map_dimensions( int(ceil((1.0*(upper_bound[0]-lower_bound[0]) + 2.*sig_cutoff*(resolution+maxradius))/voxel_size)), int(ceil((1.0*(upper_bound[1]-lower_bound[1]) + 2.*sig_cutoff*(resolution+maxradius))/voxel_size)), int(ceil((1.0*(upper_bound[2]-lower_bound[2]) + 2.*sig_cutoff*(resolution+maxradius))/voxel_size))); header_.set_xorigin( floor(lower_bound[0]-sig_cutoff*(resolution + maxradius))); header_.set_yorigin( floor(lower_bound[1]-sig_cutoff*(resolution + maxradius))); header_.set_zorigin( floor(lower_bound[2]-sig_cutoff*(resolution + maxradius))); header_.alpha = header_.beta = header_.gamma = 90.0; // TODO : in MRC format mx equals Grid size in X // ( http://bio3d.colorado.edu/imod/doc/mrc_format.txt) // We assueme that grid size means number of voxels ( which is the meaning // of nx). It might be worth asking MRC people whether this assumption // is correct. header_.mx = header_.get_nx(); header_.my = header_.get_ny(); header_.mz = header_.get_nz(); header_.compute_xyz_top(); header_.update_cell_dimensions(); } SampledDensityMap::SampledDensityMap(const IMP::Particles &ps, emreal resolution, emreal voxel_size, IMP::FloatKey radius_key,IMP::FloatKey mass_key, int sig_cutoff) { IMP_LOG(VERBOSE, "start SampledDensityMap with resolution: "<get_kdist(), iminx, iminy, iminz, imaxx, imaxy, imaxz); IMP_LOG(IMP::VERBOSE,"Calculated bounding box for voxel: " << ii << " is :"<get_inv_sigsq()); //tmp = exp(-rsq * params->get_inv_sigsq()); // if statement to ensure even sampling within the box if (tmp>kernel_params_.get_lim()) { data_[ivox]+= params->get_normfac() * ps_[ii]->get_value(weight_key_) * tmp; } ivox++; } } } } // The values of dmean, dmin,dmax, and rms have changed rms_calculated_ = false; normalized_ = false; IMP_LOG(VERBOSE,"finish resampling particles " <get_x()+shift[0]) / spacing; y_loc = ny_half + (it->get_y()+shift[1]) / spacing; z_loc = nz_half + (it->get_z()+shift[2]) / spacing; x0=static_cast(floor(x_loc)); y0=static_cast(floor(y_loc)); z0=static_cast(floor(z_loc)); x1=x0+1; y1=y0+1; z1=z0+1; //check that the point is within the boundaries bool is_valid=true; is_valid = is_valid & (x0= lower_margin[0]); is_valid = is_valid & (y0= lower_margin[1]); is_valid = is_valid & (z0= lower_margin[2]); if (!is_valid) { IMP_WARN("particle:"<get_particle()->get_name() <<" is not interpolated \n"); continue; } //interpolate a = x1-x_loc; b = y1-y_loc; c = z1-z_loc; ab= a*b; ab1=a * (1-b); a1b=(1-a) * b; a1b1=(1-a) * (1-b); a=(1-c); float mass = (it->get_particle())->get_value(mass_key); long ind; ind=xyz_ind2voxel(x0,y0,z0); set_value(ind,get_value(ind)+ab*c*mass); ind=xyz_ind2voxel(x0,y0,z1); set_value(ind,get_value(ind)+ab*a*mass); ind=xyz_ind2voxel(x0,y1,z0); set_value(ind,get_value(ind)+ab1*c*mass); ind=xyz_ind2voxel(x0,y1,z1); set_value(ind,get_value(ind)+ab1*a*mass); ind=xyz_ind2voxel(x1,y0,z0); set_value(ind,get_value(ind)+a1b*c*mass); ind=xyz_ind2voxel(x1,y0,z1); set_value(ind,get_value(ind)+a1b*a*mass); ind=xyz_ind2voxel(x1,y1,z0); set_value(ind,get_value(ind)+a1b1*c*mass); ind=xyz_ind2voxel(x1,y1,z1); set_value(ind,get_value(ind)+a1b1*a*mass); } } void SampledDensityMap::determine_grid_size(emreal resolution, emreal voxel_size,int sig_cutoff) { std::vector > all_points; float max_radius = -1; for(core::XYZRs::const_iterator it = xyzr_.begin(); it != xyzr_.end(); it++ ){ all_points.push_back(it->get_coordinates()); if (it->get_radius()>max_radius) { max_radius = it->get_radius(); } } IMP::algebra::BoundingBox3D bb = IMP::algebra::BoundingBox3D(all_points); IMP_IF_LOG(VERBOSE) { IMP_LOG(VERBOSE, "particles bounding box is : "); IMP_LOG_WRITE(VERBOSE,bb.show()); IMP_LOG(VERBOSE,std::endl); IMP_LOG(VERBOSE,"max radius is: " << max_radius<