TDMSファイル形式内部構造

概要

この記事では、TDMストリーミング(TDMS)ファイル形式の内部構造を詳しく説明します。

内容

論理構造

TDMSファイルは、3階層のオブジェクトでデータを組織化します。最上位は、作成者やタイトルなどファイル特有の情報を持つ単一オブジェクトによって構成されています。各ファイルは無制限数のグループを持つことができ、各グループは無制限数のチャンネルを持つことが可能です。以下の図に示すexample events.tdmsファイルでは、2グループに2チャンネルずつ含まれています。

各TDMSオブジェクトは、パスによって一意に識別されます。パスは、オブジェクト名およびTDMS階層内の所有者名が含まれた、/(スラッシュ)で区切られている文字列です。各名前は、'(シングル引用符)記号で囲まれます。オブジェクト名に含まれる'記号は、"(ダブル引用符)記号で置換されます。以下の表は、各種TDMSオブジェクトにおけるパス形式の例を示しています。

オブジェクト名オブジェクトパス
--ファイル/
Measured Dataグループ/'Measured Data'
Amplitude Sweepチャンネル/'Measured Data'/'Amplitude Sweep'
Dr. T's Eventsグループ/'Dr. T''s Events'
Timeチャンネル/'Events'/'Time'

すべてのTDMSクライアントアプリケーションが適切に動作するためには、各TDMSファイルにファイルオブジェクトが含まれている必要があります。また、チャンネルパスで使用されるグループ名のために、グループオブジェクトが含まれている必要があります。さらに、チャンネルを含まない任意の数のグループオブジェクトを含めることもできます。

各TDMSオブジェクトには無制限数のプロパティを付与できます。TDMSプロパティは、名前(常に文字列)、タイプ識別子、値を組み合わせたもので構成されます。プロパティの一般的なデータタイプには、整数や浮動小数点などの数値タイプ、タイムスタンプ、または文字列が挙げられます。TDMSプロパティは配列や複合データタイプはサポートしません。TDMSファイルがNIデータファインダの検索範囲内にある場合、すべてのプロパティは自動的に検索対象となります。

未処理データの配列を含むことができるのは、TDMSファイル内のチャンネルオブジェクトのみです。現在のTDMSバージョンでは、1次元配列のみがサポートされています。

バイナリレイアウト

各TDMSファイルには、メタデータと未処理データの2種類のデータが含まれます。メタデータは、オブジェクトまたはプロパティに含まれる説明用のデータです。チャンネルオブジェクトに追加されるデータ配列が、未処理データと呼ばれます。TDMSファイルに含まれるのは、連続したブロックの1つにおける複数チャンネル用未処理データです。TDMSファイルは、未処理データの指標を使用してそのブロックから未処理データを抽出します。未処理データ指標には、データに対応するチャンネルなどのデータブロック構成情報や、そのチャンネル用にブロックに含まれる値の数、データの格納順序に関する情報が含まれます。

TDMSセグメントレイアウト

データはTDMSにセグメント単位で書き込まれます。データがTDMSファイルに追加されるたびに、セグメントが新規作成されます。この規則の例外については、この記事の「未処理データ」セクションを参照してください。セグメントは、以下の3つの部分で構成されます。

  • リードイン ― ファイルをTDMSとして識別するタグ、バージョン番号、およびそのセグメント全体の長さなど基本的な情報が含まれます。
  • メタデータ ― このセグメント内のすべてのオブジェクト名とプロパティが含まれます。未処理データ(チャンネル)を含むオブジェクトの場合、この部分には、未処理データやオブジェクトをセグメント内で検索するための指標情報も含まれます。
  • 未処理データ ― このセグメントに含まれる任意のオブジェクトに関連するすべての未処理データの連続ブロックです。未処理データ部分には、インタリーブされたデータ値や、連続したデータチャンクが含まれる場合があります。また、DAQmxからの未処理データを含む場合もあります。

