File indexing completed on 2024-12-22 04:17:16
0001 /*************************************************************************** 0002 * * 0003 * copyright : (C) 2007 The University of Toronto * 0004 * netterfield@astro.utoronto.ca * 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 ***************************************************************************/ 0012 0013 #include "matlab.h" 0014 0015 #include <QXmlStreamWriter> 0016 #include <QFileInfo> 0017 0018 using namespace Kst; 0019 0020 // Define enum to handle the various classes of variables with readable code 0021 // (taken from matio 1.3.4, file mat5.c static const char *class_type_desc at line 33 0022 // and turned into an enum). Some overlap with the data type, see below. I don't exactly 0023 // understand why... 0024 enum matio_class_type {UNDEFINED_CT, 0025 CELL_ARRAY_CT, 0026 STRUCTURE_CT, 0027 OBJECT_CT, 0028 CHARACTER_ARRAY_CT, 0029 SPARSE_ARRAY_CT, 0030 DOUBLE_PRECISION_ARRAY_CT, 0031 SINGLE_PRECISION_ARRAY_CT, 0032 EIGHT_BIT_SIGNED_INT_ARRAY_CT, 0033 EIGHT_BIT_UNSIGNED_INT_ARRAY_CT, 0034 SIXTEEN_BIT_SIGNED_INT_ARRAY_CT, 0035 SIXTEEN_BIT_UNSIGNED_INT_ARRAY_CT, 0036 THIRTYTWO_BIT_SIGNED_INT_ARRAY_CT, 0037 THIRTYTWO_BIT_UNSIGNED_INT_ARRAY_CT, 0038 MATLAB_ARRAY_CT, 0039 COMPRESSED_DATA_CT}; 0040 0041 // Define enum to handle the various data types with readable code 0042 // (taken from matio 1.3.4, file mat5.c static const char *data_type_desc at line 39) 0043 enum matio_data_type {UNKNOWN_DT, 0044 EIGHT_BIT_SIGNED_INT_DT, 0045 EIGHT_BIT_UNSIGNED_INT_DT, 0046 SIXTEEN_BIT_SIGNED_INT_DT, 0047 SIXTEEN_BIT_UNSIGNED_INT_DT, 0048 THIRTYTWO_BIT_SIGNED_INT_DT, 0049 THIRTYTWO_BIT_UNSIGNED_INT_DT, 0050 IEEE_754_SINGLE_PRECISION_DT, 0051 RESERVED_1_DT, 0052 IEEE_754_DOUBLE_PRECISION_DT, 0053 RESERVED_2_DT, 0054 RESERVED_3_DT, 0055 SIXTYFOUR_BIT_SIGNED_INT_DT, 0056 SIXTYFOUR_BIT_UNSIGNED_INT_DT, 0057 MATLAB_ARRAY_DT, 0058 COMPRESSED_DATA_DT, 0059 UTF8_CHARACTER_DATA_DT, 0060 UTF16_CHARACTER_DATA_DT, 0061 UTF32_CHARACTER_DATA_DT, 0062 STRING_DT, 0063 CELL_ARRAY_DT, 0064 STRUCTURE_DT}; 0065 0066 0067 // 0068 // Scalar interface 0069 // 0070 0071 class DataInterfaceMatlabScalar : public DataSource::DataInterface<DataScalar> 0072 { 0073 public: 0074 DataInterfaceMatlabScalar(MatlabSource& s) : matlab(s) {} 0075 0076 // read one element 0077 int read(const QString&, DataScalar::ReadInfo&); 0078 0079 // named elements 0080 QStringList list() const { return matlab._scalarList; } 0081 bool isListComplete() const { return true; } 0082 bool isValid(const QString&) const; 0083 0084 // T specific 0085 const DataScalar::DataInfo dataInfo(const QString&, int frame=0) const { Q_UNUSED(frame) return DataScalar::DataInfo(); } 0086 void setDataInfo(const QString&, const DataScalar::DataInfo&) {} 0087 0088 // meta data 0089 QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); } 0090 QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); } 0091 0092 0093 private: 0094 MatlabSource& matlab; 0095 }; 0096 0097 0098 int DataInterfaceMatlabScalar::read(const QString& scalar, DataScalar::ReadInfo& p) 0099 { 0100 return matlab.readScalar(p.value, scalar); 0101 } 0102 0103 0104 bool DataInterfaceMatlabScalar::isValid(const QString& scalar) const 0105 { 0106 return matlab._scalarList.contains( scalar ); 0107 } 0108 0109 0110 // 0111 // String interface 0112 // 0113 0114 class DataInterfaceMatlabString : public DataSource::DataInterface<DataString> 0115 { 0116 public: 0117 DataInterfaceMatlabString(MatlabSource& s) : matlab(s) {} 0118 0119 // read one element 0120 int read(const QString&, DataString::ReadInfo&); 0121 0122 // named elements 0123 QStringList list() const { return matlab._strings.keys(); } 0124 bool isListComplete() const { return true; } 0125 bool isValid(const QString&) const; 0126 0127 // T specific 0128 const DataString::DataInfo dataInfo(const QString&, int frame=0) const { Q_UNUSED(frame) return DataString::DataInfo(); } 0129 void setDataInfo(const QString&, const DataString::DataInfo&) {} 0130 0131 // meta data 0132 QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); } 0133 QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); } 0134 0135 0136 private: 0137 MatlabSource& matlab; 0138 }; 0139 0140 0141 int DataInterfaceMatlabString::read(const QString& string, DataString::ReadInfo& p) 0142 { 0143 if (isValid(string) && p.value) { 0144 *p.value = matlab._strings[string]; 0145 return 1; 0146 } 0147 return 0; 0148 } 0149 0150 0151 bool DataInterfaceMatlabString::isValid(const QString& string) const 0152 { 0153 return matlab._strings.contains( string ); 0154 } 0155 0156 0157 0158 0159 /********************** 0160 Vector interface 0161 ***********************/ 0162 0163 class DataInterfaceMatlabVector : public DataSource::DataInterface<DataVector> 0164 { 0165 public: 0166 DataInterfaceMatlabVector(MatlabSource& s) : matlab(s) {} 0167 0168 // read one element 0169 int read(const QString&, DataVector::ReadInfo&); 0170 0171 // named elements 0172 QStringList list() const { return matlab._fieldList; } 0173 bool isListComplete() const { return true; } 0174 bool isValid(const QString&) const; 0175 0176 // T specific 0177 const DataVector::DataInfo dataInfo(const QString&, int frame = 0) const; 0178 void setDataInfo(const QString&, const DataVector::DataInfo&) {} 0179 0180 // meta data 0181 QMap<QString, double> metaScalars(const QString&); 0182 QMap<QString, QString> metaStrings(const QString&); 0183 0184 0185 private: 0186 MatlabSource& matlab; 0187 }; 0188 0189 0190 const DataVector::DataInfo DataInterfaceMatlabVector::dataInfo(const QString &field, int) const 0191 { 0192 if (!matlab._fieldList.contains(field)) 0193 return DataVector::DataInfo(); 0194 0195 return DataVector::DataInfo(matlab.frameCount(field), matlab.samplesPerFrame(field)); 0196 } 0197 0198 0199 0200 int DataInterfaceMatlabVector::read(const QString& field, DataVector::ReadInfo& p) 0201 { 0202 return matlab.readField(p.data, field, p.startingFrame, p.numberOfFrames); 0203 } 0204 0205 0206 bool DataInterfaceMatlabVector::isValid(const QString& field) const 0207 { 0208 return matlab._fieldList.contains( field ); 0209 } 0210 0211 QMap<QString, double> DataInterfaceMatlabVector::metaScalars(const QString& field) 0212 { 0213 Q_UNUSED(field); 0214 QMap<QString, double> fieldScalars; 0215 return fieldScalars; 0216 } 0217 0218 QMap<QString, QString> DataInterfaceMatlabVector::metaStrings(const QString& field) 0219 { 0220 QMap<QString, QString> fieldStrings; 0221 return fieldStrings; 0222 } 0223 0224 0225 0226 // 0227 // Matrix interface 0228 // 0229 0230 class DataInterfaceMatlabMatrix : public DataSource::DataInterface<DataMatrix> 0231 { 0232 public: 0233 0234 DataInterfaceMatlabMatrix(MatlabSource& s) : matlab(s) {} 0235 0236 // read one element 0237 int read(const QString&, DataMatrix::ReadInfo&); 0238 0239 // named elements 0240 QStringList list() const { return matlab._matrixList; } 0241 bool isListComplete() const { return true; } 0242 bool isValid(const QString&) const; 0243 0244 // T specific 0245 const DataMatrix::DataInfo dataInfo (const QString&, int frame = 0) const; 0246 void setDataInfo(const QString&, const DataMatrix::DataInfo&) {} 0247 0248 // meta data 0249 QMap<QString, double> metaScalars(const QString&) { return QMap<QString, double>(); } 0250 QMap<QString, QString> metaStrings(const QString&) { return QMap<QString, QString>(); } 0251 0252 0253 private: 0254 MatlabSource& matlab; 0255 }; 0256 0257 0258 const DataMatrix::DataInfo DataInterfaceMatlabMatrix::dataInfo(const QString& matrix, int) const 0259 { 0260 if (!matlab._matrixList.contains( matrix ) ) { 0261 return DataMatrix::DataInfo(); 0262 } 0263 0264 QByteArray bytes = matrix.toLatin1(); 0265 matvar_t *matvar = Mat_VarRead(matlab._matfile, bytes.data()); 0266 if (!matvar) { 0267 return DataMatrix::DataInfo(); 0268 } 0269 0270 if (matvar->rank != 2) { 0271 return DataMatrix::DataInfo(); 0272 } 0273 0274 DataMatrix::DataInfo info; 0275 info.xSize = matvar->dims[0]; 0276 info.ySize = matvar->dims[1]; 0277 0278 Mat_VarFree(matvar); 0279 0280 return info; 0281 } 0282 0283 0284 int DataInterfaceMatlabMatrix::read(const QString& field, DataMatrix::ReadInfo& p) 0285 { 0286 int count = matlab.readMatrix(p.data->z, field); 0287 0288 p.data->xMin = 0; 0289 p.data->yMin = 0; 0290 p.data->xStepSize = 1; 0291 p.data->yStepSize = 1; 0292 0293 return count; 0294 } 0295 0296 0297 bool DataInterfaceMatlabMatrix::isValid(const QString& field) const { 0298 return matlab._matrixList.contains( field ); 0299 } 0300 0301 0302 0303 /********************** 0304 MatlabDatasourceSource - This class defines the main DataSource which derives from DataSource. 0305 The key functions that this class must provide is the ability to create the source, provide details about the source 0306 be able to process the data. 0307 0308 ***********************/ 0309 MatlabSource::MatlabSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) 0310 : Kst::DataSource(store, cfg, filename, type), 0311 _matfile(0L), 0312 _config(0L), 0313 is(new DataInterfaceMatlabScalar(*this)), 0314 it(new DataInterfaceMatlabString(*this)), 0315 iv(new DataInterfaceMatlabVector(*this)), 0316 im(new DataInterfaceMatlabMatrix(*this)) 0317 { 0318 setInterface(is); 0319 setInterface(it); 0320 setInterface(iv); 0321 setInterface(im); 0322 0323 setUpdateType(None); 0324 0325 if (!type.isEmpty() && type != "Matlab") { 0326 return; 0327 } 0328 0329 _valid = false; 0330 _maxFrameCount = 0; 0331 0332 _filename = filename; 0333 0334 if (init()) { 0335 _valid = true; 0336 } 0337 0338 registerChange(); 0339 } 0340 0341 0342 0343 MatlabSource::~MatlabSource() { 0344 Mat_Close(_matfile); 0345 _matfile = 0L; 0346 } 0347 0348 0349 void MatlabSource::reset() { 0350 Mat_Close(_matfile); 0351 _matfile = 0L; 0352 _maxFrameCount = 0; 0353 _valid = init(); 0354 } 0355 0356 0357 // If the datasource has any predefined fields they should be populated here. 0358 bool MatlabSource::init() { 0359 // First, try to open the file 0360 _matfile = Mat_Open(_filename.toStdString().c_str(),MAT_ACC_RDONLY); 0361 if (!_matfile) { 0362 _valid = false; 0363 return false; 0364 } 0365 0366 _scalarList.clear(); 0367 _fieldList.clear(); 0368 _matrixList.clear(); 0369 _strings.clear(); 0370 0371 // Some standard stuff 0372 _fieldList += "INDEX"; 0373 _strings = fileMetas(); 0374 0375 _maxFrameCount = 0; 0376 0377 // Now iterate over the variables and keep the usable ones plus store some interesting data like number of samples 0378 matvar_t *matvar = Mat_VarReadNextInfo(_matfile); 0379 while (matvar) { 0380 switch (matvar->class_type) { 0381 // All array types = matrix, scalar or vector - check rank and sizes to determine which 0382 case DOUBLE_PRECISION_ARRAY_CT: 0383 case SINGLE_PRECISION_ARRAY_CT: 0384 case EIGHT_BIT_SIGNED_INT_ARRAY_CT: 0385 case EIGHT_BIT_UNSIGNED_INT_ARRAY_CT: 0386 case SIXTEEN_BIT_SIGNED_INT_ARRAY_CT: 0387 case SIXTEEN_BIT_UNSIGNED_INT_ARRAY_CT: 0388 case THIRTYTWO_BIT_SIGNED_INT_ARRAY_CT: 0389 case THIRTYTWO_BIT_UNSIGNED_INT_ARRAY_CT: 0390 case MATLAB_ARRAY_CT: 0391 case COMPRESSED_DATA_CT: 0392 // Scalar 0393 if ( (matvar->rank == 1 && matvar->dims[0] == 1) || 0394 (matvar->rank == 2 && matvar->dims[0] == 1 && matvar->dims[1] == 1) ) { 0395 _scalarList << QString(matvar->name); 0396 // qDebug() << "Found a scalar: " << matvar->name; 0397 } 0398 // Vector 0399 if ( (matvar->rank == 1 && matvar->dims[0] > 1) || 0400 (matvar->rank == 2 && matvar->dims[0] == 1 && matvar->dims[1] > 1) || // matrix with one "flat" dim and at least 2 samples in the other direction 0401 (matvar->rank == 2 && matvar->dims[1] == 1 && matvar->dims[0] > 1) ) { // symmetrical case to the previous one 0402 _fieldList << QString(matvar->name); 0403 int fc = (matvar->rank == 1) ? matvar->dims[0] : qMax(matvar->dims[0], matvar->dims[1]); 0404 _maxFrameCount = qMax(_maxFrameCount, fc); 0405 _frameCounts[matvar->name] = fc; 0406 // qDebug() << "Found a vector: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]"; 0407 } 0408 // Dimension 2 matrix 0409 if ( matvar->rank == 2 && matvar->dims[0] > 1 && matvar->dims[1] > 1 ) { 0410 _matrixList << QString(matvar->name); 0411 // qDebug() << "Found a matrix: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]"; 0412 } 0413 break; 0414 0415 case CHARACTER_ARRAY_CT: { // String 0416 matvar_t *string = Mat_VarRead(_matfile, matvar->name); 0417 _strings[QString(matvar->name)] = QString((char*)string->data); 0418 Mat_VarFree(string); 0419 // qDebug() << "Found a string: " << matvar->name << ", size: [" << matvar->dims[0] << "x" << matvar->dims[1] << "]"; 0420 break; 0421 } 0422 0423 default: 0424 // qDebug() << "Variable " << matvar->name << ", type not supported (" << matvar->class_type << ")"; 0425 break; 0426 } 0427 0428 0429 matvar = Mat_VarReadNextInfo(_matfile); 0430 } 0431 Mat_VarFree(matvar); 0432 0433 0434 registerChange(); 0435 return true; // false if something went wrong 0436 } 0437 0438 0439 // Check if the data in the from the source has updated. 0440 // Considering how Matlab files are built up we can consider that they are always fixed 0441 Kst::Object::UpdateType MatlabSource::internalDataSourceUpdate() { 0442 return Kst::Object::NoChange; 0443 } 0444 0445 0446 int MatlabSource::readScalar(double *v, const QString& field) 0447 { 0448 matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data()); 0449 if (matvar) { // TODO: add data type check. Or is the cast enough? 0450 *v = (double)*(double *)matvar->data; 0451 Mat_VarFree(matvar); 0452 return 1; 0453 } 0454 qDebug() << "Error reading scalar " << field; 0455 return 0; 0456 } 0457 0458 int MatlabSource::readString(QString *stringValue, const QString& stringName) 0459 { 0460 // TODO more error handling? Especially data type 0461 matvar_t *matvar = Mat_VarRead(_matfile, stringName.toLatin1().data()); 0462 if (matvar) { 0463 *stringValue = QString((const char*)matvar->data); 0464 Mat_VarFree(matvar); 0465 return 1; 0466 } 0467 return 0; 0468 } 0469 0470 int MatlabSource::readField(double *v, const QString& field, int s, int n) { 0471 0472 KST_DBG qDebug() << "Entering MatlabSource::readField with params: " << field << ", from " << s << " for " << n << " frames" << endl; 0473 0474 /* For INDEX field */ 0475 if (field.toLower() == "index") { 0476 if (n < 0) { 0477 v[0] = double(s); 0478 return 1; 0479 } 0480 for (int i = 0; i < n; ++i) { 0481 v[i] = double(s + i); 0482 } 0483 return n; 0484 } 0485 0486 /* For a variable from the Matlab file */ 0487 matio_data_type dataType; 0488 matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data()); 0489 if (!matvar) { 0490 KST_DBG qDebug() << "MatlabSource: queried field " << field << " which can't be read" << endl; 0491 return -1; 0492 } 0493 0494 if (s >= _frameCounts[field]) { 0495 return 0; 0496 } 0497 0498 dataType = (matio_data_type) matvar->data_type; 0499 switch (dataType) { // We have to be careful with the dimension of data elements 0500 case EIGHT_BIT_SIGNED_INT_DT: 0501 { 0502 int8_t *dataPointer = (int8_t*)matvar->data; 0503 for (int i = 0; i < n; ++i) { 0504 v[i] = (double)dataPointer[i+s]; 0505 } 0506 } 0507 break; 0508 0509 case EIGHT_BIT_UNSIGNED_INT_DT: 0510 { 0511 uint8_t *dataPointer = (uint8_t*)matvar->data; 0512 for (int i = 0; i < n; ++i) { 0513 v[i] = (double)dataPointer[i+s]; 0514 } 0515 } 0516 break; 0517 0518 case SIXTEEN_BIT_SIGNED_INT_DT: 0519 { 0520 int16_t *dataPointer = (int16_t*)matvar->data; 0521 for (int i = 0; i < n; ++i) { 0522 v[i] = (double)dataPointer[i+s]; 0523 } 0524 } 0525 break; 0526 0527 case SIXTEEN_BIT_UNSIGNED_INT_DT: 0528 { 0529 uint16_t *dataPointer = (uint16_t*)matvar->data; 0530 for (int i = 0; i < n; ++i) { 0531 v[i] = (double)dataPointer[i+s]; 0532 } 0533 } 0534 break; 0535 0536 case THIRTYTWO_BIT_SIGNED_INT_DT: 0537 { 0538 int32_t *dataPointer = (int32_t*)matvar->data; 0539 for (int i = 0; i < n; ++i) { 0540 v[i] = (double)dataPointer[i+s]; 0541 } 0542 } 0543 break; 0544 0545 case THIRTYTWO_BIT_UNSIGNED_INT_DT: 0546 { 0547 uint32_t *dataPointer = (uint32_t*)matvar->data; 0548 for (int i = 0; i < n; ++i) { 0549 v[i] = (double)dataPointer[i+s]; 0550 } 0551 } 0552 break; 0553 0554 case IEEE_754_SINGLE_PRECISION_DT: 0555 { 0556 float *dataPointer = (float*)matvar->data; 0557 for (int i = 0; i < n; ++i) { 0558 v[i] = (double)dataPointer[i+s]; 0559 } 0560 } 0561 break; 0562 0563 case IEEE_754_DOUBLE_PRECISION_DT: 0564 { 0565 double *dataPointer = (double*)matvar->data; 0566 for (int i = 0; i < n; ++i) { 0567 v[i] = (double)dataPointer[i+s]; 0568 } 0569 } 0570 break; 0571 0572 case SIXTYFOUR_BIT_SIGNED_INT_DT: 0573 { 0574 int64_t *dataPointer = (int64_t*)matvar->data; 0575 for (int i = 0; i < n; ++i) { 0576 v[i] = (double)dataPointer[i+s]; 0577 } 0578 } 0579 break; 0580 0581 case SIXTYFOUR_BIT_UNSIGNED_INT_DT: 0582 { 0583 uint64_t *dataPointer = (uint64_t*)matvar->data; 0584 for (int i = 0; i < n; ++i) { 0585 v[i] = (double)dataPointer[i+s]; 0586 } 0587 } 0588 break; 0589 0590 default: 0591 KST_DBG qDebug() << "MatlabSource, field " << field << ": wrong datatype for kst, no values read" << endl; 0592 return -1; 0593 break; 0594 } 0595 0596 KST_DBG qDebug() << "Finished reading " << field << endl; 0597 Mat_VarFree(matvar); 0598 return n; 0599 } 0600 0601 0602 int MatlabSource::readMatrix(double *v, const QString& field) 0603 { 0604 /* For a variable from the Matlab file */ 0605 matvar_t *matvar = Mat_VarRead(_matfile, field.toLatin1().data()); 0606 if (!matvar) { 0607 KST_DBG qDebug() << "MatlabSource: queried matrix " << field << " which can't be read" << endl; 0608 return -1; 0609 } 0610 0611 // Matrices are always read from the beginning to the end 0612 // But we have to first store the data in a buffer of the right type, then copy it to v 0613 int n = matvar->dims[0] * matvar->dims[1]; 0614 0615 matio_data_type dataType = (matio_data_type) matvar->data_type; 0616 switch (dataType) { 0617 case EIGHT_BIT_SIGNED_INT_DT: 0618 { 0619 int8_t *dataPointer = (int8_t *) matvar->data; 0620 for (int i = 0; i < n; ++i) { 0621 v[i] = (double)dataPointer[i]; 0622 } 0623 } 0624 break; 0625 0626 case EIGHT_BIT_UNSIGNED_INT_DT: 0627 { 0628 uint8_t *dataPointer = (uint8_t *) matvar->data; 0629 for (int i = 0; i < n; ++i) { 0630 v[i] = (double)dataPointer[i]; 0631 } 0632 free(dataPointer); 0633 } 0634 break; 0635 0636 case SIXTEEN_BIT_SIGNED_INT_DT: 0637 { 0638 int16_t *dataPointer = (int16_t *) matvar->data;; 0639 for (int i = 0; i < n; ++i) { 0640 v[i] = (double)dataPointer[i]; 0641 } 0642 } 0643 break; 0644 0645 case SIXTEEN_BIT_UNSIGNED_INT_DT: 0646 { 0647 uint16_t *dataPointer = (uint16_t *) matvar->data;; 0648 for (int i = 0; i < n; ++i) { 0649 v[i] = (double)dataPointer[i]; 0650 } 0651 } 0652 break; 0653 0654 case THIRTYTWO_BIT_SIGNED_INT_DT: 0655 { 0656 int32_t *dataPointer = (int32_t *) matvar->data; 0657 for (int i = 0; i < n; ++i) { 0658 v[i] = (double)dataPointer[i]; 0659 } 0660 } 0661 break; 0662 0663 case THIRTYTWO_BIT_UNSIGNED_INT_DT: 0664 { 0665 uint32_t *dataPointer = (uint32_t *) matvar->data; 0666 for (int i = 0; i < n; ++i) { 0667 v[i] = (double)dataPointer[i]; 0668 } 0669 } 0670 break; 0671 0672 case IEEE_754_SINGLE_PRECISION_DT: 0673 { 0674 float *dataPointer = (float *) matvar->data; 0675 for (int i = 0; i < n; ++i) { 0676 v[i] = (double)dataPointer[i]; 0677 } 0678 } 0679 break; 0680 0681 case IEEE_754_DOUBLE_PRECISION_DT: 0682 { 0683 double *dataPointer = (double *) matvar->data; 0684 for (int i = 0; i < n; ++i) { 0685 v[i] = (double)dataPointer[i]; 0686 } 0687 } 0688 break; 0689 0690 case SIXTYFOUR_BIT_SIGNED_INT_DT: 0691 { 0692 int64_t *dataPointer = (int64_t *) matvar->data; 0693 for (int i = 0; i < n; ++i) { 0694 v[i] = (double)dataPointer[i]; 0695 } 0696 } 0697 break; 0698 0699 case SIXTYFOUR_BIT_UNSIGNED_INT_DT: 0700 { 0701 uint64_t *dataPointer = (uint64_t *) matvar->data; 0702 for (int i = 0; i < n; ++i) { 0703 v[i] = (double)dataPointer[i]; 0704 } 0705 } 0706 break; 0707 0708 default: 0709 KST_DBG qDebug() << "MatlabSource, field " << field << ": wrong datatype for kst, no values read" << endl; 0710 return -1; 0711 break; 0712 } 0713 0714 Mat_VarFree(matvar); 0715 0716 return n; 0717 } 0718 0719 0720 int MatlabSource::frameCount(const QString& field) const { 0721 if (field.isEmpty() || field.toLower() == "index") { 0722 return _maxFrameCount; 0723 } else { 0724 return _frameCounts[field]; 0725 } 0726 } 0727 0728 0729 QString MatlabSource::fileType() const { 0730 return "Matlab Datasource"; 0731 } 0732 0733 0734 void MatlabSource::save(QXmlStreamWriter &streamWriter) { 0735 Kst::DataSource::save(streamWriter); 0736 } 0737 0738 int MatlabSource::samplesPerFrame(const QString& field) { 0739 return 1; 0740 } 0741 0742 0743 // Name used to identify the plugin. Used when loading the plugin. 0744 QString MatlabSourcePlugin::pluginName() const { return tr("Matlab Datasource Reader"); } 0745 QString MatlabSourcePlugin::pluginDescription() const { return tr("Matlab's .mat Datasource Reader"); } 0746 0747 /********************** 0748 MatlabDatasourcePlugin - This class defines the plugin interface to the DataSource defined by the plugin. 0749 The primary requirements of this class are to provide the necessary connections to create the object 0750 which includes providing access to the configuration widget. 0751 0752 ***********************/ 0753 0754 Kst::DataSource *MatlabSourcePlugin::create(Kst::ObjectStore *store, 0755 QSettings *cfg, 0756 const QString &filename, 0757 const QString &type, 0758 const QDomElement &element) const { 0759 0760 return new MatlabSource(store, cfg, filename, type, element); 0761 } 0762 0763 0764 // Provides the matrix list that this dataSource can provide from the provided filename. 0765 // This function should use understands to validate the file and then open and calculate the 0766 // list of matrices. 0767 QStringList MatlabSourcePlugin::matrixList(QSettings *cfg, 0768 const QString& filename, 0769 const QString& type, 0770 QString *typeSuggestion, 0771 bool *complete) const { 0772 0773 0774 if (typeSuggestion) { 0775 *typeSuggestion = "Matlab Datasource"; 0776 } 0777 if ((!type.isEmpty() && !provides().contains(type)) || 0778 0 == understands(cfg, filename)) { 0779 if (complete) { 0780 *complete = false; 0781 } 0782 return QStringList(); 0783 } 0784 QStringList matrixList; 0785 0786 return matrixList; 0787 0788 } 0789 0790 0791 // Provides the scalar list that this dataSource can provide from the provided filename. 0792 // This function should use understands to validate the file and then open and calculate the 0793 // list of scalars if necessary. 0794 QStringList MatlabSourcePlugin::scalarList(QSettings *cfg, 0795 const QString& filename, 0796 const QString& type, 0797 QString *typeSuggestion, 0798 bool *complete) const { 0799 0800 QStringList scalarList; 0801 0802 if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { 0803 if (complete) { 0804 *complete = false; 0805 } 0806 return QStringList(); 0807 } 0808 0809 if (typeSuggestion) { 0810 *typeSuggestion = "Matlab Datasource"; 0811 } 0812 0813 scalarList.append("FRAMES"); 0814 return scalarList; 0815 0816 } 0817 0818 0819 // Provides the string list that this dataSource can provide from the provided filename. 0820 // This function should use understands to validate the file and then open and calculate the 0821 // list of strings if necessary. 0822 QStringList MatlabSourcePlugin::stringList(QSettings *cfg, 0823 const QString& filename, 0824 const QString& type, 0825 QString *typeSuggestion, 0826 bool *complete) const { 0827 0828 QStringList stringList; 0829 0830 if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { 0831 if (complete) { 0832 *complete = false; 0833 } 0834 return QStringList(); 0835 } 0836 0837 if (typeSuggestion) { 0838 *typeSuggestion = "Matlab Datasource"; 0839 } 0840 0841 stringList.append("FILENAME"); 0842 return stringList; 0843 0844 } 0845 0846 0847 // Provides the field list that this dataSource can provide from the provided filename. 0848 // This function should use understands to validate the file and then open and calculate the 0849 // list of fields if necessary. 0850 QStringList MatlabSourcePlugin::fieldList(QSettings *cfg, 0851 const QString& filename, 0852 const QString& type, 0853 QString *typeSuggestion, 0854 bool *complete) const { 0855 Q_UNUSED(cfg) 0856 Q_UNUSED(filename) 0857 Q_UNUSED(type) 0858 0859 if (complete) { 0860 *complete = true; 0861 } 0862 0863 if (typeSuggestion) { 0864 *typeSuggestion = "Matlab Datasource"; 0865 } 0866 0867 QStringList fieldList; 0868 return fieldList; 0869 } 0870 0871 0872 // The main function used to determine if this plugin knows how to process the provided file. 0873 // Each datasource plugin should check the file and return a number between 0 and 100 based 0874 // on the likelyhood of the file being this type. 100 should only be returned if there is no way 0875 // that the file could be any datasource other than this one. 0876 int MatlabSourcePlugin::understands(QSettings *cfg, const QString& filename) const { 0877 Q_UNUSED(cfg) 0878 QFileInfo fi(filename); 0879 if (fi.suffix() == "mat") { 0880 return 80; 0881 } else return 0; 0882 } 0883 0884 0885 0886 bool MatlabSourcePlugin::supportsTime(QSettings *cfg, const QString& filename) const { 0887 //FIXME 0888 Q_UNUSED(cfg) 0889 Q_UNUSED(filename) 0890 return false; 0891 } 0892 0893 0894 QStringList MatlabSourcePlugin::provides() const { 0895 QStringList rc; 0896 rc += "Matlab Datasource"; 0897 return rc; 0898 } 0899 0900 0901 // Request for this plugins configuration widget. 0902 Kst::DataSourceConfigWidget *MatlabSourcePlugin::configWidget(QSettings *cfg, const QString& filename) const { 0903 Q_UNUSED(cfg) 0904 Q_UNUSED(filename) 0905 return 0;; 0906 0907 } 0908 0909 0910 #ifndef QT5 0911 Q_EXPORT_PLUGIN2(kstdata_matlab, MatlabSourcePlugin) 0912 #endif 0913 0914 // vim: ts=2 sw=2 et