/** perform reconstruction */ int rec(void) { std::string file_name = po.get("source"); std::cout << "loading source..." <<std::endl; std::auto_ptr<ImageModel> handle(new ImageModel); if (!handle->load_from_file(file_name.c_str())) { std::cout << "Load src file failed:" << handle->error_msg << std::endl; return 1; } std::cout << "src loaded" <<std::endl; if (po.has("flip")) { std::string flip_seq = po.get("flip"); for(unsigned int index = 0;index < flip_seq.length();++index) if(flip_seq[index] >= '0' && flip_seq[index] <= '5') { handle->flip(flip_seq[index]-'0'); std::cout << "Flip image volume:" << (int)flip_seq[index]-'0' << std::endl; } } // apply affine transformation if (po.has("affine")) { std::cout << "reading transformation matrix" <<std::endl; std::ifstream in(po.get("affine").c_str()); std::vector<double> T((std::istream_iterator<float>(in)), (std::istream_iterator<float>())); if(T.size() != 12) { std::cout << "Invalid transfformation matrix." <<std::endl; return 1; } image::transformation_matrix<double> affine; affine.load_from_transform(T.begin()); std::cout << "rotating images" << std::endl; handle->rotate(handle->voxel.dim,affine); } float param[4] = {0,0,0,0}; int method_index = 0; method_index = po.get("method",int(0)); std::cout << "method=" << method_index << std::endl; if(method_index == 0) // DSI param[0] = 17.0; if(method_index == 2) { param[0] = 5; param[1] = 15; } if(method_index == 3) // QBI-SH { param[0] = 0.006; param[1] = 8; } if(method_index == 4) param[0] = 1.2; if(method_index == 6) // Convert to HARDI { param[0] = 1.25; param[1] = 3000; param[2] = 0.05; } if(method_index == 7) { if (po.has("template")) { std::cout << "loading external template:" << po.get("template") << std::endl; fa_template_imp.template_file_name = po.get("template"); } if(!fa_template_imp.load_from_file()) { std::cout << "failed to locate template for QSDR reconstruction" << std::endl; return -1; } param[0] = 1.2; param[1] = 2.0; std::fill(handle->mask.begin(),handle->mask.end(),1.0); } param[3] = 0.0002; if(po.get("deconvolution",int(0))) { param[2] = 7; } if(po.get("decomposition",int(0))) { param[3] = 0.05; param[4] = 10; } if (po.has("param0")) { param[0] = po.get("param0",float(0)); std::cout << "param0=" << param[0] << std::endl; } if (po.has("param1")) { param[1] = po.get("param1",float(0)); std::cout << "param1=" << param[1] << std::endl; } if (po.has("param2")) { param[2] = po.get("param2",float(0)); std::cout << "param2=" << param[2] << std::endl; } if (po.has("param3")) { param[3] = po.get("param3",float(0)); std::cout << "param3=" << param[3] << std::endl; } if (po.has("param4")) { param[4] = po.get("param4",float(0)); std::cout << "param4=" << param[4] << std::endl; } handle->voxel.ti.init(po.get("odf_order",int(8))); handle->voxel.need_odf = po.get("record_odf",int(0)); handle->voxel.output_jacobian = po.get("output_jac",int(0)); handle->voxel.output_mapping = po.get("output_map",int(0)); handle->voxel.output_diffusivity = po.get("output_dif",int(1)); handle->voxel.output_tensor = po.get("output_tensor",int(0)); handle->voxel.output_rdi = po.get("output_rdi",int(1)); handle->voxel.odf_deconvolusion = po.get("deconvolution",int(0)); handle->voxel.odf_decomposition = po.get("decomposition",int(0)); handle->voxel.max_fiber_number = po.get("num_fiber",int(5)); handle->voxel.r2_weighted = po.get("r2_weighted",int(0)); handle->voxel.reg_method = po.get("reg_method",int(0)); handle->voxel.interpo_method = po.get("interpo_method",int(2)); handle->voxel.csf_calibration = po.get("csf_calibration",int(0)) && method_index == 4; std::vector<unsigned int> shell; calculate_shell(handle->voxel.bvalues,shell); handle->voxel.half_sphere = po.get("half_sphere", int(((shell.size() > 5) && (shell[1] - shell[0] <= 3)) ? 1:0)); handle->voxel.scheme_balance = po.get("scheme_balance", int((shell.size() <= 5) && !shell.empty() && handle->voxel.bvalues.size()-shell.back() < 100 ? 1:0)); { if(handle->voxel.need_odf) std::cout << "record ODF in the fib file" << std::endl; if(handle->voxel.odf_deconvolusion) std::cout << "apply deconvolution" << std::endl; if(handle->voxel.odf_decomposition) std::cout << "apply decomposition" << std::endl; if(handle->voxel.r2_weighted && method_index == 4) std::cout << "r2 weighted is used for GQI" << std::endl; } if(po.has("other_image")) { QStringList file_list = QString(po.get("other_image").c_str()).split(";"); for(unsigned int i = 0;i < file_list.size();++i) { QStringList name_value = file_list[i].split(","); if(name_value.size() != 2) { std::cout << "Invalid command: " << file_list[i].toStdString() << std::endl; return 0; } if(!add_other_image(handle.get(),name_value[0],name_value[1],true)) return 0; } } if(po.has("mask")) { std::string mask_file = po.get("mask"); std::cout << "reading mask..." << mask_file << std::endl; gz_nifti header; if(header.load_from_file(mask_file.c_str())) { image::basic_image<unsigned char,3> external_mask; header.toLPS(external_mask); if(external_mask.geometry() != handle->voxel.dim) std::cout << "In consistent the mask dimension...using default mask" << std::endl; else handle->mask = external_mask; } else std::cout << "fail reading the mask...using default mask" << std::endl; } if(po.get("motion_correction",int(0))) { std::vector<image::affine_transform<double> > arg; unsigned int progress = 0; bool terminated = false; std::cout << "correct for motion and eddy current..." << std::endl; rec_motion_correction(handle.get(),po.get("thread_count",int(std::thread::hardware_concurrency())), arg,progress,terminated); std::cout << "Done." <<std::endl; } std::cout << "start reconstruction..." <<std::endl; const char* msg = reconstruction(handle.get(),method_index, param,po.get("check_btable",int(1)), po.get("thread_count",int(std::thread::hardware_concurrency()))); if (!msg) std::cout << "Reconstruction finished:" << msg << std::endl; return 0; }
virtual void init(Voxel& voxel) { if(!voxel.scheme_balance) return; unsigned int b_count = voxel.bvalues.size(); std::vector<unsigned int> shell; calculate_shell(voxel.bvalues,shell); if(shell.size() > 5) // more than 3 shell { voxel.scheme_balance = false; return; } unsigned int total_signals = 0; tessellated_icosahedron new_dir; new_dir.init(6); std::vector<image::vector<3,float> > new_bvectors; std::vector<float> new_bvalues; // if b0 if(voxel.bvalues.front() == 0.0) { trans.resize(b_count); trans[0] = 1; new_bvectors.resize(1); new_bvalues.resize(1); total_signals += 1; } for(unsigned int shell_index = 0;shell_index < shell.size();++shell_index) { unsigned int from = shell[shell_index]; unsigned int to = (shell_index + 1 == shell.size() ? b_count:shell[shell_index+1]); unsigned int num = to-from; //calculate averaged angle distance double averaged_angle = 0.0; for(unsigned int i = from;i < to;++i) { double max_cos = 0.0; for(unsigned int j = from;j < to;++j) { if(i == j) continue; double cur_cos = std::fabs(std::cos(voxel.bvectors[i]*voxel.bvectors[j])); if(cur_cos > 0.998) continue; max_cos = std::max<double>(max_cos,cur_cos); } averaged_angle += std::acos(max_cos); } averaged_angle /= num; //calculate averaged b_value double avg_b = image::mean(voxel.bvalues.begin()+from,voxel.bvalues.begin()+to); unsigned int trans_old_size = trans.size(); trans.resize(trans.size() + new_dir.half_vertices_count*b_count); for(unsigned int i = 0; i < new_dir.half_vertices_count;++i) { std::vector<double> t(b_count); double effective_b = 0.0; for(unsigned int j = from;j < to;++j) { double angle = std::acos(std::min<double>(1.0,std::fabs(new_dir.vertices[i]*voxel.bvectors[j]))); angle/=averaged_angle; t[j] = std::exp(-2.0*angle*angle); // if the angle == 1, then weighting = 0.135 effective_b += t[j]*voxel.bvalues[j]; } double sum_t = std::accumulate(t.begin(),t.end(),0.0); std::for_each(t.begin(),t.end(),boost::lambda::_1 *= (avg_b/1000.0/sum_t)); std::copy(t.begin(),t.end(),trans.begin() + trans_old_size + i * b_count); new_bvalues.push_back(effective_b/sum_t); new_bvectors.push_back(new_dir.vertices[i]); } total_signals += new_dir.half_vertices_count; } old_q_count = voxel.bvalues.size(); new_q_count = total_signals; voxel.bvalues.swap(new_bvalues); voxel.bvectors.swap(new_bvectors); new_bvalues.swap(old_bvalues); new_bvectors.swap(old_bvectors); stored_voxel = &voxel; }