bool gtPlusIOWorker::open() { try { if ( fid_.is_open() ) { fid_.close(); } if ( readFlag_ ) { fid_.open(ioTag_.c_str(), std::ios::in | std::ios::binary); } else { fid_.open(ioTag_.c_str(), std::ios::out | std::ios::binary); } if ( !fid_ ) { GERROR_STREAM("gtPlusIOWorker::open() cannot open file stream : " << ioTag_); return false; } } catch(...) { GERROR_STREAM("Errors in gtPlusIOWorker::open() ... "); return false; } return true; }
template <class T> void ht_grappa_solve_spd_system(hoNDArray<T> *A, hoNDArray<T> *B) { /* We are swithcing off OpenMP threading before this call to posv. There seems to be a bad interaction between openmp, cuda, and BLAS. So far this problem has only been observed from *.cu files (or in functions called from *.cu files) but the problem may be more general. This is a temporary fix that we should keep an eye on. */ hoNDArray<T> A_ori; A_ori = *A; try { posv(*A, *B); } catch(...) { // it is found that if signal is very very high, the posv can throw exceptions due to ill-conditioned matrix of A // hesv does not require A to be a positive-definite matrix, but an n-by-n symmetric matrix GERROR_STREAM("ht_grappa_solve_spd_system : posv(*A, *B) throws exceptions ... "); *A = A_ori; hesv(*A, *B); GERROR_STREAM("ht_grappa_solve_spd_system : hesv(*A, *B) is called "); } }
gtPlusIOWorker::~gtPlusIOWorker() { if ( !close() ) { GERROR_STREAM("Errors in gtPlusIOWorker::~gtPlusIOWorker() ... "); } }
bool getISMRMRMetaValues(const ISMRMRD::MetaContainer& attrib, const std::string& name, std::vector<std::string>& v) { try { size_t num = attrib.length(name.c_str()); if ( num == 0 ) { v.clear(); GWARN_STREAM("getISMRMRMetaValues, can not find field : " << name); return true; } v.resize(num); size_t ii; for ( ii=0; ii<num; ii++ ) { v[ii] = std::string( attrib.as_str(name.c_str(), ii) ); } } catch(...) { GERROR_STREAM("Error happened in getISMRMRMetaValues(const ISMRMRD::MetaContainer& attrib, const std::string& name, std::vector<std::string>& v) ... "); return false; } return true; }
template <typename T> EXPORTGTPLPLOT bool plotCurves(const std::vector<hoNDArray<T> >& x, const std::vector<hoNDArray<T> >& y, const std::string& xlabel, const std::string& ylabel, const std::string& title, const std::vector<std::string>& legend, const std::vector<std::string>& symbols, size_t xsize, size_t ysize, bool trueColor, bool drawLine, hoNDArray<float>& plotIm) { try { GADGET_CHECK_RETURN_FALSE(x.size()>0); GADGET_CHECK_RETURN_FALSE(y.size()>0); GADGET_CHECK_RETURN_FALSE(x.size() == y.size()); T xlim[2], ylim[2]; findDataRange(x, y, xlim[0], xlim[1], ylim[0], ylim[1]); return Gadgetron::plotCurves(x, y, xlabel, ylabel, title, legend, symbols, xsize, ysize, xlim, ylim, trueColor, drawLine, plotIm); } catch(...) { GERROR_STREAM("Errors happened in plotCurves(...) ... "); return false; } return true; }
bool findEncodingLimits(ISMRMRD::IsmrmrdHeader& h, ISMRMRD::EncodingCounters& meas_max_idx, bool verbose) { try { ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; meas_max_idx.kspace_encode_step_1 = (uint16_t)e_space.matrixSize.y-1; meas_max_idx.set = (e_limits.set && (e_limits.set->maximum>0)) ? e_limits.set->maximum : 0; meas_max_idx.phase = (e_limits.phase && (e_limits.phase->maximum>0)) ? e_limits.phase->maximum : 0; meas_max_idx.kspace_encode_step_2 = (uint16_t)e_space.matrixSize.z-1; meas_max_idx.contrast = (e_limits.contrast && (e_limits.contrast->maximum > 0)) ? e_limits.contrast->maximum : 0; meas_max_idx.slice = (e_limits.slice && (e_limits.slice->maximum > 0)) ? e_limits.slice->maximum : 0; meas_max_idx.repetition = e_limits.repetition ? e_limits.repetition->maximum : 0; meas_max_idx.average = e_limits.average ? e_limits.average->maximum : 0; // always combine the SEG meas_max_idx.segment = 0; } catch(...) { GERROR_STREAM("Error happened in findEncodingLimits(...) ... "); return false; } return true; }
bool appendISMRMRMetaValues(ISMRMRD::MetaContainer& attrib, const std::string& name, const std::vector<std::string>& v) { try { size_t num = v.size(); if ( num == 0 ) { GWARN_STREAM("appendISMRMRMetaValues, input vector is empty ... " << name); return true; } attrib.append(name.c_str(), v[0].c_str()); size_t ii; for ( ii=1; ii<v.size(); ii++ ) { attrib.append(name.c_str(), v[ii].c_str()); } } catch(...) { GERROR_STREAM("Error happened in appendISMRMRMetaValues(ISMRMRD::MetaContainer& attrib, const std::string& name, const std::vector<std::string>& v) ... "); return false; } return true; }
bool NoiseAdjustGadget::saveNoiseCovariance() { char* buf = NULL; size_t len(0); //Do we have any noise? if (noise_covariance_matrixf_.get_number_of_elements() == 0) { return true; } //Scale the covariance matrix before saving hoNDArray< std::complex<float> > covf(noise_covariance_matrixf_); if (number_of_noise_samples_ > 1) { covf *= std::complex<float>(1.0/(float)(number_of_noise_samples_-1),0.0); } if ( !covf.serialize(buf, len) ) { GDEBUG("Noise covariance serialization failed ...\n"); return false; } std::stringstream xml_ss; ISMRMRD::serialize(current_ismrmrd_header_, xml_ss); std::string xml_str = xml_ss.str(); uint32_t xml_length = static_cast<uint32_t>(xml_str.size()); std::ofstream outfile; std::string filename = this->generateNoiseDependencyFilename(measurement_id_); outfile.open (filename.c_str(), std::ios::out|std::ios::binary); if (outfile.good()) { GDEBUG("write out the noise dependency file : %s\n", filename.c_str()); outfile.write( reinterpret_cast<char*>(&xml_length), 4); outfile.write( xml_str.c_str(), xml_length ); outfile.write( reinterpret_cast<char*>(&noise_dwell_time_us_), sizeof(float)); outfile.write( reinterpret_cast<char*>(&len), sizeof(size_t)); outfile.write(buf, len); outfile.close(); // set the permission for the noise file to be rewritable #ifndef _WIN32 int res = chmod(filename.c_str(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); if ( res != 0 ) { GDEBUG("Changing noise prewhitener file permission failed ...\n"); } #endif // _WIN32 } else { delete [] buf; GERROR_STREAM("Noise prewhitener file is not good for writing"); return false; } delete [] buf; return true; }
bool prepOpenMP() { try { GDEBUG_STREAM("--> OpenMP info <--"); GDEBUG_STREAM("--------------------------------------------------------"); int numOpenMPProcs = omp_get_num_procs(); GDEBUG_STREAM("GtPlusRecon, numOpenMPProcs : " << numOpenMPProcs); #ifndef WIN32 int maxOpenMPLevels = omp_get_max_active_levels(); GDEBUG_STREAM("GtPlusRecon, maxOpenMPLevels : " << maxOpenMPLevels); #endif // WIN32 int maxOpenMPThreads = omp_get_max_threads(); GDEBUG_STREAM("GtPlusRecon, maxOpenMPThreads : " << maxOpenMPThreads); if ( numOpenMPProcs != maxOpenMPThreads ) { GDEBUG_STREAM("GtPlusRecon, numOpenMPProcs != maxOpenMPThreads , hyperthreading must be disabled ... "); omp_set_num_threads(numOpenMPProcs); } // omp_set_nested(1); int allowOpenMPNested = omp_get_nested(); GDEBUG_STREAM("GtPlusRecon, allowOpenMPNested : " << allowOpenMPNested); #ifdef WIN32 GDEBUG_STREAM("----------------------------------"); GDEBUG_STREAM("GtPlus, set thread affinity ... "); /// lock the threads #pragma omp parallel default(shared) { int tid = omp_get_thread_num(); DWORD_PTR mask = (1 << tid); GDEBUG_STREAM("thread id : " << tid << " - mask : " << mask); SetThreadAffinityMask( GetCurrentThread(), mask ); } #endif // WIN32 GDEBUG_STREAM("--------------------------------------------------------"); } catch(...) { GERROR_STREAM("Errors in GtPlus prepOpenMP() ... "); return false; } return true; }
bool gtPlusIOWorker::close() { try { if ( fid_.is_open() ) { fid_.close(); } } catch (...) { GERROR_STREAM("Errors in gtPlusIOWorker::close() ... "); return false; } return true; }
bool estimateMaxSEGForRetroGating(Gadgetron::ISMRMRDCALIBMODE CalibMode, double acceFactorE1, double acceFactorE2, size_t retro_gated_segment_size, uint16_t E1, uint16_t embedded_ref_lines_E1, uint16_t E2, uint16_t embedded_ref_lines_E2, uint16_t& segment, bool verbose) { try { if ( acceFactorE2 <= 1 ) { if ( CalibMode == ISMRMRD_embedded ) { segment = (uint16_t)std::ceil( (double)E1/acceFactorE1/retro_gated_segment_size + (acceFactorE1-1)*(double)embedded_ref_lines_E1/acceFactorE1/retro_gated_segment_size ); } else { segment = (uint16_t)std::ceil( (double)E1/acceFactorE1/retro_gated_segment_size ); } } else { if ( CalibMode == ISMRMRD_embedded ) { segment = (uint16_t)std::ceil( (double)E1*E2/(acceFactorE1*acceFactorE2*retro_gated_segment_size) + (acceFactorE1*acceFactorE2-1)*(double)(embedded_ref_lines_E1*embedded_ref_lines_E2)/(acceFactorE1*acceFactorE2*retro_gated_segment_size) ); } else { segment = (uint16_t)std::ceil( (double)E1*E2/(acceFactorE1*acceFactorE2*retro_gated_segment_size) ); } } if ( segment > 1 ) segment--; } catch(...) { GERROR_STREAM("Error happened in estimateMaxSEGForRetroGating(...) ... "); return false; } return true; }
int CmrParametricT2MappingGadget::perform_mapping(IsmrmrdImageArray& data, IsmrmrdImageArray& map, IsmrmrdImageArray& para, IsmrmrdImageArray& map_sd, IsmrmrdImageArray& para_sd) { try { if (perform_timing.value()) { gt_timer_.start("CmrParametricT2MappingGadget::perform_mapping"); } GDEBUG_CONDITION_STREAM(verbose.value(), "CmrParametricT2MappingGadget::perform_mapping(...) starts ... "); size_t RO = data.data_.get_size(0); size_t E1 = data.data_.get_size(1); size_t E2 = data.data_.get_size(2); size_t CHA = data.data_.get_size(3); size_t N = data.data_.get_size(4); size_t S = data.data_.get_size(5); size_t SLC = data.data_.get_size(6); size_t ro, e1, s, slc, p; GADGET_CHECK_RETURN(E2 == 1, GADGET_FAIL); GADGET_CHECK_RETURN(CHA == 1, GADGET_FAIL); GADGET_CHECK_RETURN(this->prep_times_.size() >= N, GADGET_FAIL); hoNDArray<float> mag; Gadgetron::abs(data.data_, mag); if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array(mag, debug_folder_full_path_ + "CmrParametricT2Mapping_data_mag"); } bool need_sd_map = send_sd_map.value(); Gadgetron::GadgetronTimer gt_timer(false); // ------------------------------------------------------------- // set mapping parameters Gadgetron::CmrT2Mapping<float> t2_mapper; t2_mapper.fill_holes_in_maps_ = perform_hole_filling.value(); t2_mapper.max_size_of_holes_ = max_size_hole.value(); t2_mapper.compute_SD_maps_ = need_sd_map; t2_mapper.ti_.resize(N, 0); memcpy(&(t2_mapper.ti_)[0], &this->prep_times_[0], sizeof(float)*N); t2_mapper.data_.create(RO, E1, N, S, SLC, mag.begin()); t2_mapper.max_iter_ = max_iter.value(); t2_mapper.thres_fun_ = thres_func.value(); t2_mapper.max_map_value_ = max_T2.value(); t2_mapper.verbose_ = verbose.value(); t2_mapper.debug_folder_ = debug_folder_full_path_; t2_mapper.perform_timing_ = perform_timing.value(); // ------------------------------------------------------------- // compute mask if needed if (mapping_with_masking.value()) { t2_mapper.mask_for_mapping_.create(RO, E1, SLC); // get the image with shortest prep time hoNDArray<float> mag_shortest_TE; mag_shortest_TE.create(RO, E1, SLC); for (slc = 0; slc < SLC; slc++) { size_t ind = 0; float min_te = this->prep_times_[0]; for (size_t n = 1; n < this->prep_times_.size(); n++) { if(this->prep_times_[n]<min_te) { min_te = this->prep_times_[n]; ind = n; } } memcpy(&mag_shortest_TE(0, 0, slc), &mag(0, 0, ind, 0, slc), sizeof(float)*RO*E1); } if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array(mag_shortest_TE, debug_folder_full_path_ + "CmrParametricT2Mapping_mag_shortest_TE"); } double scale_factor = 1.0; if (data.meta_[0].length(GADGETRON_IMAGE_SCALE_RATIO) > 0) { scale_factor = data.meta_[0].as_double(GADGETRON_IMAGE_SCALE_RATIO); } GDEBUG_STREAM("CmrParametricT2MappingGadget, find incoming image has scale factor of " << scale_factor); if (perform_timing.value()) { gt_timer.start("CmrParametricT2MappingGadget::compute_mask_for_mapping"); } this->compute_mask_for_mapping(mag, t2_mapper.mask_for_mapping_, (float)scale_factor); if (perform_timing.value()) { gt_timer.stop(); } if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array(t2_mapper.mask_for_mapping_, debug_folder_full_path_ + "CmrParametricT2Mapping_mask_for_mapping"); } } // ------------------------------------------------------------- // perform mapping if (perform_timing.value()) { gt_timer.start("CmrParametricT2MappingGadget, t2_mapper.perform_parametric_mapping"); } t2_mapper.perform_parametric_mapping(); if (perform_timing.value()) { gt_timer.stop(); } size_t num_para = t2_mapper.get_num_of_paras(); // ------------------------------------------------------------- // get the results map.data_.create(RO, E1, E2, CHA, 1, S, SLC); Gadgetron::clear(map.data_); map.headers_.create(1, S, SLC); map.meta_.resize(S*SLC); para.data_.create(RO, E1, E2, CHA, num_para, S, SLC); Gadgetron::clear(para.data_); para.headers_.create(num_para, S, SLC); para.meta_.resize(num_para*S*SLC); if (need_sd_map) { map_sd.data_.create(RO, E1, E2, CHA, 1, S, SLC); Gadgetron::clear(map_sd.data_); map_sd.headers_.create(1, S, SLC); map_sd.meta_.resize(S*SLC); para_sd.data_.create(RO, E1, E2, CHA, num_para, S, SLC); Gadgetron::clear(para_sd.data_); para_sd.headers_.create(num_para, S, SLC); para_sd.meta_.resize(num_para*S*SLC); } for (slc = 0; slc < SLC; slc++) { for (s = 0; s < S; s++) { for (e1 = 0; e1 < E1; e1++) { for (ro = 0; ro < RO; ro++) { map.data_(ro, e1, 0, 0, 0, s, slc) = t2_mapper.map_(ro, e1, s, slc); if (need_sd_map) { map_sd.data_(ro, e1, 0, 0, 0, s, slc) = t2_mapper.sd_map_(ro, e1, s, slc); } for (p = 0; p < num_para; p++) { para.data_(ro, e1, 0, 0, p, s, slc) = t2_mapper.para_(ro, e1, p, s, slc); if (need_sd_map) { para_sd.data_(ro, e1, 0, 0, p, s, slc) = t2_mapper.sd_para_(ro, e1, p, s, slc); } } } } size_t slc_ind = data.headers_(0, s, slc).slice; map.headers_(0, s, slc) = data.headers_(0, s, slc); map.headers_(0, s, slc).image_index = 1 + slc_ind; map.headers_(0, s, slc).image_series_index = 11; map.meta_[s+slc*S] = data.meta_[s + slc*S]; map.meta_[s + slc*S].set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_T2MAP); map.meta_[s + slc*S].append(GADGETRON_SEQUENCEDESCRIPTION, GADGETRON_IMAGE_T2MAP); map.meta_[s + slc*S].append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_T2MAP); map_sd.headers_(0, s, slc) = data.headers_(0, s, slc); map_sd.headers_(0, s, slc).image_index = 1 + slc_ind; map_sd.headers_(0, s, slc).image_series_index = 12; map_sd.meta_[s + slc*S] = data.meta_[s + slc*S]; map_sd.meta_[s + slc*S].set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_T2SDMAP); map_sd.meta_[s + slc*S].append(GADGETRON_SEQUENCEDESCRIPTION, GADGETRON_IMAGE_T2SDMAP); map_sd.meta_[s + slc*S].append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_T2SDMAP); if (need_sd_map) { for (p = 0; p < num_para; p++) { para.headers_(p, s, slc) = data.headers_(0, s, slc); para.headers_(p, s, slc).image_index = 1 + p + slc_ind*num_para; para.meta_[p + s*num_para + slc*num_para*S] = data.meta_[s + slc*S]; para_sd.headers_(p, s, slc) = data.headers_(0, s, slc); para_sd.headers_(p, s, slc).image_index = 1 + p + slc_ind*num_para; para_sd.meta_[p + s*num_para + slc*num_para*S] = data.meta_[s + slc*S]; } } } } // ------------------------------------------------------------- if (perform_timing.value()) { gt_timer_.stop(); } } catch (...) { GERROR_STREAM("Exceptions happened in CmrParametricT2MappingGadget::perform_mapping(...) ... "); return GADGET_FAIL; } return GADGET_OK; }
int GenericReconFieldOfViewAdjustmentGadget::adjust_FOV(IsmrmrdImageArray& recon_res) { try { size_t RO = recon_res.data_.get_size(0); size_t E1 = recon_res.data_.get_size(1); size_t E2 = recon_res.data_.get_size(2); double encodingFOV_RO = recon_res.meta_[0].as_double("encoding_FOV", 0); double encodingFOV_E1 = recon_res.meta_[0].as_double("encoding_FOV", 1); double encodingFOV_E2 = recon_res.meta_[0].as_double("encoding_FOV", 2); double reconFOV_RO = recon_res.meta_[0].as_double("recon_FOV", 0); double reconFOV_E1 = recon_res.meta_[0].as_double("recon_FOV", 1); double reconFOV_E2 = recon_res.meta_[0].as_double("recon_FOV", 2); long encoding = recon_res.meta_[0].as_long("encoding", 0); size_t reconSizeRO = recon_size_[encoding][0]; size_t reconSizeE1 = recon_size_[encoding][1]; size_t reconSizeE2 = recon_size_[encoding][2]; // if 2D reconstruction, no need to process along E2 if (E2 <= 1) { reconSizeE2 = E2; reconFOV_E2 = encodingFOV_E2; } // if encoded FOV are the same as recon FOV if ((std::abs(encodingFOV_RO / 2 - reconFOV_RO)<0.1) && (std::abs(encodingFOV_E1 - reconFOV_E1)<0.1) && (std::abs(encodingFOV_E2 - reconFOV_E2)<0.1)) { if (RO <= reconSizeRO && E1 <= reconSizeE1 && E2 <= reconSizeE2) { Gadgetron::zero_pad_resize(recon_res.data_, reconSizeRO, reconSizeE1, reconSizeE2, res_); } else if (RO >= reconSizeRO && E1 >= reconSizeE1 && E2 >= reconSizeE2) { this->perform_fft(E2, recon_res.data_, kspace_buf_); Gadgetron::crop(reconSizeRO, reconSizeE1, reconSizeE2, &kspace_buf_, &res_); this->perform_ifft(E2, res_, recon_res.data_); } else { GDEBUG_STREAM("Inconsistent image size [" << RO << " " << E1 << " " << E2 << "]; recon image size [" << reconSizeRO << " " << reconSizeE1 << " " << reconSizeE2 << "] ... "); return GADGET_FAIL; } } else if ((encodingFOV_E1 >= reconFOV_E1) && (encodingFOV_E2 >= reconFOV_E2)) { size_t encodingE1 = reconSizeE1; if (encodingFOV_E1 > reconFOV_E1) { double spacingE1 = reconFOV_E1 / reconSizeE1; encodingE1 = (size_t)std::floor(encodingFOV_E1 / spacingE1 + 0.5); } size_t encodingE2 = reconSizeE2; if (encodingFOV_E2 > reconFOV_E2) { double spacingE2 = reconFOV_E2 / reconSizeE2; encodingE2 = (size_t)std::floor(encodingFOV_E2 / spacingE2 + 0.5); } hoNDArray< std::complex<float> >* pSrc = &recon_res.data_; hoNDArray< std::complex<float> >* pDst = &res_; hoNDArray< std::complex<float> >* pTmp; // adjust E1 if (encodingE1 >= E1 + 1) { Gadgetron::zero_pad_resize(*pSrc, RO, encodingE1, E2, *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } else if (encodingE1 <= E1 - 1) { this->perform_fft(E2, *pSrc, kspace_buf_); Gadgetron::crop(RO, encodingE1, E2, &kspace_buf_, pDst); this->perform_ifft(E2, *pDst, *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } // adjust E2 if (encodingE2 >= E2 + 1) { Gadgetron::zero_pad_resize(*pSrc, RO, pSrc->get_size(1), encodingE2, *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } else if (encodingE2 <= E2 - 1) { this->perform_fft(E2, *pSrc, kspace_buf_); Gadgetron::crop(RO, pSrc->get_size(1), encodingE2, &kspace_buf_, pDst); this->perform_ifft(E2, *pDst, *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } //adjust RO if (RO < reconSizeRO) { Gadgetron::zero_pad_resize(*pSrc, reconSizeRO, pSrc->get_size(1), pSrc->get_size(2), *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } else if (RO > reconSizeRO) { this->perform_fft(E2, *pSrc, kspace_buf_); Gadgetron::crop(reconSizeRO, pSrc->get_size(1), pSrc->get_size(2), &kspace_buf_, pDst); this->perform_ifft(E2, *pDst, *pDst); pTmp = pSrc; pSrc = pDst; pDst = pTmp; } // final cut on image GADGET_CHECK_EXCEPTION_RETURN_FALSE(Gadgetron::crop(reconSizeRO, reconSizeE1, reconSizeE2, pSrc, pDst)); if (pDst != &recon_res.data_) { recon_res.data_ = *pDst; } } } catch (...) { GERROR_STREAM("Errors in GenericReconFieldOfViewAdjustmentGadget::adjust_FOV(IsmrmrdImageArray& data) ... "); return GADGET_FAIL; } return GADGET_OK; }
int MultiChannelCartesianGrappaReconGadget::send_out_image_array(IsmrmrdReconBit& recon_bit, IsmrmrdImageArray& res, size_t encoding, int series_num, const std::string& data_role) { try { size_t RO = res.data_.get_size(0); size_t E1 = res.data_.get_size(1); size_t E2 = res.data_.get_size(2); size_t CHA = res.data_.get_size(3); size_t N = res.data_.get_size(4); size_t S = res.data_.get_size(5); size_t SLC = res.data_.get_size(6); GDEBUG_CONDITION_STREAM(true, "sending out image array, acquisition boundary [RO E1 E2 CHA N S SLC] = [" << RO << " " << E1 << " " << E2 << " " << CHA << " " << N << " " << S << " " << SLC << "] "); // compute image numbers and fill the image meta size_t n, s, slc; for (slc = 0; slc < SLC; slc++) { for (s = 0; s < S; s++) { for (n = 0; n < N; n++) { ISMRMRD::ImageHeader header = res.headers_(n, s, slc); if (header.measurement_uid == 0) continue; res.headers_(n, s, slc).image_index = (uint16_t)this->compute_image_number(res.headers_(n, s, slc), encoding, CHA, 0, E2); res.headers_(n, s, slc).image_series_index = series_num; size_t offset = n + s*N + slc*N*S; res.meta_[offset].set(GADGETRON_IMAGENUMBER, (long)res.headers_(n, s, slc).image_index); res.meta_[offset].set(GADGETRON_IMAGEPROCESSINGHISTORY, "GT"); if (data_role == GADGETRON_IMAGE_REGULAR) { res.headers_(n, s, slc).image_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; res.meta_[offset].append(GADGETRON_IMAGECOMMENT, "GT"); res.meta_[offset].append(GADGETRON_SEQUENCEDESCRIPTION, "_GT"); res.meta_[offset].set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_REGULAR); } else if (data_role == GADGETRON_IMAGE_GFACTOR) { res.headers_(n, s, slc).image_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; res.meta_[offset].append(GADGETRON_IMAGECOMMENT, GADGETRON_IMAGE_GFACTOR); res.meta_[offset].append(GADGETRON_SEQUENCEDESCRIPTION, GADGETRON_IMAGE_GFACTOR); res.meta_[offset].set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_GFACTOR); // set the skip processing flag, so gfactor map will not be processed during e.g. partial fourier handling or kspace filter gadgets res.meta_[offset].set(GADGETRON_SKIP_PROCESSING_AFTER_RECON, (long)1); // set the flag to use dedicated scaling factor res.meta_[offset].set(GADGETRON_USE_DEDICATED_SCALING_FACTOR, (long)1); } if (verbose.value()) { for (size_t cha = 0; cha < CHA; cha++) { GDEBUG_STREAM("sending out " << data_role << " image [CHA SLC CON PHS REP SET AVE] = [" << cha << " "<< res.headers_(n, s, slc).slice << " " << res.headers_(n, s, slc).contrast << " "<< res.headers_(n, s, slc).phase << " " << res.headers_(n, s, slc).repetition << " " << res.headers_(n, s, slc).set << " " << res.headers_(n, s, slc).average << " " << "] "<< " -- Image number -- " << res.headers_(n, s, slc).image_index); } } } } } // send out the images Gadgetron::GadgetContainerMessage<IsmrmrdImageArray>* cm1 = new Gadgetron::GadgetContainerMessage<IsmrmrdImageArray>(); *(cm1->getObjectPtr()) = res; if (this->next()->putq(cm1) < 0) { GERROR_STREAM("Put image array to Q failed ... "); return GADGET_FAIL; } } catch (...) { GERROR_STREAM("Errors in MultiChannelCartesianGrappaReconGadget::send_out_image_array(...) ... "); return GADGET_FAIL; } return GADGET_OK; }
bool findCalibMode(ISMRMRD::IsmrmrdHeader& h, Gadgetron::ISMRMRDCALIBMODE& CalibMode, ISMRMRDDIM& InterleaveDim, double& acceFactorE1, double& acceFactorE2, bool verbose) { try { if (!h.encoding[0].parallelImaging) { GERROR_STREAM("Parallel Imaging section not found in header"); return false; } ISMRMRD::ParallelImaging p_imaging = *h.encoding[0].parallelImaging; acceFactorE1 = (double)(p_imaging.accelerationFactor.kspace_encoding_step_1); acceFactorE2 = (double)(p_imaging.accelerationFactor.kspace_encoding_step_2); GDEBUG_CONDITION_STREAM(verbose, "acceFactorE1 is " << acceFactorE1); GDEBUG_CONDITION_STREAM(verbose, "acceFactorE2 is " << acceFactorE2); if ( !p_imaging.calibrationMode.is_present() ) { GERROR_STREAM("Parallel calibration mode not found in header"); return false; } std::string calib = *p_imaging.calibrationMode; if ( calib.compare("interleaved") == 0 ) { CalibMode = Gadgetron::ISMRMRD_interleaved; GDEBUG_CONDITION_STREAM(verbose, "Calibration mode is interleaved"); if ( p_imaging.interleavingDimension ) { if ( p_imaging.interleavingDimension->compare("phase") == 0 ) { InterleaveDim = Gadgetron::DIM_Phase; } else if ( p_imaging.interleavingDimension->compare("repetition") == 0 ) { InterleaveDim = Gadgetron::DIM_Repetition; } else if ( p_imaging.interleavingDimension->compare("average") == 0 ) { InterleaveDim = Gadgetron::DIM_Average; } else if ( p_imaging.interleavingDimension->compare("contrast") == 0 ) { InterleaveDim = Gadgetron::DIM_Contrast; } else if ( p_imaging.interleavingDimension->compare("other") == 0 ) { InterleaveDim = Gadgetron::DIM_other1; } else { GERROR_STREAM("Unknown interleaving dimension. Bailing out"); return false; } } } else if ( calib.compare("embedded") == 0 ) { CalibMode = Gadgetron::ISMRMRD_embedded; GDEBUG_CONDITION_STREAM(verbose, "Calibration mode is embedded"); } else if ( calib.compare("separate") == 0 ) { CalibMode = Gadgetron::ISMRMRD_separate; GDEBUG_CONDITION_STREAM(verbose, "Calibration mode is separate"); } else if ( calib.compare("external") == 0 ) { CalibMode = Gadgetron::ISMRMRD_external; } else if ( (calib.compare("other") == 0) && acceFactorE1==1 && acceFactorE2==1 ) { CalibMode = Gadgetron::ISMRMRD_noacceleration; acceFactorE1=1; } else if ( (calib.compare("other") == 0) && (acceFactorE1>1 || acceFactorE2>1) ) { CalibMode = Gadgetron::ISMRMRD_interleaved; acceFactorE1=2; InterleaveDim = Gadgetron::DIM_Phase; } else { GERROR_STREAM("Failed to process parallel imaging calibration mode"); return false; } } catch(...) { GERROR_STREAM("Error happened in findCalibMode(...) ... "); return false; } return true; }
// C = A*B bool GeneralMatrixProduct(hoNDArray<float>& C, const hoNDArray<float>& A, bool transA, const hoNDArray<float>& B, bool transB) { try { typedef float T; size_t M = A.get_size(0); size_t K = A.get_size(1); if ( transA ) { M = A.get_size(1); K = A.get_size(0); } size_t K2 = B.get_size(0); size_t N = B.get_size(1); if ( transB ) { K2 = B.get_size(1); N = B.get_size(0); } GADGET_CHECK_RETURN_FALSE(K==K2); if ( (C.get_size(0)!=M) || (C.get_size(1)!=N) ) { C.create(M, N); } const T* pA = A.begin(); const T* pB = B.begin(); T* pC = C.begin(); size_t m, n, k; if ( !transA && !transB ) { for ( m=0; m<M; m++ ) { for ( n=0; n<N; n++ ) { pC[m+n*M] = 0; for ( k=0; k<K; k++ ) { pC[m+n*M] += pA[m+k*M]*pB[k+n*K]; } } } } if ( transA && !transB ) { for ( m=0; m<M; m++ ) { for ( n=0; n<N; n++ ) { pC[m+n*M] = 0; for ( k=0; k<K; k++ ) { pC[m+n*M] += pA[k+m*K]*pB[k+n*K]; } } } } if ( !transA && transB ) { for ( m=0; m<M; m++ ) { for ( n=0; n<N; n++ ) { pC[m+n*M] = 0; for ( k=0; k<K; k++ ) { pC[m+n*M] += pA[m+k*M]*pB[n+k*K]; } } } } if ( transA && transB ) { for ( m=0; m<M; m++ ) { for ( n=0; n<N; n++ ) { pC[m+n*M] = 0; for ( k=0; k<K; k++ ) { pC[m+n*M] += pA[k+m*K]*pB[n+k*K]; } } } } } catch(...) { GERROR_STREAM("Errors in GeneralMatrixProduct(hoNDArray<float>& C, const hoNDArray<float>& A, bool transA, const hoNDArray<float>& B, bool transB) ..."); return false; } return true; }
template <typename T> EXPORTGTPLPLOT bool plotCurves(const std::vector<hoNDArray<T> >& x, const std::vector<hoNDArray<T> >& y, const std::string& xlabel, const std::string& ylabel, const std::string& title, const std::vector<std::string>& legend, const std::vector<std::string>& symbols, size_t xsize, size_t ysize, T xlim[2], T ylim[2], bool trueColor, bool drawLine, hoNDArray<float>& plotIm) { try { GADGET_CHECK_RETURN_FALSE(x.size()>0); GADGET_CHECK_RETURN_FALSE(y.size()>0); GADGET_CHECK_RETURN_FALSE(x.size() == y.size()); T minX = xlim[0]; T maxX = xlim[1]; T minY = ylim[0]; T maxY = ylim[1]; plsdev("mem"); hoNDArray<unsigned char> im; im.create(3, xsize, ysize); Gadgetron::clear(im); plsmem(im.get_size(1), im.get_size(2), im.begin()); plinit(); plfont(2); pladv(0); if (legend.size() == x.size()) { plvpor(0.11, 0.75, 0.1, 0.9); } else { plvpor(0.15, 0.85, 0.1, 0.9); } T spaceX = 0.01*(maxX - minX); T spaceY = 0.05*(maxY - minY); plwind(minX - spaceX, maxX + spaceX, minY - spaceY, maxY + spaceY); plcol0(15); plbox("bgcnst", 0.0, 0, "bgcnstv", 0.0, 0); // int mark[2], space[2]; //mark[0] = 4000; //space[0] = 2500; //plstyl(1, mark, space); size_t num = x.size(); size_t n; hoNDArray<double> xd, yd; // draw lines for (n = 0; n < num; n++) { size_t N = y[n].get_size(0); xd.copyFrom(x[n]); yd.copyFrom(y[n]); if (drawLine) { int c; getPlotColor(n, c); plcol0(c); pllsty(n % 8 + 1); plline(N, xd.begin(), yd.begin()); } std::string gly; if(symbols.size()>n) { gly = symbols[n]; } else getPlotGlyph(n, gly); plstring(N, xd.begin(), yd.begin(), gly.c_str()); } plcol0(15); plmtex("b", 3.2, 0.5, 0.5, xlabel.c_str()); plmtex("t", 2.0, 0.5, 0.5, title.c_str()); plmtex("l", 5.0, 0.5, 0.5, ylabel.c_str()); // draw the legend if (legend.size() == x.size()) { std::vector<PLINT> opt_array(num), text_colors(num), line_colors(num), line_styles(num), symbol_numbers(num), symbol_colors(num); std::vector<PLFLT> symbol_scales(num), line_widths(num), box_scales(num, 1); std::vector<std::string> glyphs(num); std::vector<const char*> symbols(num); PLFLT legend_width, legend_height; std::vector<const char*> legend_text(num); for (n = 0; n < num; n++) { int c; getPlotColor(n, c); getPlotGlyph(n, glyphs[n]); opt_array[n] = PL_LEGEND_SYMBOL | PL_LEGEND_LINE; text_colors[n] = 15; line_colors[n] = c; line_styles[n] = (n%8+1); line_widths[n] = 0.2; symbol_colors[n] = c; symbol_scales[n] = 0.75; symbol_numbers[n] = 1; symbols[n] = glyphs[n].c_str(); legend_text[n] = legend[n].c_str(); } pllegend(&legend_width, &legend_height, PL_LEGEND_BACKGROUND, PL_POSITION_OUTSIDE | PL_POSITION_RIGHT | PL_POSITION_TOP, 0.02, // x 0.0, // y 0.05, // plot_width 0, // bg_color 15, // bb_color 1, // bb_style 0, // nrow 0, // ncolumn num, // nlegend &opt_array[0], 0.05, // text_offset 0.35, // text_scale 1.0, // text_spacing 0.5, // text_justification &text_colors[0], (const char **)(&legend_text[0]), NULL, // box_colors NULL, // box_patterns &box_scales[0], // box_scales NULL, // box_line_widths &line_colors[0], &line_styles[0], &line_widths[0], &symbol_colors[0], &symbol_scales[0], &symbol_numbers[0], (const char **)(&symbols[0]) ); } plend(); outputPlotIm(im, trueColor, plotIm); } catch (...) { GERROR_STREAM("Errors happened in plotCurves(xlim, ylim) ... "); return false; } return true; }
bool checkReadoutStatus(uint64_t flag, int samples, Gadgetron::ISMRMRDCALIBMODE& CalibMode, int roLen, bool& bIsKSpace, bool& bIsRef, bool& bIsNoise, bool& bIsPhaseCorr, bool& bIsReflect, bool& bIsOther, bool& bIsNavigator, bool& bIsRTFeedback, bool& bIsHPFeedback, bool& bIsDummyScan) { try { bIsNoise = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT).isSet(flag); bool is_ref = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION).isSet(flag); bool is_ref_kspace = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING).isSet(flag); bIsReflect = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_REVERSE).isSet(flag); bIsPhaseCorr = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_PHASECORR_DATA).isSet(flag); bIsNavigator = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_NAVIGATION_DATA).isSet(flag); bIsRTFeedback = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_RTFEEDBACK_DATA).isSet(flag); bIsHPFeedback = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_HPFEEDBACK_DATA).isSet(flag); bIsDummyScan = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_DUMMYSCAN_DATA).isSet(flag); bIsKSpace = false; bIsRef = false; bIsOther = false; if ( bIsNoise || bIsDummyScan ) { return true; } if ( CalibMode==ISMRMRD_noacceleration ) { bIsKSpace = true; bIsRef = false; } // in interleaved mode, only store the image data if ( CalibMode==ISMRMRD_interleaved ) { bIsKSpace = true; bIsRef = false; } // in embedded, kspace stores only the undersampled lines // ref stores all lines used for references if ( CalibMode==ISMRMRD_embedded ) { if ( is_ref && !is_ref_kspace ) { bIsKSpace = false; bIsRef = true; } if ( !is_ref && is_ref_kspace ) { bIsKSpace = true; bIsRef = true; } if ( is_ref && is_ref_kspace ) { bIsKSpace = true; bIsRef = true; } if ( !is_ref && !is_ref_kspace ) { bIsKSpace = true; bIsRef = false; } } // in separate mode if ( CalibMode==ISMRMRD_separate || CalibMode==ISMRMRD_external ) { if ( is_ref ) { bIsKSpace = false; bIsRef = true; } if ( !is_ref ) { bIsKSpace = true; bIsRef = false; } } // store other data, e.g. AIF // only for tpat if ( !is_ref && !is_ref_kspace && (samples!=roLen) ) { bIsOther = true; bIsKSpace = false; bIsRef = false; } } catch(...) { GERROR_STREAM("Error happened in checkReadoutStatus(...) ... "); return false; } return true; }
int GenericReconCartesianReferencePrepGadget::process(Gadgetron::GadgetContainerMessage< IsmrmrdReconData >* m1) { if (perform_timing.value()) { gt_timer_.start("GenericReconCartesianReferencePrepGadget::process"); } process_called_times_++; IsmrmrdReconData* recon_bit_ = m1->getObjectPtr(); if (recon_bit_->rbit_.size() > num_encoding_spaces_) { GWARN_STREAM("Incoming recon_bit has more encoding spaces than the protocol : " << recon_bit_->rbit_.size() << " instead of " << num_encoding_spaces_); } // for every encoding space, prepare the recon_bit_->rbit_[e].ref_ size_t e; for (e = 0; e < recon_bit_->rbit_.size(); e++) { auto & rbit = recon_bit_->rbit_[e]; std::stringstream os; os << "_encoding_" << e; // ----------------------------------------- // no acceleration mode // check the availability of ref data // ----------------------------------------- if (calib_mode_[e] == Gadgetron::ISMRMRD_noacceleration) { if (prepare_ref_always_no_acceleration.value() || !ref_prepared_[e]) { // if no ref data is set, make copy the ref point from the data if (!rbit.ref_) { rbit.ref_ = rbit.data_; ref_prepared_[e] = true; } } else { if (ref_prepared_[e]) { if (rbit.ref_) { // remove the ref rbit.ref_ = boost::none; } } continue; } } if (!rbit.ref_) continue; // useful variables hoNDArray< std::complex<float> >& ref = (*rbit.ref_).data_; SamplingLimit sampling_limits[3]; for (int i = 0; i < 3; i++) sampling_limits[i] = (*rbit.ref_).sampling_.sampling_limits_[i]; size_t RO = ref.get_size(0); size_t E1 = ref.get_size(1); size_t E2 = ref.get_size(2); size_t CHA = ref.get_size(3); size_t N = ref.get_size(4); size_t S = ref.get_size(5); size_t SLC = ref.get_size(6); // stored the ref data ready for calibration hoNDArray< std::complex<float> > ref_calib; // ----------------------------------------- // 1) average the ref according to the input parameters; // if interleaved mode, sampling times for every E1/E2 location is detected and line by line averaging is performed // this is required when irregular cartesian sampling is used or number of frames cannot be divided in full by acceleration factor // 2) detect the sampled region and crop the ref data if needed // 3) update the sampling_limits // ----------------------------------------- hoNDArray< std::complex<float> > ref_recon_buf; // step 1 bool count_sampling_freq = (calib_mode_[e] == ISMRMRD_interleaved); GADGET_CHECK_EXCEPTION_RETURN(Gadgetron::compute_averaged_data_N_S(ref, average_all_ref_N.value(), average_all_ref_S.value(), count_sampling_freq, ref_calib), GADGET_FAIL); // step 2, detect sampled region in ref, along E1 and E2 size_t start_E1(0), end_E1(0); auto t = Gadgetron::detect_sampled_region_E1(ref); start_E1 = std::get<0>(t); end_E1 = std::get<1>(t); size_t start_E2(0), end_E2(0); if (E2 > 1) { auto t = Gadgetron::detect_sampled_region_E2(ref); start_E2 = std::get<0>(t); end_E2 = std::get<1>(t); } // crop the ref_calib, along RO, E1 and E2 vector_td<size_t, 3> crop_offset; crop_offset[0] = sampling_limits[0].min_; crop_offset[1] = start_E1; crop_offset[2] = start_E2; vector_td<size_t, 3> crop_size; crop_size[0] = sampling_limits[0].max_ - sampling_limits[0].min_ + 1; crop_size[1] = end_E1 - start_E1 + 1; crop_size[2] = end_E2 - start_E2 + 1; if(crop_size[0]> (ref_calib.get_size(0)-crop_offset[0])) { crop_size[0] = ref_calib.get_size(0) - crop_offset[0]; } Gadgetron::crop(crop_offset, crop_size, &ref_calib, &ref_recon_buf); ref_calib = ref_recon_buf; // step 3, update the sampling limits sampling_limits[0].center_ = (uint16_t)(RO/2); if ( (calib_mode_[e] == Gadgetron::ISMRMRD_interleaved) || (calib_mode_[e] == Gadgetron::ISMRMRD_noacceleration) ) { // need to keep the ref kspace center information sampling_limits[1].min_ = (uint16_t)(start_E1); sampling_limits[1].max_ = (uint16_t)(end_E1); sampling_limits[2].min_ = (uint16_t)(start_E2); sampling_limits[2].max_ = (uint16_t)(end_E2); sampling_limits[1].center_ = (uint16_t)(E1 / 2); sampling_limits[2].center_ = (uint16_t)(E2 / 2); } else { // sepearate, embedded mode, the ref center is the kspace center sampling_limits[1].min_ = 0; sampling_limits[1].max_ = (uint16_t)(end_E1 - start_E1); sampling_limits[2].min_ = 0; sampling_limits[2].max_ = (uint16_t)(end_E2 - start_E2); sampling_limits[1].center_ = (sampling_limits[1].max_ + 1) / 2; sampling_limits[2].center_ = (sampling_limits[2].max_ + 1) / 2; } if(sampling_limits[0].max_>=RO) { sampling_limits[0].max_ = RO - 1; } ref = ref_calib; ref_prepared_[e] = true; for (int i = 0; i < 3; i++) (*rbit.ref_).sampling_.sampling_limits_[i] = sampling_limits[i]; } if (this->next()->putq(m1) < 0) { GERROR_STREAM("Put IsmrmrdReconData to Q failed ... "); return GADGET_FAIL; } if (perform_timing.value()) { gt_timer_.stop(); } return GADGET_OK; }
int WhiteNoiseInjectorGadget::process(GadgetContainerMessage<ISMRMRD::AcquisitionHeader>* m1, GadgetContainerMessage< hoNDArray< std::complex<float> > >* m2) { bool is_noise = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT).isSet(m1->getObjectPtr()->flags); bool is_scc_correction = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA).isSet(m1->getObjectPtr()->flags); bool is_ref = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION).isSet(m1->getObjectPtr()->flags); bool is_ref_kspace = ISMRMRD::FlagBit(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING).isSet(m1->getObjectPtr()->flags); size_t channels = m1->getObjectPtr()->active_channels; size_t samples = m1->getObjectPtr()->number_of_samples; if (!is_noise && !is_scc_correction ) { bool add_noise = true; if ( is_ref && !is_ref_kspace && (is_seperate_||is_external_) ) { add_noise = add_noise_ref_; if ( !add_noise ) { GDEBUG_STREAM("WhiteNoiseInjectorGadget, noise is not added to the ref acquisitions ... "); } } if ( add_noise ) { if ( !noise_.dimensions_equal(m2->getObjectPtr()) ) { noise_.create(m2->getObjectPtr()->get_dimensions()); noise_fl_.create(m2->getObjectPtr()->get_dimensions()); } if ( !randn_->gen(noise_) ) { GERROR_STREAM("WhiteNoiseInjectorGadget, randn_->gen(noise_) failed ... "); return GADGET_FAIL; } if ( !noise_fl_.copyFrom(noise_) ) { GERROR_STREAM("WhiteNoiseInjectorGadget, noise_fl_.copyFrom(noise_) failed ... "); return GADGET_FAIL; } try { Gadgetron::add(*m2->getObjectPtr(), noise_fl_, *m2->getObjectPtr()); } catch(...) { GERROR_STREAM("WhiteNoiseInjectorGadget, Gadgetron::add(*m2->getObjectPtr(), noise_, *m2->getObjectPtr()) failed ... "); return GADGET_FAIL; } } } if (this->next()->putq(m1) == -1) { GERROR("WhiteNoiseInjectorGadget::process, passing data on to next gadget"); return -1; } return GADGET_OK; }
bool plotNoiseStandardDeviation(const hoNDArray< std::complex<T> >& m, const std::vector<std::string>& coilStrings, const std::string& xlabel, const std::string& ylabel, const std::string& title, size_t xsize, size_t ysize, bool trueColor, hoNDArray<float>& plotIm) { try { size_t CHA = m.get_size(0); GADGET_CHECK_RETURN_FALSE(coilStrings.size() == CHA); hoNDArray<double> xd, yd, yd2; xd.create(CHA); yd.create(CHA); size_t c; for (c = 0; c < CHA; c++) { xd(c) = c+1; yd(c) = std::sqrt( std::abs(m(c, c)) ); } double maxY = Gadgetron::max(&yd); yd2 = yd; std::sort(yd2.begin(), yd2.end()); double medY = yd2(CHA / 2); // increase dot line to be 1 sigma ~= 33% double medRange = 0.33; if (maxY < medY*(1 + medRange)) { maxY = medY*(1 + medRange); } hoNDArray<unsigned char> im; im.create(3, xsize, ysize); Gadgetron::clear(im); plsdev("mem"); plsmem(im.get_size(1), im.get_size(2), im.begin()); plinit(); plfont(2); pladv(0); plvpor(0.15, 0.75, 0.1, 0.8); plwind(0, CHA+1, 0, maxY*1.05); plcol0(15); plbox("bcnst", 0.0, 0, "bcnstv", 0.0, 0); std::string gly; getPlotGlyph(0, gly); // circle plstring(CHA, xd.begin(), yd.begin(), gly.c_str()); // draw the median line pllsty(1); double px[2], py[2]; px[0] = 0; px[1] = CHA+1; py[0] = medY; py[1] = medY; plline(2, px, py); pllsty(2); py[0] = medY*(1 - medRange); py[1] = medY*(1 - medRange); plline(2, px, py); py[0] = medY*(1 + medRange); py[1] = medY*(1 + medRange); plline(2, px, py); plmtex("b", 3.2, 0.5, 0.5, xlabel.c_str()); plmtex("t", 2.0, 0.5, 0.5, title.c_str()); plmtex("l", 5.0, 0.5, 0.5, ylabel.c_str()); // draw the legend std::vector<PLINT> opt_array(CHA), text_colors(CHA), line_colors(CHA), line_styles(CHA), symbol_numbers(CHA), symbol_colors(CHA); std::vector<PLFLT> symbol_scales(CHA), line_widths(CHA), box_scales(CHA, 1); std::vector<const char*> symbols(CHA); PLFLT legend_width, legend_height; std::vector<const char*> legend_text(CHA); std::vector<std::string> legends(CHA); size_t n; for (n = 0; n < CHA; n++) { opt_array[n] = PL_LEGEND_SYMBOL; text_colors[n] = 15; line_colors[n] = 15; line_styles[n] = (n % 8 + 1); line_widths[n] = 0.2; symbol_colors[n] = 15; symbol_scales[n] = 0.75; symbol_numbers[n] = 1; symbols[n] = gly.c_str(); std::ostringstream ostr; ostr << n+1 << ":" << coilStrings[n]; legends[n] = ostr.str(); legend_text[n] = legends[n].c_str(); } pllegend(&legend_width, &legend_height, PL_LEGEND_BACKGROUND, PL_POSITION_OUTSIDE | PL_POSITION_RIGHT, 0.02, // x 0.0, // y 0.05, // plot_width 0, // bg_color 15, // bb_color 1, // bb_style 0, // nrow 0, // ncolumn CHA, // nlegend &opt_array[0], 0.05, // text_offset 0.5, // text_scale 1.0, // text_spacing 0.5, // text_justification &text_colors[0], (const char **)(&legend_text[0]), NULL, // box_colors NULL, // box_patterns &box_scales[0], // box_scales NULL, // box_line_widths &line_colors[0], &line_styles[0], &line_widths[0], &symbol_colors[0], &symbol_scales[0], &symbol_numbers[0], (const char **)(&symbols[0]) ); plend(); outputPlotIm(im, trueColor, plotIm); } catch (...) { GERROR_STREAM("Errors happened in plotNoiseStandardDeviation(...) ... "); return false; } return true; }
bool DeviceCoordinateSystemToPatientCoordinateSystem(double& x, double& y, double& z, const std::string& position) { if ( position == "HFS" ) // Head-first supine (HFS) { y = -y; z = -z; } else if ( position == "HFP" ) // Head-first prone (HFP) { x = -x; z = -z; } else if ( position == "HFDR" ) // Head-first decubitus-right { double v = x; x = y; y = v; z = -z; } else if ( position == "HFDL" ) // Head-first decubitus-left (HFDL) { double v = x; x = y; y = v; x = -x; y = -y; z = -z; } else if ( position == "FFDR" ) // Feet-first decubitus-right (FFDR) { double v = x; x = y; y = v; y = -y; } else if ( position == "FFDL" ) // Feet-first decubitus-left (FFDL) { double v = x; x = y; y = v; x = -x; } else if ( position == "FFP" ) // Feet-first prone (FFP) { } else if ( position == "FFS" ) // Feet-first supine (FFS) { x = -x; y = -y; } else { GERROR_STREAM("Unknown position string :" << position); return false; } return true; }
int GenericReconEigenChannelGadget::process(Gadgetron::GadgetContainerMessage< IsmrmrdReconData >* m1) { if (perform_timing.value()) { gt_timer_.start("GenericReconEigenChannelGadget::process"); } process_called_times_++; IsmrmrdReconData* recon_bit_ = m1->getObjectPtr(); if (recon_bit_->rbit_.size() > num_encoding_spaces_) { GWARN_STREAM("Incoming recon_bit has more encoding spaces than the protocol : " << recon_bit_->rbit_.size() << " instead of " << num_encoding_spaces_); } // for every encoding space, prepare the recon_bit_->rbit_[e].ref_ size_t e, n, s, slc; for (e = 0; e < recon_bit_->rbit_.size(); e++) { auto & rbit = recon_bit_->rbit_[e]; std::stringstream os; os << "_encoding_" << e; hoNDArray< std::complex<float> >& data = recon_bit_->rbit_[e].data_.data_; size_t RO = data.get_size(0); size_t E1 = data.get_size(1); size_t E2 = data.get_size(2); size_t CHA = data.get_size(3); size_t N = data.get_size(4); size_t S = data.get_size(5); size_t SLC = data.get_size(6); GDEBUG_CONDITION_STREAM(verbose.value(), "GenericReconEigenChannelGadget - incoming data array : [RO E1 E2 CHA N S SLC] - [" << RO << " " << E1 << " " << E2 << " " << CHA << " " << N << " " << S << " " << SLC << "]"); // whether it is needed to update coefficients bool recompute_coeff = false; if ( (KLT_[e].size()!=SLC) || update_eigen_channel_coefficients.value() ) { recompute_coeff = true; } else { if(KLT_[e].size() == SLC) { for (slc = 0; slc < SLC; slc++) { if (KLT_[e][slc].size() != S) { recompute_coeff = true; break; } else { for (s = 0; s < S; s++) { if (KLT_[e][slc][s].size() != N) { recompute_coeff = true; break; } } } } } } if(recompute_coeff) { bool average_N = average_all_ref_N.value(); bool average_S = average_all_ref_S.value(); if(rbit.ref_) { // use ref to compute coefficients Gadgetron::compute_eigen_channel_coefficients(rbit.ref_->data_, average_N, average_S, (calib_mode_[e] == Gadgetron::ISMRMRD_interleaved), N, S, upstream_coil_compression_thres.value(), upstream_coil_compression_num_modesKept.value(), KLT_[e]); } else { // use data to compute coefficients Gadgetron::compute_eigen_channel_coefficients(rbit.data_.data_, average_N, average_S, (calib_mode_[e] == Gadgetron::ISMRMRD_interleaved), N, S, upstream_coil_compression_thres.value(), upstream_coil_compression_num_modesKept.value(), KLT_[e]); } if (verbose.value()) { hoNDArray< std::complex<float> > E; for (slc = 0; slc < SLC; slc++) { for (s = 0; s < S; s++) { for (n = 0; n < N; n++) { KLT_[e][slc][s][n].eigen_value(E); GDEBUG_STREAM("Number of modes kept: " << KLT_[e][slc][s][n].output_length() << "; Eigen value, slc - " << slc << ", S - " << s << ", N - " << n << " : ["); for (size_t c = 0; c < E.get_size(0); c++) { GDEBUG_STREAM(" " << E(c)); } GDEBUG_STREAM("]"); } } } } } /*if (!debug_folder_full_path_.empty()) { gt_exporter_.exportArrayComplex(rbit.data_.data_, debug_folder_full_path_ + "data_before_KLT" + os.str()); }*/ // apply KL coefficients Gadgetron::apply_eigen_channel_coefficients(KLT_[e], rbit.data_.data_); /*if (!debug_folder_full_path_.empty()) { gt_exporter_.exportArrayComplex(rbit.data_.data_, debug_folder_full_path_ + "data_after_KLT" + os.str()); }*/ if (rbit.ref_) { /*if (!debug_folder_full_path_.empty()) { gt_exporter_.exportArrayComplex(rbit.ref_->data_, debug_folder_full_path_ + "ref_before_KLT" + os.str()); }*/ Gadgetron::apply_eigen_channel_coefficients(KLT_[e], rbit.ref_->data_); /*if (!debug_folder_full_path_.empty()) { gt_exporter_.exportArrayComplex(rbit.ref_->data_, debug_folder_full_path_ + "ref_after_KLT" + os.str()); }*/ } } if (perform_timing.value()) { gt_timer_.stop(); } if (this->next()->putq(m1) < 0) { GERROR_STREAM("Put IsmrmrdReconData to Q failed ... "); return GADGET_FAIL; } return GADGET_OK; }
int DistributeGadget::process_config(ACE_Message_Block* m) { started_nodes_ = 0; node_parameters_ = std::string(m->rd_ptr()); //Grab the original XML conifguration std::string xml = controller_->get_xml_configuration(); GadgetronXML::GadgetStreamConfiguration cfg; GadgetronXML::deserialize(xml.c_str(),cfg); //Delete Gadgets up to this Gadget std::vector<GadgetronXML::Gadget>::iterator it = cfg.gadget.begin(); while ((it->name != std::string(this->module()->name())) && (it != cfg.gadget.end())) it++; it++; cfg.gadget.erase(cfg.gadget.begin(),it); //Delete Gadgets after collector it = cfg.gadget.begin(); while ((it->name != collector.value()) && (it != cfg.gadget.end())) it++; it++; cfg.gadget.erase(it,cfg.gadget.end()); std::stringstream o; GadgetronXML::serialize(cfg,o); node_xml_config_ = o.str(); Gadget* tmp = this; while (tmp->next()) { if (std::string(tmp->module()->name()) == collector.value()) break; tmp = dynamic_cast<Gadget*>(tmp->next()); } collect_gadget_ = tmp; if (!collect_gadget_) { GERROR("Failed to locate collector Gadget with name %s\n", collector.value().c_str()); return GADGET_FAIL; } else { collect_gadget_->set_parameter("pass_through_mode","true"); } // get current node ip addresses ACE_INET_Addr* the_addr_array = NULL; size_t num_of_ip = 0; int rc = ACE::get_ip_interfaces (num_of_ip, the_addr_array); if (rc != 0) { GERROR_STREAM("Retreive local ip addresses failed ... "); num_of_ip = 0; } if (the_addr_array!=NULL ) delete [] the_addr_array; for (size_t ii=0; ii<num_of_ip; ii++) { std::string ip = std::string(the_addr_array[ii].get_host_addr()); local_address_.push_back(ip); GDEBUG_STREAM("--> Local address : " << ip); } return GADGET_OK; }