MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
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
50using namespace Eigen;
51using namespace MNELIB;
52using 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
58static 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
75float **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
96void mne_free_cmatrix_14 (float **m)
97{
98 if (m) {
99 FREE_14(*m);
100 FREE_14(m);
101 }
102}
103
104void 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
111void 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
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{
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
171MneNamedMatrix *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
259bad : {
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
370bad : {
371 FREE_CMATRIX_14(data);
372 return NULL;
373 }
374}
FiffTag class declaration, which provides fiff tag I/O and processing methods.
Fiff constants.
FiffStream class declaration.
int k
Definition fiff_tag.cpp:324
MNE Named Matrix (MneNamedMatrix) class declaration.
QSharedPointer< FiffDirNode > SPtr
static QStringList split_name_list(QString p_sNameList)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
Definition fiff_tag.h:152
Matrix specification with a channel list.
static MneNamedMatrix * read_named_matrix(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &node, int kind)
static MneNamedMatrix * build_named_matrix(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, float **data)
MneNamedMatrix * pick_from_named_matrix(const QStringList &pickrowlist, int picknrow, const QStringList &pickcollist, int pickncol) const