From 87540f726750622148c71b5744e94ac18ad53c97 Mon Sep 17 00:00:00 2001 From: Evgueni Ovtchinnikov Date: Thu, 20 Oct 2022 15:45:41 +0100 Subject: [PATCH] introduced a quick fix for dicom output failure #1128 --- src/xGadgetron/cGadgetron/cgadgetron.cpp | 8 +++++-- src/xGadgetron/cGadgetron/gadgetron_x.cpp | 21 +++++++++++----- .../include/sirf/Gadgetron/cgadgetron.h | 2 +- .../include/sirf/Gadgetron/gadget_lib.h | 24 ++++++++++++++++++- .../include/sirf/Gadgetron/gadgetron_client.h | 4 +++- .../include/sirf/Gadgetron/gadgetron_x.h | 7 +++--- src/xGadgetron/pGadgetron/Gadgetron.py | 13 +++++++--- 7 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/xGadgetron/cGadgetron/cgadgetron.cpp b/src/xGadgetron/cGadgetron/cgadgetron.cpp index 0fce77638..98a1b5f59 100644 --- a/src/xGadgetron/cGadgetron/cgadgetron.cpp +++ b/src/xGadgetron/cGadgetron/cgadgetron.cpp @@ -154,6 +154,8 @@ void* cGT_newObject(const char* name) NEW_GADGET(PhysioInterpolationGadget); NEW_GADGET(GPURadialSensePrepGadget); NEW_GADGET(GPUCGSenseGadget); + NEW_GADGET(FFTGadget); + NEW_GADGET(CombineGadget); NEW_GADGET(ExtractGadget); NEW_GADGET(AutoScaleGadget); NEW_GADGET(ComplexToFloatGadget); @@ -1041,14 +1043,16 @@ cGT_imageParameter(void* ptr_im, const char* name) extern "C" void* -cGT_reconstructImages(void* ptr_recon, void* ptr_input) +cGT_reconstructImages(void* ptr_recon, void* ptr_input, const char* dcm_prefix) { try { CAST_PTR(DataHandle, h_recon, ptr_recon); CAST_PTR(DataHandle, h_input, ptr_input); ImagesReconstructor& recon = objectFromHandle(h_recon); MRAcquisitionData& input = objectFromHandle(h_input); - recon.process(input); + if (strlen(dcm_prefix) < 1) + dcm_prefix = 0; + recon.process(input, dcm_prefix); return new DataHandle; } CATCH; diff --git a/src/xGadgetron/cGadgetron/gadgetron_x.cpp b/src/xGadgetron/cGadgetron/gadgetron_x.cpp index 40d33fa4c..22ad599a5 100644 --- a/src/xGadgetron/cGadgetron/gadgetron_x.cpp +++ b/src/xGadgetron/cGadgetron/gadgetron_x.cpp @@ -236,13 +236,8 @@ AcquisitionsProcessor::process(MRAcquisitionData& acquisitions) } void -ImagesReconstructor::process(MRAcquisitionData& acquisitions) +ImagesReconstructor::process(MRAcquisitionData& acquisitions, const char* dcm_prefix) { - //check_gadgetron_connection(host_, port_); - - std::string config = xml(); - //std::cout << "config:\n" << config << std::endl; - uint32_t nacquisitions = 0; nacquisitions = acquisitions.number(); //std::cout << nacquisitions << " acquisitions" << std::endl; @@ -254,6 +249,19 @@ ImagesReconstructor::process(MRAcquisitionData& acquisitions) conn().register_reader(GADGET_MESSAGE_ISMRMRD_IMAGE, shared_ptr (new GadgetronClientImageMessageCollector(sptr_images_))); + if (dcm_prefix) { + add_gadget("extract", gadgetron::shared_ptr(new ExtractGadget)); + add_gadget("autoscale", gadgetron::shared_ptr(new AutoScaleGadget)); + add_writer("writer_dcm", writer_dcm_); + gadgetron::shared_ptr endgadget(new DicomFinishGadget); + set_endgadget(endgadget); + conn().register_reader(GADGET_MESSAGE_DICOM_WITHNAME, + shared_ptr + (new GadgetronClientBlobMessageReader(std::string(dcm_prefix), std::string("dcm")))); + } + std::string config = xml(); + //std::cout << "config:\n" << config << std::endl; + for (int nt = 0; nt < N_TRIALS; nt++) { try { conn().connect(host_, port_); @@ -288,6 +296,7 @@ ImagesProcessor::process(const GadgetronImageData& images) THROW("DICOM writer does not support complex images"); std::string config = xml(); + std::cout << xml() << '\n'; GTConnector conn; sptr_images_ = images.new_images_container(); if (dicom_) diff --git a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/cgadgetron.h b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/cgadgetron.h index 3d1ce8780..b356f8e54 100644 --- a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/cgadgetron.h +++ b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/cgadgetron.h @@ -97,7 +97,7 @@ extern "C" { int from, int till, int n, PTR_FLOAT values); // image methods - void* cGT_reconstructImages(void* ptr_recon, void* ptr_input); + void* cGT_reconstructImages(void* ptr_recon, void* ptr_input, const char* dcm_prefix); void* cGT_reconstructedImages(void* ptr_recon); void* cGT_readImages(const char* file); void* cGT_ImageFromAcquisitiondata(void* ptr_acqs); diff --git a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadget_lib.h b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadget_lib.h index 992c566d0..ad66874df 100644 --- a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadget_lib.h +++ b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadget_lib.h @@ -356,7 +356,29 @@ namespace sirf { } }; - class GenericReconCartesianFFTGadget : public Gadget { + class FFTGadget : public Gadget { + public: + FFTGadget() : + Gadget("FFT", "gadgetron_mricore", "FFTGadget") + {} + static const char* class_name() + { + return "FFTGadget"; + } + }; + + class CombineGadget : public Gadget { + public: + CombineGadget() : + Gadget("Combine", "gadgetron_mricore", "CombineGadget") + {} + static const char* class_name() + { + return "CombineGadget"; + } + }; + + class GenericReconCartesianFFTGadget : public Gadget { public: GenericReconCartesianFFTGadget() : Gadget("Recon", "gadgetron_mricore", "GenericReconCartesianFFTGadget") diff --git a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_client.h b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_client.h index dac87a34a..0b1e88cf9 100644 --- a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_client.h +++ b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_client.h @@ -213,12 +213,14 @@ namespace sirf { , file_prefix(fileprefix) , file_suffix(filesuffix) { + //std::cout << fileprefix << '.' << filesuffix << '\n'; } virtual ~GadgetronClientBlobMessageReader() {} virtual void read(boost::asio::ip::tcp::socket* socket) { + //std::cout << "in GadgetronClientBlobMessageReader::read...\n"; // MUST READ 32-bits uint32_t nbytes; boost::asio::read(*socket, boost::asio::buffer(&nbytes, sizeof(uint32_t))); @@ -255,7 +257,7 @@ namespace sirf { filename << "." << file_suffix; filename_attrib.append("_attrib.xml"); - std::cout << "Writing image " << filename.str() << std::endl; + //std::cout << "Writing image " << filename.str() << std::endl; std::ofstream outfile; outfile.open(filename.str().c_str(), std::ios::out | std::ios::binary); diff --git a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_x.h b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_x.h index 5d65dac13..6b21d90b4 100644 --- a/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_x.h +++ b/src/xGadgetron/cGadgetron/include/sirf/Gadgetron/gadgetron_x.h @@ -239,9 +239,9 @@ namespace sirf { ImagesReconstructor() : reader_(new IsmrmrdAcqMsgReader), - writer_(new IsmrmrdImgMsgWriter) + writer_(new IsmrmrdImgMsgWriter), + writer_dcm_(new DicomImageMessageWriter) { - //class_ = "ImagesReconstructor"; sptr_images_.reset(); add_reader("reader", reader_); add_writer("writer", writer_); @@ -253,7 +253,7 @@ namespace sirf { return "ImagesReconstructor"; } - void process(MRAcquisitionData& acquisitions); + void process(MRAcquisitionData& acquisitions, const char* dcm_prefix = "image"); gadgetron::shared_ptr get_output() { return sptr_images_; @@ -262,6 +262,7 @@ namespace sirf { private: gadgetron::shared_ptr reader_; gadgetron::shared_ptr writer_; + gadgetron::shared_ptr writer_dcm_; gadgetron::shared_ptr sptr_images_; }; diff --git a/src/xGadgetron/pGadgetron/Gadgetron.py b/src/xGadgetron/pGadgetron/Gadgetron.py index b526712a5..61ae961d4 100644 --- a/src/xGadgetron/pGadgetron/Gadgetron.py +++ b/src/xGadgetron/pGadgetron/Gadgetron.py @@ -1415,7 +1415,7 @@ class Reconstructor(GadgetChain): Class for a chain of gadgets that has AcquisitionData on input and ImageData on output. ''' - def __init__(self, list = None): + def __init__(self, list=None): self.handle = None self.handle = pygadgetron.cGT_newObject('ImagesReconstructor') check_status(self.handle) @@ -1435,14 +1435,21 @@ def set_input(self, input_data): ''' assert isinstance(input_data, AcquisitionData) self.input_data = input_data - def process(self): + def process(self, dcm_prefix=None): ''' Processes the input with the gadget chain. + dcm_prefix: Python text string. + If dcm_prefix is not None, the reconstructed images are written to + files _.dcm. + Otherwise, they are stored in memory and can be retrieved by + get_output(). ''' if self.input_data is None: raise error('no input data') + if dcm_prefix is None: + dcm_prefix = "" try_calling(pygadgetron.cGT_reconstructImages\ - (self.handle, self.input_data.handle)) + (self.handle, self.input_data.handle, dcm_prefix)) def get_output(self, subset = None): ''' Returns specified subset of the output ImageData. If no subset is