MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
fiff_coord_trans.cpp
Go to the documentation of this file.
1//=============================================================================================================
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "fiff_coord_trans.h"
42
43#include "fiff_stream.h"
44#include "fiff_tag.h"
45#include "fiff_dir_node.h"
46
47#include <iostream>
48
49#define _USE_MATH_DEFINES
50#include <math.h>
51
52//=============================================================================================================
53// EIGEN INCLUDES
54//=============================================================================================================
55
56#include <Eigen/Dense>
57
58//=============================================================================================================
59// USED NAMESPACES
60//=============================================================================================================
61
62using namespace FIFFLIB;
63using namespace Eigen;
64
65//=============================================================================================================
66// DEFINE MEMBER METHODS
67//=============================================================================================================
68
70: from(-1)
71, to(-1)
72, trans(MatrixXf::Identity(4,4))
73, invtrans(MatrixXf::Identity(4,4))
74{
75}
76
77//=============================================================================================================
78
79FiffCoordTrans::FiffCoordTrans(QIODevice &p_IODevice)
80: from(-1)
81, to(-1)
82, trans(MatrixXf::Identity(4,4))
83, invtrans(MatrixXf::Identity(4,4))
84{
85 if(!read(p_IODevice, *this))
86 {
87 printf("\tCoordindate transform not found.\n");//ToDo Throw here
88 return;
89 }
90}
91
92//=============================================================================================================
93
95: from(p_FiffCoordTrans.from)
96, to(p_FiffCoordTrans.to)
97, trans(p_FiffCoordTrans.trans)
98, invtrans(p_FiffCoordTrans.invtrans)
99{
100}
101
102//=============================================================================================================
103
107
108//=============================================================================================================
109
111{
112 from = -1;
113 to = -1;
114 trans.setIdentity();
115 invtrans.setIdentity();
116}
117
118//=============================================================================================================
119
121{
122 fiff_int_t from_new = this->to;
123 this->to = this->from;
124 this->from = from_new;
125 this->trans = this->trans.inverse().eval();
126 this->invtrans = this->invtrans.inverse().eval();
127
128 return true;
129}
130
131//=============================================================================================================
132
133bool FiffCoordTrans::read(QIODevice& p_IODevice, FiffCoordTrans& p_Trans)
134{
135 FiffStream::SPtr pStream(new FiffStream(&p_IODevice));
136
137 printf("Reading coordinate transform from %s...\n", pStream->streamName().toUtf8().constData());
138 if(!pStream->open())
139 return false;
140
141 //
142 // Locate and read the coordinate transformation
143 //
144 FiffTag::SPtr t_pTag;
145 bool success = false;
146
147 //
148 // Get the MRI <-> head coordinate transformation
149 //
150 for ( qint32 k = 0; k < pStream->dir().size(); ++k )
151 {
152 if ( pStream->dir()[k]->kind == FIFF_COORD_TRANS )
153 {
154 pStream->read_tag(t_pTag,pStream->dir()[k]->pos);
155 p_Trans = t_pTag->toCoordTrans();
156 success = true;
157 }
158 }
159
160 return success;
161}
162
163//=============================================================================================================
164
165void FiffCoordTrans::write(QIODevice &qIODevice)
166{
167 // Create the file and save the essentials
168 FiffStream::SPtr pStream = FiffStream::start_file(qIODevice);
169 printf("Write coordinate transform in %s...\n", pStream->streamName().toUtf8().constData());
170 this->writeToStream(pStream.data());
171 pStream->end_file();
172 qIODevice.close();
173}
174
175//=============================================================================================================
176
178{
179 pStream->write_coord_trans(*this);
180}
181
182//=============================================================================================================
183
184MatrixX3f FiffCoordTrans::apply_trans(const MatrixX3f& rr, bool do_move) const
185{
186 MatrixX4f rr_ones = do_move ? MatrixX4f::Ones(rr.rows(),4) : MatrixX4f::Zero(rr.rows(),4);
187 rr_ones.block(0,0,rr.rows(),3) = rr;
188 return rr_ones*trans.block<3,4>(0,0).transpose();
189}
190
191//=============================================================================================================
192
193MatrixX3f FiffCoordTrans::apply_inverse_trans(const MatrixX3f& rr, bool do_move) const
194{
195 MatrixX4f rr_ones = do_move ? MatrixX4f::Ones(rr.rows(),4) : MatrixX4f::Zero(rr.rows(),4);
196 rr_ones.block(0,0,rr.rows(),3) = rr;
197 return rr_ones*invtrans.block<3,4>(0,0).transpose();
198}
199
200//=============================================================================================================
201
202QString FiffCoordTrans::frame_name (int frame)
203{
204 switch(frame) {
205 case FIFFV_COORD_UNKNOWN: return "unknown";
206 case FIFFV_COORD_DEVICE: return "MEG device";
207 case FIFFV_COORD_ISOTRAK: return "isotrak";
208 case FIFFV_COORD_HPI: return "hpi";
209 case FIFFV_COORD_HEAD: return "head";
210 case FIFFV_COORD_MRI: return "MRI (surface RAS)";
211 case FIFFV_MNE_COORD_MRI_VOXEL: return "MRI voxel";
212 case FIFFV_COORD_MRI_SLICE: return "MRI slice";
213 case FIFFV_COORD_MRI_DISPLAY: return "MRI display";
214 case FIFFV_MNE_COORD_CTF_DEVICE: return "CTF MEG device";
215 case FIFFV_MNE_COORD_CTF_HEAD: return "CTF/4D/KIT head";
216 case FIFFV_MNE_COORD_RAS: return "RAS (non-zero origin)";
217 case FIFFV_MNE_COORD_MNI_TAL: return "MNI Talairach";
218 case FIFFV_MNE_COORD_FS_TAL_GTZ: return "Talairach (MNI z > 0)";
219 case FIFFV_MNE_COORD_FS_TAL_LTZ: return "Talairach (MNI z < 0)";
220 default: return "unknown";
221 }
222}
223
224//=============================================================================================================
225
226FiffCoordTrans FiffCoordTrans::make(int from, int to, const Matrix3f& rot, const VectorXf& move)
227{
229 t.trans = MatrixXf::Zero(4,4);
230
231 t.from = from;
232 t.to = to;
233
234 t.trans.block<3,3>(0,0) = rot;
235 t.trans.block<3,1>(0,3) = move;
236 t.trans(3,3) = 1.0f;
237
239
240 return t;
241}
242
243//=============================================================================================================
244
245FiffCoordTrans FiffCoordTrans::make(int from, int to, const Matrix4f& matTrans, bool bStandard)
246{
248
249 t.trans = matTrans;
250 t.from = from;
251 t.to = to;
252
253 if(bStandard) {
254 // make sure that it is a standard transform if requested
255 t.trans.row(3) = Vector4f(0,0,0,1);
256 }
257
259
260 return t;
261}
262
263//=============================================================================================================
264
266{
267 t.invtrans = t.trans.inverse().eval();
268 return true;
269}
270
271//=============================================================================================================
272
274{
275 std::cout << "Coordinate transformation: ";
276 std::cout << (QString("%1 -> %2\n").arg(frame_name(this->from)).arg(frame_name(this->to))).toUtf8().data();
277
278 for (int p = 0; p < 3; p++)
279 printf("\t% 8.6f % 8.6f % 8.6f\t% 7.2f mm\n", trans(p,0),trans(p,1),trans(p,2),1000*trans(p,3));
280 printf("\t% 8.6f % 8.6f % 8.6f % 7.2f\n",trans(3,0),trans(3,1),trans(3,2),trans(3,3));
281}
282
283//=============================================================================================================
284
285float FiffCoordTrans::angleTo(Eigen::MatrixX4f mTransDest)
286{
287 MatrixX4f mDevHeadT = this->trans;
288 Matrix3f mRot = mDevHeadT.block(0,0,3,3);
289 Matrix3f mRotNew = mTransDest.block(0,0,3,3);
290
291 Quaternionf quat(mRot);
292 Quaternionf quatNew(mRotNew);
293
294 float fAngle;
295
296 // calculate rotation
297 Quaternionf quatCompare;
298
299 quatCompare = quat*quatNew.inverse();
300 fAngle = quat.angularDistance(quatNew);
301 fAngle = fAngle * 180 / M_PI;
302
303 return fAngle;
304}
305
306//=============================================================================================================
307
308float FiffCoordTrans::translationTo(Eigen::MatrixX4f mTransDest)
309{
310 VectorXf vTrans = this->trans.col(3);
311 VectorXf vTransDest = mTransDest.col(3);
312
313 float fMove = (vTrans-vTransDest).norm();
314 return fMove;
315}
316
317//=============================================================================================================
318
320{
322 tOld.from = this->from;
323 tOld.to = this->to;
324 tOld.rot = this->trans.block(0,0,3,3);
325 tOld.move = this->trans.block(0,3,3,1);
326 tOld.invrot = this->invtrans.block(0,0,3,3);
327 tOld.invmove = this->invtrans.block(0,3,3,1);
328
329 return tOld;
330}
FiffTag class declaration, which provides fiff tag I/O and processing methods.
#define FIFFV_MNE_COORD_MNI_TAL
#define FIFFV_MNE_COORD_FS_TAL_LTZ
#define FIFFV_MNE_COORD_CTF_DEVICE
#define FIFFV_MNE_COORD_MRI_VOXEL
#define FIFFV_MNE_COORD_CTF_HEAD
#define FIFFV_MNE_COORD_FS_TAL_GTZ
#define FIFFV_MNE_COORD_RAS
FiffStream class declaration.
FiffDirNode class declaration, which provides fiff dir tree processing methods.
int k
Definition fiff_tag.cpp:324
#define FIFF_COORD_TRANS
Definition fiff_file.h:475
FiffCoordTrans class declaration.
Coordinate transformation descriptor.
Coordinate transformation description.
FiffCoordTransOld toOld()
void write(QIODevice &p_IODevice)
Writes the transformation to file.
static FiffCoordTrans make(int from, int to, const Eigen::Matrix3f &rot, const Eigen::VectorXf &move)
float translationTo(Eigen::MatrixX4f mTransDest)
static bool read(QIODevice &p_IODevice, FiffCoordTrans &p_Trans)
float angleTo(Eigen::MatrixX4f mTransDest)
Eigen::MatrixX3f apply_inverse_trans(const Eigen::MatrixX3f &rr, bool do_move=true) const
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > trans
void writeToStream(FiffStream *p_pStream)
Writes the transformation to stream.
static QString frame_name(int frame)
Eigen::MatrixX3f apply_trans(const Eigen::MatrixX3f &rr, bool do_move=true) const
static bool addInverse(FiffCoordTrans &t)
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > invtrans
FIFF File I/O routines.
fiff_long_t write_coord_trans(const FiffCoordTrans &trans)
static FiffStream::SPtr start_file(QIODevice &p_IODevice)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
Definition fiff_tag.h:152