Open-source pulse sequences  
Easily create and execute MR sequences
ExternalSequence.h
Go to the documentation of this file.
1 
3 #include <vector>
4 #include <iostream>
5 #include <string>
6 #include <sstream>
7 #include <fstream>
8 #include <map>
9 
10 #ifndef CLASS_EXTERNAL_SEQUENCE
11 #define CLASS_EXTERNAL_SEQUENCE
12 
13 //#define MASTER_SLAVE_FORMAT
14 
15 #define PI 3.1415926535897932384626433832795
16 #define TWO_PI 6.283185307179586476925286766558
17 
18 
23  ERROR_MSG=-2,
24  WARNING_MSG,
25  NORMAL_MSG,
26  DEBUG_HIGH_LEVEL,
27  DEBUG_MEDIUM_LEVEL,
28  DEBUG_LOW_LEVEL
29 };
30 
31 // Define the current level of messages to display
32 const MessageType MSG_LEVEL = NORMAL_MSG;
33 
34 
38 enum Event {
39  DELAY,
40  RF,
41  GX,
42  GY,
43  GZ,
44  ADC,
45 };
46 const int NUM_EVENTS=ADC+1;
47 const int NUM_GRADS=ADC-GX;
48 
55 struct RFEvent
56 {
57  float amplitude;
58  int magShape;
59  int phaseShape;
60  float freqOffset;
61  float phaseOffset;
62 };
63 
64 
73 struct GradEvent
74 {
75  float amplitude;
76  // Trapezoid:
77  long rampUpTime;
78  long flatTime;
79  long rampDownTime;
80  // Arbitrary:
81  int shape;
82 };
83 
84 
92 struct ADCEvent
93 {
94  int numSamples;
95  int dwellTime;
96  int delay;
97  float freqOffset;
98  float phaseOffset;
99 };
100 
106 struct EventIDs
107 {
108  int id[NUM_EVENTS];
109 };
110 
111 
119 class SeqBlock
120 {
121  friend class ExternalSequence;
122 public:
126  SeqBlock() { gradWaveforms.resize(NUM_GRADS); }
127 
131  bool isRF();
132 
136  bool isTrapGradient(int channel);
137 
141  bool isArbitraryGradient(int channel);
142 
146  bool isADC();
147 
151  bool isDelay();
152 
156  int GetIndex();
157 
162  int GetEventIndex(Event type);
163 
167  long GetDelay();
168 
172  long GetDuration();
173 
178  int GetGradientLength(int channel);
179 
183  GradEvent& GetGradEvent(int channel);
184 
188  float* GetGradientPtr(int channel);
189 
193  RFEvent& GetRFEvent();
194 
198  int GetRFLength();
199 
203  float* GetRFAmplitudePtr();
204 
208  float* GetRFPhasePtr();
209 
214 
218  std::string GetTypeString();
219 
223  void free();
224 protected:
225  int index;
227  // Event array contains integer indices to events stored in the parent ExternalSequence object
228  int events[NUM_EVENTS];
230  long delay;
231  long duration;
234  GradEvent grad[NUM_GRADS];
237  // Below is only valid once decompressed:
238 
239  // RF
240  std::vector<float> rfAmplitude;
241  std::vector<float> rfPhase;
243  // Gradient waveforms
244  std::vector< std::vector<float> > gradWaveforms;
246 };
247 
248 // * ------------------------------------------------------------------ *
249 // * Inline functions *
250 // * ------------------------------------------------------------------ *
251 inline int SeqBlock::GetIndex() { return index; }
252 
253 inline bool SeqBlock::isRF() { return (events[RF]>0); }
254 inline bool SeqBlock::isTrapGradient(int channel) { return ((events[channel+GX]>0) & (grad[channel].shape==0)); }
255 inline bool SeqBlock::isArbitraryGradient(int channel) { return ((events[channel+GX]>0) & (grad[channel].shape>0)); }
256 inline bool SeqBlock::isADC() { return (events[ADC]>0); }
257 inline bool SeqBlock::isDelay() { return (events[DELAY]>0); }
258 
259 inline long SeqBlock::GetDelay() { return delay; }
260 inline long SeqBlock::GetDuration() { return duration; }
261 
262 inline int SeqBlock::GetEventIndex(Event type) { return events[type]; }
263 
264 inline GradEvent& SeqBlock::GetGradEvent(int channel) { return grad[channel]; }
265 inline RFEvent& SeqBlock::GetRFEvent() { return rf; }
266 inline ADCEvent& SeqBlock::GetADCEvent() { return adc; }
267 
268 
269 inline std::string SeqBlock::GetTypeString() {
270  std::string type;
271  if (isRF()) type = type + "RF";
272  if (isTrapGradient(0)) type += " TrapX";
273  if (isTrapGradient(1)) type += " TrapY";
274  if (isTrapGradient(2)) type += " TrapZ";
275  if (isArbitraryGradient(0)) type += " ArbX";
276  if (isArbitraryGradient(1)) type += " ArbY";
277  if (isArbitraryGradient(2)) type += " ArbZ";
278  if (isADC()) type += " ADC";
279  if (isDelay()) type += " Delay";
280  return type;
281 }
282 
283 inline float* SeqBlock::GetGradientPtr(int channel) { return (gradWaveforms[channel].size()>0) ? &gradWaveforms[channel][0] : NULL; }
284 inline int SeqBlock::GetGradientLength(int channel) { return gradWaveforms[channel].size(); }
285 
286 inline float* SeqBlock::GetRFAmplitudePtr() { return &rfAmplitude[0]; }
287 inline float* SeqBlock::GetRFPhasePtr() { return &rfPhase[0]; }
288 inline int SeqBlock::GetRFLength() { return rfAmplitude.size(); }
289 
290 inline void SeqBlock::free() {
291  // Force the memory to be freed
292  std::vector<float>().swap(rfAmplitude);
293  std::vector<float>().swap(rfPhase);
294  std::vector<std::vector<float> >().swap(gradWaveforms);
295  }
296 
297 
306 {
308  std::vector<float> samples;
309 };
310 
311 
331 {
332  public:
333 
338 
343 
355  bool load(std::string path);
356 
357 
368  static void print_msg(MessageType level, std::ostream& ss);
369 
373  typedef void (*PrintFunPtr)(const std::string &str);
374 
383  static void SetPrintFunction(PrintFunPtr fun);
384 
394  std::vector<double> GetDefinition(std::string key);
395 
399  int GetNumberOfBlocks(void);
400 
409  SeqBlock* GetBlock(int blockIndex);
410 
419  bool decodeBlock(SeqBlock *block);
420 
421  private:
422 
423  static const int MAX_LINE_SIZE;
424  static const char COMMENT_CHAR;
426  // *** Private helper functions ***
427 
441  static std::istream& getline(std::istream& stream, char *buffer, const int MAX_SIZE);
442 
449  void buildFileIndex(std::ifstream &stream);
450 
457  void skipComments(std::ifstream &stream, char* buffer);
458 
465  bool decompressShape(CompressedShape& encoded, float *shape);
466 
467 
475  bool checkBlockReferences(EventIDs& events);
476 
485  void checkGradient(SeqBlock& block);
486 
495  void checkRF(SeqBlock& block);
496 
497  // *** Static helper function ***
498 
502  static void defaultPrint(const std::string &str);
503 
504  // *** Static members ***
505 
508  // *** Members ***
509 
510  std::map<std::string,int> m_fileIndex;
512  // Low level sequence blocks
513  std::vector<EventIDs> m_blocks;
515  // Global user-specified definitions
516  std::map<std::string, std::vector<double> >m_definitions;
518  // List of events (referenced by blocks)
519  std::map<int,RFEvent> m_rfLibrary;
520  std::map<int,GradEvent> m_gradLibrary;
521  std::map<int,ADCEvent> m_adcLibrary;
522  std::map<int,long> m_delayLibrary;
524  // List of basic shapes (referenced by events)
525  std::map<int,CompressedShape> m_shapeLibrary;
526 };
527 
528 // * ------------------------------------------------------------------ *
529 // * Inline functions *
530 // * ------------------------------------------------------------------ *
531 
532 inline int ExternalSequence::GetNumberOfBlocks(void){return m_blocks.size();}
533 inline std::vector<double> ExternalSequence::GetDefinition(std::string key){
534  if (m_definitions.count(key)>0)
535  return m_definitions[key];
536  else
537  return std::vector<double>();
538 }
539 
540 inline void ExternalSequence::defaultPrint(const std::string &str) { std::cout << str << std::endl; }
541 inline void ExternalSequence::SetPrintFunction(PrintFunPtr fun) { print_fun=fun; }
542 
543 
544 
545 #endif //CLASS_EXTERNAL_SEQUENCE
float phaseOffset
Phase offset of receiver (rad)
Definition: ExternalSequence.h:98
RFEvent rf
RF event.
Definition: ExternalSequence.h:233
int phaseShape
ID of shape for phase.
Definition: ExternalSequence.h:59
static std::istream & getline(std::istream &stream, char *buffer, const int MAX_SIZE)
Read a line from the input stream independent of line ending.
Definition: ExternalSequence.cpp:573
Compressed shape data.
Definition: ExternalSequence.h:305
std::map< int, long > m_delayLibrary
Library of delays.
Definition: ExternalSequence.h:522
std::vector< float > samples
Compressed samples.
Definition: ExternalSequence.h:308
MessageType
Output message types.
Definition: ExternalSequence.h:22
int GetIndex()
Return index of this block.
Definition: ExternalSequence.h:251
int GetRFLength()
Return the number of samples of the RF shape.
Definition: ExternalSequence.h:288
static const char COMMENT_CHAR
Character defining the start of a comment line.
Definition: ExternalSequence.h:424
int index
Index of this block.
Definition: ExternalSequence.h:225
long duration
duration of this block (in us) used for error checking
Definition: ExternalSequence.h:231
SeqBlock()
Constructor.
Definition: ExternalSequence.h:126
long delay
delay of this block (in us)
Definition: ExternalSequence.h:230
int shape
ID of shape for arbitrary gradient.
Definition: ExternalSequence.h:81
bool isArbitraryGradient(int channel)
Return true if block has arbitrary event on given channel.
Definition: ExternalSequence.h:255
void buildFileIndex(std::ifstream &stream)
Search the file stream for section headers e.g. [RF], [GRAD] etc.
Definition: ExternalSequence.cpp:362
static void print_msg(MessageType level, std::ostream &ss)
Display an output message.
Definition: ExternalSequence.cpp:28
SeqBlock * GetBlock(int blockIndex)
Construct a sequence block from the library events.
Definition: ExternalSequence.cpp:378
std::map< int, RFEvent > m_rfLibrary
Library of RF events.
Definition: ExternalSequence.h:519
void skipComments(std::ifstream &stream, char *buffer)
Skip the comments and empty lines in the given input stream.
Definition: ExternalSequence.cpp:351
std::vector< float > rfAmplitude
RF amplitude shape (uncompressed)
Definition: ExternalSequence.h:240
GradEvent grad[NUM_GRADS]
gradient events
Definition: ExternalSequence.h:234
void checkRF(SeqBlock &block)
Check the shapes defining the RF event (if present)
Definition: ExternalSequence.cpp:560
std::map< int, GradEvent > m_gradLibrary
Library of gradient events.
Definition: ExternalSequence.h:520
Sequence block.
Definition: ExternalSequence.h:119
static const int MAX_LINE_SIZE
Maximum length of line.
Definition: ExternalSequence.h:423
bool decodeBlock(SeqBlock *block)
Decode a block by looking up indexed events.
Definition: ExternalSequence.cpp:422
float * GetGradientPtr(int channel)
Directly get a pointer to the samples of the arbitrary gradient.
Definition: ExternalSequence.h:283
bool checkBlockReferences(EventIDs &events)
Check the IDs contains references to valid events in the library.
Definition: ExternalSequence.cpp:529
long GetDuration()
Return duration of block.
Definition: ExternalSequence.h:260
bool isRF()
Return true if block has RF event.
Definition: ExternalSequence.h:253
float freqOffset
Frequency offset of transmitter (Hz)
Definition: ExternalSequence.h:60
long rampDownTime
Ramp down time of trapezoid (us)
Definition: ExternalSequence.h:79
long rampUpTime
Ramp up time of trapezoid (us)
Definition: ExternalSequence.h:77
std::map< std::string, int > m_fileIndex
File location of sections, [RF], [ADC] etc.
Definition: ExternalSequence.h:510
RF event data.
Definition: ExternalSequence.h:55
long flatTime
Flat-top time of trapezoid (us)
Definition: ExternalSequence.h:78
int events[NUM_EVENTS]
list of event indices (RF, GX, GY, GZ, ADC)
Definition: ExternalSequence.h:228
static void SetPrintFunction(PrintFunPtr fun)
Set the output print function.
Definition: ExternalSequence.h:541
bool isDelay()
Return true if block has delay.
Definition: ExternalSequence.h:257
float * GetRFAmplitudePtr()
Directly get a pointer to the samples of the RF amplitude shape.
Definition: ExternalSequence.h:286
bool decompressShape(CompressedShape &encoded, float *shape)
Decompress a run-length compressed shape.
Definition: ExternalSequence.cpp:490
int delay
Delay before first sample (us)
Definition: ExternalSequence.h:96
std::vector< EventIDs > m_blocks
List of sequence blocks.
Definition: ExternalSequence.h:513
std::map< std::string, std::vector< double > > m_definitions
Custom definitions provided through [DEFINITIONS] section)
Definition: ExternalSequence.h:516
RFEvent & GetRFEvent()
Return the RF event.
Definition: ExternalSequence.h:265
bool load(std::string path)
Load the sequence from file.
Definition: ExternalSequence.cpp:39
Event
Internal storage order.
Definition: ExternalSequence.h:38
std::map< int, ADCEvent > m_adcLibrary
Library of ADC readouts.
Definition: ExternalSequence.h:521
ADCEvent adc
ADC event.
Definition: ExternalSequence.h:235
std::vector< double > GetDefinition(std::string key)
Lookup the custom definition.
Definition: ExternalSequence.h:533
void free()
Free the memory associated with decompressed shapes of this block.
Definition: ExternalSequence.h:290
List of event IDs.
Definition: ExternalSequence.h:106
Data representing the entire MR sequence.
Definition: ExternalSequence.h:330
bool isTrapGradient(int channel)
Return true if block has trapezoid event on given channel.
Definition: ExternalSequence.h:254
~ExternalSequence()
Destructor.
Definition: ExternalSequence.cpp:25
int GetGradientLength(int channel)
Return the number of samples of the given gradient channel. Only relevant for arbitrary gradients...
Definition: ExternalSequence.h:284
int numUncompressedSamples
Number of samples after decompression.
Definition: ExternalSequence.h:307
GradEvent & GetGradEvent(int channel)
Return the gradient event of the given channel.
Definition: ExternalSequence.h:264
int numSamples
Number of samples.
Definition: ExternalSequence.h:94
bool isADC()
Return true if block has ADC readout event.
Definition: ExternalSequence.h:256
static PrintFunPtr print_fun
Pointer to output print function.
Definition: ExternalSequence.h:506
ExternalSequence()
Constructor.
Definition: ExternalSequence.cpp:18
float phaseOffset
Phase offset of transmitter (rad)
Definition: ExternalSequence.h:61
long GetDelay()
Return delay of block.
Definition: ExternalSequence.h:259
ADC readout event.
Definition: ExternalSequence.h:92
int dwellTime
Dwell time of ADC readout (ns)
Definition: ExternalSequence.h:95
ADCEvent & GetADCEvent()
Return the ADC event.
Definition: ExternalSequence.h:266
std::map< int, CompressedShape > m_shapeLibrary
Library of compressed shapes.
Definition: ExternalSequence.h:525
int GetEventIndex(Event type)
Return ID of the corresponding given event type.
Definition: ExternalSequence.h:262
void(* PrintFunPtr)(const std::string &str)
A pointer-type to the low-level print function.
Definition: ExternalSequence.h:373
float * GetRFPhasePtr()
Directly get a pointer to the samples of the RF phase shape.
Definition: ExternalSequence.h:287
float amplitude
Amplitude of RF event (Hz)
Definition: ExternalSequence.h:57
std::vector< float > rfPhase
RF phase shape (uncompressed)
Definition: ExternalSequence.h:241
static void defaultPrint(const std::string &str)
Print string to standard output (with newline character)
Definition: ExternalSequence.h:540
float freqOffset
Frequency offset of receiver (Hz)
Definition: ExternalSequence.h:97
Gradient event data.
Definition: ExternalSequence.h:73
int magShape
ID of shape for magnitude.
Definition: ExternalSequence.h:58
std::string GetTypeString()
Return a brief string description of the block.
Definition: ExternalSequence.h:269
int GetNumberOfBlocks(void)
Return number of sequence blocks.
Definition: ExternalSequence.h:532
float amplitude
Amplitude of gradient (Hz/m)
Definition: ExternalSequence.h:75
std::vector< std::vector< float > > gradWaveforms
Arbitrary gradient shapes for each channel (uncompressed)
Definition: ExternalSequence.h:244
void checkGradient(SeqBlock &block)
Check the shapes defining the arbitrary gradient events (if present)
Definition: ExternalSequence.cpp:543