50#if defined(__LITTLE_ENDIAN__)
53#define BIG_ENDIAN_ARCH
58#if defined(__hpux) || defined(__Lynx__) || defined(__sun)
59#define BIG_ENDIAN_ARCH
61#if defined(__linux) || defined(WIN32) || defined(__APPLE__)
68#define NATIVE_ENDIAN FIFFV_LITTLE_ENDIAN
71#define NATIVE_ENDIAN FIFFV_LITTLE_ENDIAN
75#define NATIVE_ENDIAN FIFFV_BIG_ENDIAN
98#include <Eigen/SparseCore>
107#include <QSharedPointer>
133#define IS_MATRIX 0xFFFF0000
134#define MATRIX_CODING_DENSE 0x00004000
135#define MATRIX_CODING_CCS 0x00004010
136#define MATRIX_CODING_RCS 0x00004020
137#define DATA_TYPE 0x0000FFFF
163 using SPtr = QSharedPointer<FiffTag>;
165 using UPtr = std::unique_ptr<FiffTag>;
270 inline quint8*
toByte()
const;
288 inline qint16*
toShort()
const;
306 inline qint32*
toInt()
const;
324 inline const float*
toFloat()
const;
333 inline const double*
toDouble()
const;
399 inline QList<QSharedPointer<FiffDirEntry>>
toDirEntry()
const;
561 return (quint8*)this->data();
571 return (quint16*)this->data();
581 return (qint16*)this->data();
591 return (quint32*)this->data();
599 qWarning(
"Expected an integer tag : %d (found data type %d instead)\n", this->
kind, this->
getType());
602 return (qint32*)this->data();
610 qWarning(
"Expected a julian tag : %d (found data type %d instead)\n", this->
kind, this->
getType());
613 return (qint32*)this->data();
623 return reinterpret_cast<const float*
>(this->data());
633 return reinterpret_cast<const double*
>(this->data());
653 return (qint16*)this->data();
666 const qint32* t_pInt32 = (qint32*)this->data();
668 p_fiffID.
version = t_pInt32[0];
669 p_fiffID.
machid[0] = t_pInt32[1];
670 p_fiffID.
machid[1] = t_pInt32[2];
684 return t_fiffDigPoint;
686 auto* t_pInt32 =
reinterpret_cast<const qint32*
>(this->data());
688 t_fiffDigPoint.
kind = t_pInt32[0];
689 t_fiffDigPoint.
ident = t_pInt32[1];
691 auto* t_pFloat =
reinterpret_cast<const float*
>(this->data());
692 t_fiffDigPoint.
r[0] = t_pFloat[2];
693 t_fiffDigPoint.
r[1] = t_pFloat[3];
694 t_fiffDigPoint.
r[2] = t_pFloat[4];
697 return t_fiffDigPoint;
707 return p_FiffCoordTrans;
709 auto* t_pInt32 =
reinterpret_cast<const qint32*
>(this->data());
710 p_FiffCoordTrans.
from = t_pInt32[0];
711 p_FiffCoordTrans.
to = t_pInt32[1];
713 p_FiffCoordTrans.
trans.setIdentity(4, 4);
714 auto* t_pFloat =
reinterpret_cast<const float*
>(this->data());
717 for (r = 0; r < 3; ++r) {
718 p_FiffCoordTrans.
trans(r, 3) = t_pFloat[11 + r];
719 for (c = 0; c < 3; ++c) {
720 p_FiffCoordTrans.
trans(r, c) = t_pFloat[2 + count];
725 p_FiffCoordTrans.
invtrans.setIdentity(4, 4);
727 for (r = 0; r < 3; ++r) {
728 p_FiffCoordTrans.
invtrans(r, 3) = t_pFloat[23 + r];
729 for (c = 0; c < 3; ++c) {
730 p_FiffCoordTrans.
invtrans(r, c) = t_pFloat[14 + count];
735 return p_FiffCoordTrans;
750 auto* t_pInt32 =
reinterpret_cast<const qint32*
>(this->data());
751 p_FiffChInfo.
scanNo = t_pInt32[0];
752 p_FiffChInfo.
logNo = t_pInt32[1];
753 p_FiffChInfo.
kind = t_pInt32[2];
754 auto* t_pFloat =
reinterpret_cast<const float*
>(this->data());
755 p_FiffChInfo.
range = t_pFloat[3];
756 p_FiffChInfo.
cal = t_pFloat[4];
765 for (r = 0; r < 3; ++r)
766 p_FiffChInfo.
chpos.
r0[r] = t_pFloat[6 + r];
768 for (r = 0; r < 3; ++r)
769 p_FiffChInfo.
chpos.
ex[r] = t_pFloat[6 + 3 + r];
771 for (r = 0; r < 3; ++r)
772 p_FiffChInfo.
chpos.
ey[r] = t_pFloat[6 + 6 + r];
774 for (r = 0; r < 3; ++r)
775 p_FiffChInfo.
chpos.
ez[r] = t_pFloat[6 + 9 + r];
785 for (r = 0; r < 3; ++r)
788 for (r = 0; r < 3; ++r)
791 for (r = 0; r < 3; ++r)
794 for (r = 0; r < 3; ++r)
799 if (p_FiffChInfo.
chpos.
ex.norm() > 0) {
800 p_FiffChInfo.
eeg_loc.block(0, 0, 3, 1) = p_FiffChInfo.
chpos.
r0.block(0, 0, 3, 1);
801 p_FiffChInfo.
eeg_loc.block(0, 1, 3, 1) = p_FiffChInfo.
chpos.
ex.block(0, 0, 3, 1);
803 p_FiffChInfo.
eeg_loc.block(0, 0, 3, 1) = p_FiffChInfo.
chpos.
r0.block(0, 0, 3, 1);
810 p_FiffChInfo.
unit = t_pInt32[18];
811 p_FiffChInfo.
unit_mul = t_pInt32[19];
816 const char* orig =
static_cast<const char*
>(this->data());
817 p_FiffChInfo.
ch_name = QString::fromUtf8(orig + 80).replace(
" ",
"");
837 QList<QSharedPointer<FiffDirEntry>> p_ListFiffDir;
839 return p_ListFiffDir;
841 QSharedPointer<FiffDirEntry> t_pFiffDirEntry;
842 qint32* t_pInt32 = (qint32*)this->data();
843 for (
int k = 0; k < this->size() / 16; ++k) {
844 t_pFiffDirEntry = QSharedPointer<FiffDirEntry>(
new FiffDirEntry);
845 t_pFiffDirEntry->kind = t_pInt32[k * 4];
846 t_pFiffDirEntry->type = t_pInt32[k * 4 + 1];
847 t_pFiffDirEntry->size = t_pInt32[k * 4 + 2];
848 t_pFiffDirEntry->pos = t_pInt32[k * 4 + 3];
849 p_ListFiffDir.append(t_pFiffDirEntry);
852 return p_ListFiffDir;
864 return Eigen::MatrixXi();
867 QVector<qint32> dims;
871 qWarning(
"Only two-dimensional matrices are supported at this time");
872 return Eigen::MatrixXi();
876 Eigen::MatrixXi p_Matrix(Eigen::Map<const Eigen::MatrixXi>(
reinterpret_cast<const int*
>(this->data()), dims[0], dims[1]));
886 return Eigen::MatrixXf();
889 qWarning(
"Error in FiffTag::toFloatMatrix(): Matrix is not dense!");
890 return Eigen::MatrixXf();
894 QVector<qint32> dims;
898 qWarning(
"Only two-dimensional matrices are supported at this time");
899 return Eigen::MatrixXf();
903 Eigen::MatrixXf p_Matrix(Eigen::Map<const Eigen::MatrixXf>(
reinterpret_cast<const float*
>(this->data()), dims[0], dims[1]));
913 return Eigen::SparseMatrix<double>();
916 qCritical(
"Error in FiffTag::toSparseFloatMatrix(): Matrix is not sparse!\n");
917 return Eigen::SparseMatrix<double>();
921 QVector<qint32> dims;
925 qWarning(
"Only two-dimensional matrices are supported at this time");
926 return Eigen::SparseMatrix<double>();
929 qint32 nnz = dims[0];
930 qint32 nrow = dims[1];
931 qint32 ncol = dims[2];
933 using T = Eigen::Triplet<double>;
934 std::vector<T> tripletList;
935 tripletList.reserve(nnz);
937 auto* t_pFloat =
reinterpret_cast<const float*
>(this->data());
938 auto* t_pInt =
reinterpret_cast<const int*
>(this->data());
939 qint32 offset1 = nnz;
940 qint32 offset2 = 2 * nnz;
945 qWarning(
"Warning in FiffTag::toSparseFloatMatrix(): CCS has to be debugged - never done before.");
947 for (qint32 j = 0; j < ncol; ++j) {
948 while (p < t_pInt[offset2 + j + 1]) {
950 tripletList.push_back(T(t_pInt[offset1 + p], j,
static_cast<double>(t_pFloat[p])));
959 for (qint32 j = 0; j < nrow; ++j) {
960 while (p < t_pInt[offset2 + j + 1]) {
962 tripletList.push_back(T(j, t_pInt[offset1 + p],
static_cast<double>(t_pFloat[p])));
973 Eigen::SparseMatrix<double> p_Matrix(nrow, ncol);
974 p_Matrix.setFromTriplets(tripletList.begin(), tripletList.end());
FIFF channel descriptor record (FIFF_CH_INFO): per-channel logical/scanner numbers,...
Symbolic FIFF tag, block, value, unit and channel-type constants shared across FIFFLIB.
#define FIFFV_COORD_DEVICE
#define FIFFV_COORD_UNKNOWN
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
FIFF tag-kind, block-kind and type-code numerical definitions, authoritative for FIFFLIB.
#define FIFFT_CH_INFO_STRUCT
#define FIFFT_DIR_ENTRY_STRUCT
#define FIFFT_COORD_TRANS_STRUCT
#define FIFFT_DIG_POINT_STRUCT
Export/import macros and build-info accessors for the FIFFLIB shared library.
#define FIFFSHARED_EXPORT
fiff_int_t fiff_type_base(fiff_int_t type)
fiff_int_t fiff_type_matrix_coding(fiff_int_t type)
fiff_int_t fiff_type_fundamental(fiff_int_t type)
Coil-frame position record embedded inside FIFF_CH_INFO: coil location and 3x3 EX/EY/EZ orientation t...
Single entry of the FIFF tag directory: kind, type, byte size and absolute file position.
Single digitization point (FIFF_DIG_POINT) with kind (cardinal/HPI/EEG/extra), identifier and 3D coor...
128-bit FIFF identifier record (machine ID + creation time) used to stamp files, blocks and parent re...
Primitive scalar typedefs and forward-compatible aliases backing the FIFF type system.
FIFF file I/O, in-memory data structures and high-level readers/writers.
Per-channel FIFF descriptor: identifiers, kind, calibration, coil type, channel-frame coil position a...
Eigen::Matrix< float, 3, 2, Eigen::DontAlign > eeg_loc
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > coil_trans
Channel coil-frame placement: origin r0 (m) and orthonormal axes ex / ey / ez in FIFFV_COORD_DEVICE.
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > invtrans
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > trans
One digitizer point: kind (cardinal/HPI/EEG/extra), ident, 3D position in FIFFV_COORD_HEAD.
Directory entry: tag kind + on-disk type + byte size + absolute file offset (16-byte record).
128-bit FIFF identifier: hardware machine ID plus creation time, stamped on every file and block.
static fiff_int_t fiff_type_matrix_coding(fiff_int_t type)
QSharedPointer< FiffTag > SPtr
Eigen::MatrixXf toFloatMatrix() const
quint32 * toUnsignedInt() const
FiffTag(FiffTag &&other)=default
std::unique_ptr< FiffTag > UPtr
FiffCoordTrans toCoordTrans() const
std::unique_ptr< const FiffTag > ConstUPtr
qint32 * toJulian() const
fiff_int_t getMatrixCoding() const
Eigen::MatrixXi toIntMatrix() const
quint16 * toUnsignedShort() const
FiffChInfo toChInfo() const
qint16 * toDauPack16() const
FiffDigPoint toDigPoint() const
const double * toDouble() const
const float * toFloat() const
static void convert_tag_data(const FiffTag::UPtr &tag, int from_endian, int to_endian)
static void convert_matrix_to_file_data(const FiffTag::UPtr &tag)
FiffTag & operator=(FiffTag &&other)=default
fiff_int_t getType() const
Eigen::SparseMatrix< double > toSparseFloatMatrix() const
static qint32 storageSize()
FiffTag & operator=(const FiffTag &other)=default
static void convert_matrix_from_file_data(const FiffTag::UPtr &tag)
static void convert_ch_pos(FiffChPos *pos)
FiffTag(const FiffTag &p_FiffTag)=default
QSharedPointer< const FiffTag > ConstSPtr
bool getMatrixDimensions(qint32 &p_ndim, QVector< qint32 > &p_Dims) const
QList< QSharedPointer< FiffDirEntry > > toDirEntry() const