v2.0.0
Loading...
Searching...
No Matches
mri_cor_fif_io.cpp
Go to the documentation of this file.
1//=============================================================================================================
25
26//=============================================================================================================
27// INCLUDES
28//=============================================================================================================
29
30#include "mri_cor_fif_io.h"
31
32#include <fiff/fiff_stream.h>
33#include <fiff/fiff_tag.h>
35#include <fiff/fiff_file.h>
36#include <fiff/fiff_constants.h>
37
38//=============================================================================================================
39// QT INCLUDES
40//=============================================================================================================
41
42#include <QFile>
43#include <QDebug>
44
45//=============================================================================================================
46// EIGEN INCLUDES
47//=============================================================================================================
48
49#include <Eigen/Core>
50
51//=============================================================================================================
52// USED NAMESPACES
53//=============================================================================================================
54
55using namespace MRILIB;
56using namespace FIFFLIB;
57using namespace Eigen;
58
59//=============================================================================================================
60// DEFINE MEMBER METHODS
61//=============================================================================================================
62
63bool MriCorFifIO::write(const QString& fileName,
64 const QVector<MriSlice>& slices,
65 const QVector<FiffCoordTrans>& additionalTrans)
66{
67 //
68 // File structure (ported from save_slices() / write_slice() in write_mri_set.c):
69 //
70 // FIFFB_MRI
71 // FIFF_BLOCK_ID
72 // FIFFB_MRI_SET
73 // HEAD -> MRI identity transform
74 // Additional transforms (Talairach etc.)
75 // For each slice:
76 // FIFFB_MRI_SLICE
77 // FIFF_MRI_WIDTH
78 // FIFF_MRI_WIDTH_M
79 // FIFF_MRI_HEIGHT
80 // FIFF_MRI_HEIGHT_M
81 // CoordTrans (slice -> MRI)
82 // FIFF_MRI_PIXEL_ENCODING
83 // FIFF_MRI_PIXEL_DATA
84 // /FIFFB_MRI_SLICE
85 // /FIFFB_MRI_SET
86 // /FIFFB_MRI
87 //
88
89 QFile file(fileName);
91
92 if (!stream) {
93 qCritical() << "MriCorFifIO::write - Could not open file for writing:" << fileName;
94 return false;
95 }
96
97 // Start MRI block
98 stream->start_block(FIFFB_MRI);
99 stream->write_id(FIFF_BLOCK_ID);
100
101 // Start MRI set block
102 stream->start_block(FIFFB_MRI_SET);
103
104 // Write identity HEAD -> MRI transform
105 // Ported from write_mri_set.c: identity rotation, zero translation
106 Matrix3f identityRot = Matrix3f::Identity();
107 Vector3f zeroMove = Vector3f::Zero();
108 FiffCoordTrans headMriT(
109 FIFFV_COORD_HEAD, FIFFV_COORD_MRI, identityRot, zeroMove);
110 stream->write_coord_trans(headMriT);
111
112 // Write additional transforms (Talairach etc.)
113 for (const FiffCoordTrans& t : additionalTrans) {
114 stream->write_coord_trans(t);
115 }
116
117 // Write each slice
118 for (int k = 0; k < slices.size(); ++k) {
119 const MriSlice& slice = slices[k];
120
121 stream->start_block(FIFFB_MRI_SLICE);
122
123 // Width and height in pixels
124 fiff_int_t w = slice.width;
125 fiff_int_t h = slice.height;
126 stream->write_int(FIFF_MRI_WIDTH, &w);
127
128 float wm = static_cast<float>(slice.width) * slice.dimx;
129 stream->write_float(FIFF_MRI_WIDTH_M, &wm);
130
131 stream->write_int(FIFF_MRI_HEIGHT, &h);
132
133 float hm = static_cast<float>(slice.height) * slice.dimy;
134 stream->write_float(FIFF_MRI_HEIGHT_M, &hm);
135
136 // Coordinate transform
137 stream->write_coord_trans(slice.trans);
138
139 // Pixel encoding
140 fiff_int_t encoding = slice.pixelFormat;
141 stream->write_int(FIFF_MRI_PIXEL_ENCODING, &encoding);
142
143 // Pixel data
144 auto pixelTag = std::make_unique<FiffTag>();
145 pixelTag->kind = FIFF_MRI_PIXEL_DATA;
146
147 int nPixels = slice.width * slice.height;
148 switch (slice.pixelFormat) {
150 pixelTag->type = FIFFT_BYTE;
151 pixelTag->resize(nPixels);
152 memcpy(pixelTag->data(), slice.pixels.constData(), nPixels);
153 break;
154 }
156 pixelTag->type = FIFFT_USHORT;
157 pixelTag->resize(nPixels * 2);
158 memcpy(pixelTag->data(), slice.pixelsWord.constData(), nPixels * 2);
159 break;
160 }
162 pixelTag->type = FIFFT_FLOAT;
163 pixelTag->resize(nPixels * 4);
164 memcpy(pixelTag->data(), slice.pixelsFloat.constData(), nPixels * 4);
165 break;
166 }
167 }
168
169 stream->write_tag(pixelTag);
170
171 stream->end_block(FIFFB_MRI_SLICE);
172 }
173
174 // End blocks
175 stream->end_block(FIFFB_MRI_SET);
176 stream->end_block(FIFFB_MRI);
177 stream->end_file();
178
179 return true;
180}
Writer for the COR.fif FIFF representation of an MRI volume (Neuromag/MNE convention used by all mne-...
Symbolic FIFF tag, block, value, unit and channel-type constants shared across FIFFLIB.
#define FIFFV_COORD_HEAD
#define FIFFV_COORD_MRI
FIFF tag-kind, block-kind and type-code numerical definitions, authoritative for FIFFLIB.
#define FIFF_MRI_HEIGHT_M
Definition fiff_file.h:649
#define FIFF_MRI_PIXEL_DATA
Definition fiff_file.h:641
#define FIFF_MRI_WIDTH_M
Definition fiff_file.h:647
#define FIFF_MRI_HEIGHT
Definition fiff_file.h:648
#define FIFFV_MRI_PIXEL_BYTE
Definition fiff_file.h:695
#define FIFFB_MRI_SLICE
Definition fiff_file.h:385
#define FIFFT_BYTE
Definition fiff_file.h:222
#define FIFF_BLOCK_ID
Definition fiff_file.h:319
#define FIFFB_MRI_SET
Definition fiff_file.h:384
#define FIFFT_USHORT
Definition fiff_file.h:228
#define FIFFT_FLOAT
Definition fiff_file.h:225
#define FIFF_MRI_PIXEL_ENCODING
Definition fiff_file.h:638
#define FIFFV_MRI_PIXEL_FLOAT
Definition fiff_file.h:698
#define FIFFB_MRI
Definition fiff_file.h:383
#define FIFF_MRI_WIDTH
Definition fiff_file.h:646
#define FIFFV_MRI_PIXEL_WORD
Definition fiff_file.h:696
FIFF tag: the 16-byte tag header (kind, type, size, next) plus its decoded payload.
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
FIFF file I/O, in-memory data structures and high-level readers/writers.
Volume I/O, voxel geometry and slice resampling for structural MRI data inside mne-cpp.
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
QSharedPointer< FiffStream > SPtr
static FiffStream::SPtr start_file(QIODevice &p_IODevice)
static bool write(const QString &fileName, const QVector< MriSlice > &slices, const QVector< FIFFLIB::FiffCoordTrans > &additionalTrans)
Single 2D MRI slice (pixels + slice→RAS transform) used as the volume's storage unit.
QVector< unsigned char > pixels
FIFFLIB::FiffCoordTrans trans
QVector< unsigned short > pixelsWord
QVector< float > pixelsFloat