この記事では、DAQmxデータのデコード方法については説明しません。TDMSはネイティブサポートされていますが、ナショナルインスツルメンツが提供する任意のコンポーネントを使用していないソフトウェアでTDMSファイルを読み取る必要がある場合、このデータを読み取ることはできません。

TDMSファイルにおけるすべての文字列(オブジェクトパス、プロパティ名、プロパティ値、未処理データ値など)は、UTF-8 Unicodeでコーディングされています。未処理データ値を除き、これらの文字列の前には、長さの値自体は含めない文字列長をビットで表した32ビット符号なし整数が付与されます。TDMS内における文字列の終端文字はNULLである場合もありますが、長さ情報が格納されているため、ファイルから読み出す際はNULL終端文字は無視されます。

TDMSのタイムスタンプは2つのコンポーネント構造で保持されています。

  • (i64)秒:始点は01/01/1904 00:00:00.00 UTC(グレゴリオ歴を使用し、うるう秒を無視)
  • (u64)正の数:1秒の2^-64

ブール値はそれぞれ1バイトで保持されます。1がTRUEを、0がFALSEを表します。

リードイン

リードインには、セグメントの検証に使用される情報が含まれます。また、TDMSファイルへのランダムアクセスに使用される情報も含まれます。以下の例は、TDMSファイルのリードイン部分のバイナリフットプリントを示しています。

バイナリレイアウト(16進法)説明
54 44 53 6D"TDSm"タグ
0E 00 00 00ToCマスク0x1110(セグメントにはオブジェクトリスト、メタデータ、未処理データが含まれる)
69 12 00 00バージョン番号(4713)
E6 00 00 00 00 00 00 00次のセグメントのオフセット(値:230)
DE 00 00 00 00 00 00 00未処理データのオフセット(値:222)

上の表のリードイン部分には、以下の情報が含まれます。

  • リードインは、TDMSセグメントとして識別する4バイトのタグ("TDSm")で開始します。
  • 次の4バイトはビットマスクとして使用され、そのセグメントが含むデータの種類が示されます。このビットマスクは、ToC(目次:Table of Contents)と呼ばれます。以下のフラグを任意で組み合わせてToC内でエンコードすることができます。
    フラグ説明
    #define kTocMetaData         (1L<<1)セグメントにメタデータが含まれる
    #define kTocRawData          (1L<<3)セグメントに未処理データが含まれる
    #define kTocDAQmxRawData     (1L<<7)セグメントにDAQmx未処理データが含まれる
    #define kTocInterleavedData  (1L<<5)セグメント内の未処理データをインタリーブする(フラグが設定されない場合、データは連続的)
    #define kTocBigEndian        (1L<<6)セグメント内のすべての数値(プロパティ、未処理データなど)がビッグエンディアン形式である(フラグが設定されない場合、データはリトルエンディアン)
    #define kTocNewObjList       (1L<<2)セグメントに新規オブジェクトリストが含まれる(例:このセグメントのチャンネルが前のセグメントに含まれるチャンネルと同じでない)
  • その後の4バイトはバージョン番号(32ビットの符号なし整数)で、セグメントがコンパイルされる一番古いTDMSバージョンが指定されます。この書き込みにおけるバージョン番号は4713です。TDMSの旧バージョンは4712のみです。
  • その後の8バイト(符号なし64ビット整数)は、残りのセグメント長を示します(セグメント全体の長さからリードイン部分を引いたもの)。ファイルにさらにセグメントが追加される場合、この数値は後続のセグメントの開始点を特定するために使用されます。TDMSへの書き込み中にアプリケーションで深刻な問題(クラッシュ、停電)が発生した場合、この整数のすべてのバイトが0xFFになる可能性があります。これは、ファイル内の最後のセグメントにのみ発生します。
  • 最後の8バイト(符号なし64ビット整数)は、セグメント内メタ情報の全体の長さを示します。この情報は、未処理データへのランダムアクセスに使用されます。セグメントにメタデータ(プロパティ、指標情報、オブジェクトリスト)がまったく含まれない場合、この値は0になります。

