Что содержится в поле «Рабочая область функции» в файле .mat? - PullRequest
0 голосов
/ 18 сентября 2018

Я работаю с файлами .mat, которые сохраняются в конце программы.Команда save foo.mat, поэтому все сохранено.Я надеюсь определить, изменяется ли программа, проверяя файлы .mat.Я вижу, что от запуска к запуску большинство файлов .mat одинаковы, но поле, помеченное __function_workspace__, несколько меняется.

(я проверяю файлы .mat через scipy.io.loadmat - просто загружаю файлы и распечатываю их как обычный текст, а затем сравниваю текст. Я обнаружил, что save -ascii в Matlab не помещает строкуярлыки на вещах, поэтому обход Python обходится, но я получаю ярлыки, и это полезно.)

Я пытаюсь определить, откуда происходят эти изменения.Кто-нибудь может объяснить, что содержит __function_workspace__?Почему это не должно быть то же самое от одного запуска данной программы к другому?

Переменные, которые меня действительно интересуют, одинаковы, но я беспокоюсь, что могу пропустить некоторые изменения, которые могут вернуться, чтобы укусить меня.Заранее благодарен за любой свет, который вы можете пролить на эту проблему.

РЕДАКТИРОВАТЬ: Как я уже упоминал в комментарии, значение __function_workspace__ представляет собой массив целых чисел.Я посмотрел на элементы массива, и оказалось, что эти числа представляют собой коды символов ASCII или не ASCII.Я вижу серии символов, которые выглядят как имена переменных или функций, так что это имеет смысл.Но есть также некоторые символы (не ASCII), которые не являются частью имени, и также есть много нулевых (нулевых) символов.Поэтому, кроме того, что я вижу имена вещей в __function_workspace__, я не уверен, что это за штука точно.

ВТОРОЕ РЕДАКТИРОВАНИЕ: Я обнаружил, что после комментирования вызовов функций построения графиков, содержание __function_workspace__то же самое от одного запуска программы к другому, так что это здорово.На данный момент единственное отличие от одного прогона к следующему состоит в том, что существует поле __header__, которое содержит метку времени для времени, в которое был создан файл .mat, который изменяется от прогона к прогону.

Третье редактирование. Я нашел статью http://nbviewer.jupyter.org/gist/mbauman/9121961 "Анализ файлов MAT с объектами классов в них", посвященную обратному проектированию поля __function_workspace__.Спасибо Мэтту Бауману за эту очень полезную статью и спасибо @mpaskov за указатель.Похоже, что __function_workspace__ является недокументированным универсальным материалом для различных вещей, только одна часть которого фактически является «рабочим пространством функции».

1 Ответ

0 голосов
/ 09 июля 2019

1) Различные файлы .mat

Возможно, вы захотите взглянуть на DiffPlug .Он может делать различия в файлах MAT, и я считаю, что для него также есть интерфейс командной строки.

2) Содержимое function_workspace

SciPy's __function_workspace__ ссылается на специальную переменную в концефайла MAT, который содержит дополнительные данные, необходимые для ссылочных типов (например, table, string, handle и т. д.) и различные другие материалы, которые не включены в официальную документацию.Имя вводит в заблуждение, поскольку оно действительно ссылается на «Подсистему» ​​(кратко упоминается в официальной спецификации как смещение в заголовке).

Например, если вы сохраняете ссылочный тип, например, emptyString = "",результирующий .mat будет содержать следующие две записи:

(1) Сама переменная.Это похоже на матрицу UInt32, но на самом деле это Opaque MCOS Reference (объектная система классов MATLAB) для string объекта в некотором месте в подсистеме.

 [0] Compressed (81 bytes, position = 128)
  [0] Matrix (144 bytes, position = 0)
    [0] UInt32[2] = [17, 0] // Opaque
    [1] Int8[11] = ['emptyString'] // Variable Name
    [2] Int8[4] = ['MCOS'] // Object Type
    [3] Int8[6] = ['string'] // Class Name
    [4] Matrix (72 bytes, position = 72)
      [0] UInt32[2] = [13, 0] // UInt32
      [1] Int32[2] = [6, 1] // Dimensions
      [2] Int8[0] = [''] // Variable Name (not needed)
      [3] UInt32[6] = [-587202560, 2, 1, 1, 1, 1] // Data (Reference Target)

(2) Матрица UInt8 без имени (SciPy переименовала ее в __function_workspace__) в конце файла.Помимо отсутствующего имени, оно выглядит как стандартная матрица, но на самом деле данные - это еще один файл MAT (с сокращенным заголовком), который содержит реальные данные.

[1] Compressed (251 bytes, position = 217)
  [0] Matrix (968 bytes, position = 0)
    [0] UInt32[2] = [9, 0] // UInt8
    [1] Int32[2] = [1, 920] // Dimensions
    [2] Int8[0] = [''] // Variable Name
    [3] ... 920 bytes ... // Data (Nested MAT File)

Формат данных, к сожалению, полностью недокументировани немного беспорядка.Я мог бы опубликовать содержимое подсистемы, но это становится несколько подавляющим даже для такого простого случая.По сути, это файл MAT, который содержит struct, который содержит специальную переменную (MCOS FileWrapper__), которая содержит массив ячеек с различными значениями, включая тот, который магически кодирует различные Object Properties.

, которые сделал Мэтт Бауманнекоторые большие усилия по обратному проектированию ( парсинг файлов MAT с объектами классов в них ), на которых, я полагаю, основаны все поддерживающие реализации.Java-библиотека MFL содержит полную (только для чтения) реализацию этого (см. McosFileWrapper.java ).

Некоторые обновления поста Мэтта Баумана, которые мы обнаружили::

  • Ссылка MCOS может ссылаться на массив объектов дескрипторов и может иметь более 6 значений.Он содержит информацию о размерах, за которой следует массив индексов (см. McosReference.java ).
  • Поле Object Id выглядит как уникальный идентификатор, но порядок кажется случайным, а иногда нетматч.Я не знаю, что это за значение, но полное игнорирование, похоже, работает хорошо:)
  • Я видел Segment 5, заполненный в .fig файлах, но я не смог сузитьчто там еще.

Редактировать: К вашему сведению, после правильного разбора объекта string и заполнения всех свойств фактическое строковое значение кодируется в еще одном недокументированном формате (см. testDoubleQuoteString )

...