int main(int argc, char ** argv) { invalid_argument er( "Bond angle correlation function\n" #ifdef use_periodic "Syntax : periodic_g6 [path]filename NbOfBins Nb dx dy dz [mode=0 [l=6]]\n" #else "Syntax : g6 [path]filename radius NbOfBins range [mode=0 [l=6 [zmin zmax]]]\n" " range is in diameter unit\n" #endif " mode\t0 raw boo\n" " \t1 coarse grained boo\n" ); try { if(argc<3) throw er; const string filename(argv[1]); const string inputPath = filename.substr(0,filename.find_last_of(".")); vector<size_t> inside; //construct the particle container out of the datafile #ifdef use_periodic if(argc<7) throw er; const size_t Nbins = atoi(argv[2]); const size_t Nb = atoi(argv[3]); double nbDiameterCutOff =atof(argv[4]); BoundingBox b; for(size_t d=0;d<3;++d) { b.edges[d].first=0.0; b.edges[d].second = atof(argv[4+d]); if(nbDiameterCutOff>b.edges[d].second) nbDiameterCutOff=b.edges[d].second; } nbDiameterCutOff /=4.0; const bool mode = (argc<8)?0:atoi(argv[7]); const size_t l = (argc<9)?6:atoi(argv[8]); PeriodicParticles Centers(Nb,b,filename,1.0); cout << "With periodic boundary conditions"<<endl; #else const double radius = atof(argv[2]), nbDiameterCutOff = atof(argv[4]); const size_t Nbins = atoi(argv[3]); const bool mode = (argc<6)?0:atoi(argv[5]); const size_t l = (argc<7)?6:atoi(argv[6]); Particles Centers(filename,radius); #endif cout << Centers.size() << " particles ... "; //read q6m vector<BooData> rawBoo, allBoo; Centers.load_qlm(inputPath+".qlm", rawBoo); if(mode) { Centers.makeNgbList(loadBonds(inputPath+".bonds")); //select all particles who's all neighbours' qlms are not null vector<size_t> second_inside; second_inside.reserve(Centers.size()); for(size_t p=0; p<Centers.getNgbList().size(); ++p) { bool hasNullNgb = false; for(size_t n=0; n<Centers.getNgbList()[p].size(); ++n) hasNullNgb = (hasNullNgb || rawBoo[Centers.getNgbList()[p][n]].isnull()); if(!hasNullNgb) second_inside.push_back(p); } cout<< second_inside.size()<< " have coarse grained qlms ... "; Centers.getCgBOOs(second_inside, rawBoo, allBoo); } else allBoo=rawBoo; #ifndef use_periodic vector<size_t> slab; slab.reserve(Centers.size()); //Case where we ask to discard all points out of the interval [zmin, zmax] if(argc>8) { const double zmin = atof(argv[7]), zmax = atof(argv[8]); //look for the particles that are in the slab and have non null qlm for(size_t p=0; p<Centers.size(); ++p) if(Centers[p][2]>zmin && Centers[p][2]<zmax && !allBoo[p].isnull()) slab.push_back(p); } else for(size_t p=0; p<Centers.size(); ++p) if(!allBoo[p].isnull()) slab.push_back(p); //reduce the centers list Particles cen; cen.radius = Centers.radius; cen.reserve(slab.size()); for(size_t p=0; p<slab.size(); ++p) cen.push_back(Centers[slab[p]]); Centers.swap(cen); Centers.delNgbList(); //reduce the qlm vector<BooData> boo(slab.size()); for(size_t p=0; p<slab.size(); ++p) boo[p] = allBoo[slab[p]]; allBoo.swap(boo); #endif vector<size_t> nb(Nbins, 0); vector<double> gl(Nbins, 0.0); const double maxdistsq = pow(2.0*nbDiameterCutOff, 2); for(size_t p=0; p<Centers.size(); ++p) for(size_t q=p+1; q<Centers.size(); ++q) { Coord diff = Centers.getDiff(p, q); const double distsq = (diff*diff).sum(); if(distsq<maxdistsq) { const size_t r = sqrt(distsq) / (2.0*nbDiameterCutOff) * Nbins; nb[r]++; gl[r] += allBoo[p].innerProduct(allBoo[q], l); } } cout << " done !" << endl; ostringstream rdffilename; rdffilename << inputPath << (mode?".cg":".g") << l; ofstream rdfFile(rdffilename.str().c_str(), ios::out | ios::trunc); rdfFile << "#r\tg"<<l<<"(r)\tg(r)"<<endl; for(size_t r=0; r<Nbins; ++r) rdfFile<< r/(double)Nbins*nbDiameterCutOff <<"\t"<< gl[r] <<"\t"<< nb[r] <<"\n"; //all particles are "inside" /*inside.reserve(Centers.size()); for(size_t p=0; p<Centers.size(); ++p) inside[p] = p; cout << Centers.size() << " inside ... "; Centers.makeRTreeIndex();*/ //create binner //Particles::GlBinner binner(Centers, Nbins, nbDiameterCutOff, allBoo, l); //select particles and bin them //vector<size_t> inside = Centers.selectInside(2.0*radius*(nbDiameterCutOff+(1+mode)*1.3/2)); //Case where we ask to discard all points out of the interval [zmin, zmax] /*if(argc>8) { const double zmin = atof(argv[7]), zmax = atof(argv[8]); //cout<<"\tl="<<l<<"\tzmin="<<zmin<<"\tzmax="<<zmax; vector<size_t> in; in.reserve(inside.size()); for(vector<size_t>::const_iterator p=inside.begin(); p!=inside.end(); ++p) if(Centers[*p][2]>=zmin && Centers[*p][2]<=zmax) in.push_back(*p); in.swap(inside); }*/ /*binner << inside; //binner.normalize(inside.size()); cout << " done !" << endl; ostringstream rdffilename; rdffilename << inputPath << (mode?".cg":".g") << l; ofstream rdfFile(rdffilename.str().c_str(), ios::out | ios::trunc); rdfFile << "#r\tg"<<l<<"(r)\tg(r)"<<endl; for(size_t r=0; r<Nbins; ++r) rdfFile<< r/(double)Nbins*nbDiameterCutOff <<"\t"<< binner.gl[r] <<"\t"<< binner.g[r] <<"\n";*/ } catch(const std::exception &e) { cerr<<e.what() << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
void WaterSimApp::resetParticles() { particles->clear_particles(); }
void add(Particle *p) { particles.push_back(p); }
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 ¶ms = 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 PusherPonderomotivePositionBorisV::operator()( Particles &particles, SmileiMPI *smpi, int istart, int iend, int ithread, int ipart_ref ) { /////////// not vectorized std::vector<double> *Phi_mpart = &( smpi->dynamics_PHI_mpart[ithread] ); std::vector<double> *GradPhi_mpart = &( smpi->dynamics_GradPHI_mpart[ithread] ); double charge_sq_over_mass_dts4, charge_over_mass_sq; double gamma0, gamma0_sq, gamma_ponderomotive; double pxsm, pysm, pzsm; //int* cell_keys; double *momentum[3]; for( int i = 0 ; i<3 ; i++ ) { momentum[i] = &( particles.momentum( i, 0 ) ); } double *position[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position[i] = &( particles.position( i, 0 ) ); } #ifdef __DEBUG double *position_old[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i] = &( particles.position_old( i, 0 ) ); } #endif short *charge = &( particles.charge( 0 ) ); int nparts = GradPhi_mpart->size()/3; double *Phi_m = &( ( *Phi_mpart )[0*nparts] ); double *GradPhi_mx = &( ( *GradPhi_mpart )[0*nparts] ); double *GradPhi_my = &( ( *GradPhi_mpart )[1*nparts] ); double *GradPhi_mz = &( ( *GradPhi_mpart )[2*nparts] ); //particles.cell_keys.resize(nparts); //cell_keys = &( particles.cell_keys[0]); #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { // begin loop on particles // ! ponderomotive force is proportional to charge squared and the field is divided by 4 instead of 2 charge_sq_over_mass_dts4 = ( double )( charge[ipart] )*( double )( charge[ipart] )*one_over_mass_*dts4; // (charge over mass)^2 charge_over_mass_sq = ( double )( charge[ipart] )*one_over_mass_*( charge[ipart] )*one_over_mass_; // compute initial ponderomotive gamma gamma0_sq = 1. + momentum[0][ipart]*momentum[0][ipart] + momentum[1][ipart]*momentum[1][ipart] + momentum[2][ipart]*momentum[2][ipart] + ( *( Phi_m+ipart-ipart_ref ) )*charge_over_mass_sq; gamma0 = sqrt( gamma0_sq ) ; // ponderomotive force for ponderomotive gamma advance (Grad Phi is interpolated in time, hence the division by 2) pxsm = charge_sq_over_mass_dts4 * ( *( GradPhi_mx+ipart-ipart_ref ) ) / gamma0_sq ; pysm = charge_sq_over_mass_dts4 * ( *( GradPhi_my+ipart-ipart_ref ) ) / gamma0_sq ; pzsm = charge_sq_over_mass_dts4 * ( *( GradPhi_mz+ipart-ipart_ref ) ) / gamma0_sq ; // update of gamma ponderomotive gamma_ponderomotive = gamma0 + ( pxsm*momentum[0][ipart]+pysm*momentum[1][ipart]+pzsm*momentum[2][ipart] ) ; // Move the particle #ifdef __DEBUG for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i][ipart] = position[i][ipart]; } #endif for( int i = 0 ; i<nDim_ ; i++ ) { position[i][ipart] += dt*momentum[i][ipart]/gamma_ponderomotive; } } // end loop on particles //#pragma omp simd //for (int ipart=0 ; ipart<nparts; ipart++ ) { // // for ( int i = 0 ; i<nDim_ ; i++ ){ // cell_keys[ipart] *= nspace[i]; // cell_keys[ipart] += round( (position[i][ipart]-min_loc_vec[i]) * dx_inv_[i] ); // } // //} // end loop on particles }
// --------------------------------------------------------------------------------------------------------------------- //! Project charge : frozen & diagFields timstep // --------------------------------------------------------------------------------------------------------------------- void Projector2D4Order::basic( double *rhoj, Particles &particles, unsigned int ipart, unsigned int type ) { //Warning : this function is used for frozen species or initialization only and doesn't use the standard scheme. //rho type = 0 //Jx type = 1 //Jy type = 2 //Jz type = 3 int iloc; int ny( nprimy ); // (x,y,z) components of the current density for the macro-particle double charge_weight = inv_cell_volume * ( double )( particles.charge( ipart ) )*particles.weight( ipart ); if( type > 0 ) { charge_weight *= 1./sqrt( 1.0 + particles.momentum( 0, ipart )*particles.momentum( 0, ipart ) + particles.momentum( 1, ipart )*particles.momentum( 1, ipart ) + particles.momentum( 2, ipart )*particles.momentum( 2, ipart ) ); if( type == 1 ) { charge_weight *= particles.momentum( 0, ipart ); } else if( type == 2 ) { charge_weight *= particles.momentum( 1, ipart ); ny ++; } else { charge_weight *= particles.momentum( 2, ipart ); } } // variable declaration double xpn, ypn; double delta, delta2, delta3, delta4; // arrays used for the Esirkepov projection method double Sx1[7], Sy1[7]; for( unsigned int i=0; i<7; i++ ) { Sx1[i] = 0.; Sy1[i] = 0.; } // -------------------------------------------------------- // Locate particles & Calculate Esirkepov coef. S, DS and W // -------------------------------------------------------- // locate the particle on the primal grid at current time-step & calculate coeff. S1 xpn = particles.position( 0, ipart ) * dx_inv_; int ip = round( xpn + 0.5 * ( type==1 ) ); // index of the central node delta = xpn - ( double )ip; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sx1[1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sx1[2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx1[3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sx1[4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx1[5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; ypn = particles.position( 1, ipart ) * dy_inv_; int jp = round( ypn + 0.5*( type==2 ) ); delta = ypn - ( double )jp; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sy1[1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sy1[2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy1[3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sy1[4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy1[5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; // --------------------------- // Calculate the total current // --------------------------- ip -= i_domain_begin + 3; jp -= j_domain_begin + 3; for( unsigned int i=0 ; i<7 ; i++ ) { iloc = ( i+ip )*ny+jp; for( unsigned int j=0 ; j<7 ; j++ ) { rhoj[iloc+j] += charge_weight * Sx1[i]*Sy1[j]; } }//i }
unsigned int _take_particles(const Particles &ps) { for (unsigned int i = 0; i < ps.size(); ++i) { IMP_CHECK_OBJECT(ps[i]); } return ps.size(); }
ParticleIndexesAdaptor::ParticleIndexesAdaptor(const Particles &ps) : tmp_(new ParticleIndexes(ps.size())), val_(tmp_.get()) { *tmp_ = get_indexes(ParticlesTemp(ps.begin(), ps.end())); }
// --------------------------------------------------------------------------------------------------------------------- // 2nd Order Interpolation of the fields at a the particle position (3 nodes are used) // --------------------------------------------------------------------------------------------------------------------- void Interpolator2D1Order::operator() (ElectroMagn* EMfields, Particles &particles, int ipart, LocalFields* ELoc, LocalFields* BLoc) { // Static cast of the electromagnetic fields Field2D* Ex2D = static_cast<Field2D*>(EMfields->Ex_); Field2D* Ey2D = static_cast<Field2D*>(EMfields->Ey_); Field2D* Ez2D = static_cast<Field2D*>(EMfields->Ez_); Field2D* Bx2D = static_cast<Field2D*>(EMfields->Bx_m); Field2D* By2D = static_cast<Field2D*>(EMfields->By_m); Field2D* Bz2D = static_cast<Field2D*>(EMfields->Bz_m); // Normalized particle position double xpn = particles.position(0, ipart)*dx_inv_; double ypn = particles.position(1, ipart)*dy_inv_; // Indexes of the central nodes ip_ = floor(xpn); jp_ = floor(ypn); // Declaration and calculation of the coefficient for interpolation double delta; delta = xpn - (double)ip_; coeffxp_[0] = 1.0 - delta; coeffxp_[1] = delta; delta = ypn - (double)jp_; coeffyp_[0] = 1.0 - delta; coeffyp_[1] = delta; //!\todo CHECK if this is correct for both primal & dual grids !!! // First index for summation ip_ = ip_ - i_domain_begin; jp_ = jp_ - j_domain_begin; // ------------------------- // Interpolation of Ex^(d,p) // ------------------------- (*ELoc).x = compute( coeffxp_, coeffyp_, Ex2D, ip_, jp_); // ------------------------- // Interpolation of Ey^(p,d) // ------------------------- (*ELoc).y = compute( coeffxp_, coeffyp_, Ey2D, ip_, jp_); // ------------------------- // Interpolation of Ez^(p,p) // ------------------------- (*ELoc).z = compute( coeffxp_, coeffyp_, Ez2D, ip_, jp_); // ------------------------- // Interpolation of Bx^(p,d) // ------------------------- (*BLoc).x = compute( coeffxp_, coeffyp_, Bx2D, ip_, jp_); // ------------------------- // Interpolation of By^(d,p) // ------------------------- (*BLoc).y = compute( coeffxp_, coeffyp_, By2D, ip_, jp_); // ------------------------- // Interpolation of Bz^(d,d) // ------------------------- (*BLoc).z = compute( coeffxp_, coeffyp_, Bz2D, ip_, jp_); } // END Interpolator2D1Order
//---------------------------------------------------------------------------- void ParticleSystems::CreateScene () { mScene = new0 Node(); mWireState = new0 WireState(); mRenderer->SetOverrideWireState(mWireState); VertexFormat* vformat = VertexFormat::Create(2, VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0, VertexFormat::AU_TEXCOORD, VertexFormat::AT_FLOAT2, 0); int vstride = vformat->GetStride(); const int numParticles = 32; VertexBuffer* vbuffer = new0 VertexBuffer(4*numParticles, vstride); Float4* positionSizes = new1<Float4>(numParticles); for (int i = 0; i < numParticles; ++i) { positionSizes[i][0] = Mathf::SymmetricRandom(); positionSizes[i][1] = Mathf::SymmetricRandom(); positionSizes[i][2] = Mathf::SymmetricRandom(); positionSizes[i][3] = 0.25f*Mathf::UnitRandom(); } Particles* particles = new0 Particles(vformat, vbuffer, sizeof(int), positionSizes, 1.0f); particles->AttachController(new0 BloodCellController()); mScene->AttachChild(particles); // Create an image with transparency. const int xsize = 32, ysize = 32; Texture2D* texture = new0 Texture2D(Texture::TF_A8R8G8B8, xsize, ysize, 1); unsigned char* data = (unsigned char*)texture->GetData(0); float factor = 1.0f/(xsize*xsize + ysize*ysize); for (int y = 0, i = 0; y < ysize; ++y) { for (int x = 0; x < xsize; ++x) { // The image is red. data[i++] = 0; data[i++] = 0; data[i++] = 255; // Semitransparent within a disk, dropping off to zero outside the // disk. int dx = 2*x - xsize; int dy = 2*y - ysize; float value = factor*(dx*dx + dy*dy); if (value < 0.125f) { value = Mathf::Cos(4.0f*Mathf::PI*value); } else { value = 0.0f; } data[i++] = (unsigned char)(255.0f*value); } } Texture2DEffect* effect = new0 Texture2DEffect(Shader::SF_LINEAR); effect->GetAlphaState(0, 0)->BlendEnabled = true; effect->GetDepthState(0, 0)->Enabled = false; particles->SetEffectInstance(effect->CreateInstance(texture)); }
void MapModel::verifyPoses(Particles& particles){ double minX, minY, minZ, maxX, maxY, maxZ; m_map->getMetricMin(minX, minY, minZ); m_map->getMetricMax(maxX, maxY, maxZ); // find min. particle weight: double minWeight = std::numeric_limits<double>::max(); for (Particles::iterator it = particles.begin(); it != particles.end(); ++it) { if (it->weight < minWeight) minWeight = it->weight; } minWeight -= 200; unsigned numWall = 0; unsigned numOut = 0; unsigned numMotion = 0; // TODO possible speedup: cluster particles by grid voxels first? // iterate over samples, multi-threaded: #pragma omp parallel for for (unsigned i = 0; i < particles.size(); ++i){ octomap::point3d position(particles[i].pose.getOrigin().getX(), particles[i].pose.getOrigin().getY(), particles[i].pose.getOrigin().getZ()); // see if outside of map bounds: if (position(0) < minX || position(0) > maxX || position(1) < minY || position(1) > maxY || position(2) < minZ || position(2) > maxZ) { particles[i].weight = minWeight; #pragma omp atomic numOut++; } else { // see if occupied cell: if (this->isOccupied(position)){ particles[i].weight = minWeight; #pragma omp atomic numWall++; } else { // see if current pose is a valid walking pose: // TODO: need to check height over floor! if (m_motionRangeZ >= 0.0 && std::abs(particles[i].pose.getOrigin().getZ() - m_motionMeanZ) > m_motionRangeZ) { particles[i].weight = minWeight; #pragma omp atomic numMotion++; } else if (m_motionRangePitch >= 0.0 || m_motionRangeRoll >= 0.0){ double yaw, pitch, roll; particles[i].pose.getBasis().getRPY(roll, pitch, yaw); if ((m_motionRangePitch >= 0.0 && std::abs(pitch) > m_motionRangePitch) || (m_motionRangeRoll >= 0.0 && std::abs(roll) > m_motionRangeRoll)) { particles[i].weight = minWeight; #pragma omp atomic numMotion++; } } } } } // end loop over particles if (numWall > 0 || numOut > 0 || numMotion > 0){ ROS_INFO("Particle weights minimized: %d out of map, %d in obstacles, %d out of motion range", numOut, numWall, numMotion); } if (numOut + numWall >= particles.size()){ ROS_WARN("All particles are out of the valid map area or in obstacles!"); } }
Field TriCubicHermite::scalarCurl2D( const Particles& aParticles ) const { assert(data->nDim() == 2); Field result("n/a","n/a", 1, aParticles.N()); return result; };
Field TriCubicHermite::vectorDivergence( const Particles& aParticles ) const { assert(data->nDim() == 2); Field result("n/a","n/a", 1, aParticles.N()); return result; };
void FMM_load_balance(string file, int nbParticles, double dist, double tolerance, double maxEdge, int LBStrategy) { int size; MPI_Comm_size(MPI_COMM_WORLD,&size); decompo nb1ers(size); int first = 0; int last = nbParticles-1; vec3D center(0,0,0); Node<Particles> * treeHead = nullptr; Gaspi_communicator * gComm = nullptr; // tree creation Particles p; if ( LBStrategy == HIST_EXACT || LBStrategy == HIST_APPROX || LBStrategy == MORTON_MPI_SYNC) { p.loadCoordinatesASCII(nbParticles, file); } else { gComm = new Gaspi_communicator(512, nbParticles); p.loadCoordinatesASCII(nbParticles, file, gComm); } p.scale(); treeHead = new Node<Particles>(p); // Node Owners array i64 * nodeOwners = nullptr; // Load Balancing LB_Base * LBB = nullptr; switch (LBStrategy) { case HIST_EXACT : cout <<"--> Exact Histograms" << endl; LBB = new LoadBalancer<Particles, HistExact> (treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case HIST_APPROX : cout <<"--> Approx Histograms" << endl; LBB = new LoadBalancer<Particles, HistApprox> (treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case MORTON_MPI_SYNC : cout <<"--> Morton DFS, with tolerance : " << tolerance << endl; LBB = new LoadBalancer<Particles, MortonSyncMPI>(treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; case MORTON_GASPI_ASYNC : cout <<"--> Morton DFS Async, with tolerance : " << tolerance << endl; LBB = new LoadBalancer<Particles, MortonAsyncGASPI>(treeHead, nb1ers, dist, tolerance, first, last, maxEdge, center, gComm, nullptr, nodeOwners, 0); LBB->run(); break; default : cerr << "No load balancing strategy detected !"; exit(5); } }
// --------------------------------------------------------------------------------------------------------------------- //! Project current densities : main projector // --------------------------------------------------------------------------------------------------------------------- void Projector1D4Order::currents( double *Jx, double *Jy, double *Jz, Particles &particles, unsigned int ipart, double invgf, int *iold, double *delta ) { // Declare local variables int ipo, ip; int ip_m_ipo; double charge_weight = inv_cell_volume * ( double )( particles.charge( ipart ) )*particles.weight( ipart ); double xjn, xj_m_xipo, xj_m_xipo2, xj_m_xipo3, xj_m_xipo4, xj_m_xip, xj_m_xip2, xj_m_xip3, xj_m_xip4; double crx_p = charge_weight*dx_ov_dt; // current density for particle moving in the x-direction double cry_p = charge_weight*particles.momentum( 1, ipart )*invgf; // current density in the y-direction of the macroparticle double crz_p = charge_weight*particles.momentum( 2, ipart )*invgf; // current density allow the y-direction of the macroparticle double S0[7], S1[7], Wl[7], Wt[7], Jx_p[7]; // arrays used for the Esirkepov projection method // Initialize variables for( unsigned int i=0; i<7; i++ ) { S0[i]=0.; S1[i]=0.; Wl[i]=0.; Wt[i]=0.; Jx_p[i]=0.; }//i // Locate particle old position on the primal grid xj_m_xipo = *delta; // normalized distance to the nearest grid point xj_m_xipo2 = xj_m_xipo * xj_m_xipo; // square of the normalized distance to the nearest grid point xj_m_xipo3 = xj_m_xipo2 * xj_m_xipo; // cube of the normalized distance to the nearest grid point xj_m_xipo4 = xj_m_xipo3 * xj_m_xipo; // 4th power of the normalized distance to the nearest grid point // Locate particle new position on the primal grid xjn = particles.position( 0, ipart ) * dx_inv_; ip = round( xjn ); // index of the central node xj_m_xip = xjn - ( double )ip; // normalized distance to the nearest grid point xj_m_xip2 = xj_m_xip * xj_m_xip; // square of the normalized distance to the nearest grid point xj_m_xip3 = xj_m_xip2 * xj_m_xip; // cube of the normalized distance to the nearest grid point xj_m_xip4 = xj_m_xip3 * xj_m_xip; // 4th power of the normalized distance to the nearest grid point // coefficients 4th order interpolation on 5 nodes S0[1] = dble_1_ov_384 - dble_1_ov_48 * xj_m_xipo + dble_1_ov_16 * xj_m_xipo2 - dble_1_ov_12 * xj_m_xipo3 + dble_1_ov_24 * xj_m_xipo4; S0[2] = dble_19_ov_96 - dble_11_ov_24 * xj_m_xipo + dble_1_ov_4 * xj_m_xipo2 + dble_1_ov_6 * xj_m_xipo3 - dble_1_ov_6 * xj_m_xipo4; S0[3] = dble_115_ov_192 - dble_5_ov_8 * xj_m_xipo2 + dble_1_ov_4 * xj_m_xipo4; S0[4] = dble_19_ov_96 + dble_11_ov_24 * xj_m_xipo + dble_1_ov_4 * xj_m_xipo2 - dble_1_ov_6 * xj_m_xipo3 - dble_1_ov_6 * xj_m_xipo4; S0[5] = dble_1_ov_384 + dble_1_ov_48 * xj_m_xipo + dble_1_ov_16 * xj_m_xipo2 + dble_1_ov_12 * xj_m_xipo3 + dble_1_ov_24 * xj_m_xipo4; // coefficients 2nd order interpolation on 5 nodes ipo = *iold; // index of the central node ip_m_ipo = ip-ipo-index_domain_begin; S1[ip_m_ipo+1] = dble_1_ov_384 - dble_1_ov_48 * xj_m_xip + dble_1_ov_16 * xj_m_xip2 - dble_1_ov_12 * xj_m_xip3 + dble_1_ov_24 * xj_m_xip4; S1[ip_m_ipo+2] = dble_19_ov_96 - dble_11_ov_24 * xj_m_xip + dble_1_ov_4 * xj_m_xip2 + dble_1_ov_6 * xj_m_xip3 - dble_1_ov_6 * xj_m_xip4; S1[ip_m_ipo+3] = dble_115_ov_192 - dble_5_ov_8 * xj_m_xip2 + dble_1_ov_4 * xj_m_xip4; S1[ip_m_ipo+4] = dble_19_ov_96 + dble_11_ov_24 * xj_m_xip + dble_1_ov_4 * xj_m_xip2 - dble_1_ov_6 * xj_m_xip3 - dble_1_ov_6 * xj_m_xip4; S1[ip_m_ipo+5] = dble_1_ov_384 + dble_1_ov_48 * xj_m_xip + dble_1_ov_16 * xj_m_xip2 + dble_1_ov_12 * xj_m_xip3 + dble_1_ov_24 * xj_m_xip4; // coefficients used in the Esirkepov method for( unsigned int i=0; i<7; i++ ) { Wl[i] = S0[i] - S1[i]; // for longitudinal current (x) Wt[i] = 0.5 * ( S0[i] + S1[i] ); // for transverse currents (y,z) }//i // local current created by the particle // calculate using the charge conservation equation for( unsigned int i=1; i<7; i++ ) { Jx_p[i] = Jx_p[i-1] + crx_p * Wl[i-1]; } ipo -= 3 ; // 4th order projection for the total currents & charge density // At the 4th order, oversize = 3. for( unsigned int i=0; i<7; i++ ) { Jx[i + ipo] += Jx_p[i]; Jy[i + ipo] += cry_p * Wt[i]; Jz[i + ipo] += crz_p * Wt[i]; }//i }
Particle& GetOrigin(){ return *(*m_particles.begin() ); }
Particles ResamplingResidual::resample(Particles* particles){ Particles resampledSet; Particles stage1; int count = 0; resampledSet.samples = fmat(particles->samples.n_rows,particles->samples.n_cols); resampledSet.weights = frowvec(particles->weights.n_cols); fvec cumsum; fvec random; unsigned int number = particles->samples.n_cols; unsigned int numberOfStage1 = 0; // Generating copie information of every particle ivec copies = zeros<ivec>(particles->samples.n_cols); for (unsigned int i=0;i<particles->samples.n_cols;++i){ copies = (int) floor(number*particles->weights(i)); } numberOfStage1 = sum(copies); stage1.samples = fmat(particles->samples.n_rows,numberOfStage1); stage1.weights = frowvec(numberOfStage1); //Picking N_i = N*w_i copies of i-th particle for (unsigned int i=1; i < copies.n_rows;++i){ for (int j=0;j<copies(i);++j){ for (unsigned int k=0;k<particles->samples.n_rows;++k){ stage1.samples(k,count) = particles->samples(k,i); } stage1.weights(count) = particles->weights(i) - (float)copies(i)/number; count++; } } // multinomial resampling with residuum weights w_i = w_i - N_i/N cumsum = zeros<fvec>(numberOfStage1); for (unsigned int i=1; i < stage1.weights.n_cols;++i){ cumsum(i) = cumsum(i-1) + stage1.weights(i); } // generate sorted random set random = randu<fvec>(numberOfStage1); random=random*cumsum(cumsum.n_rows-1); random = sort(random); for (unsigned int j=0; j < random.n_rows; ++j){ for (unsigned int i=0 ; i < cumsum.n_rows; ++i){ if (random(j) <= cumsum(i)){ if(i > 0){ if(random(j) >= cumsum(i-1)) { for (unsigned int k=0;k<stage1.samples.n_rows;++k){ resampledSet.samples(k,j) = stage1.samples(k,i); assignmentVec.push_back(i); } break; } } else { for (unsigned int k=0; k<stage1.samples.n_rows; ++k){ resampledSet.samples(k,j) = stage1.samples(k,i); assignmentVec.push_back(i); } break; } } // Normalize weights resampledSet.weights(j) = 1.0f/particles->weights.n_cols; } } return resampledSet; }
Particle& GetEnd(){ return *(*m_particles.end() ); }
// --------------------------------------------------------------------------------------------------------------------- //! Project current densities : main projector // --------------------------------------------------------------------------------------------------------------------- void Projector2D4Order::currents( double *Jx, double *Jy, double *Jz, Particles &particles, unsigned int ipart, double invgf, int *iold, double *deltaold ) { int nparts = particles.size(); // ------------------------------------- // Variable declaration & initialization // ------------------------------------- int iloc; // (x,y,z) components of the current density for the macro-particle double charge_weight = inv_cell_volume * ( double )( particles.charge( ipart ) )*particles.weight( ipart ); double crx_p = charge_weight*dx_ov_dt; double cry_p = charge_weight*dy_ov_dt; double crz_p = charge_weight*one_third*particles.momentum( 2, ipart )*invgf; // variable declaration double xpn, ypn; double delta, delta2, delta3, delta4; // arrays used for the Esirkepov projection method double Sx0[7], Sx1[7], Sy0[7], Sy1[7], DSx[7], DSy[7], tmpJx[7]; for( unsigned int i=0; i<7; i++ ) { Sx1[i] = 0.; Sy1[i] = 0.; tmpJx[i] = 0.; } Sx0[0] = 0.; Sx0[6] = 0.; Sy0[0] = 0.; Sy0[6] = 0.; // -------------------------------------------------------- // Locate particles & Calculate Esirkepov coef. S, DS and W // -------------------------------------------------------- // locate the particle on the primal grid at former time-step & calculate coeff. S0 delta = deltaold[0*nparts]; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sx0[1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sx0[2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx0[3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sx0[4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx0[5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; delta = deltaold[1*nparts]; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sy0[1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sy0[2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy0[3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sy0[4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy0[5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; // locate the particle on the primal grid at current time-step & calculate coeff. S1 xpn = particles.position( 0, ipart ) * dx_inv_; int ip = round( xpn ); int ipo = iold[0*nparts]; int ip_m_ipo = ip-ipo-i_domain_begin; delta = xpn - ( double )ip; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sx1[ip_m_ipo+1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sx1[ip_m_ipo+2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx1[ip_m_ipo+3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sx1[ip_m_ipo+4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sx1[ip_m_ipo+5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; ypn = particles.position( 1, ipart ) * dy_inv_; int jp = round( ypn ); int jpo = iold[1*nparts]; int jp_m_jpo = jp-jpo-j_domain_begin; delta = ypn - ( double )jp; delta2 = delta*delta; delta3 = delta2*delta; delta4 = delta3*delta; Sy1[jp_m_jpo+1] = dble_1_ov_384 - dble_1_ov_48 * delta + dble_1_ov_16 * delta2 - dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; Sy1[jp_m_jpo+2] = dble_19_ov_96 - dble_11_ov_24 * delta + dble_1_ov_4 * delta2 + dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy1[jp_m_jpo+3] = dble_115_ov_192 - dble_5_ov_8 * delta2 + dble_1_ov_4 * delta4; Sy1[jp_m_jpo+4] = dble_19_ov_96 + dble_11_ov_24 * delta + dble_1_ov_4 * delta2 - dble_1_ov_6 * delta3 - dble_1_ov_6 * delta4; Sy1[jp_m_jpo+5] = dble_1_ov_384 + dble_1_ov_48 * delta + dble_1_ov_16 * delta2 + dble_1_ov_12 * delta3 + dble_1_ov_24 * delta4; for( unsigned int i=0; i < 7; i++ ) { DSx[i] = Sx1[i] - Sx0[i]; DSy[i] = Sy1[i] - Sy0[i]; } // calculate Esirkepov coeff. Wx, Wy, Wz when used double tmp, tmp2, tmp3, tmpY; //Do not compute useless weights. // ------------------------------------------------ // Local current created by the particle // calculate using the charge conservation equation // ------------------------------------------------ // --------------------------- // Calculate the total current // --------------------------- ipo -= 3; //This minus 3 come from the order 4 scheme, based on a 7 points stencil from -3 to +3. jpo -= 3; // i =0 { iloc = ipo*nprimy+jpo; tmp2 = 0.5*Sx1[0]; tmp3 = Sx1[0]; Jz[iloc] += crz_p * ( Sy1[0]*tmp3 ); tmp = 0; tmpY = Sx0[0] + 0.5*DSx[0]; for( unsigned int j=1 ; j<7 ; j++ ) { tmp -= cry_p * DSy[j-1] * tmpY; Jy[iloc+j+ipo] += tmp; //Because size of Jy in Y is nprimy+1. Jz[iloc+j] += crz_p * ( Sy0[j]*tmp2 + Sy1[j]*tmp3 ); } }//i for( unsigned int i=1 ; i<7 ; i++ ) { iloc = ( i+ipo )*nprimy+jpo; tmpJx[0] -= crx_p * DSx[i-1] * ( 0.5*DSy[0] ); Jx[iloc] += tmpJx[0]; tmp2 = 0.5*Sx1[i] + Sx0[i]; tmp3 = 0.5*Sx0[i] + Sx1[i]; Jz[iloc] += crz_p * ( Sy1[0]*tmp3 ); tmp = 0; tmpY = Sx0[i] + 0.5*DSx[i]; for( unsigned int j=1 ; j<7 ; j++ ) { tmpJx[j] -= crx_p * DSx[i-1] * ( Sy0[j] + 0.5*DSy[j] ); Jx[iloc+j] += tmpJx[j]; tmp -= cry_p * DSy[j-1] * tmpY; Jy[iloc+j+i+ipo] += tmp; //Because size of Jy in Y is nprimy+1. Jz[iloc+j] += crz_p * ( Sy0[j]*tmp2 + Sy1[j]*tmp3 ); } }//i }
void calculateBoo(Particles &parts, const string& filename, const bool noZ=false, bool quiet=false) { const string inputPath = filename.substr(0,filename.find_last_of(".")); const string ext = filename.substr(filename.find_last_of(".")+1); const string head = filename.substr(0,filename.rfind("_t")); const string neck = filename.substr(head.size(), inputPath.size()-head.size()); //select interesting particles and load (or make) bonds vector<size_t> inside, secondInside; try { BondSet bonds = loadBonds(inputPath+".bonds"); parts.makeNgbList(bonds); inside = parts.selectInside_noindex(1.3*parts.radius, noZ); secondInside = parts.selectInside_noindex(2.0*1.3*parts.radius, noZ); } catch(invalid_argument &e) { if(!quiet) cout<<"bond network "; boost::progress_timer *ti; if(!quiet) ti = new boost::progress_timer(); parts.makeRTreeIndex(); parts.makeNgbList(1.3); BondSet bonds = parts.getBonds(); ofstream bondFile((inputPath+".bonds").c_str(), ios::out | ios::trunc); for(BondSet::const_iterator b=bonds.begin(); b!= bonds.end();++b) bondFile<<b->low()<<" "<<b->high()<<"\n"; inside = parts.selectInside(1.3*parts.radius, noZ); secondInside = parts.selectInside(2.0*1.3*parts.radius, noZ); if(!quiet) delete ti; } const bool empty = inside.empty(), empty2 = secondInside.empty(); if(empty) for(size_t p=0; p<parts.size(); ++p) inside.insert(inside.end(), p); if(empty2) for(size_t p=0; p<parts.size(); ++p) secondInside.insert(secondInside.end(), p); //calculate and export qlm vector<BooData> qlm, qlm_cg, qlm_sf; { boost::progress_timer *ti; if(!quiet) { cout<<"boo with and without surface bonds for "<<inside.size()<<" particles "; ti = new boost::progress_timer(); } parts.getBOOs_SurfBOOs(qlm, qlm_sf); if(!empty) { parts.removeOutside(inside, qlm); parts.removeOutside(inside, qlm_sf); } if(!quiet) delete ti; } { if(!quiet) cout<<"coarse grained for "<<secondInside.size()<<" particles "; boost::progress_timer* ti; if(!quiet) ti = new boost::progress_timer(); parts.getCgBOOs(secondInside, qlm, qlm_cg); if(!quiet) delete ti; } ofstream qlmFile((inputPath+".qlm").c_str(), ios::out | ios::trunc); copy( qlm.begin(), qlm.end(), ostream_iterator<BooData>(qlmFile,"\n") ); qlmFile.close(); ofstream qlmcgFile((head+"_space"+neck+".qlm").c_str(), ios::out | ios::trunc); copy( qlm_cg.begin(), qlm_cg.end(), ostream_iterator<BooData>(qlmcgFile,"\n") ); qlmcgFile.close(); //calculate and export invarients ofstream cloudFile((inputPath+".cloud").c_str(), ios::out | ios::trunc); cloudFile<<"#q4\tq6\tq8\tq10\tw4\tw6\tw8\tw10"<<endl; transform( qlm.begin(), qlm.end(), ostream_iterator<string>(cloudFile,"\n"), cloud_exporter() ); cloudFile.close(); ofstream cloud_cgFile((head+"_space"+neck+".cloud").c_str(), ios::out | ios::trunc); cloud_cgFile<<"#Q4\tQ6\tQ8\tQ10\tW4\tW6\tW8\tW10"<<endl; transform( qlm_cg.begin(), qlm_cg.end(), ostream_iterator<string>(cloud_cgFile,"\n"), cloud_exporter() ); cloud_cgFile.close(); ofstream cloud_sfFile((head+"_surf"+neck+".cloud").c_str(), ios::out | ios::trunc); cloud_cgFile<<"#Q4\tQ6\tW4\tW6"<<endl; transform( qlm_sf.begin(), qlm_sf.end(), ostream_iterator<string>(cloud_sfFile,"\n"), cloud_exporter() ); cloud_sfFile.close(); }
unsigned int _take_particles(Model *, const Particles &ps, base::TextOutput) { for (unsigned int i = 0; i < ps.size(); ++i) { IMP_CHECK_OBJECT(ps[i]); } return ps.size(); }
/** * This function * @param * nbElemPerNode : Array of number of elements, per octree node * @param * firstElemAdress : Array of Indexes. * Gives the index(address) first element's data in the Id's array fmmData%elem, per octree node. * @param * nbSonsPerNode : Array of number of sons, per octree node * @param * firstSonId : Array of number of first son Id, per octree node * @param * nodeOwners : Array of responsible mpi ranks, per octree node. (From 1 to nbRanks, Fortran's style) * The Result of the load balancing is read here. * @param * nodeCenters : Array of octree node centers * @param * endlev : Array of last octree node id, per octree level * @param * nbLevels : Number of Octree levels * @param * maxEdge : Edge of the first octree node. (the biggest) * @param *LBstrategy : integer used to choose the load balancing strategy */ void fmm_load_balance_( i64 * nbElemPerNode, i64 * firstElemAdress, i64 * nbSonsPerNode, i64 * firstSonId, i64 * nodeOwners, double * nodeCenters, i64 * endlev, i64 * nbLevels, double * maxEdge, int * LBstrategy) { // MPI parameters int size; MPI_Comm_size(MPI_COMM_WORLD, &size); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); // create Particles vec3D center(nodeCenters[0], nodeCenters[1], nodeCenters[2]); scale(center); Particles p; p.setAttributes(0,nbElemPerNode[0],*maxEdge, center); int nbElements = nbElemPerNode[0]; p.setNewCoordinates(elements, nbElements); p.scale(); // creatre Octree Node<Particles> * octree = nullptr; octree = new Node<Particles>(p); octree -> read_octree(nbElemPerNode, firstElemAdress, nbSonsPerNode, firstSonId, nodeCenters); // Octree useful characteristics int height = (*nbLevels) - 1; int nbLeaves = endlev[height] - endlev[height-1]; int firstLeave = endlev[height-1]; // endlev[height-1] +1(next node) -1(F to C) int firstElem = 0; int lastElem = nbElemPerNode[0]-1; int nbNodes = endlev[height]*3; double * centers = new double[nbNodes]; // Load Balancing useful parameters decompo nb1ers(size); // Load Balance LB_Base * LBB = nullptr; switch (*LBstrategy) { case MORTON_MPI_SYNC : cout << "*** ----- MORTON -----" << endl; LBB = new LoadBalancer<Particles, MortonSyncMPI>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, nullptr/*centers*/, nodeOwners, 0); break; case HIST_APPROX : cout << "*** ----- KD TREE -----" << endl; // Get a copy of the octree centers, scale them and apply load balancing strategy copyAndScaleArray(nodeCenters, centers, nbNodes); LBB = new LoadBalancer<Particles, HistApprox>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, ¢ers[firstLeave*3], &nodeOwners[firstLeave], nbLeaves); break; case HIST_APPROX_X : cout << "*** ----- SAUCISONNAGE EN X -----" << endl; // Get a copy of the octree centers, scale them and apply load balancing strategy copyAndScaleArray(nodeCenters, centers, nbNodes); // test rapide - saucissonnage en X cout << "Decomposition has been modified to : " << endl; nb1ers._list.resize(1); nb1ers._list[0] = size; nb1ers.display(); LBB = new LoadBalancer<Particles, HistApprox>(octree, nb1ers, 0, 0, firstElem, lastElem, *maxEdge, center, nullptr, ¢ers[firstLeave*3], &nodeOwners[firstLeave], nbLeaves); break; default : cerr << "No identified Load Balancing strategy" << endl; exit(0); } LBB->run(); delete Particles::_coordinates; cout << "---- Load Balancing ----> TERMINATED !" <<endl; int * counters = new int[size + 1](); }
bool Particle::update() { if (!mMap) return false; if (mLifetimeLeft == 0 && mAlive == ALIVE) mAlive = DEAD_TIMEOUT; Vector oldPos = mPos; if (mAlive == ALIVE) { //calculate particle movement if (mMomentum != 1.0f) { mVelocity *= mMomentum; } if (mTarget && mAcceleration != 0.0f) { Vector dist = mPos - mTarget->getPosition(); dist.x *= SIN45; float invHypotenuse; switch (Particle::fastPhysics) { case 1: invHypotenuse = fastInvSqrt( dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); break; case 2: invHypotenuse = 2.0f / fabs(dist.x) + fabs(dist.y) + fabs(dist.z); break; default: invHypotenuse = 1.0f / sqrt( dist.x * dist.x + dist.y * dist.y + dist.z * dist.z); break; } if (invHypotenuse) { if (mInvDieDistance > 0.0f && invHypotenuse > mInvDieDistance) { mAlive = DEAD_IMPACT; } float accFactor = invHypotenuse * mAcceleration; mVelocity -= dist * accFactor; } } if (mRandomness > 0) { mVelocity.x += (rand()%mRandomness - rand()%mRandomness) / 1000.0f; mVelocity.y += (rand()%mRandomness - rand()%mRandomness) / 1000.0f; mVelocity.z += (rand()%mRandomness - rand()%mRandomness) / 1000.0f; } mVelocity.z -= mGravity; // Update position mPos.x += mVelocity.x; mPos.y += mVelocity.y * SIN45; mPos.z += mVelocity.z * SIN45; // Update other stuff if (mLifetimeLeft > 0) { mLifetimeLeft--; } mLifetimePast++; if (mPos.z < 0.0f) { if (mBounce > 0.0f) { mPos.z *= -mBounce; mVelocity *= mBounce; mVelocity.z = -mVelocity.z; } else { mAlive = DEAD_FLOOR; } } else if (mPos.z > PARTICLE_SKY) { mAlive = DEAD_SKY; } // Update child emitters if ((mLifetimePast-1)%Particle::emitterSkip == 0) { for (EmitterIterator e = mChildEmitters.begin(); e != mChildEmitters.end(); e++) { Particles newParticles = (*e)->createParticles(mLifetimePast); for (ParticleIterator p = newParticles.begin(); p != newParticles.end(); p++) { (*p)->moveBy(mPos); mChildParticles.push_back (*p); } } } } // create death effect when the particle died if (mAlive != ALIVE && mAlive != DEAD_LONG_AGO) { if ((mAlive & mDeathEffectConditions) > 0x00 && !mDeathEffect.empty()) { Particle* deathEffect = particleEngine->addEffect(mDeathEffect, 0, 0); deathEffect->moveBy(mPos); } mAlive = DEAD_LONG_AGO; } Vector change = mPos - oldPos; // Update child particles for (ParticleIterator p = mChildParticles.begin(); p != mChildParticles.end();) { //move particle with its parent if desired if ((*p)->doesFollow()) { (*p)->moveBy(change); } //update particle if ((*p)->update()) { p++; } else { delete (*p); p = mChildParticles.erase(p); } } if (mAlive != ALIVE && mChildParticles.empty() && mAutoDelete) { return false; } return true; }
void PusherBorisV::operator()( Particles &particles, SmileiMPI *smpi, int istart, int iend, int ithread, int ipart_ref ) { std::vector<double> *Epart = &( smpi->dynamics_Epart[ithread] ); std::vector<double> *Bpart = &( smpi->dynamics_Bpart[ithread] ); double *invgf = &( smpi->dynamics_invgf[ithread][0] ); double charge_over_mass_dts2; double inv_det_T, Tx, Ty, Tz; double local_invgf; //int IX; //int* cell_keys; double *momentum[3]; for( int i = 0 ; i<3 ; i++ ) { momentum[i] = &( particles.momentum( i, 0 ) ); } double *position[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position[i] = &( particles.position( i, 0 ) ); } #ifdef __DEBUG double *position_old[3]; for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i] = &( particles.position_old( i, 0 ) ); } #endif short *charge = &( particles.charge( 0 ) ); int nparts = Epart->size()/3; double *Ex = &( ( *Epart )[0*nparts] ); double *Ey = &( ( *Epart )[1*nparts] ); double *Ez = &( ( *Epart )[2*nparts] ); double *Bx = &( ( *Bpart )[0*nparts] ); double *By = &( ( *Bpart )[1*nparts] ); double *Bz = &( ( *Bpart )[2*nparts] ); //particles.cell_keys.resize(nparts); //cell_keys = &( particles.cell_keys[0]); double dcharge[nparts]; #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { dcharge[ipart] = ( double )( charge[ipart] ); } #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { double psm[3], um[3]; charge_over_mass_dts2 = dcharge[ipart]*one_over_mass_*dts2; // init Half-acceleration in the electric field psm[0] = charge_over_mass_dts2*( *( Ex+ipart-ipart_ref ) ); psm[1] = charge_over_mass_dts2*( *( Ey+ipart-ipart_ref ) ); psm[2] = charge_over_mass_dts2*( *( Ez+ipart-ipart_ref ) ); //(*this)(particles, ipart, (*Epart)[ipart], (*Bpart)[ipart] , (*invgf)[ipart]); um[0] = momentum[0][ipart] + psm[0]; um[1] = momentum[1][ipart] + psm[1]; um[2] = momentum[2][ipart] + psm[2]; // Rotation in the magnetic field local_invgf = charge_over_mass_dts2 / sqrt( 1.0 + um[0]*um[0] + um[1]*um[1] + um[2]*um[2] ); Tx = local_invgf * ( *( Bx+ipart-ipart_ref ) ); Ty = local_invgf * ( *( By+ipart-ipart_ref ) ); Tz = local_invgf * ( *( Bz+ipart-ipart_ref ) ); inv_det_T = 1.0/( 1.0+Tx*Tx+Ty*Ty+Tz*Tz ); psm[0] += ( ( 1.0+Tx*Tx-Ty*Ty-Tz*Tz )* um[0] + 2.0*( Tx*Ty+Tz )* um[1] + 2.0*( Tz*Tx-Ty )* um[2] )*inv_det_T; psm[1] += ( 2.0*( Tx*Ty-Tz )* um[0] + ( 1.0-Tx*Tx+Ty*Ty-Tz*Tz )* um[1] + 2.0*( Ty*Tz+Tx )* um[2] )*inv_det_T; psm[2] += ( 2.0*( Tz*Tx+Ty )* um[0] + 2.0*( Ty*Tz-Tx )* um[1] + ( 1.0-Tx*Tx-Ty*Ty+Tz*Tz )* um[2] )*inv_det_T; // finalize Half-acceleration in the electric field local_invgf = 1. / sqrt( 1.0 + psm[0]*psm[0] + psm[1]*psm[1] + psm[2]*psm[2] ); invgf[ipart-ipart_ref] = local_invgf; momentum[0][ipart] = psm[0]; momentum[1][ipart] = psm[1]; momentum[2][ipart] = psm[2]; // Move the particle #ifdef __DEBUG for( int i = 0 ; i<nDim_ ; i++ ) { position_old[i][ipart] = position[i][ipart]; } #endif local_invgf *= dt; for( int i = 0 ; i<nDim_ ; i++ ) { position[i][ipart] += psm[i]*local_invgf; } } // This is temporarily moved to SpeciesV.cpp //#pragma omp simd //for (int ipart=istart ; ipart<iend; ipart++ ) { // // for ( int i = 0 ; i<nDim_ ; i++ ){ // cell_keys[ipart] *= nspace[i]; // cell_keys[ipart] += round( (position[i][ipart]-min_loc_vec[i]) * dx_inv_[i] ); // } // //} }
IMPCNMULTIFIT_BEGIN_NAMESPACE Floats get_rmsd_for_models(const std::string param_filename, const std::string trans_filename, const std::string ref_filename, int start_model, int end_model) { std::string protein_filename, surface_filename; int cn_symm_deg; std::cout << "============= parameters ============" << std::endl; std::cout << "params filename : " << param_filename << std::endl; std::cout << "trans filename : " << trans_filename << std::endl; std::cout << "ref filename : " << ref_filename << std::endl; std::cout << "start index to rmsd : " << start_model << std::endl; std::cout << "end index to rmsd : " << end_model << std::endl; std::cout << "=====================================" << std::endl; internal::Parameters params(param_filename.c_str()); protein_filename = params.get_unit_pdb_fn(); cn_symm_deg = params.get_cn_symm(); IMP_NEW(Model, mdl, ()); atom::Hierarchy asmb_ref; atom::Hierarchies mhs; // read the monomer core::XYZs model_xyzs; for (int i = 0; i < cn_symm_deg; i++) { atom::Hierarchy h = atom::read_pdb(protein_filename, mdl, new atom::CAlphaPDBSelector()); atom::Chain c = atom::get_chain( atom::Residue(atom::get_residue(atom::Atom(core::get_leaves(h)[0])))); c.set_id(std::string(1, char(65 + i))); atom::add_radii(h); atom::create_rigid_body(h); mhs.push_back(h); Particles leaves = core::get_leaves(h); for (Particles::iterator it = leaves.begin(); it != leaves.end(); it++) { model_xyzs.push_back(core::XYZ(*it)); } } // read the transformations multifit::FittingSolutionRecords recs = multifit::read_fitting_solutions(trans_filename.c_str()); // read the reference structure asmb_ref = atom::read_pdb(ref_filename, mdl, new atom::CAlphaPDBSelector()); atom::Hierarchies ref_chains = atom::Hierarchies(atom::get_by_type(asmb_ref, atom::CHAIN_TYPE)); std::cout << "number of records:" << recs.size() << std::endl; Floats rmsd; std::ofstream out; out.open("rmsd.output"); if (end_model < 0 || end_model >= static_cast<int>(recs.size())) { end_model = recs.size() - 1; } for (int i = start_model; i >= 0 && i <= end_model; ++i) { algebra::Transformation3D t1 = recs[i].get_dock_transformation(); algebra::Transformation3D t2 = recs[i].get_fit_transformation(); algebra::Transformation3D t2_inv = t1.get_inverse(); transform_cn_assembly(mhs, t1); for (unsigned int j = 0; j < model_xyzs.size(); j++) { model_xyzs[j] .set_coordinates(t2.get_transformed(model_xyzs[j].get_coordinates())); } std::cout << mhs.size() << "," << ref_chains.size() << std::endl; Float cn_rmsd = get_cn_rmsd(mhs, ref_chains); out << " trans:" << i << " rmsd: " << cn_rmsd << " cc: " << 1. - recs[i].get_fitting_score() << std::endl; rmsd.push_back(cn_rmsd); for (unsigned int j = 0; j < model_xyzs.size(); j++) { model_xyzs[j].set_coordinates( t2_inv.get_transformed(model_xyzs[j].get_coordinates())); } /* std::stringstream ss; ss<<"asmb_"<<i<<".pdb"; atom::write_pdb(mhs,ss.str());*/ transform_cn_assembly(mhs, t1.get_inverse()); } out.close(); return rmsd; }
void PusherPonderomotiveBorisV::operator()( Particles &particles, SmileiMPI *smpi, int istart, int iend, int ithread, int ipart_ref ) { std::vector<double> *Epart = &( smpi->dynamics_Epart[ithread] ); std::vector<double> *Bpart = &( smpi->dynamics_Bpart[ithread] ); std::vector<double> *GradPhipart = &( smpi->dynamics_GradPHIpart[ithread] ); std::vector<double> *dynamics_inv_gamma_ponderomotive = &( smpi->dynamics_inv_gamma_ponderomotive[ithread] ); double charge_over_mass_dts2, charge_sq_over_mass_sq_dts4; double alpha, inv_det_T, Tx, Ty, Tz, Tx2, Ty2, Tz2; double TxTy, TyTz, TzTx; double one_ov_gamma_ponderomotive; double *momentum[3]; for( int i = 0 ; i<3 ; i++ ) { momentum[i] = &( particles.momentum( i, 0 ) ); } short *charge = &( particles.charge( 0 ) ); int nparts = Epart->size()/3; double *Ex = &( ( *Epart )[0*nparts] ); double *Ey = &( ( *Epart )[1*nparts] ); double *Ez = &( ( *Epart )[2*nparts] ); double *Bx = &( ( *Bpart )[0*nparts] ); double *By = &( ( *Bpart )[1*nparts] ); double *Bz = &( ( *Bpart )[2*nparts] ); double *GradPhix = &( ( *GradPhipart )[0*nparts] ); double *GradPhiy = &( ( *GradPhipart )[1*nparts] ); double *GradPhiz = &( ( *GradPhipart )[2*nparts] ); double *inv_gamma_ponderomotive = &( ( *dynamics_inv_gamma_ponderomotive )[0*nparts] ); double dcharge[nparts]; #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { dcharge[ipart] = ( double )( charge[ipart] ); } #pragma omp simd for( int ipart=istart ; ipart<iend; ipart++ ) { double psm[3], um[3]; charge_over_mass_dts2 = dcharge[ipart]*one_over_mass_*dts2; // ! ponderomotive force is proportional to charge squared and the field is divided by 4 instead of 2 charge_sq_over_mass_sq_dts4 = ( double )( charge[ipart] )*( double )( charge[ipart] )*one_over_mass_*one_over_mass_*dts4; // ponderomotive gamma buffered from susceptibility one_ov_gamma_ponderomotive = ( *( inv_gamma_ponderomotive+ipart ) ); // init Half-acceleration in the electric field and ponderomotive force psm[0] = charge_over_mass_dts2 * ( *( Ex+ipart-ipart_ref ) ) - charge_sq_over_mass_sq_dts4 * ( *( GradPhix+ipart-ipart_ref ) ) * one_ov_gamma_ponderomotive; psm[1] = charge_over_mass_dts2 * ( *( Ey+ipart-ipart_ref ) ) - charge_sq_over_mass_sq_dts4 * ( *( GradPhiy+ipart-ipart_ref ) ) * one_ov_gamma_ponderomotive; psm[2] = charge_over_mass_dts2 * ( *( Ez+ipart-ipart_ref ) ) - charge_sq_over_mass_sq_dts4 * ( *( GradPhiz+ipart-ipart_ref ) ) * one_ov_gamma_ponderomotive; um[0] = momentum[0][ipart] + psm[0]; um[1] = momentum[1][ipart] + psm[1]; um[2] = momentum[2][ipart] + psm[2]; // Rotation in the magnetic field, using updated gamma ponderomotive alpha = charge_over_mass_dts2 * one_ov_gamma_ponderomotive; Tx = alpha * ( *( Bx+ipart-ipart_ref ) ); Ty = alpha * ( *( By+ipart-ipart_ref ) ); Tz = alpha * ( *( Bz+ipart-ipart_ref ) ); Tx2 = Tx*Tx; Ty2 = Ty*Ty; Tz2 = Tz*Tz; TxTy = Tx*Ty; TyTz = Ty*Tz; TzTx = Tz*Tx; inv_det_T = 1.0/( 1.0+Tx2+Ty2+Tz2 ); psm[0] += ( ( 1.0+Tx2-Ty2-Tz2 )* um[0] + 2.0*( TxTy+Tz )* um[1] + 2.0*( TzTx-Ty )* um[2] )*inv_det_T; psm[1] += ( 2.0*( TxTy-Tz )* um[0] + ( 1.0-Tx2+Ty2-Tz2 )* um[1] + 2.0*( TyTz+Tx )* um[2] )*inv_det_T; psm[2] += ( 2.0*( TzTx+Ty )* um[0] + 2.0*( TyTz-Tx )* um[1] + ( 1.0-Tx2-Ty2+Tz2 )* um[2] )*inv_det_T; momentum[0][ipart] = psm[0]; momentum[1][ipart] = psm[1]; momentum[2][ipart] = psm[2]; } }
void add_BallMover(Particles ps, double dx, core::MonteCarloMovers &mvs) { for (unsigned int k = 0; k < ps.size(); ++k) { IMP_NEW(core::BallMover, bmv, (ps[k]->get_model(), ps[k]->get_index(), dx)); mvs.push_back(bmv); } }
// --------------------------------------------------------------------------------------------------------------------- //! Project charge : frozen & diagFields timstep // --------------------------------------------------------------------------------------------------------------------- void Projector1D4Order::basic( double *rhoj, Particles &particles, unsigned int ipart, unsigned int type ) { //Warning : this function is used for frozen species or initialization only and doesn't use the standard scheme. //rho type = 0 //Jx type = 1 //Jy type = 2 //Jz type = 3 // Declare local variables //int ipo, ip, iloc; int ip; //int ip_m_ipo; double charge_weight = inv_cell_volume * ( double )( particles.charge( ipart ) )*particles.weight( ipart ); double xjn, xj_m_xip, xj_m_xip2, xj_m_xip3, xj_m_xip4; double S1[7]; // arrays used for the Esirkepov projection method // Initialize variables for( unsigned int i=0; i<7; i++ ) { S1[i]=0.; }//i if( type > 0 ) { charge_weight *= 1./sqrt( 1.0 + particles.momentum( 0, ipart )*particles.momentum( 0, ipart ) + particles.momentum( 1, ipart )*particles.momentum( 1, ipart ) + particles.momentum( 2, ipart )*particles.momentum( 2, ipart ) ); if( type == 1 ) { charge_weight *= particles.momentum( 0, ipart ); } else if( type == 2 ) { charge_weight *= particles.momentum( 1, ipart ); } else { charge_weight *= particles.momentum( 2, ipart ); } } // Locate particle new position on the primal grid xjn = particles.position( 0, ipart ) * dx_inv_; ip = round( xjn + 0.5 * ( type==1 ) ); // index of the central node xj_m_xip = xjn - ( double )ip; // normalized distance to the nearest grid point xj_m_xip2 = xj_m_xip * xj_m_xip; // square of the normalized distance to the nearest grid point xj_m_xip3 = xj_m_xip2 * xj_m_xip; // cube of the normalized distance to the nearest grid point xj_m_xip4 = xj_m_xip3 * xj_m_xip; // 4th power of the normalized distance to the nearest grid point // coefficients 2nd order interpolation on 5 nodes //ip_m_ipo = ip-ipo; S1[1] = dble_1_ov_384 - dble_1_ov_48 * xj_m_xip + dble_1_ov_16 * xj_m_xip2 - dble_1_ov_12 * xj_m_xip3 + dble_1_ov_24 * xj_m_xip4; S1[2] = dble_19_ov_96 - dble_11_ov_24 * xj_m_xip + dble_1_ov_4 * xj_m_xip2 + dble_1_ov_6 * xj_m_xip3 - dble_1_ov_6 * xj_m_xip4; S1[3] = dble_115_ov_192 - dble_5_ov_8 * xj_m_xip2 + dble_1_ov_4 * xj_m_xip4; S1[4] = dble_19_ov_96 + dble_11_ov_24 * xj_m_xip + dble_1_ov_4 * xj_m_xip2 - dble_1_ov_6 * xj_m_xip3 - dble_1_ov_6 * xj_m_xip4; S1[5] = dble_1_ov_384 + dble_1_ov_48 * xj_m_xip + dble_1_ov_16 * xj_m_xip2 + dble_1_ov_12 * xj_m_xip3 + dble_1_ov_24 * xj_m_xip4; ip -= index_domain_begin + 3 ; // 4th order projection for the charge density // At the 4th order, oversize = 3. for( unsigned int i=0; i<7; i++ ) { //iloc = i + ipo - 3; rhoj[i + ip ] += charge_weight * S1[i]; }//i }
void remove(Particle *p) { removeList.push_back(p); }
/** @brief get the centers as intensity centroids of local maxima neighbourhood * * Local maxima are taken as the bright pixels of centersMap */ Particles Tracker::getSubPixel(bool autoThreshold) { //boost::progress_timer ptimer; //get the positions of the bright centers from flatten centersMap if(!quiet) cout<<"get positions ... "; list<size_t> flat_positions; bool* b = centersMap.origin(); for(size_t i=0; i<centersMap.num_elements(); ++i) if(*b++) flat_positions.push_back(i); //sort by increasing pixel intensity if(!quiet) cout<<flat_positions.size()<<" potential centers ... "; flat_positions.sort(compIntensities(data)); //Find the best intensity threshold if(autoThreshold) { //construct the centers intensity histogram const long double minhist = *(data+flat_positions.front()), maxhist = *(data+flat_positions.back()); const long double scale = 100.0/(maxhist-minhist); vector<size_t> hist(100, 0); for(list<size_t>::const_iterator c = flat_positions.begin(); c!= flat_positions.end(); ++c) { size_t l = (*(data + (*c)) - minhist) * scale; if(l<hist.size()) hist[l]++; } //find the population global maximum vector<size_t>::iterator peak = max_element(hist.begin(), hist.end()); if(!quiet) cout<<"peak ="<<distance(hist.begin(), peak)<<" ... "; //find the last non-null bin before the peak, and at the same time the bin with the minimum population between it and the peak vector<size_t>::iterator non_z = lower_bound(hist.begin(), peak, 1); vector<size_t>::iterator lowest = min_element(non_z, peak); //cout<<"non_z="<<distance(hist.begin(),non_z)<<"\tlowest="<<distance(hist.begin(),lowest)<<endl; while((*lowest)==0) { non_z = lowest; lowest = min_element(lowest, peak); //cout<<"non_z="<<distance(hist.begin(),non_z)<<"\tlowest="<<distance(hist.begin(),lowest)<<endl; } //lowest gives the position of the valley of the histogram, ie the best threshold if(!quiet) cout<<"best threshold = "<<distance(hist.begin(), lowest)/scale + minhist<<" ("<<distance(hist.begin(), lowest)<<"%) ... "; //We remove all centers that have lower intensity than the best threshold list<size_t>::iterator i = flat_positions.begin(); advance(i, accumulate(hist.begin(), lowest, (size_t)0)); flat_positions.erase(flat_positions.begin(), i); if(!quiet) cout<<flat_positions.size()<<" centers after auto thresholding ... "; } //centroid binning if(!quiet) cout<<"centroid ... "; list< valarray<double> > positions; boost::array<size_t,3> shape; copy(centersMap.shape(), centersMap.shape()+3, shape.begin()); transform( flat_positions.rbegin(), flat_positions.rend(), back_inserter(positions), centroid(boost::multi_array_ref<float,3>(data,shape)) ); //removing marked centers positions.remove_if(markedPositionRemover<valarray<double> >()); if(!quiet) cout<<positions.size()<<" are real local maxima ... "; Particles centers; for(size_t d=0;d<3;++d) { centers.bb.edges[d].first = 0; centers.bb.edges[d].second = centersMap.shape()[d]; } //centers.reserve(positions.size()); copy(positions.begin(), positions.end(), back_inserter(centers)); if(fortran_order) { //If the image was filled in row major ordering of the dimensions, the coordinates are given as z,y,x by the tracker. //Here we convert to the human-readable x,y,z coordinates for_each(centers.begin(), centers.end(), revert<valarray<double> >()); //don't forget the bounding box swap(centers.bb.edges[0].second, centers.bb.edges[2].second); } if(!quiet) cout << "done!" << endl; if(view) { markCenters(); display("Centers"); } return centers; }