MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
fwd_coil.cpp
Go to the documentation of this file.
1//=============================================================================================================
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "fwd_coil.h"
42//#include <fiff/fiff_types.h>
43#include <fiff/fiff_ch_info.h>
44#include <stdio.h>
45
46//=============================================================================================================
47// QT INCLUDES
48//=============================================================================================================
49
50#include <QDebug>
51
52//=============================================================================================================
53// USED NAMESPACES
54//=============================================================================================================
55
56using namespace Eigen;
57using namespace FIFFLIB;
58using namespace FWDLIB;
59
60#define MALLOC_5(x,t) (t *)malloc((x)*sizeof(t))
61
62#define FREE_5(x) if ((char *)(x) != NULL) free((char *)(x))
63#define FREE_CMATRIX_5(m) mne_free_cmatrix_5((m))
64
65#define ALLOC_CMATRIX_5(x,y) mne_cmatrix_5((x),(y))
66
67#define X_5 0
68#define Y_5 1
69#define Z_5 2
70
71#define VEC_DOT_5(x,y) ((x)[X_5]*(y)[X_5] + (x)[Y_5]*(y)[Y_5] + (x)[Z_5]*(y)[Z_5])
72#define VEC_LEN_5(x) sqrt(VEC_DOT_5(x,x))
73
74#define VEC_COPY_5(to,from) {\
75 (to)[X_5] = (from)[X_5];\
76 (to)[Y_5] = (from)[Y_5];\
77 (to)[Z_5] = (from)[Z_5];\
78 }
79
80static void matrix_error_5(int kind, int nr, int nc)
81
82{
83 if (kind == 1)
84 printf("Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
85 else if (kind == 2)
86 printf("Failed to allocate memory for a %d x %d matrix\n",nr,nc);
87 else
88 printf("Allocation error for a %d x %d matrix\n",nr,nc);
89 if (sizeof(void *) == 4) {
90 printf("This is probably because you seem to be using a computer with 32-bit architecture.\n");
91 printf("Please consider moving to a 64-bit platform.");
92 }
93 printf("Cannot continue. Sorry.\n");
94 exit(1);
95}
96
97float **mne_cmatrix_5(int nr,int nc)
98
99{
100 int i;
101 float **m;
102 float *whole;
103
104 m = MALLOC_5(nr,float *);
105 if (!m) matrix_error_5(1,nr,nc);
106 whole = MALLOC_5(nr*nc,float);
107 if (!whole) matrix_error_5(2,nr,nc);
108
109 for(i=0;i<nr;i++)
110 m[i] = whole + i*nc;
111 return m;
112}
113
114void mne_free_cmatrix_5 (float **m)
115{
116 if (m) {
117 FREE_5(*m);
118 FREE_5(m);
119 }
120}
121
122static void normalize_5(float *rr)
123/*
124 * Scale vector to unit length
125 */
126{
127 float ll = VEC_LEN_5(rr);
128 int k;
129 if (ll > 0) {
130 for (k = 0; k < 3; k++)
131 rr[k] = rr[k]/ll;
132 }
133 return;
134}
135
136//=============================================================================================================
137// DEFINE MEMBER METHODS
138//=============================================================================================================
139
141{
142 coil_class = FWD_COILC_UNKNOWN;
143 accuracy = FWD_COIL_ACCURACY_POINT;
144 base = 0.0;
145 size = 0.0;
146 np = p_np;
147 rmag = ALLOC_CMATRIX_5(np,3);
148 cosmag = ALLOC_CMATRIX_5(np,3);
149 w = MALLOC_5(np,float);
150 /*
151 * Reasonable defaults
152 */
153 for (int k = 0; k < 3; k++) {
154 r0[k] = 0.0;
155 ex[k] = 0.0;
156 ey[k] = 0.0;
157 ez[k] = 0.0;
158 }
159 ex[0] = 1.0;
160 ey[1] = 1.0;
161 ez[2] = 1.0;
162}
163
164//=============================================================================================================
165
166FwdCoil::FwdCoil(const FwdCoil& p_FwdCoil)
167{
168 if (!p_FwdCoil.chname.isEmpty())
169 this->chname = p_FwdCoil.chname;
170 if (!p_FwdCoil.desc.isEmpty())
171 this->desc = p_FwdCoil.desc;
172 this->coil_class = p_FwdCoil.coil_class;
173 this->accuracy = p_FwdCoil.accuracy;
174 this->base = p_FwdCoil.base;
175 this->size = p_FwdCoil.size;
176 this->np = p_FwdCoil.np;
177 this->type = p_FwdCoil.type;
178
179 rmag = ALLOC_CMATRIX_5(this->np,3);
180 cosmag = ALLOC_CMATRIX_5(this->np,3);
181 w = MALLOC_5(this->np,float);
182
183 VEC_COPY_5(this->r0,p_FwdCoil.r0);
184 VEC_COPY_5(this->ex,p_FwdCoil.ex);
185 VEC_COPY_5(this->ey,p_FwdCoil.ey);
186 VEC_COPY_5(this->ez,p_FwdCoil.ez);
187
188 for (int p = 0; p < p_FwdCoil.np; p++) {
189 this->w[p] = p_FwdCoil.w[p];
190 VEC_COPY_5(this->rmag[p],p_FwdCoil.rmag[p]);
191 VEC_COPY_5(this->cosmag[p],p_FwdCoil.cosmag[p]);
192 }
193 this->coord_frame = p_FwdCoil.coord_frame;
194}
195
196//=============================================================================================================
197
199{
200 FREE_CMATRIX_5(rmag);
201 FREE_CMATRIX_5(cosmag);
202 FREE_5(w);
203}
204
205//=============================================================================================================
206
208{
209 FwdCoil* res = NULL;
210 int c;
211
212 if (ch.kind != FIFFV_EEG_CH) {
213 qWarning() << ch.ch_name << "is not an EEG channel. Cannot create an electrode definition.";
214 goto bad;
215 }
216 if (t && t->from != FIFFV_COORD_HEAD) {
217 printf("Inappropriate coordinate transformation in fwd_create_eeg_el");
218 goto bad;
219 }
220
221 if (ch.chpos.ex.norm() < 1e-4)
222 res = new FwdCoil(1); /* No reference electrode */
223 else
224 res = new FwdCoil(2); /* Reference electrode present */
225
226 res->chname = ch.ch_name;
227 res->desc = "EEG electrode";
228 res->coil_class = FWD_COILC_EEG;
229 res->accuracy = FWD_COIL_ACCURACY_NORMAL;
230 res->type = ch.chpos.coil_type;
231 VEC_COPY_5(res->r0,ch.chpos.r0);
232 VEC_COPY_5(res->ex,ch.chpos.ex);
233 /*
234 * Optional coordinate transformation
235 */
236 if (t) {
237 FiffCoordTransOld::fiff_coord_trans(res->r0,t,FIFFV_MOVE);
238 FiffCoordTransOld::fiff_coord_trans(res->ex,t,FIFFV_MOVE);
239 res->coord_frame = t->to;
240 }
241 else
242 res->coord_frame = FIFFV_COORD_HEAD;
243 /*
244 * The electrode location
245 */
246 for (c = 0; c < 3; c++)
247 res->rmag[0][c] = res->cosmag[0][c] = res->r0[c];
248 normalize_5(res->cosmag[0]);
249 res->w[0] = 1.0;
250 /*
251 * Add the reference electrode, if appropriate
252 */
253 if (res->np == 2) {
254 for (c = 0; c < 3; c++)
255 res->rmag[1][c] = res->cosmag[1][c] = res->ex[c];
256 normalize_5(res->cosmag[1]);
257 res->w[1] = -1.0;
258 }
259 return res;
260
261bad : {
262 return NULL;
263 }
264}
265
266//=============================================================================================================
267
269{
270 return (this->coil_class == FWD_COILC_MAG ||
271 this->coil_class == FWD_COILC_AXIAL_GRAD ||
272 this->coil_class == FWD_COILC_AXIAL_GRAD2);
273}
274
275//=============================================================================================================
276
278{
279 return this->coil_class == FWD_COILC_MAG;
280}
281
282//=============================================================================================================
283
285{
286 return this->coil_class == FWD_COILC_PLANAR_GRAD;
287}
288
289//=============================================================================================================
290
292{
293 return this->coil_class == FWD_COILC_EEG;
294}
FiffChInfo class declaration.
int k
Definition fiff_tag.cpp:324
FwdCoil class declaration.
Coordinate transformation descriptor.
Channel info descriptor.
Eigen::Vector3f r0
fiff_int_t coil_type
Eigen::Vector3f ex
FwdCoil description.
Definition fwd_coil.h:89
float ** rmag
Definition fwd_coil.h:180
QString chname
Definition fwd_coil.h:167
FwdCoil(int p_np)
Definition fwd_coil.cpp:140
bool is_eeg_electrode() const
Definition fwd_coil.cpp:291
bool is_planar_coil() const
Definition fwd_coil.cpp:284
bool is_axial_coil() const
Definition fwd_coil.cpp:268
float ez[3]
Definition fwd_coil.h:178
float ey[3]
Definition fwd_coil.h:177
float ** cosmag
Definition fwd_coil.h:181
bool is_magnetometer_coil() const
Definition fwd_coil.cpp:277
float r0[3]
Definition fwd_coil.h:175
static FwdCoil * create_eeg_el(const FIFFLIB::FiffChInfo &ch, const FIFFLIB::FiffCoordTransOld *t)
Definition fwd_coil.cpp:207
float ex[3]
Definition fwd_coil.h:176