4 #include "../c/mne_meas_data_set.h"
8 #include <QScopedPointer>
10 using namespace INVERSELIB;
11 using namespace MNELIB;
12 using namespace FWDLIB;
14 #if defined(_WIN32) || defined(_WIN64)
15 #define snprintf _snprintf
16 #define vsnprintf _vsnprintf
17 #define strcasecmp _stricmp
18 #define strncasecmp _strnicmp
25 #ifndef PROGRAM_VERSION
26 #define PROGRAM_VERSION "1.00"
49 #define EPS_VALUES 0.05
55 #define MALLOC(x,t) (t *)malloc((x)*sizeof(t))
56 #define REALLOC(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
57 #define FREE(x) if ((char *)(x) != NULL) free((char *)(x))
59 #define ALLOC_CMATRIX(x,y) mne_cmatrix((x),(y))
61 #define FREE_CMATRIX(m) mne_free_cmatrix((m))
63 static void matrix_error(
int kind,
int nr,
int nc)
67 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
69 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
71 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
72 if (
sizeof(
void *) == 4) {
73 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
74 printf(
"Please consider moving to a 64-bit platform.");
76 printf(
"Cannot continue. Sorry.\n");
80 float **mne_cmatrix (
int nr,
int nc)
87 m = MALLOC(nr,
float *);
88 if (!m) matrix_error(1,nr,nc);
89 whole = MALLOC(nr*nc,
float);
90 if (!whole) matrix_error(2,nr,nc);
97 void mne_free_cmatrix (
float **m)
143 void mne_free_name_list(
char **list,
int nlist)
149 if (list == NULL || nlist == 0)
151 for (
k = 0;
k < nlist;
k++) {
153 printf(
"%d %s\n",
k,list[
k]);
171 newsel->name.clear();
172 newsel->chdef.clear();
173 newsel->chspick.clear();
174 newsel->chspick_nospace.clear();
176 newsel->pick_deriv = NULL;
177 newsel->ch_kind = NULL;
180 newsel->kind = MNE_CH_SELECTION_UNKNOWN;
184 mneChSelection mne_ch_selection_these(
const QString& selname,
const QStringList& names,
int nch)
192 sel = new_ch_selection();
196 sel->kind = MNE_CH_SELECTION_USER;
198 for (c = 0; c < nch; c++)
199 sel->chdef.append(names[c]);
204 static void omit_spaces(QStringList names,
int nnames)
208 for (
int k = 0;
k < names.size();
k++) {
209 while( names[
k].startsWith(
" ") ) {
210 names[
k].remove(0,1);
231 sel->chspick.clear();
232 sel->chspick_nospace.clear();
236 sel->chspick = sel->chdef;
237 sel->chspick_nospace = sel->chdef;
238 omit_spaces(sel->chspick_nospace,sel->ndef);
239 sel->nchan = sel->ndef;
241 sel->pick = REALLOC(sel->pick,sel->nchan,
int);
242 sel->pick_deriv = REALLOC(sel->pick_deriv,sel->nchan,
int);
243 sel->ch_kind = REALLOC(sel->ch_kind,sel->nchan,
int);
245 for (c = 0; c < sel->nchan; c++) {
247 sel->pick_deriv[c] = -1;
248 sel->ch_kind[c] = -1;
249 for (rc = 0; rc < info->
nchan; rc++) {
250 if (QString::compare(sel->chspick[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0 ||
251 QString::compare(sel->chspick_nospace[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0) {
253 sel->ch_kind[c] = info->
chInfo[rc].kind;
262 if (data->deriv_matched) {
263 QStringList deriv_names = data->deriv_matched->deriv_data->rowlist;
264 int nderiv = data->deriv_matched->deriv_data->nrow;
266 for (c = 0; c < sel->nchan; c++) {
267 if (sel->pick[c] == -1) {
268 for (d = 0; d < nderiv; d++) {
269 if (QString::compare(sel->chspick[c],deriv_names[d],Qt::CaseInsensitive) == 0 &&
270 data->deriv_matched->valid && data->deriv_matched->valid[d]) {
271 sel->pick_deriv[c] = d;
272 sel->ch_kind[c] = data->deriv_matched->chs[d].kind;
283 for (c = 0; c < sel->nchan; c++) {
284 if (sel->pick[c] == -1 && sel->pick_deriv[c] == -1) {
285 for (rc = 0; rc < info->
nchan; rc++) {
286 dash = QString(info->
chInfo[rc].ch_name).mid(QString(info->
chInfo[rc].ch_name).indexOf(
"-")+1);
287 if (!dash.isNull()) {
289 if (QString::compare(sel->chspick[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0 ||
290 QString::compare(sel->chspick_nospace[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0) {
293 sel->ch_kind[c] = info->
chInfo[rc].kind;
301 for (c = 0, nch = 0; c < sel->nchan; c++) {
302 if (sel->pick[c] >= 0)
306 printf(
"Selection %c%s%c has %d matched derived channels.\n",
'"',sel->name.toUtf8().constData(),
'"',sel->nderiv);
312 int mne_get_values_from_data (
float time,
332 for (ch = 0; ch < nch; ch++) {
336 if (std::fabs(sfreq*integ) < EPS_VALUES) {
337 s1 = sfreq*(time - tmin);
340 if (n1 < 0 || n1 > nsamp-1) {
341 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
348 if (std::fabs(f1-1.0) < 1e-3)
351 if (f1 < 1.0 && n1 > nsamp-2) {
352 printf(
"Sample value out of range %d (0..%d) %.4f",n1,nsamp-1,f1);
357 sum = f1*std::fabs(data[n1][ch]) + (1.0-f1)*std::fabs(data[n1+1][ch]);
359 sum = f1*data[n1][ch] + (1.0-f1)*data[n1+1][ch];
363 sum = std::fabs(data[n1][ch]);
369 s1 = sfreq*(time - 0.5*integ - tmin);
370 s2 = sfreq*(time + 0.5*integ - tmin);
371 n1 = ceil(s1); n2 = floor(s2);
374 if (n1 < 0 || n1 > nsamp-2)
379 sum = 0.5*((f1+f2)*std::fabs(data[n1+1][ch]) + (2.0-f1-f2)*std::fabs(data[n1][ch]));
381 sum = 0.5*((f1+f2)*data[n1+1][ch] + (2.0-f1-f2)*data[n1][ch]);
386 if (n1 < 0 || n1 > nsamp-1) {
387 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
390 if (n2 < 0 || n2 > nsamp-1) {
391 printf(
"Sample value out of range %d (0..%d)",n2,nsamp-1);
394 if (f1 != 0.0 && n1 < 1)
396 if (f2 != 0.0 && n2 > nsamp-2)
402 sum = 0.5 * std::fabs(data[n1][ch]);
403 for (
k = n1+1;
k < n2;
k++)
404 sum = sum + std::fabs(data[
k][ch]);
405 sum = sum + 0.5 * std::fabs(data[n2][ch]);
408 sum = 0.5*data[n1][ch];
409 for (
k = n1+1;
k < n2;
k++)
410 sum = sum + data[
k][ch];
411 sum = sum + 0.5*data[n2][ch];
420 sum = sum + 0.5 * f1 * (f1 * std::fabs(data[n1-1][ch]) + (2.0 - f1) * std::fabs(data[n1][ch]));
422 sum = sum + 0.5 * f2 * (f2 * std::fabs(data[n2+1][ch]) + (2.0 - f2) * std::fabs(data[n2][ch]));
426 sum = sum + 0.5*f1*(f1*data[n1-1][ch] + (2.0-f1)*data[n1][ch]);
428 sum = sum + 0.5*f2*(f2*data[n2+1][ch] + (2.0-f2)*data[n2][ch]);
430 width = width + f1 + f2;
439 int mne_get_values_from_data_ch (
float time,
459 for (ch = 0; ch < nch; ch++) {
463 if (std::fabs(sfreq * integ) < EPS_VALUES) {
464 s1 = sfreq*(time - tmin);
467 if (n1 < 0 || n1 > nsamp-1)
469 if (f1 < 1.0 && n1 > nsamp-2)
473 sum = f1 * std::fabs(data[ch][n1]) + (1.0 - f1) * std::fabs(data[ch][n1+1]);
475 sum = f1*data[ch][n1] + (1.0-f1)*data[ch][n1+1];
479 sum = std::fabs(data[ch][n1]);
485 s1 = sfreq*(time - 0.5*integ - tmin);
486 s2 = sfreq*(time + 0.5*integ - tmin);
487 n1 = ceil(s1); n2 = floor(s2);
490 if (n1 < 0 || n1 > nsamp-2)
495 sum = 0.5*((f1+f2)*std::fabs(data[ch][n1+1]) + (2.0-f1-f2)*std::fabs(data[ch][n1]));
497 sum = 0.5*((f1+f2)*data[ch][n1+1] + (2.0-f1-f2)*data[ch][n1]);
502 if (n1 < 0 || n1 > nsamp-1 || n2 < 0 || n2 > nsamp-1)
504 if (f1 != 0.0 && n1 < 1)
506 if (f2 != 0.0 && n2 > nsamp-2)
512 sum = 0.5 * std::fabs(data[ch][n1]);
513 for (
k = n1+1;
k < n2;
k++)
514 sum = sum + std::fabs(data[ch][
k]);
515 sum = sum + 0.5 * std::fabs(data[ch][n2]);
518 sum = 0.5*data[ch][n1];
519 for (
k = n1+1;
k < n2;
k++)
520 sum = sum + data[ch][
k];
521 sum = sum + 0.5*data[ch][n2];
530 sum = sum + 0.5 * f1 * (f1 * std::fabs(data[ch][n1-1]) + (2.0 - f1) * std::fabs(data[ch][n1]));
532 sum = sum + 0.5 * f2 * (f2 * std::fabs(data[ch][n2+1]) + (2.0 - f2) * std::fabs(data[ch][n2]));
536 sum = sum + 0.5*f1*(f1*data[ch][n1-1]+ (2.0-f1)*data[ch][n1]);
538 sum = sum + 0.5*f2*(f2*data[ch][n2+1] + (2.0-f2)*data[ch][n2]);
540 width = width + f1 + f2;
554 : settings(p_settings)
560 ECDSet DipoleFit::calculateFit()
const
562 QScopedPointer<GuessData>guess (Q_NULLPTR);
570 printf(
"---- Setting up...\n\n");
578 settings->
bemname.isEmpty() ? NULL : settings->
bemname.toUtf8().data(),
601 printf(
"\n---- Opening a raw data file...\n\n");
602 if ((raw = MneRawData::mne_raw_open_file(settings->
measname.isEmpty() ? NULL : settings->
measname.toUtf8().data(),TRUE,FALSE,&(settings->filter))) == NULL)
607 sel = mne_ch_selection_these(
"fit",fit_data->
ch_names,fit_data->
nmeg+fit_data->
neeg);
608 mne_ch_selection_assign_chs(sel,raw);
609 for (c = 0; c < sel->nchan; c++)
610 if (sel->pick[c] < 0) {
611 qCritical (
"All desired channels were not available");
614 printf(
"\tChannel selection created.\n");
618 t1 = raw->first_samp/raw->info->
sfreq;
619 t2 = (raw->first_samp+raw->nsamp-1)/raw->info->
sfreq;
620 if (settings->
tmin < t1 + settings->integ)
621 settings->
tmin = t1 + settings->integ;
622 if (settings->tmax > t2 - settings->integ)
623 settings->tmax = t2 - settings->integ;
624 if (settings->
tstep < 0)
627 printf(
"\tOpened raw data file %s : %d MEG and %d EEG \n",
631 printf(
"\n---- Reading data...\n\n");
632 if ((data = MneMeasData::mne_read_meas_data(settings->
measname,
637 fit_data->
nmeg+fit_data->
neeg)) == NULL)
640 data->adjust_baselines(settings->
bmin,settings->bmax);
642 printf(
"\tNo baseline setting in effect.\n");
643 if (settings->
tmin < data->current->tmin + settings->integ/2.0)
644 settings->
tmin = data->current->tmin + settings->integ/2.0;
645 if (settings->tmax > data->current->tmin + (data->current->np-1)*data->current->tstep - settings->integ/2.0)
646 settings->tmax = data->current->tmin + (data->current->np-1)*data->current->tstep - settings->integ/2.0;
647 if (settings->
tstep < 0)
648 settings->
tstep = data->current->tstep;
650 printf(
"\tRead data set %d from %s : %d MEG and %d EEG \n",
653 printf(
"\nScaling the noise covariance...\n");
654 if (DipoleFitData::scale_noise_cov(fit_data,data->current->nave) == FAIL)
662 printf(
"\n---- Computing the forward solution for the guesses...\n\n");
669 fprintf (stderr,
"\n---- Fitting : %7.1f ... %7.1f ms (step: %6.1f ms integ: %6.1f ms)\n\n",
670 1000*settings->
tmin,1000*settings->tmax,1000*settings->
tstep,1000*settings->integ);
673 if (
fit_dipoles_raw(settings->
measname,raw,sel,fit_data,guess.take(),settings->
tmin,settings->tmax,settings->
tstep,settings->integ,settings->verbose) == FAIL)
677 if (
fit_dipoles(settings->
measname,data,fit_data,guess.take(),settings->
tmin,settings->tmax,settings->
tstep,settings->integ,settings->verbose,set) == FAIL)
680 printf(
"%d dipoles fitted\n",set.
size());
691 float *one = MALLOC(data->nchan,
float);
696 int report_interval = 10;
700 printf(
"Fitting...%c",verbose ?
'\n' :
'\0');
701 for (s = 0, time = tmin; time < tmax; s++, time = tmin + s*tstep) {
705 if (mne_get_values_from_data(time,integ,data->current->data,data->current->np,data->nchan,data->current->tmin,
706 1.0/data->current->tstep,FALSE,one) == FAIL) {
707 printf(
"Cannot pick time: %7.1f ms\n",1000*time);
712 printf(
"t = %7.1f ms : %s\n",1000*time,
"error (tbd: catch)");
718 if (set.
size() % report_interval == 0)
719 printf(
"%d..",set.
size());
732 int DipoleFit::fit_dipoles_raw(
const QString& dataname,
MneRawData* raw,
mneChSelection sel,
DipoleFitData* fit,
GuessData* guess,
float tmin,
float tmax,
float tstep,
float integ,
int verbose,
ECDSet& p_set)
734 float *one = MALLOC(sel->nchan,
float);
735 float sfreq = raw->info->
sfreq;
736 float myinteg = integ > 0.0 ? 2*integ : 0.1;
737 int overlap = ceil(myinteg*sfreq);
738 int length = SEG_LEN*sfreq;
739 int step = length - overlap;
740 int stepo = step + overlap/2;
741 int start = raw->first_samp;
744 float **data = ALLOC_CMATRIX(sel->nchan,length);
747 int report_interval = 10;
755 if (MneRawData::mne_raw_pick_data_filt(raw,sel,start,length,data) == FAIL)
757 printf(
"Fitting...%c",verbose ?
'\n' :
'\0');
758 for (s = 0, time = tmin; time < tmax; s++, time = tmin + s*tstep) {
759 picks = time*sfreq - start;
761 start = start + step;
762 if (MneRawData::mne_raw_pick_data_filt(raw,sel,start,length,data) == FAIL)
764 picks = time*sfreq - start;
770 if (mne_get_values_from_data_ch (time,integ,data,length,sel->nchan,stime,sfreq,FALSE,one) == FAIL) {
771 printf(
"Cannot pick time: %8.3f s\n",time);
778 qWarning() <<
"Error";
784 if (set.
size() % report_interval == 0)
785 printf(
"%d..",set.
size());
808 return fit_dipoles_raw(dataname, raw, sel, fit, guess, tmin, tmax, tstep, integ, verbose, set);