MNE-CPP  0.1.9
A Framework for Electrophysiology
mne_named_matrix.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "mne_named_matrix.h"
42 #include <fiff/fiff_constants.h>
43 #include <fiff/fiff_stream.h>
44 #include <fiff/fiff_tag.h>
45 
46 //=============================================================================================================
47 // USED NAMESPACES
48 //=============================================================================================================
49 
50 using namespace Eigen;
51 using namespace MNELIB;
52 using namespace FIFFLIB;
53 
54 #define MALLOC_14(x,t) (t *)malloc((x)*sizeof(t))
55 #define REALLOC_14(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
56 #define ALLOC_CMATRIX_14(x,y) mne_cmatrix_14((x),(y))
57 
58 static void matrix_error_14(int kind, int nr, int nc)
59 
60 {
61  if (kind == 1)
62  printf("Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
63  else if (kind == 2)
64  printf("Failed to allocate memory for a %d x %d matrix\n",nr,nc);
65  else
66  printf("Allocation error for a %d x %d matrix\n",nr,nc);
67  if (sizeof(void *) == 4) {
68  printf("This is probably because you seem to be using a computer with 32-bit architecture.\n");
69  printf("Please consider moving to a 64-bit platform.");
70  }
71  printf("Cannot continue. Sorry.\n");
72  exit(1);
73 }
74 
75 float **mne_cmatrix_14(int nr,int nc)
76 
77 {
78  int i;
79  float **m;
80  float *whole;
81 
82  m = MALLOC_14(nr,float *);
83  if (!m) matrix_error_14(1,nr,nc);
84  whole = MALLOC_14(nr*nc,float);
85  if (!whole) matrix_error_14(2,nr,nc);
86 
87  for(i=0;i<nr;i++)
88  m[i] = whole + i*nc;
89  return m;
90 }
91 
92 #define FREE_14(x) if ((char *)(x) != NULL) free((char *)(x))
93 
94 #define FREE_CMATRIX_14(m) mne_free_cmatrix_14((m))
95 
96 void mne_free_cmatrix_14 (float **m)
97 {
98  if (m) {
99  FREE_14(*m);
100  FREE_14(m);
101  }
102 }
103 
104 void fromFloatEigenMatrix_14(const Eigen::MatrixXf& from_mat, float **& to_mat, const int m, const int n)
105 {
106  for ( int i = 0; i < m; ++i)
107  for ( int j = 0; j < n; ++j)
108  to_mat[i][j] = from_mat(i,j);
109 }
110 
111 void fromFloatEigenMatrix_14(const Eigen::MatrixXf& from_mat, float **& to_mat)
112 {
113  fromFloatEigenMatrix_14(from_mat, to_mat, from_mat.rows(), from_mat.cols());
114 }
115 
116 //=============================================================================================================
117 // DEFINE MEMBER METHODS
118 //=============================================================================================================
119 
120 MneNamedMatrix::MneNamedMatrix()
121 : nrow(0)
122 , ncol(0)
123 , data(NULL)
124 {
125 }
126 
127 //=============================================================================================================
128 
130 {
131  float **data = ALLOC_CMATRIX_14(p_MneNamedMatrix.nrow,p_MneNamedMatrix.ncol);
132  int j,k;
133 
134  for (j = 0; j < p_MneNamedMatrix.nrow; j++)
135  for (k = 0; k < p_MneNamedMatrix.ncol; k++)
136  data[j][k] = p_MneNamedMatrix.data[j][k];
137  MneNamedMatrix* res = build_named_matrix( p_MneNamedMatrix.nrow,p_MneNamedMatrix.ncol,p_MneNamedMatrix.rowlist,p_MneNamedMatrix.collist,data);
138  this->nrow = res->nrow;
139  this->ncol = res->ncol;
140  this->rowlist = res->rowlist;
141  this->collist = res->collist;
142  this->data = res->data;
143 }
144 
145 //=============================================================================================================
146 
148 {
149  FREE_CMATRIX_14(data);
150 }
151 
152 //=============================================================================================================
153 
155  int ncol,
156  const QStringList& rowlist,
157  const QStringList& collist,
158  float **data)
159 {
160  MneNamedMatrix* mat = new MneNamedMatrix;
161  mat->nrow = nrow;
162  mat->ncol = ncol;
163  mat->rowlist = rowlist;
164  mat->collist = collist;
165  mat->data = data;
166  return mat;
167 }
168 
169 //=============================================================================================================
170 
171 MneNamedMatrix *MneNamedMatrix::pick_from_named_matrix(const QStringList& pickrowlist, int picknrow, const QStringList& pickcollist, int pickncol) const
172 {
173  int *pick_row = NULL;
174  int *pick_col = NULL;
175  QStringList my_pickrowlist;
176  QStringList my_pickcollist;
177  float **pickdata = NULL;
178  float **data;
179  int row,j,k;
180  QString one;
181 
182  if (!pickrowlist.isEmpty() && this->rowlist.isEmpty()) {
183  printf("Cannot pick rows: no names for rows in original.");
184  return NULL;
185  }
186  if (!pickcollist.isEmpty() && this->collist.isEmpty()) {
187  printf("Cannot pick columns: no names for columns in original.");
188  return NULL;
189  }
190  if (pickrowlist.isEmpty())
191  picknrow = this->nrow;
192  if (pickcollist.isEmpty())
193  pickncol = this->ncol;
194  pick_row = MALLOC_14(picknrow,int);
195  pick_col = MALLOC_14(pickncol,int);
196  /*
197  * Decide what to pick
198  */
199  if (!pickrowlist.isEmpty()) {
200  for (j = 0; j < picknrow; j++) {
201  one = pickrowlist[j];
202  pick_row[j] = -1;
203  for (k = 0; k < this->nrow; k++) {
204  if (QString::compare(one,this->rowlist[k]) == 0) {
205  pick_row[j] = k;
206  break;
207  }
208  }
209  if (pick_row[j] == -1) {
210  printf("Row called %s not found in original matrix",one.toUtf8().constData());
211  goto bad;
212  }
213  my_pickrowlist = pickrowlist;
214  }
215  }
216  else {
217  for (k = 0; k < picknrow; k++)
218  pick_row[k] = k;
219  my_pickrowlist = this->rowlist;
220  }
221  if (!pickcollist.isEmpty()) {
222  for (j = 0; j < pickncol; j++) {
223  one = pickcollist[j];
224  pick_col[j] = -1;
225  for (k = 0; k < this->ncol; k++) {
226  if (QString::compare(one,this->collist[k]) == 0) {
227  pick_col[j] = k;
228  break;
229  }
230  }
231  if (pick_col[j] == -1) {
232  printf("Column called %s not found in original matrix",one.toUtf8().constData());
233  goto bad;
234  }
235  my_pickcollist = pickcollist;
236  }
237  }
238  else {
239  for (k = 0; k < pickncol; k++)
240  pick_col[k] = k;
241  my_pickcollist = this->collist;
242  }
243  /*
244  * Do the picking of the data accordingly
245  */
246  pickdata = ALLOC_CMATRIX_14(picknrow,pickncol);
247 
248  data = this->data;
249  for (j = 0; j < picknrow; j++) {
250  row = pick_row[j];
251  for (k = 0; k < pickncol; k++)
252  pickdata[j][k] = data[row][pick_col[k]];
253  }
254 
255  FREE_14(pick_col);
256  FREE_14(pick_row);
257  return build_named_matrix(picknrow,pickncol,my_pickrowlist,my_pickcollist,pickdata);
258 
259 bad : {
260  FREE_14(pick_col);
261  FREE_14(pick_row);
262  return NULL;
263  }
264 }
265 
266 //=============================================================================================================
267 
269 {
270  QStringList colnames;
271  QStringList rownames;
272  int ncol = 0;
273  int nrow = 0;
274  qint32 ndim;
275  QVector<qint32> dims;
276  float **data = NULL;
277  QString s;
278  FiffTag::SPtr t_pTag;
279  int k;
280 
281  FiffDirNode::SPtr tmp_node = node;
282 
283  /*
284  * If the node is a named-matrix mode, use it.
285  * Otherwise, look in first-generation children
286  */
287  if (tmp_node->type == FIFFB_MNE_NAMED_MATRIX) {
288  if(!tmp_node->find_tag(stream, kind, t_pTag))
289  goto bad;
290 
291  qint32 ndim;
292  QVector<qint32> dims;
293  t_pTag->getMatrixDimensions(ndim, dims);
294 
295  if (ndim != 2) {
296  qCritical("mne_read_named_matrix only works with two-dimensional matrices");
297  goto bad;
298  }
299 
300  MatrixXf tmp_data = t_pTag->toFloatMatrix().transpose();
301  data = ALLOC_CMATRIX_14(tmp_data.rows(),tmp_data.cols());
302  fromFloatEigenMatrix_14(tmp_data, data);
303  }
304  else {
305  for (k = 0; k < tmp_node->nchild(); k++) {
306  if (tmp_node->children[k]->type == FIFFB_MNE_NAMED_MATRIX) {
307  if(tmp_node->children[k]->find_tag(stream, kind, t_pTag)) {
308  t_pTag->getMatrixDimensions(ndim, dims);
309  if (ndim != 2) {
310  qCritical("mne_read_named_matrix only works with two-dimensional matrices");
311  goto bad;
312  }
313 
314  MatrixXf tmp_data = t_pTag->toFloatMatrix().transpose();
315  data = ALLOC_CMATRIX_14(tmp_data.rows(),tmp_data.cols());
316  fromFloatEigenMatrix_14(tmp_data, data);
317 
318  tmp_node = tmp_node->children[k];
319  break;
320  }
321  }
322  }
323  if (!data)
324  goto bad;
325  }
326  /*
327  * Separate FIFF_MNE_NROW is now optional
328  */
329  if (!tmp_node->find_tag(stream, FIFF_MNE_NROW, t_pTag))
330  nrow = dims[0];
331  else {
332  nrow = *t_pTag->toInt();
333  if (nrow != dims[0]) {
334  qCritical("Number of rows in the FIFF_MNE_NROW tag and in the matrix data conflict.");
335  goto bad;
336  }
337  }
338  /*
339  * Separate FIFF_MNE_NCOL is now optional
340  */
341  if(!tmp_node->find_tag(stream, FIFF_MNE_NCOL, t_pTag))
342  ncol = dims[1];
343  else {
344  ncol = *t_pTag->toInt();
345  if (ncol != dims[1]) {
346  qCritical("Number of columns in the FIFF_MNE_NCOL tag and in the matrix data conflict.");
347  goto bad;
348  }
349  }
350  if(!tmp_node->find_tag(stream, FIFF_MNE_ROW_NAMES, t_pTag)) {
351  s = t_pTag->toString();
352  rownames = FiffStream::split_name_list(s);
353  if (rownames.size() != nrow) {
354  qCritical("Incorrect number of entries in the row name list");
355  nrow = rownames.size();
356  goto bad;
357  }
358  }
359  if(!tmp_node->find_tag(stream, FIFF_MNE_COL_NAMES, t_pTag)) {
360  s = t_pTag->toString();
361  colnames = FiffStream::split_name_list(s);
362  if (colnames.size() != ncol) {
363  qCritical("Incorrect number of entries in the column name list");
364  ncol = colnames.size();
365  goto bad;
366  }
367  }
368  return build_named_matrix(nrow,ncol,rownames,colnames,data);
369 
370 bad : {
371  FREE_CMATRIX_14(data);
372  return NULL;
373  }
374 }
MNELIB::MneNamedMatrix::pick_from_named_matrix
MneNamedMatrix * pick_from_named_matrix(const QStringList &pickrowlist, int picknrow, const QStringList &pickcollist, int pickncol) const
Definition: mne_named_matrix.cpp:171
fiff_tag.h
FiffTag class declaration, which provides fiff tag I/O and processing methods.
FIFFLIB::FiffStream::SPtr
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:107
FIFFLIB::FiffDirNode::SPtr
QSharedPointer< FiffDirNode > SPtr
Definition: fiff_dir_node.h:76
fiff_stream.h
FiffStream class declaration.
k
int k
Definition: fiff_tag.cpp:322
MNELIB::MneNamedMatrix::MneNamedMatrix
MneNamedMatrix()
Definition: mne_named_matrix.cpp:120
MNELIB::MneNamedMatrix::build_named_matrix
static MneNamedMatrix * build_named_matrix(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, float **data)
Definition: mne_named_matrix.cpp:154
fiff_constants.h
Fiff constants.
FIFFLIB::FiffTag::SPtr
QSharedPointer< FiffTag > SPtr
Definition: fiff_tag.h:152
MNELIB::MneNamedMatrix
Matrix specification with a channel list.
Definition: mne_named_matrix.h:84
mne_named_matrix.h
MNE Named Matrix (MneNamedMatrix) class declaration.
MNELIB::MneNamedMatrix::read_named_matrix
static MneNamedMatrix * read_named_matrix(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &node, int kind)
Definition: mne_named_matrix.cpp:268
MNELIB::MneNamedMatrix::~MneNamedMatrix
~MneNamedMatrix()
Definition: mne_named_matrix.cpp:147