メタデータ

TDMSのメタデータは、ファイル、グループ、チャンネルなどデータオブジェクトの3階層で構成されます。これらのオブジェクトタイプはそれぞれ任意数のプロパティを含むことができます。メタデータセクションは、ディスク上で以下のバイナリレイアウトを取ります。

  • このセグメント内の新規オブジェクト数(符号なし32ビット整数)
  • これらの各オブジェクトのバイナリ表現

ディスク上の単一TDMSオブジェクトのバイナリレイアウトは、以下の順序のコンポーネントで構成されます。特定のセグメントに格納される情報によっては、これらのコンポーネントのサブセットのみがオブジェクトに含まれる場合もあります。

  • オブジェクトパス(文字列)
  • 未処理データ指標
    • セグメント内で、そのオブジェクトに割り当てられた未処理データがない場合、指標情報の代わりに符号なし32ビット整数(0xFFFFFFFF)が保存されます。
    • セグメント内のオブジェクトの未処理データ指標が、前のセグメント内における同一オブジェクトの指標と一致する場合、指標情報の代わりに符号なし32ビット整数(0x0000000)が保存されます。
    • オブジェクトの未処理データ指標が、前のセグメント内における同一オブジェクトの指標と一致しない場合、その未処理データの新規指標が保存されます。
      • 指標情報の長さ(符号なし32ビット整数)
      • データタイプ(tdsDataType列挙体、32ビット整数として保存)
      • 配列の次元(符号なし32ビット整数、現時点での有効値は1のみ)
      • 値の数(符号なし64ビット整数)
      • 全体のバイトサイズ(符号なし64ビット整数、文字列などの可変長データタイプの場合のみ保存)
  • プロパティ数(符号なし32ビット整数)
  • プロパティ。プロパティごとに、以下の情報が保存されます。
    • 名前(文字列)
    • データタイプ(tdsDataType)
    • 値(数値はバイナリ値で保存、文字列は上述のように保存)

以下の表は、1つのグループと1つのチャンネル用のメタ情報の例を示しています。グループには2つのプロパティ(1つの文字列と1つの整数)が含まれています。チャンネルには未処理データ指標が含まれていますが、プロパティは含まれていません。

バイナリフットプリント(16進法)説明
02 00 00 00オブジェクト数
08 00 00 00最初のオブジェクトパスの長さ
2F 27 47 72
6F 75 70 27
オブジェクトパス(/'Group')
FF FF FF FF未処理データ指標("FF FF FF FF"は、オブジェクトに未処理データが割り当てられていないことを示す)
02 00 00 00/'Group'のプロパティ数
04 00 00 00最初のプロパティ名の長さ
70 72 6F 70プロパティ名(prop)
20 00 00 00プロパティ値のデータタイプ(tdsTypeString)
05 00 00 00プロパティ値の長さ(文字列の場合のみ)
76 61 6C 75
65
propプロパティの値(値)
03 00 00 002番目のプロパティ名の長さ
6E 75 6Dプロパティ名(num)
03 00 00 00プロパティ値のデータタイプ(tdsTypeI32)
0E 00 00 00numプロパティの値(10)
13 00 00 002番目のオブジェクトパスの長さ
2F 27 47 72
6F 75 70 27
2F 27 43 68
61 6E 6E 65
6C 31 27
2番目のオブジェクトパス(/'Group'/'Channel1')
14 00 00 00指標情報の長さ
03 00 00 00このオブジェクトに割り当てられた未処理データのデータタイプ
01 00 00 00未処理データ配列の次元(1である必要がある)
02 00 00 00
00 00 00 00
未処理データ値の数
00 00 00 00/'Group'/'Channel1'のプロパティ数(プロパティなし)

