bool output_odfs(const image::basic_image<unsigned char,3>& mni_mask, const char* out_name, const char* ext, std::vector<std::vector<float> >& odfs, const tessellated_icosahedron& ti, const float* vs, const float* mni, const std::string& report, bool record_odf = true) { begin_prog("output"); ImageModel image_model; if(report.length()) image_model.voxel.report = report.c_str(); image_model.voxel.dim = mni_mask.geometry(); image_model.voxel.ti = ti; image_model.voxel.odf_decomposition = false; image_model.voxel.odf_deconvolusion = false; image_model.voxel.half_sphere = false; image_model.voxel.max_fiber_number = 5; image_model.voxel.z0 = 0.0; image_model.voxel.need_odf = record_odf; image_model.voxel.template_odfs.swap(odfs); image_model.voxel.param = mni; image_model.file_name = out_name; image_model.mask = mni_mask; std::copy(vs,vs+3,image_model.voxel.vs.begin()); if (prog_aborted() || !image_model.reconstruct<reprocess_odf>(1)) return false; image_model.save_fib(ext); image_model.voxel.template_odfs.swap(odfs); return true; }
bool output_odfs(const tipl::image<unsigned char,3>& mni_mask, const char* out_name, const char* ext, std::vector<std::vector<float> >& odfs, const tessellated_icosahedron& ti, const float* vs, const float* mni, const std::string& report, bool record_odf = true) { begin_prog("output"); ImageModel image_model; if(report.length()) image_model.voxel.report = report.c_str(); image_model.voxel.dim = mni_mask.geometry(); image_model.voxel.ti = ti; image_model.voxel.max_fiber_number = 5; image_model.voxel.need_odf = record_odf; image_model.voxel.template_odfs.swap(odfs); image_model.file_name = out_name; image_model.voxel.mask = mni_mask; std::copy(mni,mni+16,image_model.voxel.trans_to_mni); std::copy(vs,vs+3,image_model.voxel.vs.begin()); if (prog_aborted() || !image_model.reconstruct<reprocess_odf>()) return false; image_model.save_fib(ext); image_model.voxel.template_odfs.swap(odfs); return true; }
void save_fib(const std::string& ext) { std::string output_name = file_name; output_name += ext; begin_prog("saving data"); gz_mat_write mat_writer(output_name.c_str()); save_to_file(mat_writer); voxel.end(mat_writer); std::string final_report = voxel.report.c_str(); final_report += voxel.recon_report.str(); mat_writer.write("report",final_report.c_str(),1,final_report.length()); }
void MainWindow::on_RenameDICOM_clicked() { QStringList filenames = QFileDialog::getOpenFileNames( this, "Open DICOM files", ui->workDir->currentText(), "All files (*)" ); if ( filenames.isEmpty() ) return; begin_prog("Rename DICOM Files"); for (unsigned int index = 0;check_prog(index,filenames.size());++index) RenameDICOMToDir(filenames[index],QFileInfo(filenames[index]).absolutePath()); }
bool reconstruct(unsigned int thread_count) { begin_prog("reconstruction"); voxel.image_model = this; voxel.CreateProcesses<ProcessType>(); voxel.init(thread_count); boost::thread_group threads; for (unsigned int index = 1;index < thread_count;++index) threads.add_thread(new boost::thread(&Voxel::thread_run,&voxel, index,thread_count,mask)); voxel.thread_run(0,thread_count,mask); threads.join_all(); return !prog_aborted(); }
void MainWindow::loadFib(QString filename) { std::string file_name = filename.toLocal8Bit().begin(); begin_prog("load fib"); std::shared_ptr<fib_data> new_handle(new fib_data); if (!new_handle->load_from_file(&*file_name.begin())) { if(!prog_aborted()) QMessageBox::information(this,"error",new_handle->error_msg.c_str(),0); return; } tracking_window* new_mdi = new tracking_window(this,new_handle); new_mdi->setAttribute(Qt::WA_DeleteOnClose); new_mdi->setWindowTitle(filename); new_mdi->showNormal(); addFib(filename); add_work_dir(QFileInfo(filename).absolutePath()); QDir::setCurrent(QFileInfo(filename).absolutePath()); }
void individual_connectometry::on_compare_clicked() { unsigned char normalization; if(ui->norm0->isChecked()) normalization = 0; if(ui->norm1->isChecked()) normalization = 1; if(ui->norm2->isChecked()) normalization = 2; if(ui->norm3->isChecked()) normalization = 3; QSettings settings; settings.setValue("individual_connectometry_norm",(int)normalization); begin_prog("comparing"); if(ui->inv_db->isChecked()) { if(!cur_tracking_window.cnt_result.individual_vs_db(cur_tracking_window.handle,subject2_file.toLocal8Bit().begin())) QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str()); } if(ui->inv_template->isChecked()) { if(!cur_tracking_window.cnt_result.individual_vs_atlas(cur_tracking_window.handle,subject2_file.toLocal8Bit().begin(),normalization)) QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str()); } if(ui->inv_inv->isChecked()) { if(!cur_tracking_window.cnt_result.individual_vs_individual(cur_tracking_window.handle, subject_file.toLocal8Bit().begin(),subject2_file.toLocal8Bit().begin(),normalization)) QMessageBox::information(this,"Error",cur_tracking_window.cnt_result.error_msg.c_str()); } cur_tracking_window.initialize_tracking_index(cur_tracking_window.handle->dir.index_data.size()-1); cur_tracking_window.scene.show_slice(); check_prog(0,0); hide(); accept(); }
void MainWindow::on_batch_src_clicked() { QString dir = QFileDialog::getExistingDirectory( this, "Open directory", ui->workDir->currentText()); if(dir.isEmpty()) return; add_work_dir(dir); { QStringList dir_list; dir_list << dir; bool all = false; bool choice = false; begin_prog("batch creating src"); for(unsigned int i = 0;check_prog(i,dir_list.size()) && !prog_aborted();++i) { QDir cur_dir = dir_list[i]; QStringList new_list = cur_dir.entryList(QStringList(""),QDir::AllDirs|QDir::NoDotAndDotDot); for(unsigned int index = 0;index < new_list.size();++index) dir_list << cur_dir.absolutePath() + "/" + new_list[index]; std::vector<std::shared_ptr<DwiHeader> > dwi_files; if(QFileInfo(dir_list[i] + "/data.nii.gz").exists() && QFileInfo(dir_list[i] + "/bvals").exists() && QFileInfo(dir_list[i] + "/bvecs").exists() && load_4d_nii(QString(dir_list[i] + "/data.nii.gz").toLocal8Bit().begin(),dwi_files)) { DwiHeader::output_src(QString(dir_list[i] + "/data.src.gz").toLocal8Bit().begin(),dwi_files,0); continue; } QStringList nifti_file_list = cur_dir.entryList(QStringList("*.nii.gz"),QDir::Files|QDir::NoSymLinks); for (unsigned int index = 0;index < nifti_file_list.size();++index) { if(QFileInfo(dir_list[i] + "/" + QFileInfo(nifti_file_list[index]).baseName()+".bval").exists() && QFileInfo(dir_list[i] + "/" + QFileInfo(nifti_file_list[index]).baseName()+".bvec").exists() && load_4d_nii(QString(dir_list[i] + "/" + nifti_file_list[index]).toLocal8Bit().begin(),dwi_files)) { DwiHeader::output_src(QString(dir_list[i] + "/" + QFileInfo(nifti_file_list[index]).baseName() + ".src.gz").toLocal8Bit().begin(),dwi_files,0); continue; } } QStringList dicom_file_list = cur_dir.entryList(QStringList("*.dcm"),QDir::Files|QDir::NoSymLinks); if(dicom_file_list.empty()) continue; for (unsigned int index = 0;index < dicom_file_list.size();++index) dicom_file_list[index] = dir_list[i] + "/" + dicom_file_list[index]; QString output = dir_list[i] + "/" + QFileInfo(get_src_name(dicom_file_list[0])).baseName()+".src.gz"; if(QFileInfo(output).exists()) { if(!all) { QMessageBox msgBox; msgBox.setText(QString("Existing SRC file ") + output); msgBox.setInformativeText("Overwrite?"); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoAll); msgBox.setDefaultButton(QMessageBox::Save); switch(msgBox.exec()) { case QMessageBox::YesToAll: all = true; case QMessageBox::Yes: choice = true; break; case QMessageBox::NoAll: all = true; case QMessageBox::No: choice = false; break; } } if(!choice) continue; } if(!load_all_files(dicom_file_list,dwi_files) || prog_aborted()) continue; if(dwi_files.size() == 1) //MPRAGE or T2W { std::sort(dicom_file_list.begin(),dicom_file_list.end(),compare_qstring()); image::io::volume v; image::io::dicom header; std::vector<std::string> file_list; for(unsigned int index = 0;index < dicom_file_list.size();++index) file_list.push_back(dicom_file_list[index].toLocal8Bit().begin()); if(!v.load_from_files(file_list,file_list.size()) || !header.load_from_file(dicom_file_list[0].toLocal8Bit().begin())) continue; image::basic_image<float,3> I; image::vector<3> vs; v >> I; v.get_voxel_size(vs.begin()); gz_nifti nii_out; image::flip_xy(I); nii_out << I; nii_out.set_voxel_size(vs); std::string manu,make,seq,report; header.get_text(0x0008,0x0070,manu);//Manufacturer header.get_text(0x0008,0x1090,make); header.get_text(0x0018,0x1030,seq); std::replace(manu.begin(),manu.end(),' ',(char)0); make.erase(std::remove(make.begin(),make.end(),' '),make.end()); std::ostringstream out; out << manu.c_str() << " " << make.c_str() << " " << seq << ".TE=" << header.get_float(0x0018,0x0081) << ".TR=" << header.get_float(0x0018,0x0080) << "."; report = out.str(); std::copy(report.begin(),report.begin() + std::min<int>(80,report.length()+1),nii_out.nif_header.descrip); QString output_name = QFileInfo(get_src_name(dicom_file_list[0])).absolutePath() + "/" + QFileInfo(get_src_name(dicom_file_list[0])).baseName()+ "."+seq.c_str() + ".nii.gz"; nii_out.save_to_file(output_name.toLocal8Bit().begin()); } else { for(unsigned int index = 0;index < dwi_files.size();++index) if(dwi_files[index]->get_bvalue() < 100) { dwi_files[index]->set_bvalue(0); dwi_files[index]->set_bvec(0,0,0); } DwiHeader::output_src(output.toLocal8Bit().begin(),dwi_files,0); } }
const char* odf_average(const char* out_name,std::vector<std::string>& file_names) { static std::string error_msg,report; tessellated_icosahedron ti; float vs[3]; tipl::image<unsigned char,3> mask; std::vector<std::vector<float> > odfs; unsigned int half_vertex_count = 0; unsigned int row,col; float mni[16]={0}; begin_prog("averaging"); for (unsigned int index = 0;check_prog(index,file_names.size());++index) { const char* file_name = file_names[index].c_str(); gz_mat_read reader; set_title(file_names[index].c_str()); if(!reader.load_from_file(file_name)) { error_msg = "Cannot open file "; error_msg += file_name; check_prog(0,0); return error_msg.c_str(); } if(index == 0) { { const char* report_buf = 0; if(reader.read("report",row,col,report_buf)) report = std::string(report_buf,report_buf+row*col); } const float* odf_buffer; const short* face_buffer; const unsigned short* dimension; const float* vs_ptr; const float* fa0; const float* mni_ptr; unsigned int face_num,odf_num; error_msg = ""; if(!reader.read("dimension",row,col,dimension)) error_msg = "dimension"; if(!reader.read("fa0",row,col,fa0)) error_msg = "fa0"; if(!reader.read("voxel_size",row,col,vs_ptr)) error_msg = "voxel_size"; if(!reader.read("odf_faces",row,face_num,face_buffer)) error_msg = "odf_faces"; if(!reader.read("odf_vertices",row,odf_num,odf_buffer)) error_msg = "odf_vertices"; if(!reader.read("trans",row,col,mni_ptr)) error_msg = "trans"; if(error_msg.length()) { error_msg += " missing in "; error_msg += file_name; check_prog(0,0); return error_msg.c_str(); } mask.resize(tipl::geometry<3>(dimension)); for(unsigned int index = 0;index < mask.size();++index) if(fa0[index] != 0.0) mask[index] = 1; std::copy(vs_ptr,vs_ptr+3,vs); ti.init(odf_num,odf_buffer,face_num,face_buffer); half_vertex_count = odf_num >> 1; std::copy(mni_ptr,mni_ptr+16,mni); } else // check odf consistency {
void gen_dialog::on_buttonBox_accepted() { begin_prog("Generate images"); for(unsigned int index = 0;check_prog(index,file_list.size());++index) { wsi w; if(QFileInfo(file_list[index]).suffix() != "gz") // recognition file { if(!w.open(file_list[index].toLocal8Bit().begin())) { QMessageBox::information(this,"Error",file_list[index] + " is an invalid file",0); continue; } if(!w.load_text_reco_result((file_list[index]+".txt").toLocal8Bit().begin())) { QMessageBox::information(this,"Error",file_list[index] + " has no recognition results",0); continue; } } else if(!w.load_recognition_result(file_list[index].toLocal8Bit().begin())) { QMessageBox::information(this,"Error",file_list[index] + " is an invalid file",0); continue; } tipl::image<float,2> sdi_value; tipl::image<unsigned char,2> sdi_contour; w.get_distribution_image(sdi_value,sdi_contour, ui->resolution->value(),ui->resolution->value(), ui->type->currentIndex()); tipl::color_image sdi_image(sdi_value.geometry()); { float r = 255.99/(ui->value_max->value()-ui->value_min->value()); for(unsigned int index = 0;index < sdi_value.size();++index) { int i = std::max<int>(0,std::min<int>(255,std::floor((sdi_value[index]-ui->value_min->value())*r))); sdi_image[index] = colormap[i]; } } if(ui->contour->isChecked()) { for(unsigned int index = 0;index < sdi_value.size();++index) if(sdi_contour[index]) sdi_value[index] = 0; } if(ui->format->currentIndex() == 1)// mat { QString output_file = file_list[index] + ".mat"; tipl::io::mat_write mat(output_file.toLocal8Bit().begin()); mat << sdi_value; } if(ui->format->currentIndex() == 0)// tif { QString output_file = file_list[index] + ".jpg"; QImage I((unsigned char*)&*sdi_image.begin(),sdi_image.width(),sdi_image.height(),QImage::Format_RGB32); I.save(output_file); } if(w.is_tma) { QString output_file = file_list[index] + ".tma.txt"; w.save_tma_result(output_file.toStdString().c_str(),ui->label_on_right->isChecked()); } } }
void createLayout(const char* file_name, float fa_value, const std::vector<float>& angle_iteration, unsigned int repeat_num, unsigned int phantom_width, unsigned int boundary) { float iso_fraction = 0.2f; float fiber_fraction = 1.0f-iso_fraction; dim[0] = phantom_width+boundary+boundary; dim[1] = phantom_width+boundary+boundary; dim[2] = std::max<int>(1,angle_iteration.size())*repeat_num; unsigned int total_size = dim.size(); std::vector<float> fa[2]; std::vector<float> gfa; std::vector<short> findex[2]; models.resize(total_size); fa[0].resize(total_size); fa[1].resize(total_size); gfa.resize(total_size); findex[0].resize(total_size); findex[1].resize(total_size); unsigned int main_fiber_index = ti.discretize(tipl::vector<3>(1.0,0.0,0.0)); std::fill(models.begin(),models.end(),(MixGaussianModel*)0); begin_prog("creating layout"); if(angle_iteration.empty()) // use 0 to 90 degrees crossing for (unsigned int n = 0,index = 0; n < repeat_num; ++n) { if (!check_prog(index,total_size)) break; float fa2 = fa_value*fa_value; //fa*fa = (r*r-2*r+1)/(r*r+2) float r = (1.0+fa_value*std::sqrt(3-2*fa2))/(1-fa2); float l2 = mean_dif*3.0/(2.0+r); float l1 = r*l2; for (unsigned int y = 0; y < dim[1]; ++y) { for (unsigned int x = 0; x < dim[0]; ++x,++index) { if (x >= boundary && x < boundary+phantom_width && y >= boundary && y < boundary+phantom_width) { float xf = ((float)x - boundary + 1)/((float)phantom_width);//from 0.02 to 1.00 xf = 1.0f-xf;//0.00 to 0.98 xf = 0.5f+0.5f*xf;//0.50 to 0.99 float angle = ((float)y - boundary)/((float)phantom_width);//0.00 to 0.98 angle = 1.0f-angle;//0.02 to 1.00 angle *= float(M_PI*0.5f);//1.8 degrees 90 degrees models[index] = new MixGaussianModel(l1,l2,mean_dif,angle, fiber_fraction*xf, fiber_fraction*(1.0-xf)); fa[0][index] = fiber_fraction*xf; fa[1][index] = fiber_fraction*(1.0-xf); gfa[index] = fa_value; findex[0][index] = main_fiber_index; findex[1][index] = ti.discretize(tipl::vector<3>(std::cos(angle),std::sin(angle),0.0)); } } } } else for (unsigned int j = 0,index = 0; j < angle_iteration.size(); ++j) for (unsigned int n = 0; n < repeat_num; ++n) { if (!check_prog(index,total_size)) break; float inner_angle = angle_iteration[j]*M_PI/180.0; float fa2 = fa_value*fa_value; //fa*fa = (r*r-2*r+1)/(r*r+2) float r = (1.0+fa_value*std::sqrt(3-2*fa2))/(1-fa2); float l2 = mean_dif*3.0/(2.0+r); float l1 = r*l2; for (unsigned int y = 0; y < dim[1]; ++y) { for (unsigned int x = 0; x < dim[0]; ++x,++index) { if (x >= boundary && x < boundary+phantom_width && y >= boundary && y < boundary+phantom_width) { if(inner_angle >= 0.0) models[index] = new MixGaussianModel(l1,l2,mean_dif,inner_angle,0.5,0.5); else models[index] = new GaussianDispersion(l1,l2,mean_dif,inner_angle,1.0); fa[0][index] = fiber_fraction/2.0; fa[1][index] = fiber_fraction/2.0; gfa[index] = fa_value; findex[0][index] = main_fiber_index; findex[1][index] = ti.discretize(tipl::vector<3>(std::cos(inner_angle),std::sin(inner_angle),0.0)); } } } } set_title("Generating images"); std::string fib_file_name(file_name); fib_file_name += ".layout.fib"; gz_mat_write mat_writer(file_name),mat_layout(fib_file_name.c_str()); // output dimension { mat_writer.write("dimension",&*dim.begin(),1,3); mat_layout.write("dimension",&*dim.begin(),1,3); } // output vexol size { float vs[3] = {1.0,1.0,1.0}; mat_writer.write("voxel_size",vs,1,3); mat_layout.write("voxel_size",vs,1,3); } // output b_table { std::vector<float> buffer; buffer.reserve(bvalues.size()*4); for (unsigned int index = 0; index < bvalues.size(); ++index) { buffer.push_back(bvalues[index]); std::copy(bvectors[index].begin(),bvectors[index].end(),std::back_inserter(buffer)); } mat_writer.write("b_table",&*buffer.begin(),4,bvalues.size()); } // output images { std::vector<short> buffer(models.size()); begin_prog("generating images"); for (unsigned int index = 0; check_prog(index,bvectors.size()); ++index) { for (unsigned int i = 0; i < models.size(); ++i) { if (models[i]) buffer[i] = encodeNoise((*models[i])(bvalues[index]/1000.0,bvectors[index])*spin_density*0.5); // 0.5 volume of water else buffer[i] = encodeNoise(spin_density*exp(-bvalues[index]*0.0016)); // water its coefficient is 0.0016 mm?/s } std::ostringstream out; out << "image" << index; mat_writer.write(out.str().c_str(),&*buffer.begin(),1,buffer.size()); } } // output layout { std::vector<float> float_data; std::vector<short> short_data; ti.save_to_buffer(float_data,short_data); mat_layout.write("odf_vertices",&*float_data.begin(),3,ti.vertices_count); mat_layout.write("odf_faces",&*short_data.begin(),3,ti.faces.size()); mat_layout.write("fa0",&*fa[0].begin(),1,fa[0].size()); mat_layout.write("fa1",&*fa[1].begin(),1,fa[1].size()); mat_layout.write("gfa",&*gfa.begin(),1,gfa.size()); mat_layout.write("index0",&*findex[0].begin(),1,findex[0].size()); mat_layout.write("index1",&*findex[1].begin(),1,findex[1].size()); } }
virtual void init(Voxel& voxel) { if(voxel.vs[0] == 0.0 || voxel.vs[1] == 0.0 || voxel.vs[2] == 0.0) throw std::runtime_error("No spatial information found in src file. Recreate src file or contact developer for assistance"); begin_prog("normalization"); VG = fa_template_imp.I; VF = voxel.fa_map; image::filter::gaussian(voxel.fa_map); image::filter::gaussian(voxel.fa_map); image::filter::gaussian(voxel.qa_map); image::filter::gaussian(voxel.qa_map); image::normalize(voxel.fa_map,1.0); image::normalize(voxel.qa_map,1.0); for(unsigned int index = 0;index < voxel.qa_map.size();++index) if(voxel.qa_map[index] == 0.0 || voxel.fa_map[index]/voxel.qa_map[index] > 2.5) VF[index] = 0.0; image::filter::gaussian(VF); src_geo = VF.geometry(); image::normalize(VF,1.0); //VF.save_to_file<image::io::nifti<> >("VF.nii"); image::normalize(VG,1.0); // get rid of the gray matters image::minus_constant(VF.begin(),VF.end(),0.3); image::lower_threshold(VF.begin(),VF.end(),0.00); image::normalize(VF,1.0); image::minus_constant(VG.begin(),VG.end(),0.3); image::lower_threshold(VG.begin(),VG.end(),0.00); image::normalize(VG,1.0); VGvs[0] = std::fabs(fa_template_imp.tran[0]); VGvs[1] = std::fabs(fa_template_imp.tran[5]); VGvs[2] = std::fabs(fa_template_imp.tran[10]); image::affine_transform<3,double> arg_min; // VG: FA TEMPLATE // VF: SUBJECT QA arg_min.scaling[0] = voxel.vs[0] / VGvs[0]; arg_min.scaling[1] = voxel.vs[1] / VGvs[1]; arg_min.scaling[2] = voxel.vs[2] / VGvs[2]; voxel_volume_scale = arg_min.scaling[0]*arg_min.scaling[1]*arg_min.scaling[2]; // calculate center of mass image::vector<3,double> mF = center_of_mass(VF); image::vector<3,double> mG = center_of_mass(VG); arg_min.translocation[0] = mG[0]-mF[0]*arg_min.scaling[0]; arg_min.translocation[1] = mG[1]-mF[1]*arg_min.scaling[1]; arg_min.translocation[2] = mG[2]-mF[2]*arg_min.scaling[2]; bool terminated = false; set_title("linear registration"); begin_prog("conducting registration"); check_prog(0,2); image::reg::linear(VF,VG,arg_min,image::reg::affine,image::reg::square_error(),terminated,0.25); check_prog(1,2); // create VFF the affine transformed VF image::basic_image<float,3> VFF(VG.geometry()); { affine = arg_min; image::reg::linear_get_trans(VF.geometry(),VG.geometry(),affine); { std::vector<double> T(16); affine.save_to_transform(T.begin()); T[15] = 1.0; math::matrix_inverse(T.begin(),math::dim<4,4>()); affine.load_from_transform(T.begin()); } image::resample(VF,VFF,affine); //VFF.save_to_file<image::io::nifti<> >("VFF.nii"); //VG.save_to_file<image::io::nifti<> >("VG.nii"); } { switch(voxel.reg_method) { case 0: mni.normalize(VG,VFF); break; case 1: mni.normalize(VG,VFF,12,14,12,4,8); break; } //calculate the goodness of fit std::vector<float> x,y; x.reserve(VG.size()); y.reserve(VG.size()); image::interpolation<image::linear_weighting,3> trilinear_interpolation; for(image::pixel_index<3> index;VG.geometry().is_valid(index); index.next(VG.geometry())) if(VG[index.index()] != 0) { image::vector<3,double> pos; mni.warp_coordinate(index,pos); double value = 0.0; if(!trilinear_interpolation.estimate(VFF,pos,value)) continue; x.push_back(VG[index.index()]); y.push_back(value); } R2 = x.empty() ? 0.0 : image::correlation(x.begin(),x.end(),y.begin()); R2 *= R2; std::cout << "R2 = " << R2 << std::endl; } check_prog(2,2); // setup output bounding box { //setBoundingBox(-78,-112,-50,78,76,85,1.0); float voxel_size = voxel.param[1]; bounding_box_lower[0] = std::floor(-78.0/voxel_size+0.5)*voxel_size; bounding_box_lower[1] = std::floor(-112.0/voxel_size+0.5)*voxel_size; bounding_box_lower[2] = std::floor(-50.0/voxel_size+0.5)*voxel_size; bounding_box_upper[0] = std::floor(78.0/voxel_size+0.5)*voxel_size; bounding_box_upper[1] = std::floor(76.0/voxel_size+0.5)*voxel_size; bounding_box_upper[2] = std::floor(85.0/voxel_size+0.5)*voxel_size; des_geo[0] = (bounding_box_upper[0]-bounding_box_lower[0])/voxel_size+1;//79 des_geo[1] = (bounding_box_upper[1]-bounding_box_lower[1])/voxel_size+1;//95 des_geo[2] = (bounding_box_upper[2]-bounding_box_lower[2])/voxel_size+1;//69 des_offset[0] = bounding_box_lower[0]/VGvs[0]-fa_template_imp.tran[3]/fa_template_imp.tran[0]; des_offset[1] = bounding_box_lower[1]/VGvs[1]-fa_template_imp.tran[7]/fa_template_imp.tran[5]; des_offset[2] = bounding_box_lower[2]/VGvs[2]-fa_template_imp.tran[11]/fa_template_imp.tran[10]; scale[0] = voxel_size/VGvs[0]; scale[1] = voxel_size/VGvs[1]; scale[2] = voxel_size/VGvs[2]; } begin_prog("q-space diffeomorphic reconstruction"); float sigma = voxel.param[0]; //diffusion sampling length ratio, optimal 1.24 // setup mask { // set the current mask to template space voxel.image_model->set_dimension(des_geo[0],des_geo[1],des_geo[2]); for(image::pixel_index<3> index;des_geo.is_valid(index);index.next(des_geo)) { image::vector<3,int> mni_pos(index); mni_pos *= voxel.param[1]; mni_pos[0] /= VGvs[0]; mni_pos[1] /= VGvs[1]; mni_pos[2] /= VGvs[2]; mni_pos += des_offset; voxel.image_model->mask[index.index()] = fa_template_imp.I.at(mni_pos[0],mni_pos[1],mni_pos[2]) > 0.0? 1: 0; } } q_vectors_time.resize(voxel.bvalues.size()); for (unsigned int index = 0; index < voxel.bvalues.size(); ++index) { q_vectors_time[index] = voxel.bvectors[index]; q_vectors_time[index] *= std::sqrt(voxel.bvalues[index]*0.01506);// get q in (mm) -1 q_vectors_time[index] *= sigma; } b0_index = -1; if(voxel.half_sphere) for(unsigned int index = 0;index < voxel.bvalues.size();++index) if(voxel.bvalues[index] == 0) b0_index = index; ptr_images.clear(); for (unsigned int index = 0; index < voxel.image_model->dwi_data.size(); ++index) ptr_images.push_back(point_image_type((const unsigned short*)voxel.image_model->dwi_data[index],src_geo)); voxel.qa_scaling = voxel.reponse_function_scaling/voxel.vs[0]/voxel.vs[1]/voxel.vs[2]; max_accumulated_qa = 0; std::fill(voxel.vs.begin(),voxel.vs.end(),voxel.param[1]); jdet.resize(des_geo.size()); if (voxel.odf_deconvolusion) { gqi.init(voxel); deconvolution.init(voxel); } if (voxel.odf_decomposition) { gqi.init(voxel); decomposition.init(voxel); } angle_variance = 8; //degress; angle_variance *= M_PI/180; angle_variance *= angle_variance; angle_variance *= 2.0; }
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(); }