78 const float currentSfreq = 1.0f /
current->tstep;
79 const float tmin =
current->tmin;
80 const float tmax =
current->tmin + (
current->np - 1) / currentSfreq;
88 for (b1 = 0; b1 / currentSfreq + tmin < bmin; b1++)
90 b1 = qBound(0, b1,
current->np);
97 for (b2 =
current->np; b2 / currentSfreq + tmin > bmax; b2--)
99 b2 = qBound(0, b2,
current->np);
102 Eigen::MatrixXf& bdata =
current->data;
104 for (
int c = 0; c <
nchan; c++) {
106 for (
int s = b1; s < b2; s++)
110 for (
int s = 0; s <
current->np; s++)
113 qInfo(
"\t%s : using baseline %7.1f ... %7.1f ms\n",
114 current->comment.toUtf8().constData() ?
current->comment.toUtf8().constData() :
"unknown",
115 1000 * (tmin + b1 /
sfreq),
116 1000 * (tmin + b2 /
sfreq));
122bool MNEMeasData::read_evoked_set(
const QString& name,
126 const QStringList& namesp,
141 QPair<float, float>(-1.0f, -1.0f),
false)) {
142 qCritical(
"Failed to read evoked data from %s\n", name.toUtf8().constData());
149 const int nchan_file = evoked.
info.
nchan;
150 const int nsamp = evoked.
last - evoked.
first + 1;
152 const float dtmin =
static_cast<float>(evoked.
first) /
sfreq;
155 const int nave = evoked.
nave;
157 const QList<FiffChInfo>&
chs = evoked.
info.
chs;
159 const MatrixXf data = evoked.
data.cast<
float>();
177 int k, p, c, np, n1, n2;
180 if (stim14_name.isEmpty() || stim14_name.size() == 0)
183 stim14_name.remove(
' ');
186 for (
int i = 0; i < target.
nchan; i++)
187 names.append(target.
chs[i].ch_name);
191 names =
op->eigen_fields->col_names;
194 names =
fwd->collist;
205 qInfo(
"\tMeasurement file id: %s\n",
id.toString().toUtf8().constData());
211 sel = Eigen::VectorXi::Constant(
nchan, -1);
212 for (c = 0; c < nchan_file; c++) {
213 for (k = 0; k <
nchan; k++) {
214 if (sel[k] == -1 && QString::compare(
chs[c].ch_name, names[k]) == 0) {
219 if (QString(
chs[c].ch_name).remove(
' ') == stim14_name) {
223 for (k = 0; k <
nchan; k++)
225 qCritical(
"All channels needed were not in the MEG/EEG data file "
226 "(first missing: %s).",
227 names[k].toUtf8().constData());
231 sel.resize(nchan_file);
233 for (c = 0,
nchan = 0; c < nchan_file; c++) {
238 if (QString(
chs[c].ch_name).remove(
' ') == stim14_name) {
250 tmax = dtmin + (np - 1) /
sfreq;
251 qInfo(
"\tData time range: %8.1f ... %8.1f ms\n", 1000 * tmin, 1000 * tmax);
279 if (!devHeadT.isEmpty()) {
280 target.
meg_head_t = std::make_unique<FiffCoordTrans>(devHeadT);
281 qInfo(
"\tUsing MEG <-> head transform from the present data set\n");
283 if (
op !=
nullptr && !
op->mri_head_t.isEmpty()) {
284 target.
mri_head_t = std::make_unique<FiffCoordTrans>(
op->mri_head_t);
285 qInfo(
"\tPicked MRI <-> head transform from the inverse operator\n");
290 for (k = 0; k <
nchan; k++) {
291 target.
chs.append(FiffChInfo());
292 target.
chs[k] =
chs[sel[k]];
299 if (target.
proj && target.
proj->nitems > 0) {
300 qInfo(
"\tLoaded projection from %s:\n", name.toUtf8().data());
301 QTextStream errStream(stderr);
302 target.
proj->report(errStream, QStringLiteral(
"\t\t"));
306 if (target.
proj && target.
proj->nitems > 0) {
307 qInfo(
"\tLoaded projection from %s:\n", name.toUtf8().data());
308 QTextStream errStream(stderr);
309 target.
proj->report(errStream, QStringLiteral(
"\t\t"));
315 if (target.
comp->ncomp > 0)
316 qInfo(
"\tRead %d compensation data sets from %s\n", target.
comp->ncomp, name.toUtf8().data());
324 target.
bad = Eigen::VectorXi::Zero(target.
nchan);
326 for (
int b = 0; b < target.
nbad; b++) {
327 for (k = 0; k < target.
nchan; k++) {
328 if (QString::compare(target.
chs[k].ch_name, target.
badlist[b], Qt::CaseInsensitive) == 0) {
334 qInfo(
"\t%d bad channels read from %s%s", target.
nbad, name.toUtf8().data(), target.
nbad > 0 ?
":\n" :
"\n");
335 if (target.
nbad > 0) {
337 for (k = 0; k < target.
nbad; k++)
338 qInfo(
"%s%c", target.
badlist[k].toUtf8().constData(), k < target.
nbad - 1 ?
' ' :
'\n');
345 auto dataset = std::make_unique<MNEMeasDataSet>();
346 dataset->tmin = tmin;
347 dataset->tstep = 1.0 /
sfreq;
350 dataset->nave = nave;
351 dataset->kind = aspect_kind;
352 dataset->data = Eigen::MatrixXf::Zero(np,
nchan);
353 dataset->comment = evoked.
comment;
354 dataset->baselines = Eigen::VectorXf::Zero(
nchan);
358 for (k = 0; k <
nchan; k++) {
362 for (p = 0; p < np; p++)
363 dataset->data(p, k) = data(sel[k], p + n1);
369 dataset->stim14 = Eigen::VectorXf(np);
370 for (p = 0; p < np; p++)
371 dataset->stim14[p] = data(stim14, p + n1) /
chs[stim14].cal;
373 const QString comment = dataset->comment.isEmpty() ? QStringLiteral(
"unknown") : dataset->comment;
374 target.
sets.push_back(std::move(dataset));
378 qInfo(
"\t%s dataset %s from %s", fresh ?
"Loaded" :
"Added", qPrintable(comment), qPrintable(name));
388 const QStringList& namesp,
391 auto data = std::make_unique<MNEMeasData>();
392 if (!read_evoked_set(name, set,
op,
fwd, namesp, nnamesp, *data,
true))
403 const QStringList& namesp,
407 return read_evoked_set(name, set,
op,
fwd, namesp, nnamesp, add_to,
false);
Single averaged evoked response: time axis, samples, baseline, channel info and processing history.
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
Primitive scalar typedefs and forward-compatible aliases backing the FIFF type system.
One condition / averaging slice within a legacy MNELIB::MNEMeasData.
Pre-computed inverse operator (whitened SVD of the forward model) for MNE/dSPM/sLORETA.
Row/column-labelled dense matrix used wherever FIFF stores per-channel data.
Legacy MNE-C constants and shared typedefs used across MNELIB structures.
#define MNE_ENV_TRIGGER_CH
Environment variable overriding the trigger channel name.
#define MNE_DEFAULT_TRIGGER_CH
Default digital trigger channel name.
Legacy MNE-C measurement-data container assembling raw/evoked sets and their projection state.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O, in-memory data structures and high-level readers/writers.
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
Single averaged evoked response: time axis, data, baseline, channel info and averaging metadata.
static bool read(QIODevice &p_IODevice, FiffEvoked &p_FiffEvoked, QVariant setno=0, QPair< float, float > t_baseline=defaultFloatPair, bool proj=true, fiff_int_t p_aspect_kind=FIFFV_ASPECT_AVERAGE)
128-bit FIFF identifier: hardware machine ID plus creation time, stamped on every file and block.
FiffCoordTrans dev_head_t
static std::unique_ptr< MNECTFCompDataSet > read(const QString &name)
MNE-style inverse operator.
Measurement data container for MNE inverse and dipole-fit computations.
void adjust_baselines(float bmin, float bmax)
Adjust baseline offset of the current data set.
~MNEMeasData()
Destroys the measurement data and all owned data sets.
MNEMeasData()
Constructs an empty measurement data container.
FIFFLIB::FiffTime meas_date
std::vector< std::unique_ptr< MNEMeasDataSet > > sets
std::unique_ptr< FIFFLIB::FiffCoordTrans > meg_head_t
std::unique_ptr< MNECTFCompDataSet > comp
QList< FIFFLIB::FiffChInfo > chs
std::unique_ptr< FIFFLIB::FiffCoordTrans > mri_head_t
static bool mne_read_meas_data_add(const QString &name, int set, MNEInverseOperator *op, MNENamedMatrix *fwd, const QStringList &namesp, int nnamesp, MNEMeasData &add_to)
Read an evoked-response data set and append it to an existing container.
static std::unique_ptr< MNEMeasData > mne_read_meas_data(const QString &name, int set, MNEInverseOperator *op, MNENamedMatrix *fwd, const QStringList &namesp, int nnamesp)
Read an evoked-response data set into a new container.
std::unique_ptr< MNEProjOp > proj
A dense matrix with named rows and columns.
static std::unique_ptr< MNEProjOp > read(const QString &name)