前のセグメント内のメタ情報と合致するメタ情報は、後続のセグメントで省略可能です。省略はオプションですが、冗長なメタ情報を省略することでファイルの読み取り速度が大幅に増加します。冗長な情報を書き込む場合、LabVIEW、LabWindows/CVI、またはMeasurementStudioで「TDMSを最適化(TDMS Defragment)」関数を使用することにより後で削除することができます。

  • 次のセグメントに新規オブジェクトを書き込むということは、そのセグメントが前のセグメントからのすべてのオブジェクトと、ここに記述された新規オブジェクトを含むということを意味します。新規セグメントが前のセグメントからの任意のチャンネルを含まない場合、またはセグメント内のチャンネル順序が変更した場合、新規セグメントはすべてのオブジェクトの新規リストを含む必要があります。詳細は、このドキュメントの「最適化」セクションを参照してください。
  • 前のセグメントで既に存在するオブジェクトに新規プロパティを書き込むと、オブジェクトにこのプロパティが追加されます。
  • オブジェクト上で既に存在するプロパティを書き込むと、そのプロパティの前の値が上書きされます。

以下の例は、上述したセグメントのすぐ後に続くセグメントのメタデータセクションのバイナリフットプリントを示しています。新規セグメントに書き込まれるメタ情報は、プロパティの新規値のみです。

バイナリレイアウト(16進法)説明
01 00 00 00新規/変更オブジェクト数
08 00 00 00オブジェクトパスの長さ
2F 27 47 72
6F 75 70 27
オブジェクトパス(/'Group')
FF FF FF FF未処理データ指標(オブジェクトに割り当てられた未処理データなし)
01 00 00 00新規/変更プロパティ数
03 00 00 00プロパティ名の長さ
6E 75 6Dプロパティ名(num)
03 00 00 00プロパティ値のデータタイプ(tdsTypeI32)
07 00 00 00numプロパティの新規値(7)




未処理データ

最後に、セグメントには各チャンネルに関連付けられた未処理データが含まれます。各チャンネルのデータ配列は、セグメントのメタ情報部分にチャンネルが現れる順番通りに連結されます。数値データは、リードインのリトルエンディアン/ビッグエンディングフラグに従ってフォーマットする必要があります。いったん書き込まれると、チャンネルはエンディアン形式やデータタイプを変更できない点に注意してください。

文字列タイプのチャンネルは、高速ランダムアクセス用にあらかじめ処理されます。すべての文字列は連続メモリに連結されます。連続メモリ内の各文字列における最初の文字オフセットは、符号なし32ビット整数の配列に保存されます。オフセット値の配列が最初に保存され、その後に連結された文字列値が続きます。このレイアウトによって、クライアントアプリケーションは最大3回までファイルポインタの位置を変えることにより、不要なデータを読み取ることなくファイル内のどこからでも任意の文字列値にアクセスすることができます。

セグメント間でメタ情報に変更がない場合、リードインとメタ情報の部分を完全に省略し、未処理データのみをファイルの最後に追加できます。後続の未処理データチャンクのバイナリレイアウトは同じになり、チャンク数は以下の手順でリードインとメタ情報から計算されます。

  1. チャンネルの未処理データサイズを計算します。各チャンネルにはメタ情報内のデータタイプ配列の次元値の数が含まれています。詳細は、このドキュメントの「メタデータ」セクションを参照してください。タイプサイズは各データタイプに関連付けられています。チャンネルの未処理データサイズは、データタイプのタイプサイズ×配列の次元×値の数によって求められます。全体のバイトサイズが有効である場合、チャンネルの未処理データサイズがこの値になります。
  2. すべてのチャンネルの未処理データサイズを合計することにより、1チャンクの未処理データサイズを計算します。
  3. 次のセグメントのオフセット ― 未処理データのオフセットによって合計チャンクの未処理データサイズを計算します。次のセグメントのオフセットの値が-1である場合、次のセグメントのオフセットの値をファイルサイズとして使用します。
  4. チャンク数を、合計チャンクの未処理データサイズ÷1チャンクの未処理データサイズによって計算します。

