NT-MDT data: JavaScript parsing library

A native file format of NT-MDT scientific software. Usually contains any of:

Some examples of mdt files can be downloaded at:

  • http://www.ntmdt-si.ru/scan-gallery
  • http://callistosoft.narod.ru/Resources/Mdt.zip

Application

["Nova", "Image Analysis", "NanoEducator", "Gwyddion", "Callisto"]

File extension

mdt

KS implementation details

License: GPL-3.0+

This page hosts a formal specification of NT-MDT data using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

See the usage examples in the JavaScript notes.

Parse structure from an ArrayBuffer:

var arrayBuffer = ...;
var data = new NtMdt(new KaitaiStream(arrayBuffer));

After that, one can get various attributes from the structure by accessing fields or properties like:

data.size // => File size (w/o header)

JavaScript source code to parse NT-MDT data

NtMdt.js

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['kaitai-struct/KaitaiStream'], factory);
  } else if (typeof module === 'object' && module.exports) {
    module.exports = factory(require('kaitai-struct/KaitaiStream'));
  } else {
    root.NtMdt = factory(root.KaitaiStream);
  }
}(this, function (KaitaiStream) {
/**
 * A native file format of NT-MDT scientific software. Usually contains
 * any of:
 * 
 * * [Scanning probe](https://en.wikipedia.org/wiki/Scanning_probe_microscopy) microscopy scans and spectra
 * * [Raman spectra](https://en.wikipedia.org/wiki/Raman_spectroscopy)
 * * results of their analysis
 * 
 * Some examples of mdt files can be downloaded at:
 * 
 * * http://www.ntmdt-si.ru/scan-gallery
 * * http://callistosoft.narod.ru/Resources/Mdt.zip
 * @see {@link https://svn.code.sf.net/p/gwyddion/code/trunk/gwyddion/modules/file/nt-mdt.c|Source}
 */

var NtMdt = (function() {
  NtMdt.AdcMode = Object.freeze({
    HEIGHT: 0,
    DFL: 1,
    LATERAL_F: 2,
    BIAS_V: 3,
    CURRENT: 4,
    FB_OUT: 5,
    MAG: 6,
    MAG_SIN: 7,
    MAG_COS: 8,
    RMS: 9,
    CALC_MAG: 10,
    PHASE1: 11,
    PHASE2: 12,
    CALC_PHASE: 13,
    EX1: 14,
    EX2: 15,
    HV_X: 16,
    HV_Y: 17,
    SNAP_BACK: 18,
    FALSE: 255,

    0: "HEIGHT",
    1: "DFL",
    2: "LATERAL_F",
    3: "BIAS_V",
    4: "CURRENT",
    5: "FB_OUT",
    6: "MAG",
    7: "MAG_SIN",
    8: "MAG_COS",
    9: "RMS",
    10: "CALC_MAG",
    11: "PHASE1",
    12: "PHASE2",
    13: "CALC_PHASE",
    14: "EX1",
    15: "EX2",
    16: "HV_X",
    17: "HV_Y",
    18: "SNAP_BACK",
    255: "FALSE",
  });

  NtMdt.XmlScanLocation = Object.freeze({
    HLT: 0,
    HLB: 1,
    HRT: 2,
    HRB: 3,
    VLT: 4,
    VLB: 5,
    VRT: 6,
    VRB: 7,

    0: "HLT",
    1: "HLB",
    2: "HRT",
    3: "HRB",
    4: "VLT",
    5: "VLB",
    6: "VRT",
    7: "VRB",
  });

  NtMdt.DataType = Object.freeze({
    FLOATFIX: -65544,
    FLOAT80: -16138,
    FLOAT64: -13320,
    FLOAT48: -9990,
    FLOAT32: -5892,
    INT64: -8,
    INT32: -4,
    INT16: -2,
    INT8: -1,
    UNKNOWN0: 0,
    UINT8: 1,
    UINT16: 2,
    UINT32: 4,
    UINT64: 8,

    "-65544": "FLOATFIX",
    "-16138": "FLOAT80",
    "-13320": "FLOAT64",
    "-9990": "FLOAT48",
    "-5892": "FLOAT32",
    "-8": "INT64",
    "-4": "INT32",
    "-2": "INT16",
    "-1": "INT8",
    0: "UNKNOWN0",
    1: "UINT8",
    2: "UINT16",
    4: "UINT32",
    8: "UINT64",
  });

  NtMdt.XmlParamType = Object.freeze({
    NONE: 0,
    LASER_WAVELENGTH: 1,
    UNITS: 2,
    DATA_ARRAY: 255,

    0: "NONE",
    1: "LASER_WAVELENGTH",
    2: "UNITS",
    255: "DATA_ARRAY",
  });

  NtMdt.SpmMode = Object.freeze({
    CONSTANT_FORCE: 0,
    CONTACT_CONSTANT_HEIGHT: 1,
    CONTACT_ERROR: 2,
    LATERAL_FORCE: 3,
    FORCE_MODULATION: 4,
    SPREADING_RESISTANCE_IMAGING: 5,
    SEMICONTACT_TOPOGRAPHY: 6,
    SEMICONTACT_ERROR: 7,
    PHASE_CONTRAST: 8,
    AC_MAGNETIC_FORCE: 9,
    DC_MAGNETIC_FORCE: 10,
    ELECTROSTATIC_FORCE: 11,
    CAPACITANCE_CONTRAST: 12,
    KELVIN_PROBE: 13,
    CONSTANT_CURRENT: 14,
    BARRIER_HEIGHT: 15,
    CONSTANT_HEIGHT: 16,
    AFAM: 17,
    CONTACT_EFM: 18,
    SHEAR_FORCE_TOPOGRAPHY: 19,
    SFOM: 20,
    CONTACT_CAPACITANCE: 21,
    SNOM_TRANSMISSION: 22,
    SNOM_REFLECTION: 23,
    SNOM_ALL: 24,
    SNOM: 25,

    0: "CONSTANT_FORCE",
    1: "CONTACT_CONSTANT_HEIGHT",
    2: "CONTACT_ERROR",
    3: "LATERAL_FORCE",
    4: "FORCE_MODULATION",
    5: "SPREADING_RESISTANCE_IMAGING",
    6: "SEMICONTACT_TOPOGRAPHY",
    7: "SEMICONTACT_ERROR",
    8: "PHASE_CONTRAST",
    9: "AC_MAGNETIC_FORCE",
    10: "DC_MAGNETIC_FORCE",
    11: "ELECTROSTATIC_FORCE",
    12: "CAPACITANCE_CONTRAST",
    13: "KELVIN_PROBE",
    14: "CONSTANT_CURRENT",
    15: "BARRIER_HEIGHT",
    16: "CONSTANT_HEIGHT",
    17: "AFAM",
    18: "CONTACT_EFM",
    19: "SHEAR_FORCE_TOPOGRAPHY",
    20: "SFOM",
    21: "CONTACT_CAPACITANCE",
    22: "SNOM_TRANSMISSION",
    23: "SNOM_REFLECTION",
    24: "SNOM_ALL",
    25: "SNOM",
  });

  NtMdt.Unit = Object.freeze({
    RAMAN_SHIFT: -10,
    RESERVED0: -9,
    RESERVED1: -8,
    RESERVED2: -7,
    RESERVED3: -6,
    METER: -5,
    CENTI_METER: -4,
    MILLI_METER: -3,
    MICRO_METER: -2,
    NANO_METER: -1,
    ANGSTROM: 0,
    NANO_AMPERE: 1,
    VOLT: 2,
    NONE: 3,
    KILO_HERTZ: 4,
    DEGREES: 5,
    PERCENT: 6,
    CELSIUS_DEGREE: 7,
    VOLT_HIGH: 8,
    SECOND: 9,
    MILLI_SECOND: 10,
    MICRO_SECOND: 11,
    NANO_SECOND: 12,
    COUNTS: 13,
    PIXELS: 14,
    RESERVED_SFOM0: 15,
    RESERVED_SFOM1: 16,
    RESERVED_SFOM2: 17,
    RESERVED_SFOM3: 18,
    RESERVED_SFOM4: 19,
    AMPERE2: 20,
    MILLI_AMPERE: 21,
    MICRO_AMPERE: 22,
    NANO_AMPERE2: 23,
    PICO_AMPERE: 24,
    VOLT2: 25,
    MILLI_VOLT: 26,
    MICRO_VOLT: 27,
    NANO_VOLT: 28,
    PICO_VOLT: 29,
    NEWTON: 30,
    MILLI_NEWTON: 31,
    MICRO_NEWTON: 32,
    NANO_NEWTON: 33,
    PICO_NEWTON: 34,
    RESERVED_DOS0: 35,
    RESERVED_DOS1: 36,
    RESERVED_DOS2: 37,
    RESERVED_DOS3: 38,
    RESERVED_DOS4: 39,

    "-10": "RAMAN_SHIFT",
    "-9": "RESERVED0",
    "-8": "RESERVED1",
    "-7": "RESERVED2",
    "-6": "RESERVED3",
    "-5": "METER",
    "-4": "CENTI_METER",
    "-3": "MILLI_METER",
    "-2": "MICRO_METER",
    "-1": "NANO_METER",
    0: "ANGSTROM",
    1: "NANO_AMPERE",
    2: "VOLT",
    3: "NONE",
    4: "KILO_HERTZ",
    5: "DEGREES",
    6: "PERCENT",
    7: "CELSIUS_DEGREE",
    8: "VOLT_HIGH",
    9: "SECOND",
    10: "MILLI_SECOND",
    11: "MICRO_SECOND",
    12: "NANO_SECOND",
    13: "COUNTS",
    14: "PIXELS",
    15: "RESERVED_SFOM0",
    16: "RESERVED_SFOM1",
    17: "RESERVED_SFOM2",
    18: "RESERVED_SFOM3",
    19: "RESERVED_SFOM4",
    20: "AMPERE2",
    21: "MILLI_AMPERE",
    22: "MICRO_AMPERE",
    23: "NANO_AMPERE2",
    24: "PICO_AMPERE",
    25: "VOLT2",
    26: "MILLI_VOLT",
    27: "MICRO_VOLT",
    28: "NANO_VOLT",
    29: "PICO_VOLT",
    30: "NEWTON",
    31: "MILLI_NEWTON",
    32: "MICRO_NEWTON",
    33: "NANO_NEWTON",
    34: "PICO_NEWTON",
    35: "RESERVED_DOS0",
    36: "RESERVED_DOS1",
    37: "RESERVED_DOS2",
    38: "RESERVED_DOS3",
    39: "RESERVED_DOS4",
  });

  NtMdt.SpmTechnique = Object.freeze({
    CONTACT_MODE: 0,
    SEMICONTACT_MODE: 1,
    TUNNEL_CURRENT: 2,
    SNOM: 3,

    0: "CONTACT_MODE",
    1: "SEMICONTACT_MODE",
    2: "TUNNEL_CURRENT",
    3: "SNOM",
  });

  NtMdt.Consts = Object.freeze({
    FRAME_MODE_SIZE: 8,
    FRAME_HEADER_SIZE: 22,
    AXIS_SCALES_SIZE: 30,
    FILE_HEADER_SIZE: 32,
    SPECTRO_VARS_MIN_SIZE: 38,
    SCAN_VARS_MIN_SIZE: 77,

    8: "FRAME_MODE_SIZE",
    22: "FRAME_HEADER_SIZE",
    30: "AXIS_SCALES_SIZE",
    32: "FILE_HEADER_SIZE",
    38: "SPECTRO_VARS_MIN_SIZE",
    77: "SCAN_VARS_MIN_SIZE",
  });

  function NtMdt(_io, _parent, _root) {
    this._io = _io;
    this._parent = _parent;
    this._root = _root || this;

    this._read();
  }
  NtMdt.prototype._read = function() {
    this.signature = this._io.ensureFixedContents([1, 176, 147, 255]);
    this.size = this._io.readU4le();
    this.reserved0 = this._io.readBytes(4);
    this.lastFrame = this._io.readU2le();
    this.reserved1 = this._io.readBytes(18);
    this.wrondDoc = this._io.readBytes(1);
    this._raw_frames = this._io.readBytes(this.size);
    var _io__raw_frames = new KaitaiStream(this._raw_frames);
    this.frames = new Framez(_io__raw_frames, this, this._root);
  }

  var Uuid = NtMdt.Uuid = (function() {
    function Uuid(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Uuid.prototype._read = function() {
      this.data = new Array(16);
      for (var i = 0; i < 16; i++) {
        this.data[i] = this._io.readU1();
      }
    }

    return Uuid;
  })();

  var Framez = NtMdt.Framez = (function() {
    function Framez(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Framez.prototype._read = function() {
      this.frames = new Array((this._root.lastFrame + 1));
      for (var i = 0; i < (this._root.lastFrame + 1); i++) {
        this.frames[i] = new Frame(this._io, this, this._root);
      }
    }

    return Framez;
  })();

  var Frame = NtMdt.Frame = (function() {
    Frame.FrameType = Object.freeze({
      SCANNED: 0,
      SPECTROSCOPY: 1,
      TEXT: 3,
      OLD_MDA: 105,
      MDA: 106,
      PALETTE: 107,
      CURVES_NEW: 190,
      CURVES: 201,

      0: "SCANNED",
      1: "SPECTROSCOPY",
      3: "TEXT",
      105: "OLD_MDA",
      106: "MDA",
      107: "PALETTE",
      190: "CURVES_NEW",
      201: "CURVES",
    });

    function Frame(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Frame.prototype._read = function() {
      this.size = this._io.readU4le();
      this._raw_main = this._io.readBytes((this.size - 4));
      var _io__raw_main = new KaitaiStream(this._raw_main);
      this.main = new FrameMain(_io__raw_main, this, this._root);
    }

    var Dots = Frame.Dots = (function() {
      function Dots(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      Dots.prototype._read = function() {
        this.fmNdots = this._io.readU2le();
        if (this.fmNdots > 0) {
          this.coordHeader = new DotsHeader(this._io, this, this._root);
        }
        this.coordinates = new Array(this.fmNdots);
        for (var i = 0; i < this.fmNdots; i++) {
          this.coordinates[i] = new DotsData(this._io, this, this._root);
        }
        this.data = new Array(this.fmNdots);
        for (var i = 0; i < this.fmNdots; i++) {
          this.data[i] = new DataLinez(this._io, this, this._root, i);
        }
      }

      var DotsHeader = Dots.DotsHeader = (function() {
        function DotsHeader(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        DotsHeader.prototype._read = function() {
          this.headerSize = this._io.readS4le();
          this._raw_header = this._io.readBytes(this.headerSize);
          var _io__raw_header = new KaitaiStream(this._raw_header);
          this.header = new Header(_io__raw_header, this, this._root);
        }

        var Header = DotsHeader.Header = (function() {
          function Header(_io, _parent, _root) {
            this._io = _io;
            this._parent = _parent;
            this._root = _root || this;

            this._read();
          }
          Header.prototype._read = function() {
            this.coordSize = this._io.readS4le();
            this.version = this._io.readS4le();
            this.xyunits = this._io.readS2le();
          }

          return Header;
        })();

        return DotsHeader;
      })();

      var DotsData = Dots.DotsData = (function() {
        function DotsData(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        DotsData.prototype._read = function() {
          this.coordX = this._io.readF4le();
          this.coordY = this._io.readF4le();
          this.forwardSize = this._io.readS4le();
          this.backwardSize = this._io.readS4le();
        }

        return DotsData;
      })();

      var DataLinez = Dots.DataLinez = (function() {
        function DataLinez(_io, _parent, _root, index) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;
          this.index = index;

          this._read();
        }
        DataLinez.prototype._read = function() {
          this.forward = new Array(this._parent.coordinates[this.index].forwardSize);
          for (var i = 0; i < this._parent.coordinates[this.index].forwardSize; i++) {
            this.forward[i] = this._io.readS2le();
          }
          this.backward = new Array(this._parent.coordinates[this.index].backwardSize);
          for (var i = 0; i < this._parent.coordinates[this.index].backwardSize; i++) {
            this.backward[i] = this._io.readS2le();
          }
        }

        return DataLinez;
      })();

      return Dots;
    })();

    var FrameMain = Frame.FrameMain = (function() {
      function FrameMain(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      FrameMain.prototype._read = function() {
        this.type = this._io.readU2le();
        this.version = new Version(this._io, this, this._root);
        this.dateTime = new DateTime(this._io, this, this._root);
        this.varSize = this._io.readU2le();
        switch (this.type) {
        case NtMdt.Frame.FrameType.SCANNED:
          this._raw_frameData = this._io.readBytesFull();
          var _io__raw_frameData = new KaitaiStream(this._raw_frameData);
          this.frameData = new FdScanned(_io__raw_frameData, this, this._root);
          break;
        case NtMdt.Frame.FrameType.CURVES_NEW:
          this._raw_frameData = this._io.readBytesFull();
          var _io__raw_frameData = new KaitaiStream(this._raw_frameData);
          this.frameData = new FdCurvesNew(_io__raw_frameData, this, this._root);
          break;
        case NtMdt.Frame.FrameType.MDA:
          this._raw_frameData = this._io.readBytesFull();
          var _io__raw_frameData = new KaitaiStream(this._raw_frameData);
          this.frameData = new FdMetaData(_io__raw_frameData, this, this._root);
          break;
        case NtMdt.Frame.FrameType.SPECTROSCOPY:
          this._raw_frameData = this._io.readBytesFull();
          var _io__raw_frameData = new KaitaiStream(this._raw_frameData);
          this.frameData = new FdSpectroscopy(_io__raw_frameData, this, this._root);
          break;
        case NtMdt.Frame.FrameType.CURVES:
          this._raw_frameData = this._io.readBytesFull();
          var _io__raw_frameData = new KaitaiStream(this._raw_frameData);
          this.frameData = new FdSpectroscopy(_io__raw_frameData, this, this._root);
          break;
        default:
          this.frameData = this._io.readBytesFull();
          break;
        }
      }

      /**
       * h_what
       */

      /**
       * h_am, v6 and older only
       */

      /**
       * 
       */

      return FrameMain;
    })();

    var FdCurvesNew = Frame.FdCurvesNew = (function() {
      function FdCurvesNew(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      FdCurvesNew.prototype._read = function() {
        this.blockCount = this._io.readU4le();
        this.blocksHeaders = new Array(this.blockCount);
        for (var i = 0; i < this.blockCount; i++) {
          this.blocksHeaders[i] = new BlockDescr(this._io, this, this._root);
        }
        this.blocksNames = new Array(this.blockCount);
        for (var i = 0; i < this.blockCount; i++) {
          this.blocksNames[i] = KaitaiStream.bytesToStr(this._io.readBytes(this.blocksHeaders[i].nameLen), "UTF-8");
        }
        this.blocksData = new Array(this.blockCount);
        for (var i = 0; i < this.blockCount; i++) {
          this.blocksData[i] = this._io.readBytes(this.blocksHeaders[i].len);
        }
      }

      var BlockDescr = FdCurvesNew.BlockDescr = (function() {
        function BlockDescr(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        BlockDescr.prototype._read = function() {
          this.nameLen = this._io.readU4le();
          this.len = this._io.readU4le();
        }

        return BlockDescr;
      })();

      return FdCurvesNew;
    })();

    var FdMetaData = Frame.FdMetaData = (function() {
      function FdMetaData(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      FdMetaData.prototype._read = function() {
        this.headSize = this._io.readU4le();
        this.totLen = this._io.readU4le();
        this.guids = new Array(2);
        for (var i = 0; i < 2; i++) {
          this.guids[i] = new Uuid(this._io, this, this._root);
        }
        this.frameStatus = this._io.readBytes(4);
        this.nameSize = this._io.readU4le();
        this.commSize = this._io.readU4le();
        this.viewInfoSize = this._io.readU4le();
        this.specSize = this._io.readU4le();
        this.sourceInfoSize = this._io.readU4le();
        this.varSize = this._io.readU4le();
        this.dataOffset = this._io.readU4le();
        this.dataSize = this._io.readU4le();
        this.title = KaitaiStream.bytesToStr(this._io.readBytes(this.nameSize), "UTF-8");
        this.xml = KaitaiStream.bytesToStr(this._io.readBytes(this.commSize), "UTF-8");
        this.structLen = this._io.readU4le();
        this.arraySize = this._io.readU8le();
        this.cellSize = this._io.readU4le();
        this.nDimensions = this._io.readU4le();
        this.nMesurands = this._io.readU4le();
        this.dimensions = new Array(this.nDimensions);
        for (var i = 0; i < this.nDimensions; i++) {
          this.dimensions[i] = new Calibration(this._io, this, this._root);
        }
        this.mesurands = new Array(this.nMesurands);
        for (var i = 0; i < this.nMesurands; i++) {
          this.mesurands[i] = new Calibration(this._io, this, this._root);
        }
      }

      var Image = FdMetaData.Image = (function() {
        function Image(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Image.prototype._read = function() {
          this.image = [];
          var i = 0;
          while (!this._io.isEof()) {
            this.image.push(new Vec(this._io, this, this._root));
            i++;
          }
        }

        var Vec = Image.Vec = (function() {
          function Vec(_io, _parent, _root) {
            this._io = _io;
            this._parent = _parent;
            this._root = _root || this;

            this._read();
          }
          Vec.prototype._read = function() {
            this.items = new Array(this._parent._parent.nMesurands);
            for (var i = 0; i < this._parent._parent.nMesurands; i++) {
              switch (this._parent._parent.mesurands[i].dataType) {
              case NtMdt.DataType.UINT8:
                this.items[i] = this._io.readU1();
                break;
              case NtMdt.DataType.INT8:
                this.items[i] = this._io.readS1();
                break;
              case NtMdt.DataType.INT16:
                this.items[i] = this._io.readS2le();
                break;
              case NtMdt.DataType.UINT64:
                this.items[i] = this._io.readU8le();
                break;
              case NtMdt.DataType.FLOAT64:
                this.items[i] = this._io.readF8le();
                break;
              case NtMdt.DataType.INT32:
                this.items[i] = this._io.readS4le();
                break;
              case NtMdt.DataType.FLOAT32:
                this.items[i] = this._io.readF4le();
                break;
              case NtMdt.DataType.UINT16:
                this.items[i] = this._io.readU2le();
                break;
              case NtMdt.DataType.INT64:
                this.items[i] = this._io.readS8le();
                break;
              case NtMdt.DataType.UINT32:
                this.items[i] = this._io.readU4le();
                break;
              }
            }
          }

          return Vec;
        })();

        return Image;
      })();

      var Calibration = FdMetaData.Calibration = (function() {
        function Calibration(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Calibration.prototype._read = function() {
          this.lenTot = this._io.readU4le();
          this.lenStruct = this._io.readU4le();
          this.lenName = this._io.readU4le();
          this.lenComment = this._io.readU4le();
          this.lenUnit = this._io.readU4le();
          this.siUnit = this._io.readU8le();
          this.accuracy = this._io.readF8le();
          this.functionIdAndDimensions = this._io.readU8le();
          this.bias = this._io.readF8le();
          this.scale = this._io.readF8le();
          this.minIndex = this._io.readU8le();
          this.maxIndex = this._io.readU8le();
          this.dataType = this._io.readS4le();
          this.lenAuthor = this._io.readU4le();
          this.name = KaitaiStream.bytesToStr(this._io.readBytes(this.lenName), "utf-8");
          this.comment = KaitaiStream.bytesToStr(this._io.readBytes(this.lenComment), "utf-8");
          this.unit = KaitaiStream.bytesToStr(this._io.readBytes(this.lenUnit), "utf-8");
          this.author = KaitaiStream.bytesToStr(this._io.readBytes(this.lenAuthor), "utf-8");
        }
        Object.defineProperty(Calibration.prototype, 'count', {
          get: function() {
            if (this._m_count !== undefined)
              return this._m_count;
            this._m_count = ((this.maxIndex - this.minIndex) + 1);
            return this._m_count;
          }
        });

        return Calibration;
      })();
      Object.defineProperty(FdMetaData.prototype, 'image', {
        get: function() {
          if (this._m_image !== undefined)
            return this._m_image;
          var _pos = this._io.pos;
          this._io.seek(this.dataOffset);
          this._raw__m_image = this._io.readBytes(this.dataSize);
          var _io__raw__m_image = new KaitaiStream(this._raw__m_image);
          this._m_image = new Image(_io__raw__m_image, this, this._root);
          this._io.seek(_pos);
          return this._m_image;
        }
      });

      return FdMetaData;
    })();

    var FdSpectroscopy = Frame.FdSpectroscopy = (function() {
      function FdSpectroscopy(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      FdSpectroscopy.prototype._read = function() {
        this._raw_vars = this._io.readBytes(this._parent.varSize);
        var _io__raw_vars = new KaitaiStream(this._raw_vars);
        this.vars = new Vars(_io__raw_vars, this, this._root);
        this.fmMode = this._io.readU2le();
        this.fmXres = this._io.readU2le();
        this.fmYres = this._io.readU2le();
        this.dots = new Dots(this._io, this, this._root);
        this.data = new Array((this.fmXres * this.fmYres));
        for (var i = 0; i < (this.fmXres * this.fmYres); i++) {
          this.data[i] = this._io.readS2le();
        }
        this.title = new Title(this._io, this, this._root);
        this.xml = new Xml(this._io, this, this._root);
      }

      var Vars = FdSpectroscopy.Vars = (function() {
        function Vars(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Vars.prototype._read = function() {
          this.xScale = new AxisScale(this._io, this, this._root);
          this.yScale = new AxisScale(this._io, this, this._root);
          this.zScale = new AxisScale(this._io, this, this._root);
          this.spMode = this._io.readU2le();
          this.spFilter = this._io.readU2le();
          this.uBegin = this._io.readF4le();
          this.uEnd = this._io.readF4le();
          this.zUp = this._io.readS2le();
          this.zDown = this._io.readS2le();
          this.spAveraging = this._io.readU2le();
          this.spRepeat = this._io.readU1();
          this.spBack = this._io.readU1();
          this.sp4nx = this._io.readS2le();
          this.spOsc = this._io.readU1();
          this.spN4 = this._io.readU1();
          this.sp4x0 = this._io.readF4le();
          this.sp4xr = this._io.readF4le();
          this.sp4u = this._io.readS2le();
          this.sp4i = this._io.readS2le();
          this.spNx = this._io.readS2le();
        }

        return Vars;
      })();

      return FdSpectroscopy;
    })();

    var DateTime = Frame.DateTime = (function() {
      function DateTime(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      DateTime.prototype._read = function() {
        this.date = new Date(this._io, this, this._root);
        this.time = new Time(this._io, this, this._root);
      }

      var Date = DateTime.Date = (function() {
        function Date(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Date.prototype._read = function() {
          this.year = this._io.readU2le();
          this.month = this._io.readU2le();
          this.day = this._io.readU2le();
        }

        /**
         * h_yea
         */

        /**
         * h_mon
         */

        /**
         * h_day
         */

        return Date;
      })();

      var Time = DateTime.Time = (function() {
        function Time(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Time.prototype._read = function() {
          this.hour = this._io.readU2le();
          this.min = this._io.readU2le();
          this.sec = this._io.readU2le();
        }

        /**
         * h_h
         */

        /**
         * h_m
         */

        /**
         * h_s
         */

        return Time;
      })();

      return DateTime;
    })();

    var AxisScale = Frame.AxisScale = (function() {
      function AxisScale(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      AxisScale.prototype._read = function() {
        this.offset = this._io.readF4le();
        this.step = this._io.readF4le();
        this.unit = this._io.readS2le();
      }

      /**
       * x_scale->offset = gwy_get_gfloat_le(&p);# r0 (physical units)
       */

      /**
       * x_scale->step = gwy_get_gfloat_le(&p); r (physical units) x_scale->step = fabs(x_scale->step); if (!x_scale->step) {
       *   g_warning("x_scale.step == 0, changing to 1");
       *   x_scale->step = 1.0;
       * }
       */

      /**
       * U
       */

      return AxisScale;
    })();

    var FdScanned = Frame.FdScanned = (function() {
      FdScanned.Mode = Object.freeze({
        STM: 0,
        AFM: 1,
        UNKNOWN2: 2,
        UNKNOWN3: 3,
        UNKNOWN4: 4,

        0: "STM",
        1: "AFM",
        2: "UNKNOWN2",
        3: "UNKNOWN3",
        4: "UNKNOWN4",
      });

      FdScanned.InputSignal = Object.freeze({
        EXTENSION_SLOT: 0,
        BIAS_V: 1,
        GROUND: 2,

        0: "EXTENSION_SLOT",
        1: "BIAS_V",
        2: "GROUND",
      });

      FdScanned.LiftMode = Object.freeze({
        STEP: 0,
        FINE: 1,
        SLOPE: 2,

        0: "STEP",
        1: "FINE",
        2: "SLOPE",
      });

      function FdScanned(_io, _parent, _root) {
        this._io = _io;
        this._parent = _parent;
        this._root = _root || this;

        this._read();
      }
      FdScanned.prototype._read = function() {
        this._raw_vars = this._io.readBytes(this._parent.varSize);
        var _io__raw_vars = new KaitaiStream(this._raw_vars);
        this.vars = new Vars(_io__raw_vars, this, this._root);
        if (false) {
          this.origFormat = this._io.readU4le();
        }
        if (false) {
          this.tune = this._io.readU4le();
        }
        if (false) {
          this.feedbackGain = this._io.readF8le();
        }
        if (false) {
          this.dacScale = this._io.readS4le();
        }
        if (false) {
          this.overscan = this._io.readS4le();
        }
        this.fmMode = this._io.readU2le();
        this.fmXres = this._io.readU2le();
        this.fmYres = this._io.readU2le();
        this.dots = new Dots(this._io, this, this._root);
        this.image = new Array((this.fmXres * this.fmYres));
        for (var i = 0; i < (this.fmXres * this.fmYres); i++) {
          this.image[i] = this._io.readS2le();
        }
        this.title = new Title(this._io, this, this._root);
        this.xml = new Xml(this._io, this, this._root);
      }

      var Vars = FdScanned.Vars = (function() {
        function Vars(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Vars.prototype._read = function() {
          this.xScale = new AxisScale(this._io, this, this._root);
          this.yScale = new AxisScale(this._io, this, this._root);
          this.zScale = new AxisScale(this._io, this, this._root);
          this.channelIndex = this._io.readU1();
          this.mode = this._io.readU1();
          this.xres = this._io.readU2le();
          this.yres = this._io.readU2le();
          this.ndacq = this._io.readU2le();
          this.stepLength = this._io.readF4le();
          this.adt = this._io.readU2le();
          this.adcGainAmpLog10 = this._io.readU1();
          this.adcIndex = this._io.readU1();
          this.inputSignalOrVersion = this._io.readU1();
          this.substrPlaneOrderOrPassNum = this._io.readU1();
          this.scanDir = new ScanDir(this._io, this, this._root);
          this.powerOf2 = this._io.readU1();
          this.velocity = this._io.readF4le();
          this.setpoint = this._io.readF4le();
          this.biasVoltage = this._io.readF4le();
          this.draw = this._io.readU1();
          this.reserved = this._io.readU1();
          this.xoff = this._io.readS4le();
          this.yoff = this._io.readS4le();
          this.nlCorr = this._io.readU1();
        }

        /**
         * s_mode
         */

        /**
         * s_dev
         */

        /**
         * s_nx
         */

        /**
         * s_ny
         */

        /**
         * Step (DAC)
         */

        /**
         * s_rs in Angstrom's (Angstrom*gwy_get_gfloat_le(&p))
         */

        /**
         * s_adt
         */

        /**
         * s_adc_a
         */

        /**
         * ADC index
         */

        /**
         * MDTInputSignal smp_in; s_smp_in (for signal) s_8xx (for version)
         */

        /**
         * s_spl or z_03
         */

        /**
         * s_xy TODO: interpretation
         */

        /**
         * s_2n (bool)
         */

        /**
         * s_vel (Angstrom/second)
         */

        /**
         * s_i0
         */

        /**
         * s_ut
         */

        /**
         * s_draw (bool)
         */

        /**
         * s_x00 (in DAC quants)
         */

        /**
         * s_y00 (in DAC quants)
         */

        /**
         * s_cor (bool)
         */

        return Vars;
      })();

      var Dot = FdScanned.Dot = (function() {
        function Dot(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        Dot.prototype._read = function() {
          this.x = this._io.readS2le();
          this.y = this._io.readS2le();
        }

        return Dot;
      })();

      var ScanDir = FdScanned.ScanDir = (function() {
        function ScanDir(_io, _parent, _root) {
          this._io = _io;
          this._parent = _parent;
          this._root = _root || this;

          this._read();
        }
        ScanDir.prototype._read = function() {
          this.unkn = this._io.readBitsInt(4);
          this.doublePass = this._io.readBitsInt(1) != 0;
          this.bottom = this._io.readBitsInt(1) != 0;
          this.left = this._io.readBitsInt(1) != 0;
          this.horizontal = this._io.readBitsInt(1) != 0;
        }

        /**
         * Bottom - 1 Top - 0
         */

        /**
         * Left - 1 Right - 0
         */

        /**
         * Horizontal - 1 Vertical - 0
         */

        return ScanDir;
      })();

      /**
       * s_oem
       */

      /**
       * z_tune
       */

      /**
       * s_fbg
       */

      /**
       * s_s
       */

      /**
       * s_xov (in %)
       */

      /**
       * m_mode
       */

      /**
       * m_nx
       */

      /**
       * m_ny
       */

      return FdScanned;
    })();

    /**
     * h_sz
     */

    return Frame;
  })();

  var Version = NtMdt.Version = (function() {
    function Version(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Version.prototype._read = function() {
      this.minor = this._io.readU1();
      this.major = this._io.readU1();
    }

    return Version;
  })();

  var Xml = NtMdt.Xml = (function() {
    function Xml(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Xml.prototype._read = function() {
      this.xmlLen = this._io.readU4le();
      this.xml = KaitaiStream.bytesToStr(this._io.readBytes(this.xmlLen), "UTF-16LE");
    }

    return Xml;
  })();

  var Title = NtMdt.Title = (function() {
    function Title(_io, _parent, _root) {
      this._io = _io;
      this._parent = _parent;
      this._root = _root || this;

      this._read();
    }
    Title.prototype._read = function() {
      this.titleLen = this._io.readU4le();
      this.title = KaitaiStream.bytesToStr(this._io.readBytes(this.titleLen), "cp1251");
    }

    return Title;
  })();

  /**
   * File size (w/o header)
   */

  /**
   * documentation specifies 32 bytes long header, but zeroth frame starts at 33th byte in reality
   */

  return NtMdt;
})();
return NtMdt;
}));