v2.0.0
Loading...
Searching...
No Matches
fwd_comp_data.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "fwd_comp_data.h"
42
44#include <fiff/fiff_types.h>
45
46namespace {
47constexpr int FAIL = -1;
48constexpr int OK = 0;
49}
50
51//=============================================================================================================
52// USED NAMESPACES
53//=============================================================================================================
54
55using namespace Eigen;
56using namespace FIFFLIB;
57using namespace MNELIB;
58using namespace FWDLIB;
59
60//=============================================================================================================
61// DEFINE MEMBER METHODS
62//=============================================================================================================
63
65:comp_coils (nullptr)
66,field (nullptr)
67,vec_field (nullptr)
68,field_grad (nullptr)
69,client (nullptr)
70,set (nullptr)
71{
72}
73
74//=============================================================================================================
75
77{
78 if(this->comp_coils)
79 delete this->comp_coils;
80 if(this->set)
81 delete this->set;
82}
83
84//=============================================================================================================
85
86int FwdCompData::fwd_comp_field(const Eigen::Vector3f& rd, const Eigen::Vector3f& Q, FwdCoilSet &coils, Eigen::Ref<Eigen::VectorXf> res, void *client)
87{
88 FwdCompData* comp = static_cast<FwdCompData*>(client);
89
90 if (!comp->field) {
91 qWarning("Field computation function is missing in fwd_comp_field");
92 return FAIL;
93 }
94 /*
95 * First compute the field in the primary set of coils
96 */
97 if (comp->field(rd,Q,coils,res,comp->client) == FAIL)
98 return FAIL;
99 /*
100 * Compensation needed?
101 */
102 if (!comp->comp_coils || comp->comp_coils->ncoil() <= 0 || !comp->set || !comp->set->current)
103 return OK;
104 /*
105 * Workspace needed?
106 */
107 if (comp->work.size() == 0)
108 comp->work.resize(comp->comp_coils->ncoil());
109 /*
110 * Compute the field in the compensation coils
111 */
112 if (comp->field(rd,Q,*comp->comp_coils,comp->work,comp->client) == FAIL)
113 return FAIL;
114 /*
115 * Compute the compensated field
116 */
117 return comp->set->apply(true, res, comp->work);
118}
119
120//=============================================================================================================
121
123 FwdCoilSet *coils,
125{
126 QList<FiffChInfo> chs;
127 QList<FiffChInfo> compchs;
128 int nchan = 0;
129 int ncomp = 0;
130 int k,res;
131
132 if (!set)
133 return OK;
134 if (!coils || coils->ncoil() <= 0) {
135 qWarning("Coil data missing in fwd_make_ctf_comp_coils");
136 return FAIL;
137 }
138
139 for (k = 0; k < coils->ncoil(); k++) {
140 chs.append(FiffChInfo());
141 FwdCoil* coil = coils->coils[k].get();
142 chs[k].ch_name = coil->chname;
143 chs[k].chpos.coil_type = coil->type;
144 chs[k].kind = (coil->coil_class == FWD_COILC_EEG) ? FIFFV_EEG_CH : FIFFV_MEG_CH;
145 }
146 nchan = coils->ncoil();
147 if (comp_coils && comp_coils->ncoil() > 0) {
148 for (k = 0; k < comp_coils->ncoil(); k++) {
149 compchs.append(FiffChInfo());
150 FwdCoil* coil = comp_coils->coils[k].get();
151 compchs[k].ch_name = coil->chname;
152 compchs[k].chpos.coil_type = coil->type;
153 compchs[k].kind = (coil->coil_class == FWD_COILC_EEG) ? FIFFV_EEG_CH : FIFFV_MEG_CH;
154 }
155 ncomp = comp_coils->ncoil();
156 }
157 res = set->make_comp(chs,nchan,compchs,ncomp);
158
159 return res;
160}
161
162//=============================================================================================================
163
165 FwdCoilSet *coils,
170 void *client)
171{
172 FwdCompData* comp = new FwdCompData();
173
174 if(set)
175 comp->set = new MNECTFCompDataSet(*set);
176 else
177 comp->set = nullptr;
178
179 if (comp_coils) {
180 comp->comp_coils = comp_coils->dup_coil_set().release();
181 }
182 else {
183 qWarning("No coils to duplicate");
184 comp->comp_coils = nullptr;
185 }
186 comp->field = field;
187 comp->vec_field = vec_field;
188 comp->field_grad = field_grad;
189 comp->client = client;
190
192 coils,
193 comp->comp_coils) != OK) {
194 delete comp;
195 return nullptr;
196 }
197 else {
198 return comp;
199 }
200}
201
202//=============================================================================================================
203
204int FwdCompData::fwd_comp_field_vec(const Eigen::Vector3f& rd, FwdCoilSet &coils, Eigen::Ref<Eigen::MatrixXf> res, void *client)
205{
206 FwdCompData* comp = static_cast<FwdCompData*>(client);
207
208 if (!comp->vec_field) {
209 qWarning("Field computation function is missing in fwd_comp_field_vec");
210 return FAIL;
211 }
212 /*
213 * First compute the field in the primary set of coils
214 */
215 if (comp->vec_field(rd,coils,res,comp->client) == FAIL)
216 return FAIL;
217 /*
218 * Compensation needed?
219 */
220 if (!comp->comp_coils || comp->comp_coils->ncoil() <= 0 || !comp->set || !comp->set->current)
221 return OK;
222 /*
223 * Need workspace?
224 */
225 if (comp->vec_work.size() == 0)
226 comp->vec_work.resize(3, comp->comp_coils->ncoil());
227 /*
228 * Compute the field at the compensation sensors
229 */
230 if (comp->vec_field(rd,*comp->comp_coils,comp->vec_work,comp->client) == FAIL)
231 return FAIL;
232 /*
233 * Compute the compensated field of three orthogonal dipoles
234 */
235 for (int k = 0; k < 3; k++) {
236 Eigen::VectorXf resRow = res.row(k).transpose();
237 Eigen::VectorXf workRow = comp->vec_work.row(k).transpose();
238 if (comp->set->apply(true, resRow, workRow) == FAIL)
239 return FAIL;
240 res.row(k) = resRow.transpose();
241 }
242 return OK;
243}
244
245//=============================================================================================================
246
247int FwdCompData::fwd_comp_field_grad(const Eigen::Vector3f& rd, const Eigen::Vector3f& Q, FwdCoilSet& coils, Eigen::Ref<Eigen::VectorXf> res, Eigen::Ref<Eigen::VectorXf> xgrad, Eigen::Ref<Eigen::VectorXf> ygrad, Eigen::Ref<Eigen::VectorXf> zgrad, void *client)
248{
249 FwdCompData* comp = static_cast<FwdCompData*>(client);
250
251 if (!comp->field_grad) {
252 qCritical("Field and gradient computation function is missing in fwd_comp_field_grad");
253 return FAIL;
254 }
255 /*
256 * First compute the field in the primary set of coils
257 */
258 if (comp->field_grad(rd,Q,coils,res,xgrad,ygrad,zgrad,comp->client) == FAIL)
259 return FAIL;
260 /*
261 * Compensation needed?
262 */
263 if (!comp->comp_coils || comp->comp_coils->ncoil() <= 0 || !comp->set || !comp->set->current)
264 return OK;
265 /*
266 * Workspace needed?
267 */
268 if (comp->work.size() == 0)
269 comp->work.resize(comp->comp_coils->ncoil());
270 if (comp->vec_work.size() == 0)
271 comp->vec_work.resize(3, comp->comp_coils->ncoil());
272 /*
273 * Compute the field in the compensation coils
274 */
275 Eigen::VectorXf vw0 = comp->vec_work.row(0).transpose();
276 Eigen::VectorXf vw1 = comp->vec_work.row(1).transpose();
277 Eigen::VectorXf vw2 = comp->vec_work.row(2).transpose();
278 if (comp->field_grad(rd,Q,*comp->comp_coils,comp->work,vw0,vw1,vw2,comp->client) == FAIL)
279 return FAIL;
280 comp->vec_work.row(0) = vw0.transpose();
281 comp->vec_work.row(1) = vw1.transpose();
282 comp->vec_work.row(2) = vw2.transpose();
283 /*
284 * Compute the compensated field
285 */
286 if (comp->set->apply(true, res, comp->work) != OK)
287 return FAIL;
288
289 vw0 = comp->vec_work.row(0).transpose();
290 if (comp->set->apply(true, xgrad, vw0) != OK)
291 return FAIL;
292
293 vw1 = comp->vec_work.row(1).transpose();
294 if (comp->set->apply(true, ygrad, vw1) != OK)
295 return FAIL;
296
297 vw2 = comp->vec_work.row(2).transpose();
298 if (comp->set->apply(true, zgrad, vw2) != OK)
299 return FAIL;
300
301 return OK;
302}
#define OK
#define FAIL
#define FIFFV_EEG_CH
#define FIFFV_MEG_CH
Old fiff_type declarations - replace them.
MNECTFCompDataSet class declaration.
std::function< int(const Eigen::Vector3f &rd, FWDLIB::FwdCoilSet &coils, Eigen::Ref< Eigen::MatrixXf > res, void *client)> fwdVecFieldFunc
Definition fwd_types.h:55
std::function< int(const Eigen::Vector3f &rd, const Eigen::Vector3f &Q, FWDLIB::FwdCoilSet &coils, Eigen::Ref< Eigen::VectorXf > res, Eigen::Ref< Eigen::VectorXf > xgrad, Eigen::Ref< Eigen::VectorXf > ygrad, Eigen::Ref< Eigen::VectorXf > zgrad, void *client)> fwdFieldGradFunc
Definition fwd_types.h:57
std::function< int(const Eigen::Vector3f &rd, const Eigen::Vector3f &Q, FWDLIB::FwdCoilSet &coils, Eigen::Ref< Eigen::VectorXf > res, void *client)> fwdFieldFunc
Definition fwd_types.h:53
FwdCompData 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:91
constexpr int FWD_COILC_EEG
Definition fwd_coil.h:74
Channel info descriptor.
Single MEG or EEG sensor coil with integration points, weights, and coordinate frame.
Definition fwd_coil.h:93
QString chname
Definition fwd_coil.h:162
Collection of FwdCoil objects representing a full MEG or EEG sensor array.
std::vector< FwdCoil::UPtr > coils
static int fwd_comp_field_grad(const Eigen::Vector3f &rd, const Eigen::Vector3f &Q, FwdCoilSet &coils, Eigen::Ref< Eigen::VectorXf > res, Eigen::Ref< Eigen::VectorXf > xgrad, Eigen::Ref< Eigen::VectorXf > ygrad, Eigen::Ref< Eigen::VectorXf > zgrad, void *client)
MNELIB::MNECTFCompDataSet * set
static int fwd_comp_field_vec(const Eigen::Vector3f &rd, FwdCoilSet &coils, Eigen::Ref< Eigen::MatrixXf > res, void *client)
fwdVecFieldFunc vec_field
FwdCoilSet * comp_coils
Eigen::MatrixXf vec_work
static int fwd_comp_field(const Eigen::Vector3f &rd, const Eigen::Vector3f &Q, FwdCoilSet &coils, Eigen::Ref< Eigen::VectorXf > res, void *client)
fwdFieldGradFunc field_grad
static int fwd_make_ctf_comp_coils(MNELIB::MNECTFCompDataSet *set, FwdCoilSet *coils, FwdCoilSet *comp_coils)
static FwdCompData * fwd_make_comp_data(MNELIB::MNECTFCompDataSet *set, FwdCoilSet *coils, FwdCoilSet *comp_coils, fwdFieldFunc field, fwdVecFieldFunc vec_field, fwdFieldGradFunc field_grad, void *client)
Eigen::VectorXf work
Collection of CTF third-order gradient compensation operators.
std::unique_ptr< MNECTFCompData > current
int apply(int do_it, Eigen::Ref< Eigen::VectorXf > data, Eigen::Ref< const Eigen::VectorXf > compdata)