68#define MALLOC_23(x,t) (t *)malloc((x)*sizeof(t))
70#define REALLOC_23(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
72#define FREE_23(x) if ((char *)(x) != NULL) free((char *)(x))
74#define FREE_CMATRIX_23(m) mne_free_cmatrix_23((m))
84#define ALLOC_CMATRIX_23(x,y) mne_cmatrix_23((x),(y))
86static void matrix_error_23(
int kind,
int nr,
int nc)
90 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
92 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
94 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
95 if (
sizeof(
void *) == 4) {
96 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
97 printf(
"Please consider moving to a 64-bit platform.");
99 printf(
"Cannot continue. Sorry.\n");
111 if (!m) matrix_error_23(1,nr,nc);
113 if (!whole) matrix_error_23(2,nr,nc);
127 float res = sdot(&nn,v1,&one,v2,&one);
133 for (k = 0; k < nn; k++)
134 res = res + v1[k]*v2[k];
148 if (!s.isEmpty() && s.size() > 0) {
153 nlistp = list.size();
159 for (
int i = 0; i < m; ++i)
160 for (
int j = 0; j < n; ++j)
161 to_mat[i][j] = from_mat(i,j);
174 int nlist = list.size();
176 if (nlist == 0 || list.isEmpty())
179 for (
int k = 0; k < nlist-1; k++) {
183 res += list[nlist-1];
196 for (
int k = 0; k < nch; k++)
197 names.append(chs.at(k).ch_name);
206using namespace Eigen;
248 for (
int k = 0; k < from->
nitems; k++) {
249 const auto& it = from->
items[k];
250 add_item(it.vecs.get(),it.kind,it.desc);
265 auto& new_item =
items.back();
267 new_item.active = is_active;
268 new_item.vecs = std::make_unique<MNENamedMatrix>(*vecs);
271 new_item.has_meg =
FALSE;
272 new_item.has_eeg =
TRUE;
275 for (
int k = 0; k < vecs->
ncol; k++) {
276 if (vecs->
collist[k].contains(
"EEG"))
277 new_item.has_eeg =
TRUE;
278 if (vecs->
collist[k].contains(
"MEG"))
279 new_item.has_meg =
TRUE;
281 if (!new_item.has_meg && !new_item.has_eeg) {
282 new_item.has_meg =
TRUE;
283 new_item.has_eeg =
FALSE;
285 else if (new_item.has_meg && new_item.has_eeg) {
286 new_item.has_meg =
TRUE;
287 new_item.has_eeg =
FALSE;
291 new_item.desc = desc;
292 new_item.kind = kind;
293 new_item.nvec = new_item.vecs->nrow;
317 for (
int k = 0; k <
nitems; k++) {
318 const auto& it =
items[k];
320 res->
items[k].active_file = it.active_file;
337 for (k = 0; k <
nch; k++)
341 qCritical(
"No EEG channels specified for average reference.");
345 for (k = 0; k <
nch; k++)
347 names.append(chs.at(k).ch_name);
349 Eigen::MatrixXf vec_data = Eigen::MatrixXf::Constant(1, eegcount, 1.0f/sqrt((
double)eegcount));
351 QStringList emptyList;
367 for (k = 0, naff = 0; k <
nitems; k++)
369 naff +=
items[k].nvec;
400 static float *res = NULL;
410 printf(
"Data vector size does not match projection operator");
414 if (
nch > res_size) {
419 for (k = 0; k <
nch; k++)
422 for (p = 0; p < this->nvec; p++) {
425 for (k = 0; k <
nch; k++)
426 res[k] = res[k] + w*pvec[k];
429 for (k = 0; k <
nch; k++)
430 vec[k] = vec[k] - res[k];
433 for (k = 0; k <
nch; k++)
447 QList<FiffDirNode::SPtr> proj;
449 QList<FiffDirNode::SPtr>
items;
452 QString item_desc,desc_tag;
453 int global_nchan,item_nchan;
454 QStringList item_names;
461 qCritical(
"File not open read_from_node");
465 if (!start || start->isEmpty())
466 start_node = stream->dirtree();
472 if (proj.size() == 0 || proj[0]->isEmpty())
484 if(!node->find_tag(stream,
FIFF_NCHAN, t_pTag))
487 global_nchan = *t_pTag->toInt();
493 for (k = 0; k <
items.size(); k++) {
500 if (node->find_tag(stream,
FIFF_NAME, t_pTag)) {
501 item_desc += t_pTag->toString();
508 desc_tag = t_pTag->toString();
510 if((pos = desc_tag.indexOf(
"\n")) >= 0)
511 desc_tag.truncate(pos);
512 if (!item_desc.isEmpty())
514 item_desc += desc_tag;
519 if (!node->find_tag(stream,
FIFF_NCHAN, t_pTag)) {
520 item_nchan = global_nchan;
523 item_nchan = *t_pTag->toInt();
525 if (item_nchan <= 0) {
526 qCritical(
"Number of channels incorrectly specified for one of the projection items.");
537 if (item_names.size() != item_nchan) {
538 printf(
"Channel name list incorrectly specified for proj item # %d",k+1);
547 item_kind = *t_pTag->toInt();
553 item_nvec = *t_pTag->toInt();
560 MatrixXf item_vectors = t_pTag->toFloatMatrix().transpose();
566 item_active = *t_pTag->toInt();
573 QStringList emptyList;
621 out <<
"Empty operator\n";
625 for (
int k = 0; k <
nitems; k++) {
626 const auto& it =
items[k];
627 if (list_data && tag)
631 out <<
"# " << (k+1) <<
" : " << it.desc <<
" : " << it.nvec <<
" vecs : " << it.vecs->ncol <<
" chs "
632 << (it.has_meg ?
"MEG" :
"EEG") <<
" "
633 << (it.active ?
"active" :
"idle") <<
"\n";
634 if (list_data && tag)
637 vecs =
items[k].vecs.get();
639 for (q = 0; q < vecs->
ncol; q++) {
640 out << qSetFieldWidth(10) << Qt::left << vecs->
collist[q] << qSetFieldWidth(0);
641 out << (q < vecs->
ncol-1 ?
" " :
"\n");
643 for (p = 0; p < vecs->
nrow; p++)
644 for (q = 0; q < vecs->
ncol; q++) {
645 for (j = 0, found = 0; j < nexclude; j++) {
646 if (QString::compare(exclude[j],vecs->
collist[q]) == 0) {
651 out << qSetFieldWidth(10) << qSetRealNumberPrecision(5) << Qt::forcepoint
652 << (found ? 0.0 : vecs->
data(p, q)) << qSetFieldWidth(0) <<
" ";
653 out << (q < vecs->
ncol-1 ?
" " :
"\n");
655 if (list_data && tag)
FiffTag class declaration, which provides fiff tag I/O and processing methods.
#define FIFF_MNE_PROJ_ITEM_ACTIVE
#define FIFFV_MNE_PROJ_ITEM_EEG_AVREF
#define FIFF_PROJ_ITEM_VECTORS
#define FIFF_PROJ_ITEM_KIND
#define FIFF_PROJ_ITEM_CH_NAME_LIST
#define FIFF_PROJ_ITEM_NVEC
MNEProjOp class declaration.
MNEProjItem class declaration.
void mne_string_to_name_list_23(const QString &s, QStringList &listp, int &nlistp)
void mne_free_cmatrix_23(float **m)
QString mne_name_list_to_string_23(const QStringList &list)
QString mne_channel_names_to_string_23(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
float mne_dot_vectors_23(float *v1, float *v2, int nn)
void fromFloatEigenMatrix_23(const Eigen::MatrixXf &from_mat, float **&to_mat, const int m, const int n)
#define REALLOC_23(x, y, t)
float ** mne_cmatrix_23(int nr, int nc)
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
QSharedPointer< FiffDirNode > SPtr
static QStringList split_name_list(QString p_sNameList)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
A dense matrix with named rows and columns.
static std::unique_ptr< MNENamedMatrix > build(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, const Eigen::MatrixXf &data)
Factory: build a named matrix from its constituent parts.
A single SSP (Signal-Space Projection) item.
void free_proj()
Release the compiled projector data.
static MNEProjOp * read_from_node(FIFFLIB::FiffStream::SPtr &stream, const FIFFLIB::FiffDirNode::SPtr &start)
Read all linear projection items from a FIFF tree node.
RowMajorMatrixXf proj_data
int project_vector(float *vec, int nvec, int do_complement)
static MNEProjOp * read(const QString &name)
static MNEProjOp * create_average_eeg_ref(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
Create an average EEG reference projector.
void report_data(QTextStream &out, const char *tag, int list_data, char **exclude, int nexclude)
int affect(const QStringList &list, int nlist)
void report(QTextStream &out, const char *tag)
MNEProjOp()
Default constructor.
MNEProjOp * combine(MNEProjOp *from)
Append all projection items from another operator.
MNEProjOp * dup() const
Create a deep copy of this projection operator.
void add_item(const MNENamedMatrix *vecs, int kind, const QString &desc)
Add a projection item that is active by default.
int affect_chs(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
QList< MNELIB::MNEProjItem > items
void add_item_active(const MNENamedMatrix *vecs, int kind, const QString &desc, int is_active)
Add a projection item with an explicit active/inactive state.