2 // C++ Implementation: brukerimage
7 // Author: Denis Grenier, (C) 2009
9 // Copyright: See COPYING file that comes with this distribution
16 #include "brukerimage.h"
19 * @brief This method takes care of the initialization of the main parameters usually needed to deal with an MRI experiment
20 * @fn bool BrukerImage::Init(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
26 bool BrukerImage::Init(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
29 // on devrait plutot les nommer 'computeXXX' (setXXX est d'habitude réservé aux accesseurs 'publics')
31 setAbsoluteTimePosition (TheOrigAcqp,TheOrigReco,TheValue);
32 setRelativeTimePosition (TheOrigAcqp,TheOrigReco,TheValue);
33 setFOVpixels (TheOrigAcqp,TheOrigReco,TheValue);
34 setFOVcm (TheOrigAcqp,TheOrigReco,TheValue);
35 setSliceThickness (TheOrigAcqp,TheOrigReco,TheValue);
36 setTE (TheOrigAcqp,TheOrigReco,TheValue);
37 setTR (TheOrigAcqp,TheOrigReco,TheValue);
38 setTI (TheOrigAcqp,TheOrigReco,TheValue);
39 setFlipAngle (TheOrigAcqp,TheOrigReco,TheValue);
40 setLoopStamp (TheOrigAcqp,TheOrigReco,TheValue);
41 setNA (TheOrigAcqp,TheOrigReco,TheValue);
42 setNR (TheOrigAcqp,TheOrigReco,TheValue);
43 setNAE (TheOrigAcqp,TheOrigReco,TheValue);
44 setDS (TheOrigAcqp,TheOrigReco,TheValue);
45 setACQ_phase_factor (TheOrigAcqp,TheOrigReco,TheValue);
46 setRotationMatrixRPS2XYZ (TheOrigAcqp,TheOrigReco,TheValue);
47 setTranslationVectorRPS2XYZ (TheOrigAcqp,TheOrigReco,TheValue);
48 setWordType (TheOrigAcqp,TheOrigReco,TheValue);
49 setImageType (TheOrigAcqp,TheOrigReco,TheValue);
50 setDataEndianness (TheOrigAcqp,TheOrigReco,TheValue);
51 setImageByteSize (TheOrigAcqp,TheOrigReco,TheValue);
52 setBeginingOfImageInBytes (TheOrigAcqp,TheOrigReco,TheValue);
58 * @brief the constructor uses the BrukerDataSet's of the acqp and reco file
59 * @fn BrukerImage::BrukerImage(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco)
63 BrukerImage::BrukerImage(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco)
67 BrukerImage::~BrukerImage()
72 * @fn int BrukerImage::getAbsoluteTimePosition() const
73 * @brief AbsoluteTimePosition is an integer number giving the time of the begining of the acquisition of the dataset
74 * @return AbsoluteTimePosition int
76 int BrukerImage::getAbsoluteTimePosition() const
78 return AbsoluteTimePosition;
82 * @fn bool BrukerImage::setAbsoluteTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
83 * @brief AbsoluteTimePosition is an integer number giving the time of the begining of the acquisition of the dataset
89 bool BrukerImage::setAbsoluteTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
91 AbsoluteTimePosition = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_abs_time"].GetIntValue()[0];
96 * @brief RelativeTimePosition is the estimated time position of the time the k-space center was acquired
97 * This notion is very relative when dealing with long experiments and a line or object averaging (NA or NAE <> 1)
98 * @fn double BrukerImage::getRelativeTimePosition() const
101 double BrukerImage::getRelativeTimePosition() const
103 return RelativeTimePosition;
107 * @brief RelativeTimePosition is the estimated instant when the k-space center of each image was acquired
109 This notion is very relative when dealing with long experiments and a line or object averaging (NA or NAE <> 1)
110 * @fn bool BrukerImage::setRelativeTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
116 bool BrukerImage::setRelativeTimePosition (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue )
118 long lTEMP = TheOrigAcqp.GetBrukerImageList()[TheValue].back();
119 RelativeTimePosition = TheOrigAcqp.ObjectVaryingProperties.getPositionTimePerNR(lTEMP);
124 * @brief FOVpixels is a 1x2 integer vector. it's one of the view value we need to pick in the reco headermap
125 * @fn bool BrukerImage::setFOVpixels(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
131 bool BrukerImage::setFOVpixels(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
133 FOVpixels = TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_size"].GetIntValue();
138 * @brief FOVpixels is a 1x2 integer vector. it's one of the view value we need to pick in the reco headermap
139 * @fn std::vector <int > BrukerImage::getFOVpixels() const
140 * @return std::vector <int >
142 const std::vector<int > &BrukerImage::getFOVpixels() const
148 * @brief FOVcm is also picked in reco headermap
149 * @fn bool BrukerImage::setFOVcm(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
155 bool BrukerImage::setFOVcm(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
157 FOVcm = TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_fov"].GetDoubleValue();
162 * @brief FOVcm is also picked in reco headermap
163 * @fn std::vector <double > BrukerImage::getFOVcm() const
164 * @return std::vector <double >
166 const std::vector <double > &BrukerImage::getFOVcm() const
172 * @brief SliceThickness is in milimeter
173 * @fn bool BrukerImage::setSliceThickness( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
179 bool BrukerImage::setSliceThickness( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
181 SliceThickness = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_slice_thick"].GetDoubleValue()[0];
186 * @brief SliceThickness is in milimeter
187 * @fn double BrukerImage::getSliceThickness() const
190 double BrukerImage::getSliceThickness() const
192 return SliceThickness;
196 * @brief picks the echo time of the image number TheValue
197 * @fn bool BrukerImage::setTE( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
203 bool BrukerImage::setTE( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
205 TE = TheOrigAcqp.ObjectVaryingProperties.getTE(TheOrigAcqp.GetBrukerImageList()[TheValue][0]);
210 * @fn double BrukerImage::getTE() const
211 * @brief picks the echo time of the image number TheValue
214 double BrukerImage::getTE() const
220 * @brief picks the repetition time of the image number TheValue
221 * @fn bool BrukerImage::setTR( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
227 bool BrukerImage::setTR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
229 TR=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_repetition_time"].GetDoubleValue()[0];
234 * @fn double BrukerImage::getTR() const
235 * @brief picks the echo time of the image number TheValue
238 double BrukerImage::getTR() const
244 * @brief picks the invertion time of the image number TheValue
245 * @fn bool BrukerImage::setTI( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
251 bool BrukerImage::setTI(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
253 TI = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_inversion_time"].GetDoubleValue()[0];
258 * @fn double BrukerImage::getTI() const
259 * @brief picks the invertion time of the image number TheValue
262 double BrukerImage::getTI() const
268 * @brief picks the flip angle of the image number TheValue
269 * @fn bool BrukerImage::setFlipAngle( BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco,int TheValue)
275 bool BrukerImage::setFlipAngle(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
277 FlipAngle = TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_flip_angle"].GetIntValue()[0];
282 * @fn double BrukerImage::getFlipAngle() const
283 * @brief picks the flip angle of the image number TheValue
286 double BrukerImage::getFlipAngle() const
293 * @brief LoopStamp is a vector, copy of the values of all the loop for the image number TheValue
295 * The purpose of this "loopstamp" is to provide additionnal information if the methods provided by this class are not sufficient to singularize each image
296 * @fn bool BrukerImage::setLoopStamp(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
302 bool BrukerImage::setLoopStamp(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
304 LoopStamp = TheOrigAcqp.GetBrukerImageList()[TheValue];
309 * @brief LoopStamp is a vector, copy of the values of all the loop for the image number TheValue
310 * The purpose of this "loopstamp" is to provide additionnal information if the methods provided by this class are not sufficient to singularize each image
311 * @fn std::vector<int> BrukerImage::getLoopStamp() const
314 const std::vector<int> &BrukerImage::getLoopStamp() const
320 * @brief NA number of accumulation is useful to track image quality
321 * @fn bool BrukerImage::setNA(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
327 bool BrukerImage::setNA(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
329 NA=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "NA"].GetIntValue()[0];
334 * @brief NA number of accumulation is useful to track image quality
335 * @fn int BrukerImage::getNA() const
339 int BrukerImage::getNA() const
345 * @brief NAE number of object exterior accumulation is useful to track image quality and rather used than NA to average movement artefacts
346 * @fn bool BrukerImage::setNAE(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
352 bool BrukerImage::setNAE(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
354 NAE=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "NAE"].GetIntValue()[0];
359 * @brief NAE number of object exterior accumulation is useful to track image quality and rather used than NA to average movement artefacts
360 * @fn int BrukerImage::getNAE() const
364 int BrukerImage::getNAE() const
370 * @brief DS (dummy scan) is useful to establish a dynamic equilibrium or to know if one was used
371 * @fn bool BrukerImage::setDS(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
378 bool BrukerImage::setDS(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
380 DS=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "DS"].GetIntValue()[0];
385 @brief DS (dummy scan) is useful to establish a dynamic equilibrium or to know if one was used
386 @fn int BrukerImage::get() const
389 int BrukerImage::getDS() const
395 * @brief Phase factor is the number of kspace line acquired in a single shot
396 * @fn bool BrukerImage::setACQ_phase_factor(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
402 bool BrukerImage::setACQ_phase_factor(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
404 ACQ_phase_factor=TheOrigAcqp.GetBrukerHeaderMap()[(std::string) "ACQ_phase_factor"].GetIntValue()[0];
409 * @brief Phase factor is the number of kspace line acquired in a single shot
410 * @fn int BrukerImage::getACQ_phase_factor() const
413 int BrukerImage::getACQ_phase_factor() const
415 return ACQ_phase_factor;
420 * @brief The number of repetition NR is used to repeat a full objects acquisition NR times with a given delay
421 * This method returns at which repetition belongs the image TheValue
422 * @fn bool BrukerImage::NR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
428 bool BrukerImage::setNR(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
430 NR= TheOrigAcqp.GetBrukerImageList()[TheValue].back();
435 * @brief The number of repetition NR is used to repeat a full objects acquisition NR times with a given delay
436 * This method returns at which repetition belongs the image TheValue
437 * @fn int BrukerImage::getNR() const
440 int BrukerImage::getNR() const
446 * @brief RotationMatrixRPS2XYZ is a 3x3 rotation matrix giving the orientation of the TheValue image
447 * @fn bool BrukerImage::setRotationMatrixRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
453 bool BrukerImage::setRotationMatrixRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
455 RotationMatrixRPS2XYZ = TheOrigAcqp.ObjectVaryingProperties.getOrientation(TheOrigAcqp.GetBrukerImageList()[TheValue][2]);
460 @brief RotationMatrixRPS2XYZ is a 3x3 rotation matrix giving the orientation of the TheValue image
461 @fn std::vector<std::vector<double> > BrukerImage::getRotationMatrixRPS2XYZ() const
462 @return RotationMatrixRPS2XYZ
464 const std::vector<std::vector<double> > &BrukerImage::getRotationMatrixRPS2XYZ() const
466 return RotationMatrixRPS2XYZ;
470 * @brief TranslationVectorRPS2XYZ is a 1x3 vector of the TheValue image position to the magnet center (in mm)
471 * @fn bool BrukerImage::setTranslationVectorRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
477 bool BrukerImage::setTranslationVectorRPS2XYZ(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
479 TranslationVectorRPS2XYZ.clear();
480 TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionR(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
481 TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionP(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
482 TranslationVectorRPS2XYZ.push_back(TheOrigAcqp.ObjectVaryingProperties.getPositionS(TheOrigAcqp.GetBrukerImageList()[TheValue][2]));
487 @brief TranslationVectorRPS2XYZ is a 1x3 vector of the TheValue image position to the magnet center (in mm)
488 @fn std::vector<double> BrukerImage::getTranslationVectorRPS2XYZ() const
489 @return TranslationVectorRPS2XYZ
491 const std::vector<double> &BrukerImage::getTranslationVectorRPS2XYZ() const
493 return TranslationVectorRPS2XYZ;
497 * @brief WordType returns the type of data to read int32_t, int16_t, uint8_t or float32_t
498 * @fn bool BrukerImage::setWordType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
504 bool BrukerImage::setWordType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
506 WordType=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_wordtype"].GetStringValue()[0];
511 @brief WordType returns the type of data to read int32_t, int16_t, uint8_t or float32_t
512 @fn std::string BrukerImage::getWordType() const
513 @return int32_t, int16_t, uint8_t or float32_t or UNKNOWN
515 std::string BrukerImage::getWordType() const
517 if(WordType == ((std::string) "_32BIT_SGN_INT")) return ((std::string)"int32_t");
518 if(WordType == ((std::string) "_16BIT_SGN_INT")) return ((std::string)"int16_t");
519 if(WordType == ((std::string) "_8BIT_UNSGN_INT")) return ((std::string)"uint8_t");
520 if(WordType == ((std::string) "_32BIT_FLOAT")) return ((std::string)"float32_t");
521 return ((std::string)"UNKNOWN");
525 * @brief ImageType returns the type of image : values real for amplitude, real imaginary or phase images and complex for complex images
526 * @fn bool BrukerImage::setImageType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
532 bool BrukerImage::setImageType(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
534 ImageType=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_image_type"].GetStringValue()[0];
539 @brief ImageType returns the type of image : values real for amplitude, real imaginary or phase images and complex for complex images
540 @fn std::string BrukerImage::getImageType() const
541 @return complex or real
543 std::string BrukerImage::getImageType() const
545 if(ImageType == ((std::string) "COMPLEXE_IMAGE")) return ((std::string)"complex");
546 return ((std::string)"real");
550 * @brief DataEndianness gives information on how to swap or no the binary data to read
551 * @fn bool BrukerImage::setDataEndianness(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
557 bool BrukerImage::setDataEndianness(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
559 DataEndianness=TheOrigReco.GetBrukerHeaderMap()[(std::string) "RECO_byte_order"].GetStringValue()[0];
564 * @brief DataEndianness gives information on how to swap or no the binary data to read
565 * @fn std::string BrukerImage::getDataEndianness() const
566 * @return DataEndianness
568 const std::string &BrukerImage::getDataEndianness() const
570 return DataEndianness;
574 * @brief Information on the image size in byte, useful for offsets calculation
575 * @fn bool BrukerImage::setImageByteSize(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
581 bool BrukerImage::setImageByteSize(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
583 int Dimension, WordSize;
584 if (getImageType()==((std::string)"complex")) Dimension=2;
585 else if (getImageType()==((std::string)"real")) Dimension=1;
588 if (getWordType()==((std::string)"int32_t")||getWordType()==((std::string)"float32_t")) WordSize=4;
589 else if (getWordType()==((std::string)"int16_t")) WordSize=2;
590 else if (getWordType()==((std::string)"uint8_t")) WordSize=1;
591 else /*if (getWordType()==((std::string)"UNKNOWN"))*/ return false;
593 ImageByteSize = Dimension*WordSize*getFOVpixels()[0]*getFOVpixels()[1];
598 * @brief Information on the image size in byte, useful for offsets calculation
599 * @fn size_t BrukerImage::getImageByteSize() const
600 * @return ImageByteSize
602 size_t BrukerImage::getImageByteSize() const
604 return ImageByteSize;
608 * @brief BeginingOfImageInBytes is the offset of the image number TheValue to the begining of 2dseq file
609 * @fn size_t BrukerImage::getBeginingOfImageInBytes() const
610 * @return BeginingOfImageInBytes
612 size_t BrukerImage::getBeginingOfImageInBytes() const
614 return BeginingOfImageInBytes;
618 * @brief BeginingOfImageInBytes is the offset of the image number TheValue to the begining of 2dseq file
619 * @fn bool BrukerImage::setBeginingOfImageInBytes(BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
625 bool BrukerImage::setBeginingOfImageInBytes (BrukerDataSet &TheOrigAcqp, BrukerDataSet &TheOrigReco, int TheValue)
627 BeginingOfImageInBytes = TheValue*getImageByteSize();