72 for (
int k = 0; k <
nset; k++)
85 const float currentSfreq = 1.0f /
current->tstep;
86 const float tmin =
current->tmin;
87 const float tmax =
current->tmin + (
current->np - 1) / currentSfreq;
95 for (b1 = 0; b1 / currentSfreq + tmin < bmin; b1++)
97 b1 = qBound(0, b1,
current->np);
101 else if (bmax > tmax)
104 for (b2 =
current->np; b2 / currentSfreq + tmin > bmax; b2--)
106 b2 = qBound(0, b2,
current->np);
109 Eigen::MatrixXf& bdata =
current->data;
111 for (
int c = 0; c <
nchan; c++) {
113 for (
int s = b1; s < b2; s++)
117 for (
int s = 0; s <
current->np; s++)
120 qInfo(
"\t%s : using baseline %7.1f ... %7.1f ms\n",
121 current->comment.toUtf8().constData() ?
current->comment.toUtf8().constData() :
"unknown",
122 1000 * (tmin + b1 /
sfreq),
123 1000 * (tmin + b2 /
sfreq));
133 const QStringList& namesp,
147 QPair<float, float>(-1.0f, -1.0f),
false)) {
148 qCritical(
"Failed to read evoked data from %s\n", name.toUtf8().constData());
155 const int nchan_file = evoked.
info.
nchan;
156 const int nsamp = evoked.
last - evoked.
first + 1;
158 const float dtmin =
static_cast<float>(evoked.
first) /
sfreq;
161 const int nave = evoked.
nave;
163 const QList<FiffChInfo>&
chs = evoked.
info.
chs;
165 const MatrixXf data = evoked.
data.cast<
float>();
183 int k, p, c, np, n1, n2;
189 if (stim14_name.isEmpty() || stim14_name.size() == 0)
192 stim14_name.remove(
' ');
195 for (
int i = 0; i < add_to->
nchan; i++)
196 names.append(add_to->
chs[i].ch_name);
200 names =
op->eigen_fields->col_names;
203 names =
fwd->collist;
214 qInfo(
"\tMeasurement file id: %s\n",
id.toString().toUtf8().constData());
220 sel = Eigen::VectorXi::Constant(
nchan, -1);
221 for (c = 0; c < nchan_file; c++) {
222 for (k = 0; k <
nchan; k++) {
223 if (sel[k] == -1 && QString::compare(
chs[c].ch_name, names[k]) == 0) {
228 if (QString(
chs[c].ch_name).remove(
' ') == stim14_name) {
232 for (k = 0; k <
nchan; k++)
234 qCritical(
"All channels needed were not in the MEG/EEG data file "
235 "(first missing: %s).",
236 names[k].toUtf8().constData());
240 sel.resize(nchan_file);
242 for (c = 0,
nchan = 0; c < nchan_file; c++) {
247 if (QString(
chs[c].ch_name).remove(
' ') == stim14_name) {
259 tmax = dtmin + (np - 1) /
sfreq;
260 qInfo(
"\tData time range: %8.1f ... %8.1f ms\n", 1000 * tmin, 1000 * tmax);
289 if (!devHeadT.isEmpty()) {
290 new_data->
meg_head_t = std::make_unique<FiffCoordTrans>(devHeadT);
291 qInfo(
"\tUsing MEG <-> head transform from the present data set\n");
293 if (
op !=
nullptr && !
op->mri_head_t.isEmpty()) {
294 new_data->
mri_head_t = std::make_unique<FiffCoordTrans>(
op->mri_head_t);
295 qInfo(
"\tPicked MRI <-> head transform from the inverse operator\n");
300 for (k = 0; k <
nchan; k++) {
302 new_data->
chs[k] =
chs[sel[k]];
309 if (new_data->
proj && new_data->
proj->nitems > 0) {
310 qInfo(
"\tLoaded projection from %s:\n", name.toUtf8().data());
311 QTextStream errStream(stderr);
312 new_data->
proj->report(errStream, QStringLiteral(
"\t\t"));
316 if (new_data->
proj && new_data->
proj->nitems > 0) {
317 qInfo(
"\tLoaded projection from %s:\n", name.toUtf8().data());
318 QTextStream errStream(stderr);
319 new_data->
proj->report(errStream, QStringLiteral(
"\t\t"));
322 if (!new_data->
comp) {
326 if (new_data->
comp->ncomp > 0)
327 qInfo(
"\tRead %d compensation data sets from %s\n", new_data->
comp->ncomp, name.toUtf8().data());
335 new_data->
bad = Eigen::VectorXi::Zero(new_data->
nchan);
337 for (
int b = 0; b < new_data->
nbad; b++) {
338 for (k = 0; k < new_data->
nchan; k++) {
339 if (QString::compare(new_data->
chs[k].ch_name, new_data->
badlist[b], Qt::CaseInsensitive) == 0) {
340 new_data->
bad[k] = 1;
345 qInfo(
"\t%d bad channels read from %s%s", new_data->
nbad, name.toUtf8().data(), new_data->
nbad > 0 ?
":\n" :
"\n");
346 if (new_data->
nbad > 0) {
348 for (k = 0; k < new_data->
nbad; k++)
349 qInfo(
"%s%c", new_data->
badlist[k].toUtf8().constData(), k < new_data->
nbad - 1 ?
' ' :
'\n');
357 dataset->
tmin = tmin;
361 dataset->
nave = nave;
362 dataset->
kind = aspect_kind;
363 dataset->
data = Eigen::MatrixXf::Zero(np,
nchan);
369 for (k = 0; k <
nchan; k++) {
373 for (p = 0; p < np; p++)
374 dataset->
data(p, k) = data(sel[k], p + n1);
380 dataset->
stim14 = Eigen::VectorXf(np);
381 for (p = 0; p < np; p++)
382 dataset->
stim14[p] = data(stim14, p + n1) /
chs[stim14].cal;
384 new_data->
sets.append(dataset);
390 qInfo(
"\t%s dataset %s from %s\n",
391 add_to ?
"Added" :
"Loaded",
392 new_data->
sets[new_data->
nset - 1]->comment.toUtf8().constData() ? new_data->
sets[new_data->
nset - 1]->comment.toUtf8().constData() :
"unknown", name.toUtf8().data());
394 if (res ==
nullptr && !add_to)
405 const QStringList& namesp,
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.
Per-channel FIFF descriptor: identifiers, kind, calibration, coil type, channel-frame coil position a...
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
FIFF time stamp: Unix seconds plus a microsecond fraction matching the on-disk fiffTimeRec record.
static std::unique_ptr< MNECTFCompDataSet > read(const QString &name)
MNE-style inverse operator.
static MNEMeasData * 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.
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::unique_ptr< FIFFLIB::FiffCoordTrans > meg_head_t
QList< MNEMeasDataSet * > sets
std::unique_ptr< MNECTFCompDataSet > comp
QList< FIFFLIB::FiffChInfo > chs
std::unique_ptr< FIFFLIB::FiffCoordTrans > mri_head_t
std::unique_ptr< MNEProjOp > proj
static 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.
Single measurement epoch or average within MNEMeasData.
Eigen::VectorXf baselines
A dense matrix with named rows and columns.
static std::unique_ptr< MNEProjOp > read(const QString &name)