未処理データはインタリーブするものと、インタリーブしないものの2種類に分類されます。セグメントのリードイン内のToCビットマスクは、セグメント内データをインタリーブするかどうかを指定します。例:チャンネル1(1、2、3)とチャンネル2(4、5、6)に32ビット整数値を保存する場合、以下のレイアウトのようになります。

データレイアウトバイナリフットプリント(16進法)
インタリーブしない01 00 00 00  02 00 00 00  03 00 00 00  
04 00 00 00  05 00 00 00  06 00 00 00
インタリーブする01 00 00 00  04 00 00 00  02 00 00 00  
05 00 00 00  03 00 00 00  06 00 00 00




データタイプの値

以下の列挙体タイプは、TDMSファイル内のプロパティやチャンネルのデータタイプを示しています。プロパティの場合、データタイプ値は名前とバイナリ値の間に保存されます。チャンネルの場合、データタイプは未処理データ指標の一部になります。

typedef enum {
    tdsTypeVoid,
    tdsTypeI8,    
    tdsTypeI16,    
    tdsTypeI32,    
    tdsTypeI64,
    tdsTypeU8,    
    tdsTypeU16,    
    tdsTypeU32,    
    tdsTypeU64,
    tdsTypeSingleFloat,    
    tdsTypeDoubleFloat,    
    tdsTypeExtendedFloat,    
    tdsTypeSingleFloatWithUnit=0x19,    
    tdsTypeDoubleFloatWithUnit,    
    tdsTypeExtendedFloatWithUnit,
    tdsTypeString=0x20,   
    tdsTypeBoolean=0x21,   
    tdsTypeTimeStamp=0x44,   
    tdsTypeDAQmxRawData=0xFFFFFFFF
} tdsDataType;

メモ:

  • LabVIEWでtdsTypeTimeStampを使用する詳細については、Developer Zone記事LabVIEWタイムスタンプ(英語)を参照してください。
  • 単位付きLabVIEW浮動小数点タイプは、単位を文字列として含むunit_stringプロパティと一緒に浮動小数点チャンネルになります。

TDMSがどのように作成されるかの詳細については、TDMSファイルに書き込むVIベースのAPI(英語)を参照してください。

定義済みプロパティ

LabVIEW波形はTDMS内で数値チャンネルとして表されますが、波形の属性はプロパティとしてチャンネルに追加されます。

  • wf_start_time ― このプロパティは、波形が集録または生成された時間を示します。このプロパティは、時間情報が相対的な場合または波形が時間領域ではない場合(たとえば周波数領域である場合)に、0になります。
  • wf_start_offset ― このプロパティは、LabVIEW Express Dynamic Data Typeで使用されます。周波数領域データとヒストグラム結果は、この値をx軸の最初の値として使用します。
  • wf_increment ― このプロパティは、x軸上の2つの連続サンプル間の増分を示します。
  • wf_samples ― このプロパティは、波形内のサンプル数を示します。

最適化

ここまで述べたきたように、フォーマット定義を適用すれば、有効なTDMSファイルを作成することはできます。ただしTDMSでは、LabVIEW、LabWindows/CVI、またはMeasurementStudioなどのNIソフトウェアで一般的も使用される多彩な最適化を行うことが可能です。NIソフトウェアで書き込んだデータの読み取りを実行するアプリケーションでは、このパラグラフで述べる最適化の仕組みをサポートする必要があります。

増分メタ情報の例

オブジェクトパス、プロパティ、未処理データ指標などのメタ情報は、変更があった場合のみセグメントに追加されます。増分メタ情報は、以下の例で最もよく説明できます。

