// TODO: binaries should be a special case of resample, either make
//template or pass pointer to voxel update function
// TODO: pass the background value as well to the general resample function
//TODO: make this function faster
void SurfaceShellDensityMap::binaries(float scene_val) {
  reset_data(IMP_BACKGROUND_VAL);
  calc_all_voxel2loc();
  int  ivox, ivoxx, ivoxy, ivoxz, iminx, imaxx, iminy, imaxy, iminz, imaxz;

  // actual sampling
  float tmpx,tmpy,tmpz;
  int nxny=header_.get_nx()*header_.get_ny();
  int znxny;
  float rsq,tmp;

  for (unsigned int ii=0; ii<ps_.size(); ii++) {
    // compute kernel parameters if needed
    const RadiusDependentKernelParameters &params
                   = kernel_params_.get_params(xyzr_[ii].get_radius());
    // compute the box affected by each particle
    calc_local_bounding_box(this,
     xyzr_[ii].get_x(),xyzr_[ii].get_y(),xyzr_[ii].get_z(),
     params.get_kdist(),
     iminx, iminy, iminz, imaxx, imaxy, imaxz);
    for (ivoxz=iminz;ivoxz<=imaxz;ivoxz++) {
      znxny=ivoxz * nxny;
      for (ivoxy=iminy;ivoxy<=imaxy;ivoxy++)  {
        // we increment ivox this way to avoid unneceessary multiplication
        // operations.
        ivox = znxny + ivoxy * header_.get_nx() + iminx;
        for (ivoxx=iminx;ivoxx<=imaxx;ivoxx++) {
          tmpx=x_loc_[ivox] - xyzr_[ii].get_x();
          tmpy=y_loc_[ivox] - xyzr_[ii].get_y();
          tmpz=z_loc_[ivox] - xyzr_[ii].get_z();
          rsq = tmpx*tmpx+tmpy*tmpy+tmpz*tmpz;
          tmp = EXP(-rsq * params.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]= scene_val;
          }
          ivox++;
        }
      }
    }
  }

  // The values of dmean, dmin,dmax, and rms have changed
  rms_calculated_ = false;
  normalized_ = false;
}
Esempio n. 2
0
algebra::Vector3Ds CoarseCC::calc_derivatives(const DensityMap *em_map,
                                              const DensityMap *model_map,
                                              const Particles &model_ps,
                                              const FloatKey &w_key,
                                              KernelParameters *kernel_params,
                                              const float &scalefac,
                                              const algebra::Vector3Ds &dv) {
  algebra::Vector3Ds dv_out;
  dv_out.insert(dv_out.end(), dv.size(), algebra::Vector3D(0., 0., 0.));
  double tdvx = 0., tdvy = 0., tdvz = 0., tmp, rsq;
  int iminx, iminy, iminz, imaxx, imaxy, imaxz;

  const DensityHeader *model_header = model_map->get_header();
  const DensityHeader *em_header = em_map->get_header();
  const float *x_loc = em_map->get_x_loc();
  const float *y_loc = em_map->get_y_loc();
  const float *z_loc = em_map->get_z_loc();
  IMP_INTERNAL_CHECK(model_ps.size() == dv.size(),
                     "input derivatives array size does not match "
                         << "the number of particles in the model map\n");
  core::XYZRs model_xyzr = core::XYZRs(model_ps);
  // this would go away once we have XYZRW decorator
  const emreal *em_data = em_map->get_data();
  float lim = kernel_params->get_lim();
  long ivox;
  // validate that the model and em maps are not empty
  IMP_USAGE_CHECK(em_header->rms >= EPS,
                  "EM map is empty ! em_header->rms = " << em_header->rms);
  // it may be that CG takes a too large step, which causes the particles
  // to go outside of the density
  // if (model_header->rms <= EPS){
  // IMP_WARN("Model map is empty ! model_header->rms = " << model_header->rms
  //           <<" derivatives are not calculated. the model centroid is : " <<
  //           core::get_centroid(core::XYZs(model_ps))<<
  //           " the map centroid is " << em_map->get_centroid()<<
  //                 "number of particles in model:"<<model_ps.size()
  //<<std::endl);
  // return;
  // }
  // Compute the derivatives
  int nx = em_header->get_nx();
  int ny = em_header->get_ny();
  // int nz=em_header->get_nz();
  IMP_INTERNAL_CHECK(em_map->get_rms_calculated(),
                     "RMS should be calculated for calculating derivatives \n");
  long nvox = em_header->get_number_of_voxels();
  double lower_comp = 1. * nvox * em_header->rms * model_header->rms;

  for (unsigned int ii = 0; ii < model_ps.size(); ii++) {
    float x, y, z;
    x = model_xyzr[ii].get_x();
    y = model_xyzr[ii].get_y();
    z = model_xyzr[ii].get_z();
    IMP_IF_LOG(VERBOSE) {
      algebra::Vector3D vv(x, y, z);
      IMP_LOG_VERBOSE(
          "start value:: (" << x << "," << y << "," << z << " ) "
                            << em_map->get_value(x, y, z) << " : "
                            << em_map->get_dim_index_by_location(vv, 0) << ","
                            << em_map->get_dim_index_by_location(vv, 1) << ","
                            << em_map->get_dim_index_by_location(vv, 2)
                            << std::endl);
    }
    const RadiusDependentKernelParameters &params =
        kernel_params->get_params(model_xyzr[ii].get_radius());
    calc_local_bounding_box(  // em_map,
        model_map, x, y, z, params.get_kdist(), iminx, iminy, iminz, imaxx,
        imaxy, imaxz);
    IMP_LOG_WRITE(VERBOSE, params.show());
    IMP_LOG_VERBOSE("local bb: [" << iminx << "," << iminy << "," << iminz
                                  << "] [" << imaxx << "," << imaxy << ","
                                  << imaxz << "] \n");
    tdvx = .0;
    tdvy = .0;
    tdvz = .0;
    for (int ivoxz = iminz; ivoxz <= imaxz; ivoxz++) {
      for (int ivoxy = iminy; ivoxy <= imaxy; ivoxy++) {
        ivox = ivoxz * nx * ny + ivoxy * nx + iminx;
        for (int ivoxx = iminx; ivoxx <= imaxx; ivoxx++) {
          /*          if (em_data[ivox]<EPS) {
            ivox++;
            continue;
            }*/
          float dx = x_loc[ivox] - x;
          float dy = y_loc[ivox] - y;
          float dz = z_loc[ivox] - z;
          rsq = dx * dx + dy * dy + dz * dz;
          rsq = EXP(-rsq * params.get_inv_sigsq());
          tmp = (x - x_loc[ivox]) * rsq;
          if (std::abs(tmp) > lim) {
            tdvx += tmp * em_data[ivox];
          }
          tmp = (y - y_loc[ivox]) * rsq;
          if (std::abs(tmp) > lim) {
            tdvy += tmp * em_data[ivox];
          }
          tmp = (z - z_loc[ivox]) * rsq;
          if (std::abs(tmp) > lim) {
            tdvz += tmp * em_data[ivox];
          }
          ivox++;
        }
      }
    }
    tmp = model_ps[ii]->get_value(w_key) * 2. * params.get_inv_sigsq() *
          scalefac * params.get_normfac() / lower_comp;
    IMP_LOG_VERBOSE("for particle:" << ii << " (" << tdvx << "," << tdvy << ","
                                    << tdvz << ")" << std::endl);
    dv_out[ii][0] = tdvx * tmp;
    dv_out[ii][1] = tdvy * tmp;
    dv_out[ii][2] = tdvz * tmp;

  }  // particles
  return dv_out;
}
void DensitySegmentationByCommunities::build_density_graph(float edge_threshold)
{
  typedef compatibility::map<long, DGVertex> NMAP;
  NMAP voxel2node;
  typedef compatibility::map<DGVertex,long> NMAP2;
  NMAP2 node2voxel;
  int nx=dmap_->get_header()->get_nx();
  int ny=dmap_->get_header()->get_ny();
  int nz=dmap_->get_header()->get_nz();
  int ivox,ivox_z,ivox_zy;
  double *data=dmap_->get_data();
  float dens_val;
  DGVertex v,w;
  //add nodes (all voxels above a threshold
  for(int iz=0;iz<nz;iz++){
    ivox_z=iz * nx*ny;
  for(int iy=0;iy<ny;iy++){
    ivox_zy = ivox_z + iy * nx;
    for(int ix=0;ix<nx;ix++){
      ivox=ivox_zy+ix;
      dens_val=data[ivox];
      if (dens_val<dens_t_) continue;
      v=boost::add_vertex(g_);
      node2voxel_ind_.push_back(ivox);
      voxel2node[ivox]=v;
      node2voxel[v]=ivox;
    }}}

  //add edges(nodes corresponding to nieghboring voxels)
  int iminx,iminy,iminz,imaxx,imaxy,imaxz;
  int v_index;
  //  node_index_ = boost::get(boost::vertex_index, g_);

  for (std::pair<boost::graph_traits<DensityGraph>::vertex_iterator,
                 boost::graph_traits<DensityGraph>::vertex_iterator>
    be= boost::vertices(g_);
       be.first != be.second; ++be.first) {
    v=*be.first;
    v_index = node2voxel[v];
    calc_local_bounding_box(
            dmap_,v_index,
            iminx,iminy, iminz,
            imaxx,imaxy, imaxz);
    //get number of neighbors,if less than 3 it is a background
    int nn=0;
    for(int iz=iminz;iz<=imaxz;iz++){
      ivox_z=iz * nx*ny;
      for(int iy=iminy;iy<=imaxy;iy++){
        ivox_zy = ivox_z + iy * nx;
        for(int ix=iminx;ix<=imaxx;ix++){
          ivox=ivox_zy+ix;
          if (v_index==ivox) continue;
          if (voxel2node.find(ivox) == voxel2node.end()) continue;
          ++nn;}}}
    for(int iz=iminz;iz<=imaxz;iz++){
      ivox_z=iz * nx*ny;
      for(int iy=iminy;iy<=imaxy;iy++){
        ivox_zy = ivox_z + iy * nx;
          for(int ix=iminx;ix<=imaxx;ix++){
            ivox=ivox_zy+ix;
          if (v_index==ivox) continue;
            if (data[ivox]<0.000001) continue;
            if (voxel2node.find(ivox) == voxel2node.end()) continue;
            w=voxel2node[ivox];
            if (boost::edge(v,w,g_).second) continue;//edge exists
            //TODO - edge_threshold should be some fraction of var
            if (std::abs(data[v_index]-data[ivox])<edge_threshold){
              boost::add_edge(v,w,g_);
              weights_.push_back(std::abs(data[v_index]-data[ivox]));
            }
          }}}
  }
  IMP_LOG(TERSE,"Graph with "<<boost::num_vertices(g_)
          <<" vertices and " << boost::num_edges(g_)<<" edges"<< std::endl);
  IMP_LOG(TERSE,"dens t:"<<dens_t_<<std::endl);
}