SIRF  3.4.0
TrajectoryPreparation.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2020 - 2021 Physikalisch-Technische Bundesanstalt (PTB)
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 
29 #ifndef TRAJECTORYPREPARATION_H
30 #define TRAJECTORYPREPARATION_H
31 
32 #include <vector>
33 
34 #include <ismrmrd/xml.h>
35 #include <ismrmrd/ismrmrd.h>
36 
38 #include "sirf/iUtilities/LocalisedException.h"
39 
40 
41 
42 const static double SIRF_PI = 3.14159265358979323846;
43 const static double SIRF_GOLDEN_ANGLE = SIRF_PI*0.618034;
44 
45 namespace sirf{
46 
55 template <std::uint16_t D>
57 
58 public:
59  typedef typename std::array<float, D> TrajPointType;
60  typedef typename std::vector<TrajPointType> TrajPointSet;
61 
63 
64  virtual void set_trajectory(MRAcquisitionData& mr_acq)
65  {
67 
68  for(size_t ia=0; ia<mr_acq.number(); ++ia)
69  {
70  ISMRMRD::Acquisition acq;
71  mr_acq.get_acquisition(ia, acq);
72  this->set_acquisition_trajectory(acq);
73  mr_acq.set_acquisition(ia, acq);
74  }
75  }
76 
77  virtual TrajPointSet get_trajectory(const MRAcquisitionData& mr_acq) const
78  {
79  if(mr_acq.number() <= 0){
80  throw std::runtime_error("Please pass a non-empty container.");
81  }
82 
83  ISMRMRD::Acquisition acq;
84  mr_acq.get_acquisition(0, acq);
85 
86  if( acq.trajectory_dimensions() != D){
87  throw std::runtime_error("Please give Acquisition with a the correct dimensionality if you want to use it here.");
88  }
89 
90  TrajPointSet traj;
91 
92  for(int ia=0; ia<mr_acq.number(); ++ia)
93  {
94  mr_acq.get_acquisition(ia, acq);
95  append_to_trajectory(traj, acq);
96  }
97 
98  return traj;
99  }
100 
101 protected:
102  ISMRMRD::Encoding kspace_encoding_;
103 
108  ISMRMRD::TrajectoryType traj_type_;
109 
119  virtual void set_acquisition_trajectory(ISMRMRD::Acquisition& acq) const
120  {
121  acq.resize(acq.number_of_samples(),acq.active_channels(), D);
122  TrajPointSet acq_traj = this->calculate_trajectory(acq);
123  acq.setTraj(&(acq_traj[0][0]));
124  }
125 
132  {
133  ISMRMRD::IsmrmrdHeader hdr = mr_acq.acquisitions_info().get_IsmrmrdHeader();
134 
135  if(hdr.encoding.size() != 1)
136  throw LocalisedException("Currrently only files with one encoding are supported", __FILE__, __LINE__);
137 
138  hdr.encoding[0].trajectory = traj_type_;
139  kspace_encoding_ = hdr.encoding[0];
140 
141  std::stringstream hdr_stream;
142  serialize(hdr, hdr_stream);
143 
144  AcquisitionsInfo ai(hdr_stream.str());
145  mr_acq.set_acquisitions_info(ai);
146  }
147 
148  virtual TrajPointSet calculate_trajectory(ISMRMRD::Acquisition& acq) const =0;
149  virtual void append_to_trajectory(TrajPointSet& tps, ISMRMRD::Acquisition& acq) const =0;
150 
151 };
152 
155 
156 
166 public:
167  static TrajectoryPreparation2D::TrajPointSet get_trajectory(const sirf::MRAcquisitionData& ac);
168 };
169 
181 class GRPETrajectoryPrep : public TrajectoryPreparation3D {
182 
183 public:
185  traj_type_ = ISMRMRD::TrajectoryType::OTHER;
186  }
187 
188 protected:
189  TrajPointSet calculate_trajectory(ISMRMRD::Acquisition& acq) const;
190  virtual void append_to_trajectory(TrajPointSet& tps, ISMRMRD::Acquisition& acq) const;
191 
192 private:
193  std::uint16_t circ_mod(std::uint16_t const a, std::uint16_t const b) const { return (((a%b) + b ) % b);}
194  const std::vector< std::uint16_t > rad_shift_ = {0, 2, 1, 3}; //this is bit-reversed {0 1 2 3}
195 };
196 
197 
202 class NonCartesian2DTrajPrep : public TrajectoryPreparation2D {
203 
204 protected:
205  virtual TrajPointSet calculate_trajectory(ISMRMRD::Acquisition& acq) const;
206 
207  virtual void append_to_trajectory(TrajPointSet& tps, ISMRMRD::Acquisition& acq) const;
212  virtual float calculate_pe_angle(ISMRMRD::Acquisition& acq) const =0;
213 };
214 
215 
221 
222 public:
223  Radial2DTrajprep() {
224  traj_type_ = ISMRMRD::TrajectoryType::RADIAL;
225  }
226 
227 protected:
228 
229  virtual float calculate_pe_angle(ISMRMRD::Acquisition& acq) const
230  {
231  ISMRMRD::Limit ang_lims(0,0,0);
232 
233  if(this->kspace_encoding_.encodingLimits.kspace_encoding_step_1.is_present())
234  ang_lims = this->kspace_encoding_.encodingLimits.kspace_encoding_step_1.get();
235 
236  const ISMRMRD::EncodingCounters idx = acq.idx();
237  unsigned short num_angles = ang_lims.maximum;
238 
239  return (SIRF_PI/(float)num_angles * idx.kspace_encode_step_1);
240  }
241 };
242 
248 
249 public:
251  traj_type_ = ISMRMRD::TrajectoryType::GOLDENANGLE;
252  }
253 
254 protected:
255  virtual float calculate_pe_angle(ISMRMRD::Acquisition& acq) const
256  {
257  const ISMRMRD::EncodingCounters idx = acq.idx();
258  return (SIRF_GOLDEN_ANGLE * idx.kspace_encode_step_1);
259  }
260 };
261 
262 
263 }
264 #endif// TRAJECTORYPREPARATION_H
Definition: LocalisedException.h:32
Abstract class defining the interface to set trajectories.
Definition: TrajectoryPreparation.h:56
Class to get cartesian encoding phase encoding locations.
Definition: TrajectoryPreparation.h:165
Class to set the golden-angle radial phase encoding (GRPE) trajectory.
Definition: TrajectoryPreparation.h:181
virtual float calculate_pe_angle(ISMRMRD::Acquisition &acq) const
Abstract function computing a anglular increment depending on the trajectory type.
Definition: TrajectoryPreparation.h:229
virtual float calculate_pe_angle(ISMRMRD::Acquisition &acq) const
Abstract function computing a anglular increment depending on the trajectory type.
Definition: TrajectoryPreparation.h:255
Implementation to set anglular increment for 2D radial trajectory based on doi:10.1109/TMI.2006.885337.
Definition: TrajectoryPreparation.h:247
Abstract data container.
Definition: GeometricalInfo.cpp:141
Implementation to set anglular increment for 2D radial trajectory based on (Pi=3.141...)/#Angles.
Definition: TrajectoryPreparation.h:220
virtual void set_acquisition_trajectory(ISMRMRD::Acquisition &acq) const
Sets the trajectory field in an ISMRMRD::Acquisition.
Definition: TrajectoryPreparation.h:119
Definition: gadgetron_data_containers.h:83
Interface to set the 2D radial trajectory.
Definition: TrajectoryPreparation.h:202
virtual void overwrite_trajectory_name(sirf::MRAcquisitionData &mr_acq)
Overwrites the trajectory name in the argument with the traj_type_ member.
Definition: TrajectoryPreparation.h:131
Specification file for data container classes for Gadgetron data.
ISMRMRD::TrajectoryType traj_type_
Labels which trajectory type the TrajectoryPreparation is for.
Definition: TrajectoryPreparation.h:108
Abstract MR acquisition data container class.
Definition: gadgetron_data_containers.h:216