const char* reconstruction(ImageModel* image_model, unsigned int method_id, const float* param_values, bool check_b_table, unsigned int thread_count) { static std::string output_name; try { image_model->voxel.recon_report.clear(); image_model->voxel.recon_report.str(""); image_model->voxel.param = param_values; std::ostringstream out; if(method_id == 1) // DTI { image_model->voxel.need_odf = 0; image_model->voxel.output_jacobian = 0; image_model->voxel.output_mapping = 0; image_model->voxel.output_rdi = 0; image_model->voxel.scheme_balance = 0; image_model->voxel.half_sphere = 0; image_model->voxel.odf_deconvolusion = 0; image_model->voxel.odf_decomposition = 0; } else { out << ".odf" << image_model->voxel.ti.fold;// odf_order out << ".f" << image_model->voxel.max_fiber_number; if (image_model->voxel.need_odf) out << "rec"; if (image_model->voxel.scheme_balance) out << ".bal"; if (image_model->voxel.half_sphere) out << ".hs"; if (image_model->voxel.csf_calibration && method_id == 4) out << ".csfc"; else image_model->voxel.csf_calibration = false; if (image_model->voxel.odf_deconvolusion) { out << ".de" << param_values[2]; if(image_model->voxel.odf_xyz[0] != 0 || image_model->voxel.odf_xyz[1] != 0 || image_model->voxel.odf_xyz[2] != 0) out << ".at_" << image_model->voxel.odf_xyz[0] << "_" << image_model->voxel.odf_xyz[1] << "_" << image_model->voxel.odf_xyz[2]; } if (image_model->voxel.odf_decomposition) { out << ".dec" << param_values[3] << "m" << (int)param_values[4]; if(image_model->voxel.odf_xyz[0] != 0 || image_model->voxel.odf_xyz[1] != 0 || image_model->voxel.odf_xyz[2] != 0) out << ".at_" << image_model->voxel.odf_xyz[0] << "_" << image_model->voxel.odf_xyz[1] << "_" << image_model->voxel.odf_xyz[2]; } } // correct for b-table orientation if(check_b_table) { set_title("checking b-table"); bool output_dif = image_model->voxel.output_diffusivity; bool output_tensor = image_model->voxel.output_tensor; image_model->voxel.output_diffusivity = false; image_model->voxel.output_tensor = false; image_model->reconstruct<dti_process>(thread_count); image_model->voxel.output_diffusivity = output_dif; image_model->voxel.output_tensor = output_tensor; std::vector<std::vector<float> > fib_fa(1); std::vector<std::vector<float> > fib_dir(1); fib_fa[0].swap(image_model->voxel.fib_fa); fib_dir[0].swap(image_model->voxel.fib_dir); const unsigned char order[18][6] = { {0,1,2,1,0,0}, {0,1,2,0,1,0}, {0,1,2,0,0,1}, {0,2,1,1,0,0}, {0,2,1,0,1,0}, {0,2,1,0,0,1}, {1,0,2,1,0,0}, {1,0,2,0,1,0}, {1,0,2,0,0,1}, {1,2,0,1,0,0}, {1,2,0,0,1,0}, {1,2,0,0,0,1}, {2,1,0,1,0,0}, {2,1,0,0,1,0}, {2,1,0,0,0,1}, {2,0,1,1,0,0}, {2,0,1,0,1,0}, {2,0,1,0,0,1}}; const char txt[18][6] = {"012fx","012fy","012fz", "021fx","021fy","021fz", "102fx","102fy","102fz", "120fx","120fy","120fz", "210fx","210fy","210fz", "201fx","201fy","201fz"}; float result[18] = {0}; float cur_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first; for(int i = 0;i < 18;++i) { std::vector<std::vector<float> > new_dir(fib_dir); flip_fib_dir(new_dir[0],order[i]); result[i] = evaluate_fib(image_model->voxel.dim,fib_fa,new_dir).first; } int best = std::max_element(result,result+18)-result; if(result[best] > cur_score) { out << "." << txt[best]; image_model->flip_b_table(order[best]); } } switch (method_id) { case 0: //DSI local max image_model->voxel.recon_report << " The diffusion data were reconstructed using diffusion spectrum imaging (Wedeen et al. MRM, 2005) with a Hanning filter of " << (int)param_values[0] << "."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<dsi_estimate_response_function>(thread_count)) return "reconstruction canceled"; } out << ".dsi."<< (int)param_values[0] << ".fib.gz"; if (!image_model->reconstruct<dsi_process>(thread_count)) return "reconstruction canceled"; break; case 1://DTI image_model->voxel.recon_report << " The diffusion tensor was calculated."; out << ".dti.fib.gz"; image_model->voxel.max_fiber_number = 1; if (!image_model->reconstruct<dti_process>(thread_count)) return "reconstruction canceled"; break; case 2://QBI image_model->voxel.recon_report << " The diffusion data was reconstructed using q-ball imaging (Tuch, MRM 2004)."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<qbi_estimate_response_function>(thread_count)) return "reconstruction canceled"; } out << ".qbi."<< param_values[0] << "_" << param_values[1] << ".fib.gz"; if (!image_model->reconstruct<qbi_process>(thread_count)) return "reconstruction canceled"; break; case 3://QBI image_model->voxel.recon_report << " The diffusion data was reconstructed using spherical-harmonic-based q-ball imaging (Descoteaux et al., MRM 2007)."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<qbi_sh_estimate_response_function>(thread_count)) return "reconstruction canceled"; } out << ".qbi.sh"<< (int) param_values[1] << "." << param_values[0] << ".fib.gz"; if (!image_model->reconstruct<qbi_sh_process>(thread_count)) return "reconstruction canceled"; break; case 4://GQI if(param_values[0] == 0.0) // spectral analysis { image_model->voxel.recon_report << " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, ;29(9):1626-35, 2010)."; out << (image_model->voxel.r2_weighted ? ".gqi2.spec.fib.gz":".gqi.spec.fib.gz"); if (!image_model->reconstruct<gqi_spectral_process>(thread_count)) return "reconstruction canceled"; break; } image_model->voxel.recon_report << " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, ;29(9):1626-35, 2010) with a diffusion sampling length ratio of " << (float)param_values[0] << "."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<gqi_estimate_response_function>(thread_count)) return "reconstruction canceled"; } if(image_model->voxel.r2_weighted) image_model->voxel.recon_report << " The ODF calculation was weighted by the square of the diffuion displacement."; if (image_model->voxel.output_rdi) out << ".rdi"; out << (image_model->voxel.r2_weighted ? ".gqi2.":".gqi.") << param_values[0] << ".fib.gz"; if (!image_model->reconstruct<gqi_process>(thread_count)) return "reconstruction canceled"; break; case 6: image_model->voxel.recon_report << " The diffusion data were converted to HARDI using generalized q-sampling method with a regularization parameter of " << param_values[2] << "."; out << ".hardi."<< param_values[0] << ".b" << param_values[1] << ".reg" << param_values[2] << ".src.gz"; if (!image_model->reconstruct<hardi_convert_process>(thread_count)) return "reconstruction canceled"; break; case 7: image_model->voxel.recon_report << " The diffusion data were reconstructed in the MNI space using q-space diffeomorphic reconstruction (Yeh et al., Neuroimage, 58(1):91-9, 2011) to obtain the spin distribution function (Yeh et al., IEEE TMI, ;29(9):1626-35, 2010). " << " A diffusion sampling length ratio of " << (float)param_values[0] << " was used, and the output resolution was " << param_values[1] << " mm."; // run gqi to get the spin quantity std::vector<image::pointer_image<float,3> > tmp; tmp.swap(image_model->voxel.grad_dev); if (!image_model->reconstruct<gqi_estimate_response_function>(thread_count)) return "reconstruction canceled"; tmp.swap(image_model->voxel.grad_dev); out << ".reg" << (int)image_model->voxel.reg_method; out << "i" << (int)image_model->voxel.interpo_method; out << (image_model->voxel.r2_weighted ? ".qsdr2.":".qsdr."); out << param_values[0] << "." << param_values[1] << "mm"; if(image_model->voxel.output_jacobian) out << ".jac"; if(image_model->voxel.output_mapping) out << ".map"; if (!image_model->reconstruct<gqi_mni_process>(thread_count)) return "reconstruction canceled"; out << ".R" << (int)std::floor(image_model->voxel.R2*100.0) << ".fib.gz"; break; } image_model->save_fib(out.str()); output_name = image_model->file_name + out.str(); } catch (std::exception& e) { output_name = e.what(); return output_name.c_str(); } catch (...) { return "unknown exception"; } return output_name.c_str(); }
const char* reconstruction(ImageModel* image_model,unsigned int method_id,const float* param_values) { static std::string output_name; try { { std::vector<unsigned int> shell; if(image_model->voxel.bvalues.front() != 0.0) shell.push_back(0); for(unsigned int index = 1;index < image_model->voxel.bvalues.size();++index) if(std::abs(image_model->voxel.bvalues[index]-image_model->voxel.bvalues[index-1]) > 100) shell.push_back(index); image_model->voxel.half_sphere = (method_id == 7 || method_id == 4) && (shell.size() > 5) && (shell[1] - shell[0] <= 3); image_model->voxel.scheme_balance = (method_id == 7 || method_id == 4) && (shell.size() <= 5) && !shell.empty() && image_model->voxel.bvalues.size()-shell.back() < 100; } image_model->voxel.recon_report.clear(); image_model->voxel.recon_report.str(""); image_model->voxel.param = param_values; std::ostringstream out; if(method_id == 1) // DTI { image_model->voxel.need_odf = 0; image_model->voxel.output_jacobian = 0; image_model->voxel.output_mapping = 0; image_model->voxel.scheme_balance = 0; image_model->voxel.half_sphere = 0; image_model->voxel.odf_deconvolusion = 0; image_model->voxel.odf_decomposition = 0; } if(method_id != 1) // not DTI { out << ".odf" << image_model->voxel.ti.fold;// odf_order out << ".f" << image_model->voxel.max_fiber_number; if (image_model->voxel.need_odf) out << "rec"; if (image_model->voxel.scheme_balance) out << ".bal"; if (image_model->voxel.half_sphere) out << ".hs"; if (image_model->voxel.odf_deconvolusion) { out << ".de" << param_values[2]; if(image_model->voxel.odf_xyz[0] != 0 || image_model->voxel.odf_xyz[1] != 0 || image_model->voxel.odf_xyz[2] != 0) out << ".at_" << image_model->voxel.odf_xyz[0] << "_" << image_model->voxel.odf_xyz[1] << "_" << image_model->voxel.odf_xyz[2]; } if (image_model->voxel.odf_decomposition) { out << ".dec" << param_values[3] << "m" << (int)param_values[4]; if(image_model->voxel.odf_xyz[0] != 0 || image_model->voxel.odf_xyz[1] != 0 || image_model->voxel.odf_xyz[2] != 0) out << ".at_" << image_model->voxel.odf_xyz[0] << "_" << image_model->voxel.odf_xyz[1] << "_" << image_model->voxel.odf_xyz[2]; } } // correct for b-table orientation { set_title("checking b-table"); image_model->reconstruct<dti_process>(); std::vector<std::vector<float> > fib_fa(1); std::vector<std::vector<float> > fib_dir(1); fib_fa[0].swap(image_model->voxel.fib_fa); fib_dir[0].swap(image_model->voxel.fib_dir); unsigned int cur_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first; flip_fib_dir(fib_dir[0],true,false,false); unsigned int flip_x_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first; flip_fib_dir(fib_dir[0],true,true,false); unsigned int flip_y_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first; flip_fib_dir(fib_dir[0],false,true,true); unsigned int flip_z_score = evaluate_fib(image_model->voxel.dim,fib_fa,fib_dir).first; if(flip_x_score > cur_score && flip_x_score > flip_y_score && flip_x_score > flip_z_score) { std::cout << "b-table flipped x" << std::endl; for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index) image_model->voxel.bvectors[index][0] = -image_model->voxel.bvectors[index][0]; } if(flip_y_score > cur_score && flip_y_score > flip_x_score && flip_y_score > flip_z_score) { std::cout << "b-table flipped y" << std::endl; for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index) image_model->voxel.bvectors[index][1] = -image_model->voxel.bvectors[index][1]; } if(flip_z_score > cur_score && flip_z_score > flip_y_score && flip_z_score > flip_x_score) { std::cout << "b-table flipped z" << std::endl; for(unsigned int index = 0;index < image_model->voxel.bvectors.size();++index) image_model->voxel.bvectors[index][2] = -image_model->voxel.bvectors[index][2]; } } switch (method_id) { case 0: //DSI local max image_model->voxel.recon_report << " The diffusion data were reconstructed using diffusion spectrum imaging (Wedeen et al. MRM, 2005) with a Hanning filter of " << (int)param_values[0] << "."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<dsi_estimate_response_function>()) return "reconstruction calceled"; begin_prog("calculating"); } out << ".dsi."<< (int)param_values[0] << ".fib.gz"; if (!image_model->reconstruct<dsi_process>(out.str())) return "reconstruction canceled"; break; case 1://DTI image_model->voxel.recon_report << " The diffusion tensor was calculated."; out << ".dti.fib.gz"; image_model->voxel.max_fiber_number = 1; if (!image_model->reconstruct<dti_process>(out.str())) return "reconstruction canceled"; break; case 2://QBI image_model->voxel.recon_report << " The diffusion data was reconstructed using q-ball imaging (Tuch, MRM 2004)."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<qbi_estimate_response_function>()) return "reconstruction calceled"; begin_prog("calculating"); } out << ".qbi."<< param_values[0] << "_" << param_values[1] << ".fib.gz"; if (!image_model->reconstruct<qbi_process>(out.str())) return "reconstruction canceled"; break; case 3://QBI image_model->voxel.recon_report << " The diffusion data was reconstructed using spherical-harmonic-based q-ball imaging (Descoteaux et al., MRM 2007)."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<qbi_sh_estimate_response_function>()) return "reconstruction calceled"; begin_prog("calculating"); } out << ".qbi.sh"<< (int) param_values[1] << "." << param_values[0] << ".fib.gz"; if (!image_model->reconstruct<qbi_sh_process>(out.str())) return "reconstruction canceled"; break; case 4://GQI if(param_values[0] == 0.0) // spectral analysis { image_model->voxel.recon_report << " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, 2010)."; out << (image_model->voxel.r2_weighted ? ".gqi2.spec.fib.gz":".gqi.spec.fib.gz"); if (!image_model->reconstruct<gqi_spectral_process>(out.str())) return "reconstruction canceled"; break; } image_model->voxel.recon_report << " The diffusion data were reconstructed using generalized q-sampling imaging (Yeh et al., IEEE TMI, 2010) with a diffusion sampling length ratio of " << (float)param_values[0] << "."; if (image_model->voxel.odf_deconvolusion || image_model->voxel.odf_decomposition) { if (!image_model->reconstruct<gqi_estimate_response_function>()) return "reconstruction calceled"; begin_prog("calculating"); } if(image_model->voxel.r2_weighted) image_model->voxel.recon_report << " The ODF calculation was weighted by the square of the diffuion displacement."; out << (image_model->voxel.r2_weighted ? ".gqi2.":".gqi.") << param_values[0] << ".fib.gz"; if (!image_model->reconstruct<gqi_process>(out.str())) return "reconstruction canceled"; break; case 6: image_model->voxel.recon_report << " The diffusion data were converted to HARDI using generalized q-sampling method with a regularization parameter of " << param_values[2] << "."; out << ".hardi."<< param_values[0] << ".b" << param_values[1] << ".reg" << param_values[2] << ".src.gz"; if (!image_model->reconstruct<hardi_convert_process>(out.str())) return "reconstruction canceled"; break; case 7: image_model->voxel.recon_report << " The diffusion data were reconstructed using q-space diffeomorphic reconstruction (Yeh et al. Neuroimage, 2011) with a diffusion sampling length ratio of " << (float)param_values[0] << ". The output resolution was " << param_values[1] << " mm."; // run gqi to get the spin quantity if (!image_model->reconstruct<gqi_estimate_response_function>()) return "reconstruction calceled"; out << ".reg" << (int)image_model->voxel.reg_method; out << (image_model->voxel.r2_weighted ? ".qsdr2.":".qsdr."); out << param_values[0] << "." << param_values[1] << "mm"; if(image_model->voxel.output_jacobian) out << ".jac"; if(image_model->voxel.output_mapping) out << ".map"; out << ".fib.gz"; begin_prog("deforming"); if (!image_model->reconstruct<gqi_mni_process>(out.str())) return "reconstruction canceled"; break; } output_name = image_model->file_name + out.str(); } catch (std::exception& e) { output_name = e.what(); return output_name.c_str(); } catch (...) { return "unknown exception"; } return output_name.c_str(); }