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))
63static 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");
88 if (!m) matrix_error(1,nr,nc);
89 whole =
MALLOC(nr*nc,
float);
90 if (!whole) matrix_error(2,nr,nc);
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();
189 sel = new_ch_selection();
195 for (c = 0; c < nch; c++)
196 sel->
chdef.append(names[c]);
201static void omit_spaces(QStringList names,
int nnames)
205 for (
int k = 0; k < names.size(); k++) {
206 while( names[k].startsWith(
" ") ) {
207 names[k].remove(0,1);
227 info = data->
info.get();
242 for (c = 0; c < sel->
nchan; c++) {
243 for (rc = 0; rc < info->
nchan; rc++) {
244 if (QString::compare(sel->
chspick[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0 ||
257 QStringList deriv_names = data->
deriv_matched->deriv_data->rowlist;
260 for (c = 0; c < sel->
nchan; c++) {
261 if (sel->
pick[c] == -1) {
262 for (d = 0; d < nderiv; d++) {
263 if (QString::compare(sel->
chspick[c],deriv_names[d],Qt::CaseInsensitive) == 0 &&
277 for (c = 0; c < sel->
nchan; c++) {
279 for (rc = 0; rc < info->
nchan; rc++) {
280 dash = QString(info->
chInfo[rc].ch_name).mid(QString(info->
chInfo[rc].ch_name).indexOf(
"-")+1);
281 if (!dash.isNull()) {
283 if (QString::compare(sel->
chspick[c],info->
chInfo[rc].ch_name,Qt::CaseInsensitive) == 0 ||
295 for (c = 0, nch = 0; c < sel->
nchan; c++) {
296 if (sel->
pick[c] >= 0)
300 printf(
"Selection %c%s%c has %d matched derived channels.\n",
'"',sel->
name.toUtf8().constData(),
'"',sel->
nderiv);
326 for (ch = 0; ch < nch; ch++) {
331 s1 = sfreq*(time - tmin);
334 if (n1 < 0 || n1 > nsamp-1) {
335 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
342 if (std::fabs(f1-1.0) < 1e-3)
345 if (f1 < 1.0 && n1 > nsamp-2) {
346 printf(
"Sample value out of range %d (0..%d) %.4f",n1,nsamp-1,f1);
351 sum = f1*std::fabs(data[n1][ch]) + (1.0-f1)*std::fabs(data[n1+1][ch]);
353 sum = f1*data[n1][ch] + (1.0-f1)*data[n1+1][ch];
357 sum = std::fabs(data[n1][ch]);
363 s1 = sfreq*(time - 0.5*integ - tmin);
364 s2 = sfreq*(time + 0.5*integ - tmin);
365 n1 = ceil(s1); n2 = floor(s2);
368 if (n1 < 0 || n1 > nsamp-2)
373 sum = 0.5*((f1+f2)*std::fabs(data[n1+1][ch]) + (2.0-f1-f2)*std::fabs(data[n1][ch]));
375 sum = 0.5*((f1+f2)*data[n1+1][ch] + (2.0-f1-f2)*data[n1][ch]);
380 if (n1 < 0 || n1 > nsamp-1) {
381 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
384 if (n2 < 0 || n2 > nsamp-1) {
385 printf(
"Sample value out of range %d (0..%d)",n2,nsamp-1);
388 if (f1 != 0.0 && n1 < 1)
390 if (f2 != 0.0 && n2 > nsamp-2)
396 sum = 0.5 * std::fabs(data[n1][ch]);
397 for (k = n1+1; k < n2; k++)
398 sum = sum + std::fabs(data[k][ch]);
399 sum = sum + 0.5 * std::fabs(data[n2][ch]);
402 sum = 0.5*data[n1][ch];
403 for (k = n1+1; k < n2; k++)
404 sum = sum + data[k][ch];
405 sum = sum + 0.5*data[n2][ch];
414 sum = sum + 0.5 * f1 * (f1 * std::fabs(data[n1-1][ch]) + (2.0 - f1) * std::fabs(data[n1][ch]));
416 sum = sum + 0.5 * f2 * (f2 * std::fabs(data[n2+1][ch]) + (2.0 - f2) * std::fabs(data[n2][ch]));
420 sum = sum + 0.5*f1*(f1*data[n1-1][ch] + (2.0-f1)*data[n1][ch]);
422 sum = sum + 0.5*f2*(f2*data[n2+1][ch] + (2.0-f2)*data[n2][ch]);
424 width = width + f1 + f2;
453 for (ch = 0; ch < nch; ch++) {
458 s1 = sfreq*(time - tmin);
461 if (n1 < 0 || n1 > nsamp-1)
463 if (f1 < 1.0 && n1 > nsamp-2)
467 sum = f1 * std::fabs(data[ch][n1]) + (1.0 - f1) * std::fabs(data[ch][n1+1]);
469 sum = f1*data[ch][n1] + (1.0-f1)*data[ch][n1+1];
473 sum = std::fabs(data[ch][n1]);
479 s1 = sfreq*(time - 0.5*integ - tmin);
480 s2 = sfreq*(time + 0.5*integ - tmin);
481 n1 = ceil(s1); n2 = floor(s2);
484 if (n1 < 0 || n1 > nsamp-2)
489 sum = 0.5*((f1+f2)*std::fabs(data[ch][n1+1]) + (2.0-f1-f2)*std::fabs(data[ch][n1]));
491 sum = 0.5*((f1+f2)*data[ch][n1+1] + (2.0-f1-f2)*data[ch][n1]);
496 if (n1 < 0 || n1 > nsamp-1 || n2 < 0 || n2 > nsamp-1)
498 if (f1 != 0.0 && n1 < 1)
500 if (f2 != 0.0 && n2 > nsamp-2)
506 sum = 0.5 * std::fabs(data[ch][n1]);
507 for (k = n1+1; k < n2; k++)
508 sum = sum + std::fabs(data[ch][k]);
509 sum = sum + 0.5 * std::fabs(data[ch][n2]);
512 sum = 0.5*data[ch][n1];
513 for (k = n1+1; k < n2; k++)
514 sum = sum + data[ch][k];
515 sum = sum + 0.5*data[ch][n2];
524 sum = sum + 0.5 * f1 * (f1 * std::fabs(data[ch][n1-1]) + (2.0 - f1) * std::fabs(data[ch][n1]));
526 sum = sum + 0.5 * f2 * (f2 * std::fabs(data[ch][n2+1]) + (2.0 - f2) * std::fabs(data[ch][n2]));
530 sum = sum + 0.5*f1*(f1*data[ch][n1-1]+ (2.0-f1)*data[ch][n1]);
532 sum = sum + 0.5*f2*(f2*data[ch][n2+1] + (2.0-f2)*data[ch][n2]);
534 width = width + f1 + f2;
548: settings(p_settings)
556 std::unique_ptr<GuessData> guess;
564 printf(
"---- Setting up...\n\n");
565 if (settings->include_eeg) {
572 settings->bemname.isEmpty() ? NULL : settings->bemname.toUtf8().data(),
586 settings->include_meg,
587 settings->include_eeg)) == NULL)
591 if (settings->is_raw) {
595 printf(
"\n---- Opening a raw data file...\n\n");
603 for (c = 0; c < sel->
nchan; c++)
604 if (sel->
pick[c] < 0) {
605 qCritical (
"All desired channels were not available");
608 printf(
"\tChannel selection created.\n");
614 if (settings->tmin < t1 + settings->integ)
615 settings->tmin = t1 + settings->integ;
616 if (settings->tmax > t2 - settings->integ)
617 settings->tmax = t2 - settings->integ;
618 if (settings->tstep < 0)
619 settings->tstep = 1.0/raw->
info->sfreq;
621 printf(
"\tOpened raw data file %s : %d MEG and %d EEG \n",
622 settings->measname.toUtf8().data(),fit_data->
nmeg,fit_data->
neeg);
625 printf(
"\n---- Reading data...\n\n");
631 fit_data->
nmeg+fit_data->
neeg)) == NULL)
633 if (settings->do_baseline)
636 printf(
"\tNo baseline setting in effect.\n");
637 if (settings->tmin < data->
current->
tmin + settings->integ/2.0)
638 settings->tmin = data->
current->
tmin + settings->integ/2.0;
641 if (settings->tstep < 0)
644 printf(
"\tRead data set %d from %s : %d MEG and %d EEG \n",
645 settings->setno,settings->measname.toUtf8().data(),fit_data->
nmeg,fit_data->
neeg);
646 if (!settings->noisename.isEmpty()) {
647 printf(
"\nScaling the noise covariance...\n");
656 printf(
"\n---- Computing the forward solution for the guesses...\n\n");
657 guess.reset(
new GuessData( settings->guessname,
658 settings->guess_surfname,
659 settings->guess_mindist, settings->guess_exclude, settings->guess_grid, fit_data));
663 fprintf (stderr,
"\n---- Fitting : %7.1f ... %7.1f ms (step: %6.1f ms integ: %6.1f ms)\n\n",
664 1000*settings->tmin,1000*settings->tmax,1000*settings->tstep,1000*settings->integ);
667 if (
fit_dipoles_raw(settings->measname,raw,sel,fit_data,guess.release(),settings->tmin,settings->tmax,settings->tstep,settings->integ,settings->verbose) ==
FAIL)
671 if (
fit_dipoles(settings->measname,data,fit_data,guess.release(),settings->tmin,settings->tmax,settings->tstep,settings->integ,settings->verbose,set) ==
FAIL)
674 printf(
"%d dipoles fitted\n",set.
size());
690 int report_interval = 10;
694 printf(
"Fitting...%c",verbose ?
'\n' :
'\0');
695 for (s = 0, time = tmin; time < tmax; s++, time = tmin + s*tstep) {
701 printf(
"Cannot pick time: %7.1f ms\n",1000*time);
706 printf(
"t = %7.1f ms : %s\n",1000*time,
"error (tbd: catch)");
712 if (set.
size() % report_interval == 0)
713 printf(
"%d..",set.
size());
726int 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)
729 float sfreq = raw->
info->sfreq;
730 float myinteg = integ > 0.0 ? 2*integ : 0.1;
731 int overlap = ceil(myinteg*sfreq);
733 int step = length - overlap;
734 int stepo = step + overlap/2;
741 int report_interval = 10;
751 printf(
"Fitting...%c",verbose ?
'\n' :
'\0');
752 for (s = 0, time = tmin; time < tmax; s++, time = tmin + s*tstep) {
753 picks = time*sfreq - start;
755 start = start + step;
758 picks = time*sfreq - start;
765 printf(
"Cannot pick time: %8.3f s\n",time);
772 qWarning() <<
"Error";
778 if (set.
size() % report_interval == 0)
779 printf(
"%d..",set.
size());
802 return fit_dipoles_raw(dataname, raw, sel, fit, guess, tmin, tmax, tstep, integ, verbose, set);
#define MNE_CH_SELECTION_USER
#define MNE_CH_SELECTION_UNKNOWN
MNE Meas Data Set (MNEMeasDataSet) class declaration.
GuessData class declaration.
Dipole Fit class declaration.
int mne_get_values_from_data(float time, float integ, float **data, int nsamp, int nch, float tmin, float sfreq, int use_abs, float *value)
int mne_ch_selection_assign_chs(mneChSelection sel, MNERawData *data)
mneChSelection mne_ch_selection_these(const QString &selname, const QStringList &names, int nch)
int mne_get_values_from_data_ch(float time, float integ, float **data, int nsamp, int nch, float tmin, float sfreq, int use_abs, float *value)
float ** mne_cmatrix(int nr, int nc)
void mne_free_cmatrix(float **m)
void mne_free_name_list(char **list, int nlist)
#define ALLOC_CMATRIX(x, y)
Core MNE data structures (source spaces, source estimates, hemispheres).
MNEChSelection * mneChSelection
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
Forward modelling (BEM, MEG/EEG lead fields).
Multi-layer spherical head model for EEG forward computation.
static FwdEegSphereModel * setup_eeg_sphere_model(const QString &eeg_model_file, QString eeg_model_name, float eeg_sphere_rad)
Measurement data container holding multiple data sets for MNE inverse computations.
void adjust_baselines(float bmin, float bmax)
static MNEMeasData * mne_read_meas_data(const QString &name, int set, MNEInverseOperator *op, MNELIB::MNENamedMatrix *fwd, const QStringList &namesp, int nnamesp)
static int fit_dipoles_raw(const QString &dataname, MNELIB::MNERawData *raw, MNELIB::mneChSelection sel, DipoleFitData *fit, GuessData *guess, float tmin, float tmax, float tstep, float integ, int verbose, ECDSet &p_set)
DipoleFit(DipoleFitSettings *p_settings)
ECDSet calculateFit() const
static int fit_dipoles(const QString &dataname, MNEMeasData *data, DipoleFitData *fit, GuessData *guess, float tmin, float tmax, float tstep, float integ, int verbose, ECDSet &p_set)
Dipole Fit Data implementation.
static DipoleFitData * setup_dipole_fit_data(const QString &mriname, const QString &measname, const QString &bemname, Eigen::Vector3f *r0, FWDLIB::FwdEegSphereModel *eeg_model, int accurate_coils, const QString &badname, const QString &noisename, float grad_std, float mag_std, float eeg_std, float mag_reg, float grad_reg, float eeg_reg, int diagnoise, const QList< QString > &projnames, int include_meg, int include_eeg)
static bool fit_one(DipoleFitData *fit, GuessData *guess, float time, float *B, int verbose, ECD &res)
static int scale_noise_cov(DipoleFitData *f, int nave)
Dipole Fit setting implementation.
Single equivalent current dipole with position, orientation, amplitude, and goodness-of-fit.
void print(FILE *f) const
Holds a set of Electric Current Dipoles.
void addEcd(const ECD &p_ecd)
Precomputed guess point grid with forward fields for initial dipole position candidates.
Eigen::VectorXi pick_deriv
QStringList chspick_nospace
A comprehensive raw data structure.
std::unique_ptr< MNELIB::MNERawInfo > info
std::unique_ptr< MNELIB::MNEDeriv > deriv_matched
static MNERawData * open_file(const QString &name, int omit_skip, int allow_maxshield, const MNEFilterDef &filter)
int pick_data_filt(mneChSelection sel, int firsts, int ns, float **picked)
Information about raw data in a FIFF file.
QList< FIFFLIB::FiffChInfo > chInfo