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 , rowlist(NULL)
124 , collist(NULL)
125 , data(NULL)
126 {
127 }
128 
129 //=============================================================================================================
130 
132 {
133  float **data = ALLOC_CMATRIX_14(p_MneNamedMatrix.nrow,p_MneNamedMatrix.ncol);
134  int j,k;
135 
136  for (j = 0; j < p_MneNamedMatrix.nrow; j++)
137  for (k = 0; k < p_MneNamedMatrix.ncol; k++)
138  data[j][k] = p_MneNamedMatrix.data[j][k];
139  MneNamedMatrix* res = build_named_matrix( p_MneNamedMatrix.nrow,p_MneNamedMatrix.ncol,p_MneNamedMatrix.rowlist,p_MneNamedMatrix.collist,data);
140  this->nrow = res->nrow;
141  this->ncol = res->ncol;
142  this->rowlist = res->rowlist;
143  this->collist = res->collist;
144  this->data = res->data;
145 }
146 
147 //=============================================================================================================
148 
150 {
151  FREE_CMATRIX_14(data);
152 }
153 
154 //=============================================================================================================
155 
157  int ncol,
158  const QStringList& rowlist,
159  const QStringList& collist,
160  float **data)
161 {
162  MneNamedMatrix* mat = new MneNamedMatrix;
163  mat->nrow = nrow;
164  mat->ncol = ncol;
165  mat->rowlist = rowlist;
166  mat->collist = collist;
167  mat->data = data;
168  return mat;
169 }
170 
171 //=============================================================================================================
172 
173 MneNamedMatrix *MneNamedMatrix::pick_from_named_matrix(const QStringList& pickrowlist, int picknrow, const QStringList& pickcollist, int pickncol) const
174 {
175  int *pick_row = NULL;
176  int *pick_col = NULL;
177  QStringList my_pickrowlist;
178  QStringList my_pickcollist;
179  float **pickdata = NULL;
180  float **data;
181  int row,j,k;
182  QString one;
183 
184  if (!pickrowlist.isEmpty() && this->rowlist.isEmpty()) {
185  printf("Cannot pick rows: no names for rows in original.");
186  return NULL;
187  }
188  if (!pickcollist.isEmpty() && this->collist.isEmpty()) {
189  printf("Cannot pick columns: no names for columns in original.");
190  return NULL;
191  }
192  if (pickrowlist.isEmpty())
193  picknrow = this->nrow;
194  if (pickcollist.isEmpty())
195  pickncol = this->ncol;
196  pick_row = MALLOC_14(picknrow,int);
197  pick_col = MALLOC_14(pickncol,int);
198  /*
199  * Decide what to pick
200  */
201  if (!pickrowlist.isEmpty()) {
202  for (j = 0; j < picknrow; j++) {
203  one = pickrowlist[j];
204  pick_row[j] = -1;
205  for (k = 0; k < this->nrow; k++) {
206  if (QString::compare(one,this->rowlist[k]) == 0) {
207  pick_row[j] = k;
208  break;
209  }
210  }
211  if (pick_row[j] == -1) {
212  printf("Row called %s not found in original matrix",one.toUtf8().constData());
213  goto bad;
214  }
215  my_pickrowlist = pickrowlist;
216  }
217  }
218  else {
219  for (k = 0; k < picknrow; k++)
220  pick_row[k] = k;
221  my_pickrowlist = this->rowlist;
222  }
223  if (!pickcollist.isEmpty()) {
224  for (j = 0; j < pickncol; j++) {
225  one = pickcollist[j];
226  pick_col[j] = -1;
227  for (k = 0; k < this->ncol; k++) {
228  if (QString::compare(one,this->collist[k]) == 0) {
229  pick_col[j] = k;
230  break;
231  }
232  }
233  if (pick_col[j] == -1) {
234  printf("Column called %s not found in original matrix",one.toUtf8().constData());
235  goto bad;
236  }
237  my_pickcollist = pickcollist;
238  }
239  }
240  else {
241  for (k = 0; k < pickncol; k++)
242  pick_col[k] = k;
243  my_pickcollist = this->collist;
244  }
245  /*
246  * Do the picking of the data accordingly
247  */
248  pickdata = ALLOC_CMATRIX_14(picknrow,pickncol);
249 
250  data = this->data;
251  for (j = 0; j < picknrow; j++) {
252  row = pick_row[j];
253  for (k = 0; k < pickncol; k++)
254  pickdata[j][k] = data[row][pick_col[k]];
255  }
256 
257  FREE_14(pick_col);
258  FREE_14(pick_row);
259  return build_named_matrix(picknrow,pickncol,my_pickrowlist,my_pickcollist,pickdata);
260 
261 bad : {
262  FREE_14(pick_col);
263  FREE_14(pick_row);
264  return NULL;
265  }
266 }
267 
268 //=============================================================================================================
269 
271 {
272  QStringList colnames;
273  QStringList rownames;
274  int ncol = 0;
275  int nrow = 0;
276  qint32 ndim;
277  QVector<qint32> dims;
278  float **data = NULL;
279  QString s;
280  FiffTag::SPtr t_pTag;
281  int k;
282 
283  FiffDirNode::SPtr tmp_node = node;
284 
285  /*
286  * If the node is a named-matrix mode, use it.
287  * Otherwise, look in first-generation children
288  */
289  if (tmp_node->type == FIFFB_MNE_NAMED_MATRIX) {
290  if(!tmp_node->find_tag(stream, kind, t_pTag))
291  goto bad;
292 
293  qint32 ndim;
294  QVector<qint32> dims;
295  t_pTag->getMatrixDimensions(ndim, dims);
296 
297  if (ndim != 2) {
298  qCritical("mne_read_named_matrix only works with two-dimensional matrices");
299  goto bad;
300  }
301 
302  MatrixXf tmp_data = t_pTag->toFloatMatrix().transpose();
303  data = ALLOC_CMATRIX_14(tmp_data.rows(),tmp_data.cols());
304  fromFloatEigenMatrix_14(tmp_data, data);
305  }
306  else {
307  for (k = 0; k < tmp_node->nchild(); k++) {
308  if (tmp_node->children[k]->type == FIFFB_MNE_NAMED_MATRIX) {
309  if(tmp_node->children[k]->find_tag(stream, kind, t_pTag)) {
310  t_pTag->getMatrixDimensions(ndim, dims);
311  if (ndim != 2) {
312  qCritical("mne_read_named_matrix only works with two-dimensional matrices");
313  goto bad;
314  }
315 
316  MatrixXf tmp_data = t_pTag->toFloatMatrix().transpose();
317  data = ALLOC_CMATRIX_14(tmp_data.rows(),tmp_data.cols());
318  fromFloatEigenMatrix_14(tmp_data, data);
319 
320  tmp_node = tmp_node->children[k];
321  break;
322  }
323  }
324  }
325  if (!data)
326  goto bad;
327  }
328  /*
329  * Separate FIFF_MNE_NROW is now optional
330  */
331  if (!tmp_node->find_tag(stream, FIFF_MNE_NROW, t_pTag))
332  nrow = dims[0];
333  else {
334  nrow = *t_pTag->toInt();
335  if (nrow != dims[0]) {
336  qCritical("Number of rows in the FIFF_MNE_NROW tag and in the matrix data conflict.");
337  goto bad;
338  }
339  }
340  /*
341  * Separate FIFF_MNE_NCOL is now optional
342  */
343  if(!tmp_node->find_tag(stream, FIFF_MNE_NCOL, t_pTag))
344  ncol = dims[1];
345  else {
346  ncol = *t_pTag->toInt();
347  if (ncol != dims[1]) {
348  qCritical("Number of columns in the FIFF_MNE_NCOL tag and in the matrix data conflict.");
349  goto bad;
350  }
351  }
352  if(!tmp_node->find_tag(stream, FIFF_MNE_ROW_NAMES, t_pTag)) {
353  s = t_pTag->toString();
354  rownames = FiffStream::split_name_list(s);
355  if (rownames.size() != nrow) {
356  qCritical("Incorrect number of entries in the row name list");
357  nrow = rownames.size();
358  goto bad;
359  }
360  }
361  if(!tmp_node->find_tag(stream, FIFF_MNE_COL_NAMES, t_pTag)) {
362  s = t_pTag->toString();
363  colnames = FiffStream::split_name_list(s);
364  if (colnames.size() != ncol) {
365  qCritical("Incorrect number of entries in the column name list");
366  ncol = colnames.size();
367  goto bad;
368  }
369  }
370  return build_named_matrix(nrow,ncol,rownames,colnames,data);
371 
372 bad : {
373  FREE_CMATRIX_14(data);
374  return NULL;
375  }
376 }
MneNamedMatrix * pick_from_named_matrix(const QStringList &pickrowlist, int picknrow, const QStringList &pickcollist, int pickncol) const
FiffStream class declaration.
QSharedPointer< FiffDirNode > SPtr
Definition: fiff_dir_node.h:77
Fiff constants.
MNE Named Matrix (MneNamedMatrix) class declaration.
QSharedPointer< FiffTag > SPtr
Definition: fiff_tag.h:152
static MneNamedMatrix * build_named_matrix(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, float **data)
Matrix specification with a channel list.
static MneNamedMatrix * read_named_matrix(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &node, int kind)
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:107
FiffTag class declaration, which provides fiff tag I/O and processing methods.