void GenericReconCartesianNonLinearSpirit2DTGadget::perform_unwrapping(IsmrmrdReconBit& recon_bit, ReconObjType& recon_obj, size_t e) { try { size_t RO = recon_bit.data_.data_.get_size(0); size_t E1 = recon_bit.data_.data_.get_size(1); size_t E2 = recon_bit.data_.data_.get_size(2); size_t dstCHA = recon_bit.data_.data_.get_size(3); size_t N = recon_bit.data_.data_.get_size(4); size_t S = recon_bit.data_.data_.get_size(5); size_t SLC = recon_bit.data_.data_.get_size(6); hoNDArray< std::complex<float> >& src = recon_obj.ref_calib_; size_t ref_RO = src.get_size(0); size_t ref_E1 = src.get_size(1); size_t ref_E2 = src.get_size(2); size_t srcCHA = src.get_size(3); size_t ref_N = src.get_size(4); size_t ref_S = src.get_size(5); size_t ref_SLC = src.get_size(6); size_t convkRO = recon_obj.kernel_.get_size(0); size_t convkE1 = recon_obj.kernel_.get_size(1); size_t convkE2 = recon_obj.kernel_.get_size(2); recon_obj.recon_res_.data_.create(RO, E1, E2, 1, N, S, SLC); Gadgetron::clear(recon_obj.recon_res_.data_); recon_obj.full_kspace_ = recon_bit.data_.data_; Gadgetron::clear(recon_obj.full_kspace_); std::stringstream os; os << "encoding_" << e; std::string suffix = os.str(); if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(recon_bit.data_.data_, debug_folder_full_path_ + "data_src_" + suffix); } // ------------------------------------------------------------------ // compute effective acceleration factor // ------------------------------------------------------------------ float effective_acce_factor(1), snr_scaling_ratio(1); this->compute_snr_scaling_factor(recon_bit, effective_acce_factor, snr_scaling_ratio); if (effective_acce_factor > 1) { Gadgetron::scal(snr_scaling_ratio, recon_bit.data_.data_); } Gadgetron::GadgetronTimer timer(false); // ------------------------------------------------------------------ // compute the reconstruction // ------------------------------------------------------------------ if(this->acceFactorE1_[e]<=1 && this->acceFactorE2_[e]<=1) { recon_obj.full_kspace_ = recon_bit.data_.data_; } else { hoNDArray< std::complex<float> >& kspace = recon_bit.data_.data_; hoNDArray< std::complex<float> >& res = recon_obj.full_kspace_; hoNDArray< std::complex<float> >& ref = recon_obj.ref_calib_; GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_parallel_imaging_lamda : " << this->spirit_parallel_imaging_lamda.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_image_reg_lamda : " << this->spirit_image_reg_lamda.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_data_fidelity_lamda : " << this->spirit_data_fidelity_lamda.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_nl_iter_max : " << this->spirit_nl_iter_max.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_nl_iter_thres : " << this->spirit_nl_iter_thres.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_name : " << this->spirit_reg_name.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_level : " << this->spirit_reg_level.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_keep_approx_coeff : " << this->spirit_reg_keep_approx_coeff.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_keep_redundant_dimension_coeff : " << this->spirit_reg_keep_redundant_dimension_coeff.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_proximity_across_cha : " << this->spirit_reg_proximity_across_cha.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_use_coil_sen_map : " << this->spirit_reg_use_coil_sen_map.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_RO_weighting_ratio : " << this->spirit_reg_RO_weighting_ratio.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_E1_weighting_ratio : " << this->spirit_reg_E1_weighting_ratio.value()); GDEBUG_CONDITION_STREAM(this->verbose.value(), "spirit_reg_N_weighting_ratio : " << this->spirit_reg_N_weighting_ratio.value()); size_t slc, s; for (slc = 0; slc < SLC; slc++) { for (s = 0; s < S; s++) { std::stringstream os; os << "encoding_" << e << "_s" << s << "_slc" << slc; std::string suffix_2DT = os.str(); // ------------------------------ std::complex<float>* pKspace = &kspace(0, 0, 0, 0, 0, s, slc); hoNDArray< std::complex<float> > kspace2DT(RO, E1, E2, dstCHA, N, 1, 1, pKspace); // ------------------------------ long long kernelS = s; if (kernelS >= (long long)ref_S) kernelS = (long long)ref_S - 1; std::complex<float>* pKIm = &recon_obj.kernelIm2D_(0, 0, 0, 0, 0, kernelS, slc); hoNDArray< std::complex<float> > kIm2DT(RO, E1, srcCHA, dstCHA, ref_N, 1, 1, pKIm); // ------------------------------ std::complex<float>* pRef = &ref(0, 0, 0, 0, 0, kernelS, slc); hoNDArray< std::complex<float> > ref2DT(ref.get_size(0), ref.get_size(1), ref.get_size(2), dstCHA, ref_N, 1, 1, pRef); // ------------------------------ hoNDArray< std::complex<float> > coilMap2DT; if (recon_obj.coil_map_.get_size(6) == SLC) { size_t coil_S = recon_obj.coil_map_.get_size(5); std::complex<float>* pCoilMap = &recon_obj.coil_map_(0, 0, 0, 0, 0, ((s>=coil_S) ? coil_S-1 : s), slc); coilMap2DT.create(RO, E1, E2, dstCHA, ref_N, 1, 1, pCoilMap); } // ------------------------------ std::complex<float>* pRes = &res(0, 0, 0, 0, 0, s, slc); hoNDArray< std::complex<float> > res2DT(RO, E1, E2, dstCHA, N, 1, 1, pRes); // ------------------------------ if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(kspace2DT, debug_folder_full_path_ + "kspace2DT_nl_spirit_" + suffix_2DT); } if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(kIm2DT, debug_folder_full_path_ + "kIm2DT_nl_spirit_" + suffix_2DT); } if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(ref2DT, debug_folder_full_path_ + "ref2DT_nl_spirit_" + suffix_2DT); } // ------------------------------ std::string timing_str = "SPIRIT, Non-linear unwrapping, 2DT_" + suffix_2DT; if (this->perform_timing.value()) timer.start(timing_str.c_str()); this->perform_nonlinear_spirit_unwrapping(kspace2DT, kIm2DT, ref2DT, coilMap2DT, res2DT, e); if (this->perform_timing.value()) timer.stop(); if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(res2DT, debug_folder_full_path_ + "res_nl_spirit_2DT_" + suffix_2DT); } } } } // --------------------------------------------------------------------- // compute coil combined images // --------------------------------------------------------------------- if (this->perform_timing.value()) timer.start("SPIRIT Non linear, coil combination ... "); this->perform_spirit_coil_combine(recon_obj); if (this->perform_timing.value()) timer.stop(); if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(recon_obj.recon_res_.data_, debug_folder_full_path_ + "unwrappedIm_" + suffix); } } catch (...) { GADGET_THROW("Errors happened in GenericReconCartesianNonLinearSpirit2DTGadget::perform_unwrapping(...) ... "); } }