Exemplo n.º 1
0
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();
}
Exemplo n.º 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();
}