v2.0.0
Loading...
Searching...
No Matches
fwd_bem_model.h
Go to the documentation of this file.
1//=============================================================================================================
36
37#ifndef FWDBEMMODEL_H
38#define FWDBEMMODEL_H
39
40//=============================================================================================================
41// INCLUDES
42//=============================================================================================================
43
44#include "fwd_global.h"
45#include "fwd_coil_set.h"
46
48#include <fiff/fiff_dir_node.h>
49#include <fiff/fiff_tag.h>
51
52#include <memory>
53#include <vector>
54
55//=============================================================================================================
56// EIGEN INCLUDES
57//=============================================================================================================
58
59#include <Eigen/Core>
60
61//=============================================================================================================
62// QT INCLUDES
63//=============================================================================================================
64
65#include <QSharedPointer>
66#include <QString>
67
68#define FWD_BEM_UNKNOWN -1
69#define FWD_BEM_CONSTANT_COLL 1
70#define FWD_BEM_LINEAR_COLL 2
71
72#define FWD_BEM_IP_APPROACH_LIMIT 0.1
73
74#define FWD_BEM_LIN_FIELD_SIMPLE 1
75#define FWD_BEM_LIN_FIELD_FERGUSON 2
76#define FWD_BEM_LIN_FIELD_URANKAR 3
77
78//=============================================================================================================
79// FORWARD DECLARATIONS
80//=============================================================================================================
81
82namespace MNELIB
83{
84 class MNETriangle;
85 class MNESurface;
86 class MNESourceSpace;
87 class MNECTFCompDataSet;
88 class MNENamedMatrix;
89}
90
91namespace FIFFLIB {
92 class FiffNamedMatrix;
93}
94//=============================================================================================================
95// DEFINE NAMESPACE FWDLIB
96//=============================================================================================================
97
98namespace FWDLIB
99{
100
101//=============================================================================================================
102// FWDLIB FORWARD DECLARATIONS
103//=============================================================================================================
104
106
107//=============================================================================================================
114{
115public:
116 typedef QSharedPointer<FwdBemModel> SPtr;
117 typedef QSharedPointer<const FwdBemModel> ConstSPtr;
118
119 //=========================================================================================================
125 explicit FwdBemModel();
126
127 //=========================================================================================================
132 virtual ~FwdBemModel();
133
134 //=========================================================================================================
139
140//char *fwd_bem_make_bem_name(char *name)
142// * Make a standard BEM file name
143// */
144//{
145// char *s1,*s2;
146
147// s1 = strip_from(name,(char*)(".fif"));
148// s2 = strip_from(s1,(char*)("-sol"));
149// FREE_3(s1);
150// s1 = strip_from(s2,(char*)("-bem"));
151// FREE_3(s2);
152// s2 = MALLOC_3(strlen(s1)+strlen(BEM_SUFFIX)+1,char);
153// sprintf(s2,"%s%s",s1,BEM_SUFFIX);
154// FREE_3(s1);
155// return s2;
156//}
157
158 static QString fwd_bem_make_bem_sol_name(const QString& name);
159
160 //============================= fwd_bem_model.c =============================
161
162 static const QString& fwd_bem_explain_surface(int kind);
163
164 static const QString& fwd_bem_explain_method(int method);
165
166 static int get_int( FIFFLIB::FiffStream::SPtr& stream, const FIFFLIB::FiffDirNode::SPtr& node,int what,int *res);
167
168 /*
169 * Return a pointer to a specific surface in a BEM
170 */
171 // Refactored: fwd_bem_find_surface (fwd_bem_model.c)
173
174 static FwdBemModel* fwd_bem_load_surfaces(const QString& name,
175 int *kinds,
176 int nkind);
177
178 static FwdBemModel* fwd_bem_load_homog_surface(const QString& name);
179
180 static FwdBemModel* fwd_bem_load_three_layer_surfaces(const QString& name);
181
182 static int fwd_bem_load_solution(const QString& name, int bem_method, FwdBemModel* m);
183
185
186 //============================= dipole_fit_guesses.c =============================
187
188 static MNELIB::MNESurface* make_guesses(MNELIB::MNESurface* guess_surf, /* Predefined boundary for the guesses */
189 float guessrad, /* Radius for the spherical boundary if the above is missing */
190 float *guess_r0, /* Origin for the spherical boundary */
191 float grid, /* Spacing between guess points */
192 float exclude, /* Exclude points closer than this to the CM of the guess boundary surface */
193 float mindist);
194
195 //============================= fwd_bem_linear_collocation.c =============================
196
197 /*
198 * The following approach is based on:
199 *
200 * de Munck JC: "A linear discretization of the volume conductor boundary integral equation using analytically integrated elements",
201 * IEEE Trans Biomed Eng. 1992 39(9) : 986 - 990
202 *
203 */
204
205 static double calc_beta (double *rk,double *rk1);
206
207 static void lin_pot_coeff (float *from, /* Origin */
208 MNELIB::MNETriangle* to, /* The destination triangle */
209 double omega[3]);
210
211 static void correct_auto_elements (MNELIB::MNESurface* surf,
212 float **mat);
213
214 static float **fwd_bem_lin_pot_coeff (const QList<MNELIB::MNESurface*>& surfs);
215
217
218 //============================= fwd_bem_solution.c =============================
219
220 static float **fwd_bem_multi_solution (float **solids, /* The solid-angle matrix */
221 float **gamma, /* The conductivity multipliers */
222 int nsurf, /* Number of surfaces */
223 int *ntri);
224
225 static float **fwd_bem_homog_solution (float **solids,int ntri);
226
227 static void fwd_bem_ip_modify_solution(float **solution, /* The original solution */
228 float **ip_solution, /* The isolated problem solution */
229 float ip_mult, /* Conductivity ratio */
230 int nsurf, /* Number of surfaces */
231 int *ntri);
232
233 //============================= fwd_bem_constant_collocation.c =============================
234
235 static int fwd_bem_check_solids (float **angles,int ntri1,int ntri2, float desired);
236
237 static float **fwd_bem_solid_angles (const QList<MNELIB::MNESurface*>& surfs);
238
240
241 //============================= fwd_bem_model.c =============================
242
244 int bem_method);
245
246 static int fwd_bem_load_recompute_solution(const QString& name,
247 int bem_method,
248 int force_recompute,
249 FwdBemModel* m);
250
251 //============================= fwd_bem_pot.c =============================
252
253 static float fwd_bem_inf_field(float *rd, /* Dipole position */
254 float *Q, /* Dipole moment */
255 float *rp, /* Field point */
256 float *dir);
257
258 static float fwd_bem_inf_pot (float *rd, /* Dipole position */
259 float *Q, /* Dipole moment */
260 float *rp);
261
262 static int fwd_bem_specify_els(FwdBemModel* m,
263 FwdCoilSet* els);
264
265 static void fwd_bem_pot_grad_calc (float *rd, /* Dipole position */
266 float *Q, /* Dipole orientation */
267 FwdBemModel* m, /* The model */
268 FwdCoilSet* els, /* Use this electrode set if available */
269 int all_surfs, /* Compute solution on all surfaces? */
270 float *xgrad,
271 float *ygrad,
272 float *zgrad);
273
274 static void fwd_bem_lin_pot_calc (float *rd, /* Dipole position */
275 float *Q, /* Dipole orientation */
276 FwdBemModel* m, /* The model */
277 FwdCoilSet* els, /* Use this electrode set if available */
278 int all_surfs, /* Compute on all surfaces? */
279 float *pot);
280
281 static void fwd_bem_lin_pot_grad_calc (float *rd, /* Dipole position */
282 float *Q, /* Dipole orientation */
283 FwdBemModel* m, /* The model */
284 FwdCoilSet* els, /* Use this electrode set if available */
285 int all_surfs, /* Compute on all surfaces? */
286 float *xgrad,
287 float *ygrad,
288 float *zgrad);
289
290 static void fwd_bem_pot_calc (float *rd, /* Dipole position */
291 float *Q, /* Dipole orientation */
292 FwdBemModel* m, /* The model */
293 FwdCoilSet* els, /* Use this electrode set if available */
294 int all_surfs, /* Compute solution on all surfaces? */
295 float *pot);
296
297 static int fwd_bem_pot_els (float *rd, /* Dipole position */
298 float *Q, /* Dipole orientation */
299 FwdCoilSet* els, /* Electrode descriptors */
300 float *pot, /* Result */
301 void *client);
302
303 static int fwd_bem_pot_grad_els (float *rd, /* Dipole position */
304 float *Q, /* Dipole orientation */
305 FwdCoilSet* els, /* Electrode descriptors */
306 float *pot, /* Potentials */
307 float *xgrad, /* Derivatives with respect to dipole position */
308 float *ygrad,
309 float *zgrad,
310 void *client);
311
312 //============================= fwd_bem_field.c =============================
313
314 /*
315 * These are some of the integration formulas listed in
316 *
317 * L. Urankar, Common compact analytical formulas for computation of
318 * geometry integrals on a basic Cartesian sub-domain in boundary and
319 * volume integral methods, Engineering Analysis with Boundary Elements,
320 * 7 (3), 1990, 124 - 129.
321 *
322 */
323
324 static void calc_f (double *xx,
325 double *yy, /* Corner coordinates */
326 double *f0,
327 double *fx,
328 double *fy);
329
330 static void calc_magic (double u,double z,
331 double A,
332 double B,
333 double *beta,
334 double *D);
335
336 static void field_integrals (float *from,
338 double *I1p,
339 double *T,double *S1,double *S2,
340 double *f0,double *fx,double *fy);
341
342 static double one_field_coeff (float *dest, /* The destination field point */
343 float *normal, /* The field direction we are interested in */
345
346 static float **fwd_bem_field_coeff(FwdBemModel* m, /* The model */
347 FwdCoilSet* coils);
348
349 /*
350 * These are the formulas from Ferguson et al
351 * A Complete Linear Discretization for Calculating the Magnetic Field
352 * Using the Boundary-Element Method, IEEE Trans. Biomed. Eng., submitted
353 */
354 static double calc_gamma (double *rk,double *rk1);
355
356 static void fwd_bem_one_lin_field_coeff_ferg (float *dest, /* The field point */
357 float *dir, /* The interesting direction */
358 MNELIB::MNETriangle* tri, /* The destination triangle */
359 double *res);
360
361 static void fwd_bem_one_lin_field_coeff_uran(float *dest, /* The field point */
362 float *dir, /* The interesting direction */
363 MNELIB::MNETriangle* tri, /* The destination triangle */
364 double *res);
365
366 static void fwd_bem_one_lin_field_coeff_simple (float *dest, /* The destination field point */
367 float *normal, /* The field direction we are interested in */
368 MNELIB::MNETriangle* source, /* The source triangle */
369 double *res);
370
371 typedef void (* linFieldIntFunc)(float *dest,float *dir,MNELIB::MNETriangle* tri, double *res);
372
373 static float **fwd_bem_lin_field_coeff (FwdBemModel* m, /* The model */
374 FwdCoilSet* coils, /* Coil information */
375 int method);
376
378 FwdCoilSet* coils);
379
380 #define MAG_FACTOR 1e-7 /* \mu_0/4\pi */
381
382 static void fwd_bem_lin_field_calc(float *rd,
383 float *Q,
384 FwdCoilSet* coils,
385 FwdBemModel* m,
386 float *B);
387
388 static void fwd_bem_field_calc(float *rd,
389 float *Q,
390 FwdCoilSet* coils,
391 FwdBemModel* m,
392 float *B);
393
394 static void fwd_bem_field_grad_calc(float *rd,
395 float *Q,
396 FwdCoilSet *coils,
397 FwdBemModel *m,
398 float *xgrad,
399 float *ygrad,
400 float *zgrad);
401
402 static float fwd_bem_inf_field_der(float *rd, /* Dipole position */
403 float *Q, /* Dipole moment */
404 float *rp, /* Field point */
405 float *dir, /* Which field component */
406 float *comp);
407
408 static float fwd_bem_inf_pot_der (float *rd, /* Dipole position */
409 float *Q, /* Dipole moment */
410 float *rp, /* Potential point */
411 float *comp);
412
413 static void fwd_bem_lin_field_grad_calc(float *rd,
414 float *Q,
415 FwdCoilSet *coils,
416 FwdBemModel *m,
417 float *xgrad,
418 float *ygrad,
419 float *zgrad);
420
421 static int fwd_bem_field(float *rd, /* Dipole position */
422 float *Q, /* Dipole orientation */
423 FwdCoilSet* coils, /* Coil descriptors */
424 float *B, /* Result */
425 void *client);
426
427 static int fwd_bem_field_grad(float *rd, /* The dipole location */
428 float Q[], /* The dipole components (xyz) */
429 FwdCoilSet* coils, /* The coil definitions */
430 float Bval[], /* Results */
431 float xgrad[], /* The derivatives with respect to */
432 float ygrad[], /* the dipole position coordinates */
433 float zgrad[],
434 void *client);
435
436 //============================= compute_forward.c =============================
437
438 static void *meg_eeg_fwd_one_source_space(void *arg);
439
440 // TODO check if this is the correct class or move
441 static int compute_forward_meg( std::vector<std::unique_ptr<MNELIB::MNESourceSpace>>& spaces,
442 FwdCoilSet* coils,
443 FwdCoilSet* comp_coils,
444 MNELIB::MNECTFCompDataSet* comp_data,
445 bool fixed_ori,
446 FwdBemModel* bem_model,
447 Eigen::Vector3f* r0,
448 bool use_threads,
450 FIFFLIB::FiffNamedMatrix& resp_grad,
451 bool bDoGRad);
452
453 static int compute_forward_eeg( std::vector<std::unique_ptr<MNELIB::MNESourceSpace>>& spaces,
454 FwdCoilSet* els,
455 bool fixed_ori,
456 FwdBemModel* bem_model,
457 FwdEegSphereModel* m,
458 bool use_threads,
460 FIFFLIB::FiffNamedMatrix& resp_grad,
461 bool bDoGrad);
462
463 //============================= fwd_spherefield.c =============================
464 // TODO location of these functions need to be checked -> evtl moving to more suitable space
465 static int fwd_sphere_field(float *rd, /* The dipole location */
466 float Q[], /* The dipole components (xyz) */
467 FwdCoilSet* coils, /* The coil definitions */
468 float Bval[], /* Results */
469 void *client);
470
471 static int fwd_sphere_field_vec(float *rd, /* The dipole location */
472 FwdCoilSet* coils, /* The coil definitions */
473 float **Bval, /* Results: rows are the fields of the x,y, and z direction dipoles */
474 void *client);
475
476 static int fwd_sphere_field_grad(float *rd, /* The dipole location */
477 float Q[], /* The dipole components (xyz) */
478 FwdCoilSet* coils, /* The coil definitions */
479 float Bval[], /* Results */
480 float xgrad[], /* The derivatives with respect to */
481 float ygrad[], /* the dipole position coordinates */
482 float zgrad[],
483 void *client);
484
485 //============================= fwd_mag_dipole_field.c =============================
486 // TODO location of these functions need to be checked -> evtl moving to mor suitable space
487 /*
488 * Compute the field of a magnetic dipole
489 */
490 static int fwd_mag_dipole_field( float *rm, /* The dipole location in the same coordinate system as the coils */
491 float M[], /* The dipole components (xyz) */
492 FwdCoilSet* coils, /* The coil definitions */
493 float Bval[], /* Results */
494 void *client);
495
496 static int fwd_mag_dipole_field_vec( float *rm, /* The dipole location */
497 FwdCoilSet* coils, /* The coil definitions */
498 float **Bval, /* Results: rows are the fields of the x,y, and z direction dipoles */
499 void *client);
500
501public:
502 QString surf_name; /* Name of the file where surfaces were loaded from */
503 QList<MNELIB::MNESurface*> surfs; /* The interface surfaces from outside towards inside */
504 int *ntri; /* Number of triangles on each surface */
505 int *np; /* Number of vertices on each surface */
506 int nsurf; /* How many */
507 float *sigma; /* The conductivities */
508 float **gamma; /* The gamma factors */
509 float *source_mult; /* These multiply the infinite medium potentials */
510 float *field_mult; /* Multipliers for the magnetic field */
511 int bem_method; /* Which approximation method is used */
512 QString sol_name; /* Name of the file where the solution was loaded from */
513
514 float **solution; /* The potential solution matrix */
515 float *v0; /* Space for the infinite-medium potentials */
516 int nsol; /* Size of the solution matrix */
517
518 FIFFLIB::FiffCoordTrans head_mri_t; /* Coordinate transformation from head to MRI coordinates */
519
520 float ip_approach_limit; /* Controls whether we need to use the isolated problem approach */
521 bool use_ip_approach; /* Do we need it */
522
523// ### OLD STRUCT ###
524//typedef struct {
525// char *surf_name; /* Name of the file where surfaces were loaded from */
526// FWDLIB::MNESurface* *surfs; /* The interface surfaces from outside towards inside */
527// int *ntri; /* Number of triangles on each surface */
528// int *np; /* Number of vertices on each surface */
529// int nsurf; /* How many */
530// float *sigma; /* The conductivities */
531// float **gamma; /* The gamma factors */
532// float *source_mult; /* These multiply the infinite medium potentials */
533// float *field_mult; /* Multipliers for the magnetic field */
534// int bem_method; /* Which approximation method is used */
535// char *sol_name; /* Name of the file where the solution was loaded from */
536
537// float **solution; /* The potential solution matrix */
538// float *v0; /* Space for the infinite-medium potentials */
539// int nsol; /* Size of the solution matrix */
540
541// FWDLIB::FiffCoordTransOld* head_mri_t; /* Coordinate transformation from head to MRI coordinates */
542
543// float ip_approach_limit; /* Controls whether we need to use the isolated problem approach */
544// int use_ip_approach; /* Do we need it */
545//} *FwdBemModel*,FwdBemModel*Rec; /* Holds the BEM model definition */
546};
547
548//=============================================================================================================
549// INLINE DEFINITIONS
550//=============================================================================================================
551} // NAMESPACE FWDLIB
552
553#endif // FWDBEMMODEL_H
FiffTag class declaration, which provides fiff tag I/O and processing methods.
FiffNamedMatrix class declaration.
FiffDirNode class declaration, which provides fiff dir tree processing methods.
FiffCoordTrans class declaration.
forward library export/import macros.
#define FWDSHARED_EXPORT
Definition fwd_global.h:53
FwdCoilSet class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Forward modelling (BEM, MEG/EEG lead fields).
Definition compute_fwd.h:95
const QString name
Coordinate transformation description.
QSharedPointer< FiffDirNode > SPtr
QSharedPointer< FiffStream > SPtr
static float ** fwd_bem_field_coeff(FwdBemModel *m, FwdCoilSet *coils)
static FwdBemModel * fwd_bem_load_homog_surface(const QString &name)
static int get_int(FIFFLIB::FiffStream::SPtr &stream, const FIFFLIB::FiffDirNode::SPtr &node, int what, int *res)
static float ** fwd_bem_multi_solution(float **solids, float **gamma, int nsurf, int *ntri)
static double calc_beta(double *rk, double *rk1)
static void correct_auto_elements(MNELIB::MNESurface *surf, float **mat)
QSharedPointer< const FwdBemModel > ConstSPtr
static int fwd_bem_set_head_mri_t(FwdBemModel *m, const FIFFLIB::FiffCoordTrans &t)
static int fwd_bem_constant_collocation_solution(FwdBemModel *m)
static void fwd_bem_one_lin_field_coeff_uran(float *dest, float *dir, MNELIB::MNETriangle *tri, double *res)
static void fwd_bem_ip_modify_solution(float **solution, float **ip_solution, float ip_mult, int nsurf, int *ntri)
static double one_field_coeff(float *dest, float *normal, MNELIB::MNETriangle *tri)
static int fwd_bem_check_solids(float **angles, int ntri1, int ntri2, float desired)
static int fwd_bem_pot_grad_els(float *rd, float *Q, FwdCoilSet *els, float *pot, float *xgrad, float *ygrad, float *zgrad, void *client)
QSharedPointer< FwdBemModel > SPtr
static float ** fwd_bem_solid_angles(const QList< MNELIB::MNESurface * > &surfs)
static float ** fwd_bem_lin_pot_coeff(const QList< MNELIB::MNESurface * > &surfs)
static FwdBemModel * fwd_bem_load_surfaces(const QString &name, int *kinds, int nkind)
static int fwd_bem_load_solution(const QString &name, int bem_method, FwdBemModel *m)
static void calc_f(double *xx, double *yy, double *f0, double *fx, double *fy)
static QString fwd_bem_make_bem_sol_name(const QString &name)
static int fwd_bem_load_recompute_solution(const QString &name, int bem_method, int force_recompute, FwdBemModel *m)
static float ** fwd_bem_homog_solution(float **solids, int ntri)
static double calc_gamma(double *rk, double *rk1)
static void fwd_bem_pot_grad_calc(float *rd, float *Q, FwdBemModel *m, FwdCoilSet *els, int all_surfs, float *xgrad, float *ygrad, float *zgrad)
MNELIB::MNESurface * fwd_bem_find_surface(int kind)
static void field_integrals(float *from, MNELIB::MNETriangle *to, double *I1p, double *T, double *S1, double *S2, double *f0, double *fx, double *fy)
static float fwd_bem_inf_pot(float *rd, float *Q, float *rp)
static void lin_pot_coeff(float *from, MNELIB::MNETriangle *to, double omega[3])
static const QString & fwd_bem_explain_method(int method)
static float ** fwd_bem_lin_field_coeff(FwdBemModel *m, FwdCoilSet *coils, int method)
static int fwd_bem_linear_collocation_solution(FwdBemModel *m)
static int fwd_bem_specify_coils(FwdBemModel *m, FwdCoilSet *coils)
static const QString & fwd_bem_explain_surface(int kind)
static void fwd_bem_one_lin_field_coeff_simple(float *dest, float *normal, MNELIB::MNETriangle *source, double *res)
static void fwd_bem_pot_calc(float *rd, float *Q, FwdBemModel *m, FwdCoilSet *els, int all_surfs, float *pot)
void(* linFieldIntFunc)(float *dest, float *dir, MNELIB::MNETriangle *tri, double *res)
QList< MNELIB::MNESurface * > surfs
static void fwd_bem_lin_pot_grad_calc(float *rd, float *Q, FwdBemModel *m, FwdCoilSet *els, int all_surfs, float *xgrad, float *ygrad, float *zgrad)
static MNELIB::MNESurface * make_guesses(MNELIB::MNESurface *guess_surf, float guessrad, float *guess_r0, float grid, float exclude, float mindist)
static int fwd_bem_specify_els(FwdBemModel *m, FwdCoilSet *els)
static FwdBemModel * fwd_bem_load_three_layer_surfaces(const QString &name)
static void calc_magic(double u, double z, double A, double B, double *beta, double *D)
static int fwd_bem_pot_els(float *rd, float *Q, FwdCoilSet *els, float *pot, void *client)
static void fwd_bem_lin_pot_calc(float *rd, float *Q, FwdBemModel *m, FwdCoilSet *els, int all_surfs, float *pot)
static int fwd_bem_compute_solution(FwdBemModel *m, int bem_method)
FIFFLIB::FiffCoordTrans head_mri_t
static float fwd_bem_inf_field(float *rd, float *Q, float *rp, float *dir)
static void fwd_bem_one_lin_field_coeff_ferg(float *dest, float *dir, MNELIB::MNETriangle *tri, double *res)
Collection of FwdCoil objects representing a full MEG or EEG sensor array.
Multi-layer spherical head model for EEG forward computation.
Collection of CTF third-order gradient compensation operators.
This defines a surface.
Definition mne_surface.h:79
Per-triangle geometric data for a cortical or BEM surface.