Menu

Reading Older Mat file versions?

2016-10-19
2016-10-20
  • Perry Taylor

    Perry Taylor - 2016-10-19

    I am trying to read an older .mat file that I believe is saved as a V.4 style. I am using the latest version of the csmatio library and when I attempt to import it I get a "This is not a valid MATLAB 5.0 MAT-file." error with the std. code and if I comment out that check in the demo program I get a "This version of CSMatIO does not support Big Endian." error. Do you have any thoughts as to how to read the file?

     
  • Perry Taylor

    Perry Taylor - 2016-10-19
    I have included a file that errors out to help reproduce the problem.
    
     
  • David A. Zier

    David A. Zier - 2016-10-19

    The current version of CSMatIO only supports the MATLAB 5.0 MAT-file. I can put this on backlog of features that we would like to add, but it will not be added anytime soon. Right now, I am in the process or cleaning up the code base and increasing test covereage. After that is done, I will look into adding new features.

     
  • Tobias

    Tobias - 2016-10-19

    Read the version 4 mat file with Matlab, then save it as version 6 or 7 mat file. Version 6 and 7 should be readable for csmatio.
    https://de.mathworks.com/help/matlab/import_export/mat-file-versions.html

     
  • Perry Taylor

    Perry Taylor - 2016-10-19

    David/Tobias- Thanks for your responses. Unfortunately opening the files up in matlab each time and saving them as a different format is a non-starter for the project I am working on. Do either of you know of any other projects to read Matlab v4 files in either c# or c(++)?

     
  • David A. Zier

    David A. Zier - 2016-10-19

    There is none that I know of. Try looking for a matlab file converter. It has been a long time since I actually used Matlab, but when I did, I remember that it had a decent scripting language. You could write a Matlab script that reads in an old file and writes a new file. You could then have this script called just before importing into your C# program or just after generating the file.

     

    Last edit: David A. Zier 2016-10-19
  • Tobias

    Tobias - 2016-10-19

    The V4 format is much easier than the latter fomats and straight forward to read without a special library. This QND code example might get you started. It produces this output for your file 'DoublePendulum.mat':

    4 x 11 text matrix named 'Aclass'
    45 x 1097 text matrix named 'name'
    125 x 1097 text matrix named 'description'
    4 x 1097 int32 matrix named 'dataInfo'
    833 x 2 float32 matrix named 'data_1'
    68 x 502 float32 matrix named 'data_2'
    

    Source code:

    :::C#
    namespace MatlabV4Reader
    {
        using System;
        using System.Collections.Generic;
        using System.IO;
    
        static class Program
        {
            static void Main(string[] args)
            {
                var br = new BinaryReader(File.Open("DoublePendulum.mat", FileMode.Open));
                while (ReadMatrix(br)) { }
                Console.ReadLine();
            }
    
            enum DataType : int
            {
                float64 = 0,
                float32 = 10,
                int32 = 20,
                text = 51,
            }
    
            private static bool ReadMatrix(BinaryReader br)
            {
                if (br.BaseStream.Position == br.BaseStream.Length)
                    return false;
    
                int type = br.ReadInt32();
                int mrows = br.ReadInt32();
                int ncols = br.ReadInt32();
                int imagf = br.ReadInt32();
                int namlen = br.ReadInt32();
                string name = br.ReadCString();
                var dataType = (DataType)type;
    
                List<object> elems = null;
                switch (dataType)
                {
                    case DataType.float32: elems = ReadMatrixDataFloat32(br, mrows, ncols); break;
                    case DataType.int32: elems = ReadMatrixDataInt32(br, mrows, ncols); break;
                    case DataType.text: elems = ReadMatrixTextData(br, mrows, ncols); break;
                    default: throw new NotImplementedException(type.ToString());
                }
    
                Console.WriteLine("{1} x {2} {3} matrix named '{0}'", name, mrows, ncols, dataType);
                //Console.WriteLine("--> element 0: {0}", elems[0]);
                //Console.WriteLine("--> element 1: {0}", elems[1]);
                //Console.WriteLine("--> element 2: {0}", elems[2]);
                //Console.WriteLine("----------------------------------------------------------------");
                return true;
            }
    
            private static List<object> ReadMatrixTextData(BinaryReader br, int mrows, int ncols)
            {
                var elems = new List<object>(mrows);
                for (int i = 0; i < mrows; ++i)
                    elems.Add(br.ReadNonTerminatedCString(ncols));
                return elems;
            }
    
            private static List<object> ReadMatrixDataInt32(BinaryReader br, int mrows, int ncols)
            {
                var elems = new List<object>(mrows * ncols);
                for (int i = 0; i < mrows * ncols; ++i)
                    elems.Add(br.ReadInt32());
                return elems;
            }
    
            private static List<object> ReadMatrixDataFloat32(BinaryReader br, int mrows, int ncols)
            {
                var elems = new List<object>(mrows * ncols);
                for (int i = 0; i < mrows * ncols; ++i)
                    elems.Add(br.ReadSingle());
                return elems;
            }
    
            public static string ReadCString(this BinaryReader br)
            {
                var chars = new List<char>();
                char c = '\0';
                do { c = br.ReadChar(); chars.Add(c); } while (c != 0);
                chars.Remove('\0');
                return new string(chars.ToArray());
            }
    
            public static string ReadNonTerminatedCString(this BinaryReader br, int len)
            {
                var chars = br.ReadChars(len);
                return new string(chars);
            }
        }
    }
    
     

Log in to post a comment.