最初のセグメントには、チャンネル1と2が書き込まれます。各チャンネルには、3つの32ビット整数値(1、2、3および4、5、6)といくつかの説明用プロパティが含まれます。最初のセグメントのメタ情報部分には、チャンネル1と2のパス、プロパティ、および未処理データ指標が含まれます。ToCビットフィールドのフラグであるkTocMetaData、kTocNewObjList、およびkTocRawDataが設定されます。最初のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  0E 00 00 00  68 12 00 00
8F 00 00 00  00 00 00 00  77 00 00 00
00 00 00 00
オブジェクト数02 00 00 00
メタ情報(オブジェクト1)13 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 63 68  61 6E 6E 65  6C 31 27 14
00 00 00 03  00 00 00 01  00 00 00 03
00 00 00 00  00 00 00 01  00 00 00 04
00 00 00 70  72 6F 70 20  00 00 00 05
00 00 00 76  61 6C 69 64
メタ情報(オブジェクト2)13 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 63 68  61 6E 6E 65  6C 32 27 14
00 00 00 03  00 00 00 01  00 00 00 03
00 00 00 00  00 00 00 00  00 00 00
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル2)04 00 00 00  05 00 00 00  06 00 00 00

2番目のセグメントでは、プロパティに変更はなく、チャンネル1と2には依然として各3つの値が含まれ、追加のチャンネルはセグメントに書き込まれません。このセグメントにはメタデータは含まれません。前のセグメントからのメタデータが依然として有効です。未処理データビットのみがToCビットフィールドに設定されます。2番目のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  08 00 00 00  68 12 00 00
18 00 00 00  00 00 00 00  00 00 00 00
00 00 00 00
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル2)04 00 00 00  05 00 00 00  06 00 00 00

3番目のセグメントでは、さらに3つの値を各チャンネルに追加します。チャンネル1は、最初のセグメントでstatusプロパティをvalidに設定しましたが、今度はerrorに設定する必要があります。3番目のセグメントのメタデータセクションには、このプロパティ用のチャンネル、名前、タイプ、および値のオブジェクトパスが含まれます。今後ファイルが読み取られると、前に書き込まれたvalidという値がerrorという値で上書きされます。ただし、前のvalid値はデフラグされない限りファイル内に残ります。3番目のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  0A 00 00 00  68 12 00 00
60 00 00 00  00 00 00 00  48 00 00 00
00 00 00 00
オブジェクト数01 00 00 00
メタ情報(オブジェクト1)13 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 63 68  61 6E 6E 65  6C 31 27 14
00 00 00 03  00 00 00 01  00 00 00 03
00 00 00 00  00 00 00 01  00 00 00 04
00 00 00 70  72 6F 70 20  00 00 00 05
00 00 00 65  72 72 6F 72
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル2)04 00 00 00  05 00 00 00  06 00 00 00

4番目のセグメントでは、5つの値(7、8、9、10、11)を含む別のチャンネル(voltage)を追加します。前のセグメントからの他のすべてのメタデータは依然として有効であるため、4番目のセグメントのメタデータセクションにはvoltageチャンネル用のみのオブジェクトパス、プロパティ、指標情報が含まれます。未処理データセクションには、チャンネル1の3つの値、チャンネル2の3つの値、voltageチャンネルの5つの値が含まれます。4番目のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  0A 00 00 00  68 12 00 00
5E 00 00 00  00 00 00 00  32 00 00 00
00 00 00 00
オブジェクト数01 00 00 00
メタ情報(オブジェクト3)12 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 76 6F  6C 74 61 67  65 27 14 00
00 00 03 00  00 00 01 00  00 00 05 00
00 00 00 00  00 00 00 00  00 00
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル2)04 00 00 00  05 00 00 00  06 00 00 00
未処理データ(チャンネル3)07 00 00 00  08 00 00 00  09 00 00 00
0A 00 00 00  0B 00 00 00

