67 #define MALLOC_23(x,t) (t *)malloc((x)*sizeof(t)) 69 #define REALLOC_23(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t))) 71 #define FREE_23(x) if ((char *)(x) != NULL) free((char *)(x)) 73 #define FREE_CMATRIX_23(m) mne_free_cmatrix_23((m)) 75 void mne_free_cmatrix_23 (
float **m)
83 #define ALLOC_CMATRIX_23(x,y) mne_cmatrix_23((x),(y)) 85 static void matrix_error_23(
int kind,
int nr,
int nc)
89 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
91 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
93 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
94 if (
sizeof(
void *) == 4) {
95 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
96 printf(
"Please consider moving to a 64-bit platform.");
98 printf(
"Cannot continue. Sorry.\n");
102 float **mne_cmatrix_23(
int nr,
int nc)
109 m = MALLOC_23(nr,
float *);
110 if (!m) matrix_error_23(1,nr,nc);
111 whole = MALLOC_23(nr*nc,
float);
112 if (!whole) matrix_error_23(2,nr,nc);
119 float mne_dot_vectors_23 (
float *v1,
126 float res = sdot(&nn,v1,&one,v2,&one);
132 for (k = 0; k < nn; k++)
133 res = res + v1[k]*v2[k];
140 void mne_string_to_name_list_23(
const QString& s, QStringList& listp,
int &nlistp)
147 if (!s.isEmpty() && s.size() > 0) {
152 nlistp = list.size();
156 void fromFloatEigenMatrix_23(
const Eigen::MatrixXf& from_mat,
float **& to_mat,
const int m,
const int n)
158 for (
int i = 0; i < m; ++i)
159 for (
int j = 0; j < n; ++j)
160 to_mat[i][j] = from_mat(i,j);
163 void fromFloatEigenMatrix_23(
const Eigen::MatrixXf& from_mat,
float **& to_mat)
165 fromFloatEigenMatrix_23(from_mat, to_mat, from_mat.rows(), from_mat.cols());
168 QString mne_name_list_to_string_23(
const QStringList& list)
173 int nlist = list.size();
175 if (nlist == 0 || list.isEmpty())
178 for (
int k = 0; k < nlist-1; k++) {
182 res += list[nlist-1];
186 QString mne_channel_names_to_string_23(
const QList<FIFFLIB::FiffChInfo>& chs,
int nch)
195 for (
int k = 0; k < nch; k++)
196 names.append(chs.at(k).ch_name);
197 res = mne_name_list_to_string_23(names);
205 using namespace Eigen;
213 MneProjOp::MneProjOp()
227 for (
int k = 0; k < nitems; k++)
241 FREE_CMATRIX_23(op->proj_data);
246 op->proj_data = NULL;
264 for (k = 0; k < from->nitems; k++) {
267 to->items[to->nitems-1]->active_file = it->
active_file;
275 void MneProjOp::mne_proj_op_add_item_act(
MneProjOp *op,
MneNamedMatrix *vecs,
int kind,
const QString& desc,
int is_active)
287 op->items.append(new_item);
289 new_item->
active = is_active;
292 if (kind == FIFFV_MNE_PROJ_ITEM_EEG_AVREF) {
297 for (k = 0; k < vecs->ncol; k++) {
298 if (vecs->collist[k].contains(
"EEG"))
300 if (vecs->collist[k].contains(
"MEG"))
313 new_item->
desc = desc;
314 new_item->
kind = kind;
315 new_item->
nvec = new_item->
vecs->nrow;
327 mne_proj_op_add_item_act(op, vecs, kind, desc, TRUE);
344 for (k = 0; k < op->nitems; k++) {
354 MneProjOp *MneProjOp::mne_proj_op_average_eeg_ref(
const QList<FiffChInfo>& chs,
int nch)
366 for (k = 0; k < nch; k++)
367 if (chs.at(k).kind == FIFFV_EEG_CH)
370 qCritical(
"No EEG channels specified for average reference.");
374 vec_data = ALLOC_CMATRIX_23(1,eegcount);
376 for (k = 0; k < nch; k++)
377 if (chs.at(k).kind == FIFFV_EEG_CH)
378 names.append(chs.at(k).ch_name);
380 for (k = 0; k < eegcount; k++)
381 vec_data[0][k] = 1.0/sqrt((
double)eegcount);
383 QStringList emptyList;
387 mne_proj_op_add_item(op,vecs,FIFFV_MNE_PROJ_ITEM_EEG_AVREF,
"Average EEG reference");
394 int MneProjOp::mne_proj_op_affect(
MneProjOp *op,
const QStringList& list,
int nlist)
402 for (k = 0, naff = 0; k < op->nitems; k++)
403 if (op->items[k]->active && MneProjItem::mne_proj_item_affect(op->items[k],list,nlist))
404 naff += op->items[k]->nvec;
411 int MneProjOp::mne_proj_op_affect_chs(
MneProjOp *op,
const QList<FiffChInfo>& chs,
int nch)
420 ch_string = mne_channel_names_to_string_23(chs,nch);
421 mne_string_to_name_list_23(ch_string,list,nlist);
422 res = mne_proj_op_affect(op,list,nlist);
429 int MneProjOp::mne_proj_op_proj_vector(
MneProjOp *op,
float *vec,
int nvec,
int do_complement)
435 static float *res = NULL;
441 if (!op || op->nitems <= 0 || op->nvec <= 0)
444 if (op->nch != nvec) {
445 printf(
"Data vector size does not match projection operator");
449 if (op->nch > res_size) {
450 res = REALLOC_23(res,op->nch,
float);
454 for (k = 0; k < op->nch; k++)
457 for (p = 0; p < op->nvec; p++) {
458 pvec = op->proj_data[p];
459 w = mne_dot_vectors_23(pvec,vec,op->nch);
460 for (k = 0; k < op->nch; k++)
461 res[k] = res[k] + w*pvec[k];
464 for (k = 0; k < op->nch; k++)
465 vec[k] = vec[k] - res[k];
468 for (k = 0; k < op->nch; k++)
482 QList<FiffDirNode::SPtr> proj;
484 QList<FiffDirNode::SPtr> items;
487 QString item_desc,desc_tag;
488 int global_nchan,item_nchan,nlist;
489 QStringList item_names;
491 float **item_vectors = NULL;
498 qCritical(
"File not open mne_read_proj_op_from_node");
502 if (!start || start->isEmpty())
503 start_node = stream->dirtree();
508 proj = start_node->dir_tree_find(FIFFB_PROJ);
509 if (proj.size() == 0 || proj[0]->isEmpty())
514 items = proj[0]->dir_tree_find(FIFFB_PROJ_ITEM);
515 if (items.size() == 0 || items[0]->isEmpty())
521 if(!node->find_tag(stream,
FIFF_NCHAN, t_pTag))
524 global_nchan = *t_pTag->toInt();
530 for (k = 0; k < items.size(); k++) {
537 if (node->find_tag(stream,
FIFF_NAME, t_pTag)) {
538 item_desc += t_pTag->toString();
545 desc_tag = t_pTag->toString();
547 if((pos = desc_tag.indexOf(
"\n")) >= 0)
548 desc_tag.truncate(pos);
549 if (!item_desc.isEmpty())
551 item_desc += desc_tag;
556 if (!node->find_tag(stream,
FIFF_NCHAN, t_pTag)) {
557 item_nchan = global_nchan;
560 item_nchan = *t_pTag->toInt();
562 if (item_nchan <= 0) {
563 qCritical(
"Number of channels incorrectly specified for one of the projection items.");
569 if (!node->find_tag(stream, FIFF_PROJ_ITEM_CH_NAME_LIST, t_pTag))
572 item_names = FiffStream::split_name_list(t_pTag->toString());
574 if (item_names.size() != item_nchan) {
575 printf(
"Channel name list incorrectly specified for proj item # %d",k+1);
582 if (!node->find_tag(stream, FIFF_PROJ_ITEM_KIND, t_pTag))
584 item_kind = *t_pTag->toInt();
588 if (!node->find_tag(stream,FIFF_PROJ_ITEM_NVEC, t_pTag))
590 item_nvec = *t_pTag->toInt();
594 if (!node->find_tag(stream,FIFF_PROJ_ITEM_VECTORS, t_pTag))
597 MatrixXf tmp_item_vectors = t_pTag->toFloatMatrix().transpose();
598 item_vectors = ALLOC_CMATRIX_23(tmp_item_vectors.rows(),tmp_item_vectors.cols());
599 fromFloatEigenMatrix_23(tmp_item_vectors, item_vectors);
605 item_active = *t_pTag->toInt();
612 QStringList emptyList;
614 mne_proj_op_add_item_act(op,item,item_kind,item_desc,item_active);
616 op->items[op->nitems-1]->active_file = item_active;
631 MneProjOp *MneProjOp::mne_read_proj_op(
const QString &name)
642 res = mne_read_proj_op_from_node(stream,t_default);
651 void MneProjOp::mne_proj_op_report_data(FILE *out,
const char *tag,
MneProjOp *op,
int list_data,
char **exclude,
int nexclude)
665 if (op->nitems <= 0) {
666 fprintf(out,
"Empty operator\n");
670 for (k = 0; k < op->nitems; k++) {
672 if (list_data && tag)
673 fprintf(out,
"%s\n",tag);
675 fprintf(out,
"%s",tag);
676 fprintf(out,
"# %d : %s : %d vecs : %d chs %s %s\n",
677 k+1,it->
desc.toUtf8().constData(),it->
nvec,it->
vecs->ncol,
679 it->
active ?
"active" :
"idle");
680 if (list_data && tag)
681 fprintf(out,
"%s\n",tag);
683 vecs = op->items[k]->vecs;
685 for (q = 0; q < vecs->ncol; q++) {
686 fprintf(out,
"%-10s",vecs->collist[q].toUtf8().constData());
687 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
689 for (p = 0; p < vecs->nrow; p++)
690 for (q = 0; q < vecs->ncol; q++) {
691 for (j = 0, found = 0; j < nexclude; j++) {
692 if (QString::compare(exclude[j],vecs->collist[q]) == 0) {
697 fprintf(out,
"%10.5g ",found ? 0.0 : vecs->data[p][q]);
698 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
700 if (list_data && tag)
701 fprintf(out,
"%s\n",tag);
709 void MneProjOp::mne_proj_op_report(FILE *out,
const char *tag,
MneProjOp *op)
711 mne_proj_op_report_data(out,tag,op, FALSE, NULL, 0);
FiffTag class declaration, which provides fiff tag I/O and processing methods.
One linear projection item.
static MneNamedMatrix * build_named_matrix(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, float **data)
QSharedPointer< FiffTag > SPtr
static void mne_free_proj_op_proj(MneProjOp *op)
MNEProjItem class declaration.
MNEProjOp class declaration.
static QStringList split_name_list(QString p_sNameList)
QSharedPointer< FiffDirNode > SPtr
One linear projection item.
#define FIFF_MNE_PROJ_ITEM_ACTIVE
QSharedPointer< FiffStream > SPtr
Matrix specification with a channel list.