void distribute_conn_mass(floatVector& lc, floatVector& rc, intVector& lc_cgrid, intVector& rc_cgrid, int val) { floatVector lcoef(3), rcoef(3); // frational value indicating connectivity assignment along 3 axes for (int i=0; i<3; i++) { lcoef[i]=lc[i]-floor(lc[i]); rcoef[i]=rc[i]-floor(rc[i]); } intVector tmpCoords(3); int lc_cgrid_ind=coarse_map()[lc_cgrid]-1, rc_cgrid_ind=coarse_map()[rc_cgrid]-1; for (int z=0; z<2; z++) { // Note: we assume that all points are in the interios, therefore exactly 8 points float lfracZ=(1-lcoef[2])*(1-z)+lcoef[2]*z; float rfracZ=(1-rcoef[2])*(1-z)+rcoef[2]*z; for (int y=0; y<2; y++) { float lfracZY=lfracZ * ( (1-lcoef[1])*(1-y)+lcoef[1]*y ); float rfracZY=rfracZ * ( (1-rcoef[1])*(1-y)+rcoef[1]*y ); for (int x=0; x<2; x++) { float lfracZYX=lfracZY * ( (1-lcoef[0])*(1-x)+lcoef[0]*x ); float rfracZYX=rfracZY * ( (1-rcoef[0])*(1-x)+rcoef[0]*x ); tmpCoords[0]=(int)lc[0]+x; tmpCoords[1]=(int)lc[1]+y; tmpCoords[2]=(int)lc[2]+z; // left conn_profile()[tmpCoords][rc_cgrid_ind] += lfracZYX * val; tmpCoords[0]=(int)rc[0]+x; tmpCoords[1]=(int)rc[1]+y; tmpCoords[2]=(int)rc[2]+z; // right conn_profile()[tmpCoords][lc_cgrid_ind] += rfracZYX * val; } } } }
// overloaded void append_conn(string connfile, string coordfile, string coordfile_local2std, string coordfile_std2local) { // connectivity profile represented in the MNI coarser space vector<intVector> coord_map; // store the coordinate-to-index mapping vector<floatVector> coord_map_local2std; // corresponding coordinate in MNI space intVector coord(3); floatVector coord_local2std(3); // read in the coordinate mapping to memory ifstream coordstream(coordfile); ifstream coordstream_local2std(coordfile_local2std); for (int i=0; i<3; i++) coordstream >> coord[i]; while(coordstream.good()) { coord_map.push_back(coord); for (int i=0; i<3; i++) coordstream >> coord[i]; } coordstream.close(); for (int i=0; i<3; i++) coordstream_local2std >> coord_local2std[i]; while(coordstream_local2std.good()) { coord_map_local2std.push_back(coord_local2std); for (int i=0; i<3; i++) coordstream_local2std >> coord_local2std[i]; } coordstream_local2std.close(); assert(coord_map.size()==coord_map_local2std.size()); // the connectivity part ifstream connstream(connfile); int l, r, v; // left node, right node, and t=connectivity value intVector lc(3), rc(3); // coordinates of left/right nodes floatVector lc_local2std(3), rc_local2std(3); // in MNI space intVector lc_cgrid(3), rc_cgrid(3); // coordinates in the coarse grid init_profile( (conn_profile().begin()->second).size(), coord_map.size(), coordfile, conn_profile_local() ); // reset the local conn profile connstream >> l; connstream >> r; connstream >> v; while(connstream.good()) { lc = coord_map[l-1]; rc = coord_map[r-1]; lc_local2std = coord_map_local2std[l-1]; rc_local2std = coord_map_local2std[r-1]; // int MNI space fine2coarse(lc_local2std, lc_cgrid); fine2coarse(rc_local2std, rc_cgrid); if (coarse_map().count(rc_cgrid)) conn_profile_local()[lc][coarse_map()[rc_cgrid]-1] += v; if (coarse_map().count(lc_cgrid)) conn_profile_local()[rc][coarse_map()[lc_cgrid]-1] += v; connstream >> l; connstream >> r; connstream >> v; } connstream.close(); // transform local profile to MNI space profile appendpf_local2std(coordfile_std2local); }
void init_coarse(int dim_profile, string coarsefile) { coarse_map().clear(); // read in the coordinate mappings ifstream scoarse(coarsefile); intVector coord(3); for (int i=0; i<3; i++) scoarse >> coord[i]; while(scoarse.good()) { scoarse >> coarse_map()[coord]; for (int i=0; i<3; i++) scoarse >> coord[i]; } assert(coarse_map().size()==dim_profile); scoarse.close(); }
void update_hash(string coordfile) { ifstream coordstream(coordfile); floatVector fine(3); intVector fineInt(3); intVector coarse(3); while(coordstream.good()) { coordstream >> fine[0]; coordstream >> fine[1]; coordstream >> fine[2]; for (int z=0; z<2; z++) for (int y=0; y<2; y++) for (int x=0; x<2; x++) { fineInt[0]=(int)fine[0]+x; fineInt[1]=(int)fine[1]+y; fineInt[2]=(int)fine[2]+z; conn_profile()[fineInt]=vector<float>(); // just to store the key } fine2coarse(fine, coarse); if (!coarse_map().count(coarse)) coarse_map()[coarse] = coarse_map().size(); } }
// 3D full weight restriction void restriction( double* R, double* R_new, cuint I, cuint J, cuint K, cuint I_new, cuint J_new, cuint K_new ) { unsigned int nei[3][3][3]; #pragma omp parallel for shared(R, R_new) private(nei) num_threads(nt) for(int i=0; i<I; i+=2){ for(int j=0; j<J; j+=2){ for(int k=0; k<K; k+=2){ get_neighbor( nei, i,j,k, I,J,K); // get new index uint t_new; three_d_to_one_d( i/2, j/2, k/2, I_new, J_new, t_new); coarse_map( R, R_new, nei, i,j,k, t_new); } } } }