v2.0.0
Loading...
Searching...
No Matches
guess_data.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "guess_data.h"
42#include "dipole_fit_data.h"
43#include "dipole_forward.h"
44#include <mne/mne_surface.h>
46
47#include <fiff/fiff_stream.h>
48#include <fiff/fiff_tag.h>
49
50#include <memory>
51#include <QFile>
52
53//=============================================================================================================
54// USED NAMESPACES
55//=============================================================================================================
56
57using namespace Eigen;
58using namespace FIFFLIB;
59using namespace MNELIB;
60using namespace FWDLIB;
61using namespace INVERSELIB;
62
63//ToDo remove later on
64#ifndef TRUE
65#define TRUE 1
66#endif
67
68#ifndef FALSE
69#define FALSE 0
70#endif
71
72#ifndef FAIL
73#define FAIL -1
74#endif
75
76#ifndef OK
77#define OK 0
78#endif
79
80#define X_16 0
81#define Y_16 1
82#define Z_16 2
83
84#define VEC_COPY_16(to,from) {\
85 (to)[X_16] = (from)[X_16];\
86 (to)[Y_16] = (from)[Y_16];\
87 (to)[Z_16] = (from)[Z_16];\
88 }
89
90#define MALLOC_16(x,t) (t *)malloc((x)*sizeof(t))
91
92#define REALLOC_16(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
93
94#define ALLOC_CMATRIX_16(x,y) mne_cmatrix_16((x),(y))
95
96static void matrix_error_16(int kind, int nr, int nc)
97
98{
99 if (kind == 1)
100 printf("Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
101 else if (kind == 2)
102 printf("Failed to allocate memory for a %d x %d matrix\n",nr,nc);
103 else
104 printf("Allocation error for a %d x %d matrix\n",nr,nc);
105 if (sizeof(void *) == 4) {
106 printf("This is probably because you seem to be using a computer with 32-bit architecture.\n");
107 printf("Please consider moving to a 64-bit platform.");
108 }
109 printf("Cannot continue. Sorry.\n");
110 exit(1);
111}
112
113float **mne_cmatrix_16(int nr,int nc)
114
115{
116 int i;
117 float **m;
118 float *whole;
119
120 m = MALLOC_16(nr,float *);
121 if (!m) matrix_error_16(1,nr,nc);
122 whole = MALLOC_16(nr*nc,float);
123 if (!whole) matrix_error_16(2,nr,nc);
124
125 for(i=0;i<nr;i++)
126 m[i] = whole + i*nc;
127 return m;
128}
129
130#define FREE_16(x) if ((char *)(x) != NULL) free((char *)(x))
131#define FREE_CMATRIX_16(m) mne_free_cmatrix_16((m))
132
133void mne_free_cmatrix_16 (float **m)
134{
135 if (m) {
136 FREE_16(*m);
137 FREE_16(m);
138 }
139}
140
141void fromFloatEigenMatrix_16(const Eigen::MatrixXf& from_mat, float **& to_mat, const int m, const int n)
142{
143 for ( int i = 0; i < m; ++i)
144 for ( int j = 0; j < n; ++j)
145 to_mat[i][j] = from_mat(i,j);
146}
147
148void fromFloatEigenMatrix_16(const Eigen::MatrixXf& from_mat, float **& to_mat)
149{
150 fromFloatEigenMatrix_16(from_mat, to_mat, from_mat.rows(), from_mat.cols());
151}
152
153//int
154void fromIntEigenMatrix_16(const Eigen::MatrixXi& from_mat, int **&to_mat, const int m, const int n)
155{
156 for ( int i = 0; i < m; ++i)
157 for ( int j = 0; j < n; ++j)
158 to_mat[i][j] = from_mat(i,j);
159}
160
161void fromIntEigenMatrix_16(const Eigen::MatrixXi& from_mat, int **&to_mat)
162{
163 fromIntEigenMatrix_16(from_mat, to_mat, from_mat.rows(), from_mat.cols());
164}
165
166//=============================================================================================================
167// DEFINE MEMBER METHODS
168//=============================================================================================================
169
171: rr(NULL)
172, guess_fwd(NULL)
173, nguess(0)
174{
175}
176
177//=============================================================================================================
178
179//GuessData::GuessData(const GuessData& p_GuessData)
180//{
181//}
182
183//=============================================================================================================
184
185GuessData::GuessData(const QString &guessname, const QString &guess_surfname, float mindist, float exclude, float grid, DipoleFitData *f)
186{
187// GuessData* res = new GuessData();
188 int k,p;
189 float guessrad = 0.080;
190 std::unique_ptr<MNESourceSpace> guesses;
191 dipoleFitFuncs orig;
192
193 if (!guessname.isEmpty()) {
194 /*
195 * Read the guesses and transform to the appropriate coordinate frame
196 */
197 std::vector<std::unique_ptr<MNESourceSpace>> sp;
198 if (MNESourceSpace::read_source_spaces(guessname,sp) == FAIL)
199 goto bad;
200 if (static_cast<int>(sp.size()) != 1) {
201 printf("Incorrect number of source spaces in guess file");
202 goto bad;
203 }
204 printf("Read guesses from %s\n",guessname.toUtf8().constData());
205 guesses = std::move(sp[0]);
206 }
207 else {
208 MNESurface* inner_skull = NULL;
209 int free_inner_skull = FALSE;
210 float r0[3];
211
212 VEC_COPY_16(r0,f->r0);
213 Q_ASSERT(f->mri_head_t);
215 if (f->bem_model) {
216 printf("Using inner skull surface from the BEM (%s)...\n",f->bemname.toUtf8().constData());
217 if ((inner_skull = f->bem_model->fwd_bem_find_surface(FIFFV_BEM_SURF_ID_BRAIN)) == NULL)
218 goto bad;
219 }
220 else if (!guess_surfname.isEmpty()) {
221 printf("Reading inner skull surface from %s...\n",guess_surfname.toUtf8().data());
222 if ((inner_skull = MNESurface::read_bem_surface(guess_surfname,FIFFV_BEM_SURF_ID_BRAIN,TRUE,NULL)) == NULL)
223 goto bad;
224 free_inner_skull = TRUE;
225 }
226 guesses.reset((MNESourceSpace*)FwdBemModel::make_guesses(inner_skull,guessrad,r0,grid,exclude,mindist));
227 if (!guesses)
228 goto bad;
229 if (free_inner_skull)
230 delete inner_skull;
231 }
232 {
233 std::vector<std::unique_ptr<MNESourceSpace>> guesses_vec;
234 guesses_vec.push_back(std::move(guesses));
236 goto bad;
237 guesses = std::move(guesses_vec[0]);
238 }
239 printf("Guess locations are now in %s coordinates.\n",FiffCoordTrans::frame_name(f->coord_frame).toUtf8().constData());
240
241 this->nguess = guesses->nuse;
242 this->rr = ALLOC_CMATRIX_16(guesses->nuse,3);
243 for (k = 0, p = 0; k < guesses->np; k++)
244 if (guesses->inuse[k]) {
245 VEC_COPY_16(this->rr[p],&guesses->rr(k,0));
246 p++;
247 }
248 guesses.reset();
249
250 printf("Go through all guess source locations...");
251 this->guess_fwd = MALLOC_16(this->nguess,DipoleForward*);
252 for (k = 0; k < this->nguess; k++)
253 this->guess_fwd[k] = NULL;
254 /*
255 * Compute the guesses using the sphere model for speed
256 */
257 orig = f->funcs;
258 if (f->fit_mag_dipoles)
259 f->funcs = f->mag_dipole_funcs;
260 else
261 f->funcs = f->sphere_funcs;
262
263 for (k = 0; k < this->nguess; k++) {
264 if ((this->guess_fwd[k] = DipoleFitData::dipole_forward_one(f,this->rr[k],NULL)) == NULL)
265 goto bad;
266#ifdef DEBUG
267 sing = this->guess_fwd[k]->sing;
268 printf("%f %f %f\n",sing[0],sing[1],sing[2]);
269#endif
270 }
271 f->funcs = orig;
272
273 printf("[done %d sources]\n",p);
274
275 return;
276// return res;
277
278bad : {
279 return;
280// return NULL;
281 }
282}
283
284//=============================================================================================================
285
286GuessData::GuessData(const QString &guessname, const QString &guess_surfname, float mindist, float exclude, float grid, DipoleFitData *f, char *guess_save_name)
287{
288 int k,p;
289 float guessrad = 0.080f;
290 std::unique_ptr<MNESourceSpace> guesses;
291
292 if (!guessname.isEmpty()) {
293 /*
294 * Read the guesses and transform to the appropriate coordinate frame
295 */
296 std::vector<std::unique_ptr<MNESourceSpace>> sp;
298 goto bad;
299 if (static_cast<int>(sp.size()) != 1) {
300 qCritical("Incorrect number of source spaces in guess file");
301 goto bad;
302 }
303 printf("Read guesses from %s\n",guessname.toUtf8().constData());
304 guesses = std::move(sp[0]);
305 }
306 else {
307 MNESurface* inner_skull = NULL;
308 int free_inner_skull = FALSE;
309 float r0[3];
310
311 VEC_COPY_16(r0,f->r0);
312 Q_ASSERT(f->mri_head_t);
314 if (f->bem_model) {
315 printf("Using inner skull surface from the BEM (%s)...\n",f->bemname.toUtf8().constData());
316 if ((inner_skull = f->bem_model->fwd_bem_find_surface(FIFFV_BEM_SURF_ID_BRAIN)) == NULL)
317 goto bad;
318 }
319 else if (!guess_surfname.isEmpty()) {
320 printf("Reading inner skull surface from %s...\n",guess_surfname.toUtf8().data());
321 if ((inner_skull = MNESurface::read_bem_surface(guess_surfname,FIFFV_BEM_SURF_ID_BRAIN,TRUE,NULL)) == NULL)
322 goto bad;
323 free_inner_skull = TRUE;
324 }
325 guesses.reset((MNESourceSpace*)FwdBemModel::make_guesses(inner_skull,guessrad,r0,grid,exclude,mindist));
326 if (!guesses)
327 goto bad;
328 if (free_inner_skull)
329 delete inner_skull;
330 }
331 /*
332 * Save the guesses for future use
333 */
334 if (guesses->nuse == 0) {
335 qCritical("No active guess locations remaining.");
336 goto bad;
337 }
338 if (guess_save_name) {
339 printf("###################DEBUG writing source spaces not yet implemented.");
340 // if (mne_write_source_spaces(guess_save_name,&guesses,1,FALSE) != OK)
341 // goto bad;
342 // printf("Wrote guess locations to %s\n",guess_save_name);
343 }
344 /*
345 * Transform the guess locations to the appropriate coordinate frame
346 */
347 {
348 std::vector<std::unique_ptr<MNESourceSpace>> guesses_vec;
349 guesses_vec.push_back(std::move(guesses));
351 goto bad;
352 guesses = std::move(guesses_vec[0]);
353 }
354 printf("Guess locations are now in %s coordinates.\n",FiffCoordTrans::frame_name(f->coord_frame).toUtf8().constData());
355
356 this->nguess = guesses->nuse;
357 this->rr = ALLOC_CMATRIX_16(guesses->nuse,3);
358 for (k = 0, p = 0; k < guesses->np; k++)
359 if (guesses->inuse[k]) {
360 VEC_COPY_16(this->rr[p],&guesses->rr(k,0));
361 p++;
362 }
363 guesses.reset();
364
365 this->guess_fwd = MALLOC_16(this->nguess,DipoleForward*);
366 for (k = 0; k < this->nguess; k++)
367 this->guess_fwd[k] = NULL;
368 /*
369 * Compute the guesses using the sphere model for speed
370 */
371 if (!this->compute_guess_fields(f))
372 goto bad;
373
374 return;
375
376bad : {
377 return;
378 }
379}
380
381//=============================================================================================================
382
384{
386 if (guess_fwd) {
387 for (int k = 0; k < nguess; k++)
388 delete guess_fwd[k];
390 }
391 return;
392}
393
394//=============================================================================================================
395
397{
398 dipoleFitFuncs orig = NULL;
399
400 if (!f) {
401 qCritical("Data missing in compute_guess_fields");
402 return false;
403 }
404 if (!f->noise) {
405 qCritical("Noise covariance missing in compute_guess_fields");
406 return false;
407 }
408 printf("Go through all guess source locations...");
409 orig = f->funcs;
410 if (f->fit_mag_dipoles)
411 f->funcs = f->mag_dipole_funcs;
412 else
413 f->funcs = f->sphere_funcs;
414 for (int k = 0; k < this->nguess; k++) {
415 if ((this->guess_fwd[k] = DipoleFitData::dipole_forward_one(f,this->rr[k],this->guess_fwd[k])) == NULL){
416 if (orig)
417 f->funcs = orig;
418 return false;
419 }
420#ifdef DEBUG
421 sing = this->guess_fwd[k]->sing;
422 printf("%f %f %f\n",sing[0],sing[1],sing[2]);
423#endif
424 }
425 f->funcs = orig;
426 printf("[done %d sources]\n",this->nguess);
427
428 return true;
429}
FiffTag class declaration, which provides fiff tag I/O and processing methods.
#define FIFF_FAIL
FiffStream class declaration.
#define FIFFV_BEM_SURF_ID_BRAIN
Definition fiff_file.h:749
MNESurface class declaration.
MNESourceSpace class declaration.
#define TRUE
#define FALSE
#define OK
#define FAIL
GuessData class declaration.
DipoleForward class declaration.
Dipole Fit Data class declaration.
#define VEC_COPY_16(to, from)
#define ALLOC_CMATRIX_16(x, y)
void fromFloatEigenMatrix_16(const Eigen::MatrixXf &from_mat, float **&to_mat, const int m, const int n)
void fromIntEigenMatrix_16(const Eigen::MatrixXi &from_mat, int **&to_mat, const int m, const int n)
#define FREE_16(x)
float ** mne_cmatrix_16(int nr, int nc)
#define MALLOC_16(x, t)
#define FREE_CMATRIX_16(m)
void mne_free_cmatrix_16(float **m)
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
Forward modelling (BEM, MEG/EEG lead fields).
Definition compute_fwd.h:95
static MNELIB::MNESurface * make_guesses(MNELIB::MNESurface *guess_surf, float guessrad, float *guess_r0, float grid, float exclude, float mindist)
Forward field computation function pointers and client data for MEG and EEG dipole fitting.
Dipole Fit Data implementation.
std::unique_ptr< FWDLIB::FwdBemModel > bem_model
std::unique_ptr< MNELIB::MNECovMatrix > noise
std::unique_ptr< FIFFLIB::FiffCoordTrans > mri_head_t
static DipoleForward * dipole_forward_one(DipoleFitData *d, float *rd, DipoleForward *old)
Stores forward field matrices and source space data for magnetic dipole fitting.
bool compute_guess_fields(DipoleFitData *f)
DipoleForward ** guess_fwd
Definition guess_data.h:139
This defines a source space.
static int read_source_spaces(const QString &name, std::vector< std::unique_ptr< MNESourceSpace > > &spaces)
static int transform_source_spaces_to(int coord_frame, const FIFFLIB::FiffCoordTrans &t, std::vector< std::unique_ptr< MNESourceSpace > > &spaces)
This defines a surface.
Definition mne_surface.h:79
static MNESurface * read_bem_surface(const QString &name, int which, int add_geometry, float *sigmap)
Eigen::MatrixX3f apply_inverse_trans(const Eigen::MatrixX3f &rr, bool do_move=true) const
static QString frame_name(int frame)