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;
206 using namespace FIFFLIB;
207 using namespace MNELIB;
213 MneProjOp::MneProjOp()
226 for (
int k = 0;
k < nitems;
k++)
240 FREE_CMATRIX_23(op->proj_data);
245 op->proj_data = NULL;
263 for (
k = 0;
k < from->nitems;
k++) {
266 to->items[to->nitems-1]->active_file = it->
active_file;
274 void MneProjOp::mne_proj_op_add_item_act(
MneProjOp *op,
MneNamedMatrix *vecs,
int kind,
const QString& desc,
int is_active)
286 op->items.append(new_item);
288 new_item->
active = is_active;
291 if (kind == FIFFV_MNE_PROJ_ITEM_EEG_AVREF) {
296 for (
k = 0;
k < vecs->ncol;
k++) {
297 if (vecs->collist[
k].contains(
"EEG"))
299 if (vecs->collist[
k].contains(
"MEG"))
312 new_item->
desc = desc;
313 new_item->
kind = kind;
314 new_item->
nvec = new_item->
vecs->nrow;
326 mne_proj_op_add_item_act(op, vecs, kind, desc, TRUE);
343 for (
k = 0;
k < op->nitems;
k++) {
353 MneProjOp *MneProjOp::mne_proj_op_average_eeg_ref(
const QList<FiffChInfo>& chs,
int nch)
365 for (
k = 0;
k < nch;
k++)
366 if (chs.at(
k).kind == FIFFV_EEG_CH)
369 qCritical(
"No EEG channels specified for average reference.");
373 vec_data = ALLOC_CMATRIX_23(1,eegcount);
375 for (
k = 0;
k < nch;
k++)
376 if (chs.at(
k).kind == FIFFV_EEG_CH)
377 names.append(chs.at(
k).ch_name);
379 for (
k = 0;
k < eegcount;
k++)
380 vec_data[0][
k] = 1.0/sqrt((
double)eegcount);
382 QStringList emptyList;
386 mne_proj_op_add_item(op,vecs,FIFFV_MNE_PROJ_ITEM_EEG_AVREF,
"Average EEG reference");
393 int MneProjOp::mne_proj_op_affect(
MneProjOp *op,
const QStringList& list,
int nlist)
401 for (
k = 0, naff = 0;
k < op->nitems;
k++)
402 if (op->items[
k]->active && MneProjItem::mne_proj_item_affect(op->items[
k],list,nlist))
403 naff += op->items[
k]->nvec;
410 int MneProjOp::mne_proj_op_affect_chs(
MneProjOp *op,
const QList<FiffChInfo>& chs,
int nch)
419 ch_string = mne_channel_names_to_string_23(chs,nch);
420 mne_string_to_name_list_23(ch_string,list,nlist);
421 res = mne_proj_op_affect(op,list,nlist);
428 int MneProjOp::mne_proj_op_proj_vector(
MneProjOp *op,
float *vec,
int nvec,
int do_complement)
434 static float *res = NULL;
440 if (!op || op->nitems <= 0 || op->nvec <= 0)
443 if (op->nch != nvec) {
444 printf(
"Data vector size does not match projection operator");
448 if (op->nch > res_size) {
449 res = REALLOC_23(res,op->nch,
float);
453 for (
k = 0;
k < op->nch;
k++)
456 for (p = 0; p < op->nvec; p++) {
457 pvec = op->proj_data[p];
458 w = mne_dot_vectors_23(pvec,vec,op->nch);
459 for (
k = 0;
k < op->nch;
k++)
460 res[
k] = res[
k] + w*pvec[
k];
463 for (
k = 0;
k < op->nch;
k++)
464 vec[
k] = vec[
k] - res[
k];
467 for (
k = 0;
k < op->nch;
k++)
481 QList<FiffDirNode::SPtr> proj;
483 QList<FiffDirNode::SPtr> items;
486 QString item_desc,desc_tag;
487 int global_nchan,item_nchan;
488 QStringList item_names;
490 float **item_vectors = NULL;
497 qCritical(
"File not open mne_read_proj_op_from_node");
501 if (!start || start->isEmpty())
502 start_node = stream->dirtree();
507 proj = start_node->dir_tree_find(FIFFB_PROJ);
508 if (proj.size() == 0 || proj[0]->isEmpty())
513 items = proj[0]->dir_tree_find(FIFFB_PROJ_ITEM);
514 if (items.size() == 0 || items[0]->isEmpty())
520 if(!node->find_tag(stream,
FIFF_NCHAN, t_pTag))
523 global_nchan = *t_pTag->toInt();
529 for (
k = 0;
k < items.size();
k++) {
536 if (node->find_tag(stream,
FIFF_NAME, t_pTag)) {
537 item_desc += t_pTag->toString();
544 desc_tag = t_pTag->toString();
546 if((pos = desc_tag.indexOf(
"\n")) >= 0)
547 desc_tag.truncate(pos);
548 if (!item_desc.isEmpty())
550 item_desc += desc_tag;
555 if (!node->find_tag(stream,
FIFF_NCHAN, t_pTag)) {
556 item_nchan = global_nchan;
559 item_nchan = *t_pTag->toInt();
561 if (item_nchan <= 0) {
562 qCritical(
"Number of channels incorrectly specified for one of the projection items.");
568 if (!node->find_tag(stream, FIFF_PROJ_ITEM_CH_NAME_LIST, t_pTag))
571 item_names = FiffStream::split_name_list(t_pTag->toString());
573 if (item_names.size() != item_nchan) {
574 printf(
"Channel name list incorrectly specified for proj item # %d",
k+1);
581 if (!node->find_tag(stream, FIFF_PROJ_ITEM_KIND, t_pTag))
583 item_kind = *t_pTag->toInt();
587 if (!node->find_tag(stream,FIFF_PROJ_ITEM_NVEC, t_pTag))
589 item_nvec = *t_pTag->toInt();
593 if (!node->find_tag(stream,FIFF_PROJ_ITEM_VECTORS, t_pTag))
596 MatrixXf tmp_item_vectors = t_pTag->toFloatMatrix().transpose();
597 item_vectors = ALLOC_CMATRIX_23(tmp_item_vectors.rows(),tmp_item_vectors.cols());
598 fromFloatEigenMatrix_23(tmp_item_vectors, item_vectors);
604 item_active = *t_pTag->toInt();
611 QStringList emptyList;
613 mne_proj_op_add_item_act(op,item,item_kind,item_desc,item_active);
615 op->items[op->nitems-1]->active_file = item_active;
630 MneProjOp *MneProjOp::mne_read_proj_op(
const QString &name)
641 res = mne_read_proj_op_from_node(stream,t_default);
650 void MneProjOp::mne_proj_op_report_data(FILE *out,
const char *tag,
MneProjOp *op,
int list_data,
char **exclude,
int nexclude)
664 if (op->nitems <= 0) {
665 fprintf(out,
"Empty operator\n");
669 for (
k = 0;
k < op->nitems;
k++) {
671 if (list_data && tag)
672 fprintf(out,
"%s\n",tag);
674 fprintf(out,
"%s",tag);
675 fprintf(out,
"# %d : %s : %d vecs : %d chs %s %s\n",
678 it->
active ?
"active" :
"idle");
679 if (list_data && tag)
680 fprintf(out,
"%s\n",tag);
682 vecs = op->items[
k]->vecs;
684 for (q = 0; q < vecs->ncol; q++) {
685 fprintf(out,
"%-10s",vecs->collist[q].toUtf8().constData());
686 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
688 for (p = 0; p < vecs->nrow; p++)
689 for (q = 0; q < vecs->ncol; q++) {
690 for (j = 0, found = 0; j < nexclude; j++) {
691 if (QString::compare(exclude[j],vecs->collist[q]) == 0) {
696 fprintf(out,
"%10.5g ",found ? 0.0 : vecs->data[p][q]);
697 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
699 if (list_data && tag)
700 fprintf(out,
"%s\n",tag);
708 void MneProjOp::mne_proj_op_report(FILE *out,
const char *tag,
MneProjOp *op)
710 mne_proj_op_report_data(out,tag,op, FALSE, NULL, 0);