bool load_fa_template(void) { std::string fa_template_path = program_base; fa_template_path += "FMRIB58_FA_1mm.nii.gz"; if(!fa_template_imp.load_from_file(fa_template_path.c_str())) { std::string error_str = "Cannot find the fa template file at "; error_str += fa_template_path; QMessageBox::information(0,"Error",error_str.c_str(),0); return false; } return true; }
void tracking_window::subject2mni(image::vector<3>& pos) { if(mi3.get() && mi3->progress == 2) { mi3->T(pos); image::vector<3> result; mi3->bnorm_data(pos,result); pos = result; fa_template_imp.to_mni(pos); } else if(!handle->fib_data.trans_to_mni.empty()) { image::vector<3> mni; image::vector_transformation(pos.begin(),mni.begin(), handle->fib_data.trans_to_mni,image::vdim<3>()); pos = mni; } }
/** 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; }
bool tracking_window::eventFilter(QObject *obj, QEvent *event) { bool has_info = false; image::vector<3,float> pos; if (event->type() == QEvent::MouseMove) { if (obj == glWidget) { has_info = glWidget->get_mouse_pos(static_cast<QMouseEvent*>(event),pos); copy_target = 0; } if (obj->parent() == ui->graphicsView) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); QPointF point = ui->graphicsView->mapToScene(mouseEvent->pos().x(),mouseEvent->pos().y()); has_info = scene.get_location(point.x(),point.y(),pos); copy_target = 1; } // for connectivity matrix if(connectivity_matrix.get() && connectivity_matrix->is_graphic_view(obj->parent())) connectivity_matrix->mouse_move(static_cast<QMouseEvent*>(event)); } if(!has_info) return false; QString status; status = QString("(%1,%2,%3) ").arg(std::floor(pos[0]*10.0+0.5)/10.0) .arg(std::floor(pos[1]*10.0+0.5)/10.0) .arg(std::floor(pos[2]*10.0+0.5)/10.0); // show atlas position if(mi3.get() && mi3->need_update_affine_matrix) { mi3->update_affine(); handle->fib_data.trans_to_mni.resize(16); image::create_affine_transformation_matrix(mi3->T.get(),mi3->T.get() + 9,handle->fib_data.trans_to_mni.begin(),image::vdim<3>()); fa_template_imp.add_transformation(handle->fib_data.trans_to_mni); if(mi3->progress >= 1) mi3->need_update_affine_matrix = false; } if(!handle->fib_data.trans_to_mni.empty()) { image::vector<3,float> mni(pos); subject2mni(mni); status += QString("MNI(%1,%2,%3) ") .arg(std::floor(mni[0]*10.0+0.5)/10.0) .arg(std::floor(mni[1]*10.0+0.5)/10.0) .arg(std::floor(mni[2]*10.0+0.5)/10.0); if(!atlas_list.empty()) status += atlas_list[ui->atlasListBox->currentIndex()].get_label_name_at(mni).c_str(); } status += " "; std::vector<float> data; handle->get_voxel_information(std::floor(pos[0] + 0.5), std::floor(pos[1] + 0.5), std::floor(pos[2] + 0.5), data); for(unsigned int index = 0,data_index = 0;index < handle->fib_data.view_item.size() && data_index < data.size();++index) if(handle->fib_data.view_item[index].name != "color") { status += handle->fib_data.view_item[index].name.c_str(); status += QString("=%1 ").arg(data[data_index]); ++data_index; } ui->statusbar->showMessage(status); return false; }
int main(int ac, char *av[]) { if(ac > 2) { std::auto_ptr<QCoreApplication> cmd; { for (int i = 1; i < ac; ++i) if (std::string(av[i]) == std::string("--action=cnt") || std::string(av[i]) == std::string("--action=vis")) { cmd.reset(new QApplication(ac, av)); std::cout << "Starting GUI-based command line interface." << std::endl; break; } if(!cmd.get()) cmd.reset(new QCoreApplication(ac, av)); } cmd->setOrganizationName("LabSolver"); cmd->setApplicationName("DSI Studio"); try { std::cout << "DSI Studio " << __DATE__ << ", Fang-Cheng Yeh" << std::endl; // options for general options po::options_description desc("reconstruction options"); desc.add_options() ("help", "help message") ("action", po::value<std::string>(), "rec:diffusion reconstruction trk:fiber tracking") ("source", po::value<std::string>(), "assign the .src or .fib file name") ; po::variables_map vm; po::store(po::command_line_parser(ac, av).options(desc).allow_unregistered().run(),vm); if (vm.count("help")) { std::cout << "example: perform reconstruction" << std::endl; std::cout << " --action=rec --source=test.src.gz --method=4 " << std::endl; std::cout << "example: perform fiber tracking" << std::endl; std::cout << " --action=trk --source=test.src.gz.fib.gz --method=0 --fiber_count=5000" << std::endl; return 1; } if (!vm.count("action") || !vm.count("source")) { std::cout << "invalid command, use --help for more detail" << std::endl; return 1; } if(vm["action"].as<std::string>() == std::string("rec")) return rec(ac,av); if(vm["action"].as<std::string>() == std::string("trk")) return trk(ac,av); if(vm["action"].as<std::string>() == std::string("src")) return src(ac,av); if(vm["action"].as<std::string>() == std::string("ana")) return ana(ac,av); if(vm["action"].as<std::string>() == std::string("exp")) return exp(ac,av); if(vm["action"].as<std::string>() == std::string("atl")) return atl(ac,av); if(vm["action"].as<std::string>() == std::string("cnt")) return cnt(ac,av); if(vm["action"].as<std::string>() == std::string("vis")) return vis(ac,av); std::cout << "invalid command, use --help for more detail" << std::endl; return 1; } catch(const std::exception& e ) { std::cout << e.what() << std::endl; } catch(...) { std::cout << "unknown error occured" << std::endl; } return 1; } QApplication a(ac,av); a.setOrganizationName("LabSolver"); a.setApplicationName("DSI Studio"); QFont font; font.setFamily(QString::fromUtf8("Arial")); a.setFont(font); // load template if(!fa_template_imp.load_from_file()) { QMessageBox::information(0,"Error","Cannot find HCP488_QA.nii.gz in file directory",0); return false; } // load atlas load_atlas(); MainWindow w; w.setFont(font); w.show(); w.setWindowTitle(QString("DSI Studio ") + __DATE__ + " build"); return a.exec(); }