SIRF  3.5.0
gadgetron_x.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2015 - 2023 Rutherford Appleton Laboratory STFC
4 
5 This is software developed for the Collaborative Computational
6 Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR)
7 (http://www.ccpsynerbi.ac.uk/).
8 
9 Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 */
20 
30 #ifndef GADGETRON_EXTENSIONS
31 #define GADGETRON_EXTENSIONS
32 
33 #define WIN32_LEAN_AND_MEAN
34 
35 #include <cmath>
36 #include <list>
37 #include <string>
38 
39 #include <ismrmrd/ismrmrd.h>
40 #include <ismrmrd/dataset.h>
41 
42 #include "sirf/Gadgetron/cgadgetron_shared_ptr.h"
44 
45 #include "sirf/common/JacobiCG.h"
46 #include "sirf/iUtilities/LocalisedException.h"
47 #include "sirf/Gadgetron/cgadgetron_shared_ptr.h"
49 
51 
52 #if GADGETRON_TOOLBOXES_AVAILABLE
54 #endif
55 
56 #define N_TRIALS 5
57 
58 namespace sirf {
59 
60  class GadgetronClientConnector;
61 
66  class GTConnector {
67  public:
68  GTConnector();
69  GadgetronClientConnector& operator()();
70  gadgetron::shared_ptr<GadgetronClientConnector> sptr();
71  private:
72  gadgetron::shared_ptr<GadgetronClientConnector> sptr_con_;
73  };
74 
81  class GadgetHandle {
82  public:
83  GadgetHandle(std::string id, gadgetron::shared_ptr<aGadget> sptr_g) :
84  id_(id), sptr_g_(sptr_g) {}
85  std::string id() const
86  {
87  return id_;
88  }
89  aGadget& gadget()
90  {
91  return *sptr_g_.get();
92  }
93  const aGadget& gadget() const
94  {
95  return *sptr_g_.get();
96  }
97  gadgetron::shared_ptr<aGadget> gadget_sptr()
98  {
99  return sptr_g_;
100  }
101  private:
102  std::string id_;
103  gadgetron::shared_ptr<aGadget> sptr_g_;
104  };
105 
134  class GadgetChain { //: public anObject {
135  public:
136  GadgetChain() : host_("localhost"), port_("9002")
137  {
138  //class_ = "GadgetChain";
139  }
140  static const char* class_name()
141  {
142  return "GadgetChain";
143  }
144  void set_host(const std::string host)
145  {
146  host_ = host;
147  }
148  void set_port(const std::string port)
149  {
150  port_ = port;
151  }
152  // apparently caused crash in linux
153  //virtual ~GadgetChain() {}
154  // adds reader gadget
155  void add_reader(std::string id, gadgetron::shared_ptr<aGadget> sptr_g)
156  {
157  readers_.push_back(gadgetron::shared_ptr<GadgetHandle>
158  (new GadgetHandle(id, sptr_g)));
159  }
160  // adds writer gadget
161  void add_writer(std::string id, gadgetron::shared_ptr<aGadget> sptr_g)
162  {
163  writers_.push_back(gadgetron::shared_ptr<GadgetHandle>
164  (new GadgetHandle(id, sptr_g)));
165  }
166  // sdds finishig gadget
167  void set_endgadget(gadgetron::shared_ptr<aGadget> sptr_g)
168  {
169  endgadget_ = sptr_g;
170  }
171  // adds any other gadget
172  void add_gadget(std::string id, gadgetron::shared_ptr<aGadget> sptr_g)
173  {
174  gadgets_.push_back(gadgetron::shared_ptr<GadgetHandle>
175  (new GadgetHandle(id, sptr_g)));
176  }
177  gadgetron::shared_ptr<aGadget> gadget_sptr(std::string id);
178  // returns string containing the definition of the chain in xml format
179  std::string xml() const;
180  protected:
181  std::string host_;
182  std::string port_;
183  private:
184  std::list<gadgetron::shared_ptr<GadgetHandle> > readers_;
185  std::list<gadgetron::shared_ptr<GadgetHandle> > writers_;
186  std::list<gadgetron::shared_ptr<GadgetHandle> > gadgets_;
187  gadgetron::shared_ptr<aGadget> endgadget_;
188  };
189 
198  public:
200  reader_(new IsmrmrdAcqMsgReader),
201  writer_(new IsmrmrdAcqMsgWriter)
202  {
203  //class_ = "AcquisitionsProcessor";
204  sptr_acqs_.reset();
205  add_reader("reader", reader_);
206  add_writer("writer", writer_);
207  }
208  // apparently caused crash in linux
209  //virtual ~AcquisitionsProcessor() {}
210  static const char* class_name()
211  {
212  return "AcquisitionsProcessor";
213  }
214 
215  void process(MRAcquisitionData& acquisitions);
216  gadgetron::shared_ptr<MRAcquisitionData> get_output()
217  {
218  if(!sptr_acqs_->sorted())
219  sptr_acqs_->sort_by_time();
220 
221  return sptr_acqs_;
222  }
223 
224  private:
225  gadgetron::shared_ptr<IsmrmrdAcqMsgReader> reader_;
226  gadgetron::shared_ptr<IsmrmrdAcqMsgWriter> writer_;
227  gadgetron::shared_ptr<MRAcquisitionData> sptr_acqs_;
228  };
229 
238  public:
239 
241  reader_(new IsmrmrdAcqMsgReader),
242  writer_(new IsmrmrdImgMsgWriter),
243  writer_dcm_(new DicomImageMessageWriter)
244  {
245  sptr_images_.reset();
246  add_reader("reader", reader_);
247  add_writer("writer", writer_);
248  gadgetron::shared_ptr<ImageFinishGadget> endgadget(new ImageFinishGadget);
249  set_endgadget(endgadget);
250  }
251  static const char* class_name()
252  {
253  return "ImagesReconstructor";
254  }
255 
260  void set_dcm_prefix(const std::string& dcm_prefix)
261  {
262  dcm_prefix_ = dcm_prefix;
263  }
264  std::string dcm_prefix() const
265  {
266  return dcm_prefix_;
267  }
268  bool dcm_output() const
269  {
270  return !dcm_prefix_.empty();
271  }
272  void process(MRAcquisitionData& acquisitions);
273  gadgetron::shared_ptr<GadgetronImageData> get_output()
274  {
275  if (dcm_output())
276  THROW("Output to both memory and DICOM files not implemented.");
277  return sptr_images_;
278  }
279 
280  private:
281  std::string dcm_prefix_;
282  gadgetron::shared_ptr<IsmrmrdAcqMsgReader> reader_;
283  gadgetron::shared_ptr<IsmrmrdImgMsgWriter> writer_;
284  gadgetron::shared_ptr<DicomImageMessageWriter> writer_dcm_;
285  gadgetron::shared_ptr<GadgetronImageData> sptr_images_;
286  };
287 
295  class ImagesProcessor : public GadgetChain {
296  public:
297  ImagesProcessor(bool dicom = false, std::string prefix = "image") :
298  dicom_(dicom), prefix_(prefix),
299  reader_(new IsmrmrdImgMsgReader)
300  {
301  //class_ = "ImagesProcessor";
302  //gadgetron::shared_ptr<ImageFinishGadget> endgadget;
303  gadgetron::shared_ptr<aGadget> endgadget;
304  if (dicom) {
305  writer_.reset(new DicomImageMessageWriter);
306  endgadget.reset(new DicomFinishGadget);
307  }
308  else {
309  writer_.reset(new IsmrmrdImgMsgWriter);
310  endgadget.reset(new ImageFinishGadget);
311  }
312  add_reader("reader", reader_);
313  add_writer("writer", writer_);
314  set_endgadget(endgadget);
315  }
316  static const char* class_name()
317  {
318  return "ImagesProcessor";
319  }
320 
321  void check_connection();
322  void process(const GadgetronImageData& images);
323  gadgetron::shared_ptr<GadgetronImageData> get_output()
324  {
325  //if (dicom_)
326  // THROW("Output to both memory and DICOM files not implemented.");
327  return sptr_images_;
328  }
329 
330  private:
331  bool dicom_;
332  std::string prefix_;
333  gadgetron::shared_ptr<IsmrmrdImgMsgReader> reader_;
334  gadgetron::shared_ptr<ImageMessageWriter> writer_;
335 // gadgetron::shared_ptr<IsmrmrdImgMsgWriter> writer_;
336  gadgetron::shared_ptr<GadgetronImageData> sptr_images_;
337  };
338 
367  public:
375  class BFOperator : public Operator<GadgetronImageData> {
376  public:
377  BFOperator(gadgetron::shared_ptr<MRAcquisitionModel> sptr_am) : sptr_am_(sptr_am) {}
378  virtual gadgetron::shared_ptr<GadgetronImageData>
379  apply(const GadgetronImageData& image_data)
380  {
381  gadgetron::shared_ptr<MRAcquisitionData> sptr_fwd =
382  sptr_am_->fwd(image_data);
383  gadgetron::shared_ptr<GadgetronImageData> sptr_bwd =
384  sptr_am_->bwd(*sptr_fwd);
385  return sptr_bwd;
386  }
387  private:
388  gadgetron::shared_ptr<MRAcquisitionModel> sptr_am_;
389  };
390 
391  MRAcquisitionModel() {}
392  /*
393  The constructor records, by copying shared pointers, the two supplied
394  arguments as templates, to be used for obtaining scanner and image
395  discretisation data.
396  */
398  gadgetron::shared_ptr<MRAcquisitionData> sptr_ac,
399  gadgetron::shared_ptr<GadgetronImageData> sptr_ic
400  )
401  {
402  this->set_up(sptr_ac, sptr_ic);
403  }
404  MRAcquisitionModel(
405  gadgetron::shared_ptr<MRAcquisitionData> sptr_ac,
406  gadgetron::shared_ptr<GadgetronImageData> sptr_ic,
407  gadgetron::shared_ptr<CoilSensitivitiesVector> sptr_csms,
408  std::string acqs_info
409  ) : sptr_csms_(sptr_csms), acqs_info_(acqs_info)
410  {
411  this->set_up(sptr_ac, sptr_ic);
412  }
413 
422  float norm(int num_iter = 16, int verb = 0)
423  {
424  gadgetron::shared_ptr<MRAcquisitionModel> sptr_am
425  (new MRAcquisitionModel(sptr_acqs_, sptr_imgs_, sptr_csms_, acqs_info_));
426 
427  BFOperator bf(sptr_am);
429  jcg.set_num_iterations(num_iter);
430  gadgetron::unique_ptr<GadgetronImageData> sptr_id = sptr_imgs_->clone();
431  GadgetronImageData& image_data = *sptr_id;
432  image_data.fill(1.0);
433  float lmd = jcg.largest(bf, image_data, verb);
434  return std::sqrt(lmd);
435  }
436 
437  // make sure ic contains "true" images (and not e.g. G-factors)
438  void check_data_role(const GadgetronImageData& ic);
439 
440  // Records the acquisition template to be used.
441  void set_acquisition_template
442  (gadgetron::shared_ptr<MRAcquisitionData> sptr_ac)
443  {
444  sptr_acqs_ = sptr_ac;
445  }
446  // Records the image template to be used.
447  void set_image_template
448  (gadgetron::shared_ptr<GadgetronImageData> sptr_ic)
449  {
450  check_data_role(*sptr_ic);
451  sptr_imgs_ = sptr_ic;
452  }
453  // Returns shared pointer to the acquisitions template used.
454  gadgetron::shared_ptr<const MRAcquisitionData> acq_template_sptr() const
455  {
456  return sptr_acqs_;
457  }
458  // Returns shared pointer to the images template used.
459  gadgetron::shared_ptr<const GadgetronImageData> image_template_sptr() const
460  {
461  return sptr_imgs_;
462  }
463  // Records the coil sensitivities maps to be used.
464  void set_csm(gadgetron::shared_ptr<CoilSensitivitiesVector> sptr_csms)
465  {
466  sptr_csms_ = sptr_csms;
467  }
468 
469  void set_encoder(gadgetron::shared_ptr<sirf::FourierEncoding> sptr_enc)
470  {
471  sptr_enc_ = sptr_enc;
472  }
473 
474  // Records templates
475  void set_up(gadgetron::shared_ptr<MRAcquisitionData> sptr_ac,
476  gadgetron::shared_ptr<GadgetronImageData> sptr_ic);
477 
478  // Forward projects the whole ImageContainer using
479  // coil sensitivity maps in the second argument.
480  void fwd(const GadgetronImageData& ic, CoilSensitivitiesVector& cc,
481  MRAcquisitionData& ac);
482 
483  // Backprojects the whole AcquisitionContainer using
484  // coil sensitivity maps in the second argument.
485  void bwd(GadgetronImageData& ic, const CoilSensitivitiesVector& cc,
486  const MRAcquisitionData& ac);
487 
488  // Forward projects the whole ImageContainer using
489  // coil sensitivity maps referred to by sptr_csms_.
490  gadgetron::shared_ptr<MRAcquisitionData> fwd(const GadgetronImageData& ic)
491  {
492 
493  if (!sptr_acqs_.get())
494  throw LocalisedException
495  ("Acquisition data template not set", __FILE__, __LINE__);
496  if (!sptr_csms_.get() || sptr_csms_->items() < 1)
497  throw LocalisedException
498  ("Coil sensitivity maps not found", __FILE__, __LINE__);
499  check_data_role(ic);
500  gadgetron::unique_ptr<MRAcquisitionData> uptr_acqs =
501  sptr_acqs_->clone();
502 
503  fwd(ic, *sptr_csms_, *uptr_acqs);
504 
505  return gadgetron::shared_ptr<MRAcquisitionData>(std::move(uptr_acqs));
506  }
507 
508  // Backprojects the whole AcquisitionContainer using
509  // coil sensitivity maps referred to by sptr_csms_.
510  gadgetron::shared_ptr<GadgetronImageData> bwd(const MRAcquisitionData& ac)
511  {
512  if (!sptr_imgs_.get())
513  throw LocalisedException
514  ("image data template not set", __FILE__, __LINE__);
515  if (!sptr_csms_.get() || sptr_csms_->items() < 1)
516  throw LocalisedException
517  ("coil sensitivity maps not found", __FILE__, __LINE__);
518  gadgetron::shared_ptr<GadgetronImageData> sptr_imgs =
519  sptr_imgs_->new_images_container();
520  bwd(*sptr_imgs, *sptr_csms_, ac);
521  return sptr_imgs;
522  }
523 
524  private:
525  std::string acqs_info_;
526  gadgetron::shared_ptr<MRAcquisitionData> sptr_acqs_;
527  gadgetron::shared_ptr<GadgetronImageData> sptr_imgs_;
528  gadgetron::shared_ptr<CoilSensitivitiesVector> sptr_csms_;
529  gadgetron::shared_ptr<FourierEncoding> sptr_enc_;
530  };
531 
532 }
533 
534 #endif
File for cartesian fourier encoding and trajectory setting.
Specification file for non-cartesian Fourier encoding.
Definition: LocalisedException.h:32
A particular type of Gadget chain that has AcquisitionData on input and output.
Definition: gadgetron_x.h:197
Class for the generator of xml definition of DicomFinishGadget.
Definition: gadget_lib.h:849
Class for DicomImageWriter gadget xml-definition generator.
Definition: gadget_lib.h:219
Shared pointer wrap-up for GadgetronClientConnector.
Definition: gadgetron_x.h:66
Gadget chain class.
Definition: gadgetron_x.h:134
Shared pointer wrap-up for the abstract gadget class aGadget.
Definition: gadgetron_x.h:81
Class for communicating with Gadgetron server.
Definition: gadgetron_client.h:294
Abstract Gadgetron image data container class.
Definition: gadgetron_data_containers.h:785
Class for the generator of xml definition of ImageFinishGadget.
Definition: gadget_lib.h:835
A particular type of Gadget chain that has ImageData on input and output.
Definition: gadgetron_x.h:295
A particular type of Gadget chain that has AcquisitionData on input and ImageData on output.
Definition: gadgetron_x.h:237
void set_dcm_prefix(const std::string &dcm_prefix)
Setting dcm prefix to a non-empty string redirects the output images to DICOM files (cf....
Definition: gadgetron_x.h:260
Class for GadgetIsmrmrdAcquisitionMessageReader gadget xml-definition generator.
Definition: gadget_lib.h:113
Class for GadgetIsmrmrdAcquisitionMessageWriter gadget xml-definition generator.
Definition: gadget_lib.h:139
Class for MRIImageReader gadget xml-definition generator.
Definition: gadget_lib.h:164
Class for MRIImageWriter gadget xml-definition generator.
Definition: gadget_lib.h:195
Definition: JacobiCG.h:37
Abstract MR acquisition data container class.
Definition: gadgetron_data_containers.h:217
Class for the product of backward and forward projectors of the MR acquisition model.
Definition: gadgetron_x.h:375
A class for MR acquisition modelling.
Definition: gadgetron_x.h:366
float norm(int num_iter=16, int verb=0)
Method computing the norm of the MR acquisition model operator A.
Definition: gadgetron_x.h:422
Definition: Operator.h:7
Abstract base class for a gadget xml-definition generator.
Definition: gadget_lib.h:45
Specification file for the library of SIRF generators of xml-definitions of Gadgetron gadgets.
Specification file for data container classes for Gadgetron data.
Abstract data container.
Definition: GeometricalInfo.cpp:141