5番目のセグメントでは、チャンネル2に27個の値が含まれます。他のチャンネルには変更はありません。メタデータセクションには、チャンネル2のオブジェクトパス、チャンネル2の新規未処理データ指標が含まれますが、チャンネル2のプロパティは含まれません。5番目のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  0A 00 00 00  68 12 00 00
BF 00 00 00  00 00 00 00  33 00 00 00
00 00 00 00
オブジェクト数01 00 00 00
メタ情報(オブジェクト2)13 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 63 68  61 6E 6E 65  6C 32 27 14
00 00 00 03  00 00 00 01  00 00 00 1B
00 00 00 00  00 00 00 00  00 00 00
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル2)01 00 00 00  02 00 00 00  03 00 00 00
04 00 00 00  05 00 00 00  06 00 00 00
07 00 00 00  08 00 00 00  09 00 00 00
0A 00 00 00  0B 00 00 00  0C 00 00 00
0D 00 00 00  0E 00 00 00  0F 00 00 00
10 00 00 00  11 00 00 00  12 00 00 00
13 00 00 00  14 00 00 00  15 00 00 00
16 00 00 00  17 00 00 00  18 00 00 00
19 00 00 00  1A 00 00 00  1B 00 00 00
未処理データ(チャンネル3)07 00 00 00  08 00 00 00  09 00 00 00
0A 00 00 00  0B 00 00 00

6番目のセグメントでは、チャンネル2への書き込みを停止します。チャンネル1とvoltageチャンネルへの書き込みのみを継続します。これによりチャンネル順序の変更が発生するため、チャンネルパスの新規リストを書くことが必要になります。ToC bit kTocNewObjListを設定する必要があります。新規セグメントのメタデータセクションはすべてのパスの完全なリストを含む必要がありますが、プロパティと未処理データ指標は変更が発生していない限り含まれません。6番目のセグメントのバイナリフットプリントは下記のようになります。

部分バイナリフットプリント(16進法)
リードイン54 44 53 6D  0E 00 00 00  68 12 00 00
81 00 00 00  00 00 00 00  61 00 00 00
00 00 00 00
オブジェクト数02 00 00 00
メタ情報(オブジェクト1)13 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 63 68  61 6E 6E 65  6C 31 27 14
00 00 00 03  00 00 00 01  00 00 00 03
00 00 00 00  00 00 00 00  00 00 00
メタ情報(オブジェクト2)12 00 00 00  2F 27 67 72  6F 75 70 27
2F 27 76 6F  6C 74 61 67  65 27 14 00
00 00 03 00  00 00 01 00  00 00 05 00
00 00 00 00  00 00 00 00  00 00
未処理データ(チャンネル1)01 00 00 00  02 00 00 00  03 00 00 00
未処理データ(チャンネル3)07 00 00 00  08 00 00 00  09 00 00 00
0A 00 00 00  0B 00 00 00




指標ファイル

TDMSに書き込まれるすべてのデータは.tdms拡張子のファイルに保存されます。*.tdms_indexという指標ファイルもオプションで付随します。指標ファイルは*.tdmsファイルからの読み取りを高速化するために使用されます。ナショナルインスツルメンツのアプリケーションから指標ファイルなしのTDMSファイルを開くと、自動的に指標ファイルが作成されます。LabVIEWやLabVIEW Windows/CVIなどのナショナルインスツルメンツアプリケーションからTDMSファイルに書き込む場合、メインの*.tdmsファイルと指標ファイルが同時に作成されます。

指標ファイルは*.tdmsファイルのコピーですが、未処理データは含まず、すべてのセグメントがTDSmタグではなくTDShタグで開始します。指標ファイルには、*.tdmsファイル内の任意のチャンネルの任意の値を正しく検索するためのすべての情報が含まれます。

結論

このように、TDMSファイル形式は、説明用の情報の階層システムを維持しながら非常に高速に計測データの書き込み/読み取りを行なうために設計されています。バイナリレイアウト自体はシンプルですが、メタデータを増分的に書き込んで最適化することにより、非常に洗練されたファイル構成にすることができます。

Was this information helpful?

Yes

No