TDMS 파일 포맷 내부 구조

개요

이 문서에서는 TDMS(TDM 스트리밍) 파일 포맷의 내부 구조를 자세히 설명합니다.

내용

논리적 구조

TDMS 파일은 3단계 객체 계층구조로 데이터를 구성합니다. 최상위 레벨은 작성자 또는 제목과 같은 파일별 정보를 담은 단일 객체로 구성됩니다. 각 파일에 포함될 수 있는 그룹의 수는 무제한이며, 각 그룹에 속할 수 있는 채널 개수에도 제한이 없습니다. 다음 그림에서 example events.tdms 파일에는 2개의 그룹이 포함되며, 각 그룹에는 2개의 채널이 있습니다.

모든 TDMS 객체는 경로를 통해 고유하게 식별됩니다. 각 경로는 객체 이름 및 TDMS 계층구조에서 객체 소유자의 이름을 포함한 문자열이며, 사선으로 구분됩니다. 각 이름은 따옴표로 묶습니다. 객체 이름 내의 작은 따옴표는 큰 따옴표로 대체됩니다. 다음 테이블은 각 TDMS 객체 타입에 대한 경로 포맷팅 예를 보여줍니다.

객체 이름 객체 경로
-- 파일 /
측정된 데이터 그룹 /’측정된 데이터’
스윕 진폭 채널 /'측정된 데이터'/'스윕 진폭'
Dr. T의 이벤트 그룹 /'Dr. T'의 이벤트'
시간 채널 /'Dr. T'의 이벤트'/'시간'

TDMS 클라이언트 어플리케이션이 전부 제대로 작동하려면 모든 TDMS 파일에 파일 객체가 있어야 합니다. 파일 객체는 채널 경로에 사용된 각 그룹 이름에 대한 그룹 객체를 포함해야 합니다. 또한, 파일 객체는 채널이 없는 그룹 객체를 임의의 개수만큼 포함할 수 있습니다.

TDMS 객체가 가질 수 있는 프로퍼티의 수에는 제한이 없습니다. 각 TDMS 프로퍼티는 이름(항상 문자열), 타입 식별자 및 값으로 구성됩니다. 프로퍼티의 일반적인 데이터 타입은 정수 또는 부동소수점과 같은 숫자 타입, 타임스탬프 또는 문자열 등입니다. TDMS 프로퍼티는 배열을 지원하지 않습니다. TDMS 파일이 내쇼날인스트루먼트 DataFinder의 검색 영역에 있는 경우 모든 프로퍼티의 위치를 자동으로 찾을 수 있습니다.

TDMS 파일의 채널 객체만 원시 데이터 배열을 포함할 수 있습니다. 현재 TDMS 버전에서는 1차원의 배열만 지원됩니다.

2진 레이아웃

모든 TDMS 파일에는 메타 데이터와 원시 데이터라는 2가지 데이터 타입이 있습니다. 메타 데이터는 객체 또는 프로퍼티에 저장된 설명 데이터를 말합니다. 채널 객체에 연결된 데이터 배열은 원시 데이터를 뜻합니다. TDMS 파일에는 하나의 인접 블록 안에 여러 채널에 대한 원시 데이터가 들어 있습니다. 해당 블록에서 원시 데이터를 추출할 수 있도록 TDMS 파일은 원시 데이터 인덱스를 사용합니다. 여기에는 데이터에 해당하는 채널, 해당 채널에 대해 블록이 가진 총 값, 데이터가 저장되는 순서 등 데이터 블록 구성 요소에 대한 정보가 포함됩니다.

TDMS 선분 레이아웃

데이터는 선분에 있는 TDMS 파일에 작성됩니다. 데이터가 TDMS 파일에 추가될 때마다 새로운 선분이 생성됩니다. 해당 규칙에 대한 예외 사항은 이 문서의 메타 데이터원시 데이터 섹션을 참조하십시오. 선분은 다음의 세 부분으로 구성됩니다.

  • 도입—파일을 TDMS로 식별하는 태그, 버전 번호, 메타 데이터 및 원시 데이터의 길이 정보와 같은 기본 정보를 포함합니다.
  • 메타 데이터—선분에 있는 모든 객체의 이름 및 프로퍼티를 포함합니다. 원시 데이터(채널)를 포함하는 객체의 경우 선분에서 해당 객체의 원시 데이터의 위치를 찾는 데 사용되는 인덱스 정보도 메타 데이터 부분에 들어 있습니다.
  • 원시 데이터—선분에 포함된 객체와 관련된 모든 원시 데이터의 인접 블록입니다. 원시 데이터 부분에는 끼워넣기 형식의 데이터 값 또는 일련의 인접 데이터 그룹이 포함될 수 있습니다. 그밖에도 DAQmx의 원시 데이터가 속할 수 있습니다.

객체 경로, 프로퍼티 이름, 프로퍼티 값 및 원시 데이터 값과 같은 TDMS 파일의 모든 문자열은 UTF-8 유니코드로 인코딩됩니다. 원시 데이터 값을 제외한 모든 값 앞에는 부호없는 32비트 정수가 오며, 여기에는 길이 값 자체가 아닌 바이트 단위 문자열 길이가 포함됩니다. TDMS 파일의 문자열은 널 종료될 수 있지만, 길이 정보가 저장되므로 파일에서 읽을 때 널 종료자가 무시됩니다.

TDMS 파일의 타임스탬프는 다음 두 구성 요소의 구조로 저장됩니다.

  • (i64) Epoch 01/01/1904 00:00:00.00 UTC 이후의 초 수(그레고리력을 사용하고 윤초는 무시함)
  • (u64) 양의 분수: (2^-64) 초

불리언 값은 각각 1 바이트로 저장됩니다. 여기서 1은 참을 의미하며, 0은 거짓을 나타냅니다.

도입

도입에는 선분의 유효성을 검증하는 데 사용되는 정보가 있습니다. 또한, TDMS 파일에 대한 무작위 접근에 사용되는 정보도 포함되어 있습니다. 다음 예는 TDMS 파일 도입 부분에 대한 2진 배치 공간을 보여줍니다.

2진 레이아웃(16진수) 설명
54 44 53 6D ‘TDSm’ 태그
0E 00 00 00 ToC 마스크 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 선분(‘TDSm’)을 식별하는 4 바이트 태그로 시작합니다.
  • 다음 4 바이트는 비트 마스크로 사용되어 선분에 어떤 데이터 유형이 포함되어 있는지 나타냅니다. 이 비트 마스크를 ToC(목차)라고 합니다. 아래 플래그 조합은 ToC에서 인코딩될 수 있습니다.
    플래그 설명
    #define kTocMetaData         (1L<<1) 선분에 메타 데이터가 포함됩니다.
    #define kTocRawData          (1L<<3) 선분에 원시 데이터가 포함됩니다.
    #define kTocDAQmxRawData     (1L<<7) 선분에 DAQmx 원시 데이터가 포함됩니다.
    #define kTocInterleavedData  (1L<<5) 선분에 원시 데이터가 끼워넣어지며, 플래그가 설정되지 않으면 데이터는 서로 인접하게 됩니다.
    #define kTocBigEndian        (1L<<6) 도입, 원시 데이터 및 메타 데이터를 포함한 선분의 모든 숫자 값은 빅 엔디안 형식이며, 플래그가 설정되지 않은 경우 데이터는 리틀 엔디안 형식이 됩니다. ToC는 엔디안에 영향을 받지 않고 항상 리틀 엔디안 형식을 띕니다.
    #define kTocNewObjList       (1L<<2) 선분에 새로운 객체 목록이 포함됩니다. 예를 들어, 이 선분의 채널은 이전 선분에 속한 것과 동일한 채널이 아닙니다.
  • 다음 4 바이트에는 버전 번호(32비트 부호없는 정수)가 포함되는데, 이는 선분에서 따르는 가장 오래된 TDMS 개정을 지정합니다. 이 문서를 작성할 당시의 버전 번호는 4713입니다. TDMS의 이전 버전은 4712뿐입니다.

    참고:
    버전 번호 4713은 LabVIEW의 TDMS 파일 포맷 버전 2.0에 해당합니다. 버전 번호 4712는 LabVIEW의 TDMS 파일 포맷 버전 1.0에 해당합니다.
  • 다음 8 바이트(64비트 부호없는 정수)는 나머지 선분의 길이를 나타내며, 이는 선분 전체 길이에서 도입 길이를 뺀 값입니다. 추후 파일에 선분이 추가되면, 이 번호를 사용하여 다음 선분의 시작점 위치를 찾을 수 있습니다. TDMS 파일에 작성하는 동안 어플리케이션에 심각한 문제(충돌, 정전)가 발생하면, 이 정수의 모든 바이트는 0xFF가 될 수 있습니다. 이는 파일의 마지막 선분에서만 발생할 수 있습니다.
  • 마지막 8 바이트(64비트 부호없는 정수)는 선분에 있는 메타 정보의 전체 길이를 나타냅니다. 이 정보는 원시 데이터에 무작위로 접근하는 데 사용됩니다. 선분에 메타 데이터(프로퍼티, 인덱스 정보, 객체 목록)가 전혀 없는 경우 해당 값은 0이 됩니다.

메타 데이터

TDMS 메타 데이터는 파일, 그룹 및 채널을 포함한 3단계 데이터 객체 계층구조로 구성됩니다. 이러한 각 객체 타입에는 여러 프로퍼티가 포함될 수 있습니다. 메타 데이터 섹션에는 디스크에 다음과 같은 2진 레이아웃이 있습니다.

  • 해당 선분의 새 객체 수(부호없는 32비트 정수)
  • 이러한 각 객체의 2진 형

디스크에서 단일 TDMS 객체의 2진 레이아웃은 다음 순서에 따른 구성 요소로 이루어집니다. 특정 선분에 저장된 정보에 따라, 객체에는 이러한 구성 요소의 일부분만 포함될 수도 있습니다.

  • 객체 경로(문자열)
  • 원시 데이터 인덱스
    • 이 선분에 할당된 원시 데이터가 해당 객체에 없는 경우 인덱스 정보 대신 부호없는 32비트 정수(0xFFFFFFFF)가 저장됩니다.
    • 해당 객체가 이 선분에 DAQmx 원시 데이터를 포함하고 있는 경우 원시 데이터 인덱스의 처음 4 바이트는 ‘69 12 00 00’(원시 데이터에 DAQmx 포맷 변경 스케일 인자가 포함됨) 또는 ‘69 13 00 00’(원시 데이터에 DAQmx 디지털 라인 스케일 인자가 포함됨)이 됩니다. 뒤따르는 첫번째 4 바이트는 DAQmx 원시 데이터 인덱스에 대한 정보입니다. FAQmx 원시 데이터 인덱스에 대한 자세한 정보는 아래 글머리 기호의 내용을 참조하십시오.
    • 이 선분에 있는 객체의 원시 데이터 인덱스가 이전 선분의 동일 객체가 가졌던 인덱스와 정확히 일치하면, 인덱스 정보 대신 부호없는 32비트 정수(0x0000000)가 저장됩니다.
    • 이전 선분의 객체에 할당된 인덱스 정보와 일치하지 않는 원시 데이터가 객체에 포함된 경우, 다음과 같이 해당 원시 데이터에 대한 새로운 인덱스가 저장됩니다.
      • 원시 데이터 인덱스의 길이(부호없는 32비트 정수)
      • 데이터 타입(tdsDataType 열거형, 32비트 정수로 저장됨)
      • 배열 차원(부호없는 32비트 정수) (TDMS 파일 포맷 버전 2.0에서는 1이 유일한 유효 값)
      • 값의 개수(부호없는 64비트 정수)
      • 바이트 단위의 총 크기(부호없는 64비트 정수) (문자열과 같은 가변 길이 데이터 타입에 대해서만 저장됨)
  • 원시 데이터 인덱스가 DAQmx 원시 데이터 인덱스인 경우 인덱스에는 다음의 정보가 포함됩니다.
    • 데이터 타입(부호없는 32비트 정수), 여기서 ‘FF FF FF FF’는 원시 데이터가 DAQmx 원시 데이터임을 의미
    • 배열 차원(부호없는 32비트 정수) (TDMS 파일 포맷 버전 2.0에서는 1이 유일한 유효 값)
    • ‘그룹 크기'라고도 하는 값(부호없는 64 비트 정수)의 개수
    • 포맷 변경 스케일 인자의 벡터
      • 벡터 크기(부호없는 32비트 정수)
        다음은 첫번째 포맷 변경 스케일 인자 정보에 해당합니다.
      • DAQmx 데이터 타입(부호없는 32 비트 정수)
      • 원시 버퍼 인덱스(부호없는 32비트 정수)
      • 스트라이드 내 원시 바이트 오프셋(부호없는 32비트 정수)
      • 샘플 포맷 비트맵(부호없는 32비트 정수)
      • 스케일 ID(부호없는 32비트 정수)
        (벡터 크기가 1보다 크면 객체에 여러 포맷 변경 스케일 인자가 포함되며, 이전 글머리 기호 항목의 정보가 그대로 적용될 수 있습니다.)
    • 원시 데이터 너비의 벡터
      • 벡터 크기(부호없는 32비트 정수)
      • 벡터의 요소(각 부호없는 32비트 정수)
  • 프로퍼티의 개수(부호없는 32비트 정수)
  • 프로퍼티. 각 프로퍼티에 대해 다음의 정보가 저장됩니다.
    • 이름(문자열)
    • 데이터 타입(tdsDataType)
    • 값(2진수로 저장된 숫자, 앞서 설명한 대로 저장된 문자열)

다음 테이블은 그룹 및 채널에 대한 메타 정보의 예를 보여줍니다. 이 그룹에는 문자열과 정수를 하나씩 포함하는 2가지 프로퍼티가 있습니다. 채널은 프로퍼티 없이 원시 데이터 인덱스를 포함합니다.

2진 배치 공간(16진수) 설명
02 00 00 00 객체 수
08 00 00 00 첫번째 객체 경로의 길이
2F 27 47 72
6F 75 70 27
객체 경로(/'그룹')
FF FF FF FF 원시 데이터 인덱스(‘FF FF FF FF’는 객체에 할당된 원시 데이터가 없음을 의미)
02 00 00 00 /'그룹'의 프로퍼티 수
04 00 00 00 첫번째 프로퍼티 이름의 길이
70 72 6F 70 프로퍼티 이름(prop)
20 00 00 00 프로퍼티 값의 데이터 타입(tdsTypeString)
05 00 00 00 프로퍼티 값의 길이(문자열에만 해당)
76 61 6C 75
65
프로퍼티 prop의 값(value)
03 00 00 00 두번째 프로퍼티 이름의 길이
6E 75 6D 프로퍼티 이름(num)
03 00 00 00 프로퍼티 값의 데이터 타입(tdsTypeI32)
0A 00 00 00 프로퍼티 num의 값(10)
13 00 00 00 두번째 객체 경로의 길이
2F 27 47 72
6F 75 70 27
2F 27 43 68
61 6E 6E 65
6C 31 27
두번째 객체의 경로(/'그룹'/'채널1')
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 /'그룹'/채널1'에 대한 프로퍼티 수(프로퍼티 없음)

다음 테이블은 DAQmx 원시 데이터 인덱스의 예입니다.

2진 배치 공간(16진수) 설명
03 00 00 00 객체 수
23 00 00 00 그룹 객체 경로의 길이
2F 27 4D 65
61 73 75 72
65 64 20 54
68 72 6F 75
67 68 70 75
74 20 44 61
74 61 20 28
56 6F 6C 74
73 29 27
객체 경로(/'측정된 처리량 데이터(볼트)')
FF FF FF FF 원시 데이터 인덱스(‘FF FF FF FF’는 객체에 할당된 원시 데이터가 없음을 의미)
00 00 00 00 /'측정된 처리량 데이터(볼트)'에 대한 프로퍼티 수
34 00 00 00 채널 객체 경로의 길이
2F 27 4D 65
61 73 75 72
65 64 20 54
68 72 6F 75
67 68 70 75
74 20 44 61
74 61 20 28
56 6F 6C 74
73 29 27 2F
27 50 58 49
31 53 6C 6F
74 30 33 2d
61 69 30 27
69 12 00 00
/'측정된 처리량 데이터(볼트)'/'PXI1Slot03-ai0'
69 12 00 00 DAQmx 원시 데이터 인덱스, 포맷 변경 스케일 인자 포함
FF FF FF FF 데이터 타입, DAQmx 원시 데이터
01 00 00 00 데이터 차원
00 00 00 00
00 00 00 00
값의 개수, 이 선분에는 값이 없음
01 00 00 00
포맷 변경 스케일 인자의 벡터 크기
05 00 00 00
첫번째 포맷 변경 스케일 인자의 DAQmx 데이터 타입
00 00 00 00
첫번째 포맷 변경 스케일 인자의 원시 버퍼 인덱스
00 00 00 00
스트라이드 내 원시 바이트 오프셋
00 00 00 00
샘플 포맷 비트맵
00 00 00 00
스케일 ID
01 00 00 00
원시 데이터 너비의 벡터 크기
08 00 00 00
원시 데이터 너비에 대한 벡터의 첫번째 요소
06 00 00 00
/'측정된 처리량 데이터(볼트)'/'PXI1Slot03-ai0'에 대한 프로퍼티 수
11 00 00 00 첫번째 프로퍼티 이름의 길이
4E 49 5F 53
63 61 6C 69
6E 67 5F 53
74 61 74 75
73
프로퍼티 이름(‘NI_Scaling_Status’)
20 00 00 00 프로퍼티 값의 데이터 타입(tdsTypeString)
08 00 00 00 프로퍼티 값의 길이(문자열에만 해당)
75 6E 73 63
61 6C 65 64
프로퍼티 prop의 값(‘unscaled’)
13 00 00 00 두번째 프로퍼티 이름의 길이
4E 49 5F 4E
75 6D 62 65
72 5F 4F 66
5F 53 63 61
6C 65 73
프로퍼티 이름(‘NI_Number_Of_Scales’)
07 00 00 00 프로퍼티 값의 데이터 타입(tdsTypeU32)
02 00 00 00 프로퍼티의 값(2)
16 00 00 00 세번째 프로퍼티 이름의 길이
4E 49 5F 53
63 61 6C 65
5B 31 5D 5F
53 63 61 6C
65 5F 54 79
70 65
프로퍼티 이름(‘NI_Scale[1]_Scale_Type’)
20 00 00 00 프로퍼티의 데이터 타입(tdsTypeString)
06 00 00 00 프로퍼티 값의 길이
4C 69 6E 65
61 72/span>
프로퍼티 값(‘Linear’)
18 00 00 00 네번째 프로퍼티 이름의 길이
4E 49 5F 53
63 61 6C 65
5B 31 5D 5F
4C 69 6E 65
61 72 5F 53
6C 6F 70 65
프로퍼티 이름(‘NI_Scale[1]_Linear_Slope’)
0A 00 00 00 프로퍼티의 데이터 타입(tdsTypeDoubleFloat)
04 E9 47 DD
CB 17 1D 3E
프로퍼티 값(1.693433E-9)
1E 00 00 00 다섯번째 프로퍼티 이름의 길이
4E 49 5F 53
63 61 6C 65
5B 31 5D 5F
4C 69 6E 65
61 72 5F 59
5F 49 6E 74
65 72 63 65
70 74
프로퍼티 이름(‘NI_Scale[1]_Linear_Y_Intercept’)
0A 00 00 00 프로퍼티의 데이터 타입(tdsTypeDoubleFloat)
00 00 00 00
00 00 00 00
프로퍼티 값(0)
1F 00 00 00 여섯번째 프로퍼티 이름의 길이
4E 49 5F 53
63 61 6C 65
5B 31 5D 5F
4C 69 6E 65
61 72 5F 59
6E 70 75 74
5F 53 6F 75
72 63 65
프로퍼티 이름(‘NI_Scale[1]_Linear_Input_Source’)
07 00 00 00 프로퍼티의 데이터 타입(tdsTypeU32)
00 00 00 00 프로퍼티 값(0)

이전 테이블에서 ‘/'측정된 처리량 데이터(볼트)’/’PXI1Slot03-ai0’ 채널에는 2개의 스케일 인자가 있습니다. 첫번째 스케일 인자는 포맷 변경이며, 여기서 포맷 변경 스케일 인자의 정보가 DAQmx 원시 데이터 인덱스에 저장됩니다. 다른 하나는 선형 스케일 인자이며, 정보가 TDMS 프로퍼티로 저장됩니다. 선형 스케일 인자의 기울기가 1.693433E-9, 절편이 0, 입력 소스 ID가 0인 경우, 포맷 변경 스케일 인자를 식별할 수 있습니다.

이전 선분의 메타 정보와 일치하는 메타 정보는 뒤따르는 선분에서 생략할 수 있습니다. 이 옵션은 선택 사항이지만, 중복된 메타 정보를 생략하면 파일 읽기 속도가 크게 향상됩니다. 중복되는 정보를 작성하기로 한 경우, 추후 LabVIEW, LabWindows/CVI, MeasurementStudio 등에서 TDMS 세분화 기능을 사용하여 이를 제거할 수 있습니다.

  • 다음 선분에 새로운 객체를 작성하면 이전 선분의 모든 객체와 여기에서 설명한 새 객체가 이 선분에 포함되어 있음을 나타낼 수 있습니다. 새 선분에 이전 선분의 채널이 없거나, 선분의 채널 순서가 변경되면, 새로운 선분에 모든 객체의 최신 목록이 포함되어야 합니다. 자세한 내용은 이 문서의 최적화 섹션을 참조하십시오.
  • 이전 선분에 이미 존재하는 객체에 새로운 프로퍼티를 작성하면 해당 프로퍼티가 객체에 추가됩니다.
  • 객체에 이미 존재하는 프로퍼티를 작성하면 해당 프로퍼티의 이전 값을 덮어쓰게 됩니다.

    참고:
    TDMS 파일 포맷 버전 2.0에서 기존 객체의 이름 프로퍼티 값을 지정하면 해당 객체의 이름이 변경됩니다.

다음 예는 앞서 설명한 선분 바로 뒤에 오는 선분의 메타 데이터 섹션에 대한 2진 배치 공간을 보여줍니다. 새 프로퍼티 값이 새로운 선분에 작성된 유일한 메타 정보가 됩니다.

2진 레이아웃(16진수) 설명
01 00 00 00 신규/변경된 객체 수
08 00 00 00 객체 경로의 길이
2F 27 47 72
6F 75 70 27
객체 경로(/'그룹')
FF FF FF FF 원시 데이터 인덱스(객체에 할당된 원시 데이터 없음)
01 00 00 00 신규/변경된 프로퍼티 수
03 00 00 00 프로퍼티 이름의 길이
6E 75 6D 프로퍼티 이름(num)
03 00 00 00 프로퍼티 값의 데이터 타입(tdsTypeI32)
07 00 00 00 프로퍼티 num 새 값(7)

원시 데이터

선분에는 최종적으로 각 채널과 관련된 원시 데이터가 포함됩니다. 모든 채널의 데이터 배열은 채널이 선분의 메타 정보 부분에 나타나는 순서에 따라 연결됩니다. 숫자 데이터 포맷은 도입의 리틀 엔디안/빅 엔디안 플래그에 따라 지정되어야 합니다. 처음 채널이 작성되고 나면 엔디안 포맷 또는 데이터 타입을 변경할 수 없습니다.

문자열 타입 채널은 빠른 무작위 접근이 가능하도록 사전 처리됩니다. 모든 문자열은 인접한 메모리에 연결됩니다. 이 인접한 메모리에 있는 각 문자열의 첫 문자 오프셋은 부호없는 32비트 정수 배열에 저장됩니다. 이 오프셋 값 배열이 먼저 저장되고, 뒤따라 연결된 문자열 값이 저장됩니다. 이 레이아웃을 사용하면 클라이언트 어플리케이션이 파일 포인터의 위치를 최대 3번 바꾸고 클라이언트에 필요하지 않은 데이터를 읽지 않으며 파일의 어디에서나 문자열 값을 확인할 수 있게 됩니다.

선분 간 메타 정보가 변경되지 않는다면, 도입 및 메타 정보 부분을 완전히 생략하고 원시 데이터를 파일 끝에 추가할 수 있습니다. 각 후속 원시 데이터 그룹은 동일한 2진 레이아웃을 갖게 되며, 다음 단계에 따라 도입 및 메타 정보에서 그룹 수를 계산할 수 있게 됩니다.

  1. 채널의 원시 데이터 크기를 계산하십시오. 각 채널에는 메타 정보의 데이터 타입, 배열 차원값의 개수가 포함되어 있습니다. 자세한 내용은 이 문서의 메타 데이터 섹션을 참조하십시오. 각 데이터 타입은 타입 크기와 관련이 있습니다. 데이터 타입의 타입 크기, 배열 차원값 개수를 곱하여 채널의 원시 데이터 크기를 계산할 수 있습니다. 바이트 단위의 총 크기가 유효하다면, 해당 값이 채널의 원시 데이터 크기가 됩니다.
  2. 모든 채널의 원시 데이터 크기를 더하여 한 그룹의 원시 데이터 크기를 계산하십시오.
  3. 총 그룹의 원시 데이터 크기는 다음 선분 오프셋에서 원시 데이터 오프셋을 빼서 계산할 수 있습니다. 다음 선분 오프셋의 값이 -1이면, 총 그룹의 원시 데이터 크기는 파일 크기에서 원시 데이터의 절대 시작 위치를 뺀 값과 같습니다.
  4. 그룹 수는 총 그룹의 원시 데이터 크기에서 그룹 하나의 원시 데이터 크기를 나눠서 계산할 수 있습니다.

원시 데이터는 끼워넣기 레이아웃과 끼워넣기 형식이 아닌 레이아웃 등 2가지 타입으로 구성될 수 있습니다. 선분 도입의 ToC 비트 마스크는 선분 데이터가 끼워넣기 형식인지 여부를 선언합니다. 예를 들어, 채널 1(1,2,3) 및 채널 2(4,5,6)에 32비트 정수 값을 저장하면 다음과 같은 레이아웃이 만들어집니다.

데이터 레이아웃 2진 배치 공간(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 파일에서 프로퍼티 또는 채널의 데이터 타입을 설명합니다. 프로퍼티의 경우 데이터 타입 값은 이름과 2진 값 사이에 저장됩니다. 채널의 경우 데이터 타입은 원시 데이터 인덱스의 일부가 됩니다.

타입정의 열거형 {
    tdsTypeVoid,
    tdsTypeI8,    
    tdsTypeI16,    
    tdsTypeI32,    
    tdsTypeI64,
    tdsTypeU8,    
    tdsTypeU16,    
    tdsTypeU32,    
    tdsTypeU64,
    tdsTypeSingleFloat,    
    tdsTypeDoubleFloat,    
    tdsTypeExtendedFloat,    
    tdsTypeSingleFloatWithUnit=0x19,    
    tdsTypeDoubleFloatWithUnit,    
    tdsTypeExtendedFloatWithUnit,
    tdsTypeString=0x20,   
    tdsTypeBoolean=0x21,   
    tdsTypeTimeStamp=0x44,
    tdsTypeFixedPoint=0x4F,
    tdsTypeComplexSingleFloat=0x08000c,
    tdsTypeComplexDoubleFloat=0x10000d,
    tdsTypeDAQmxRawData=0xFFFFFFFF
} tdsDataType;

참고:

  • LabVIEW에서 tdsTypeTimeStamp를 사용하는 방법에 대한 자세한 정보는 LabVIEW 타임스탬프 문서를 참조하십시오.
  • 단위가 있는 LabVIEW 부동소수점 타입은 단위를 문자열로 포함하는 unit_string이라는 이름의 프로퍼티를 가진 부동소수점 채널로 변환됩니다.

TDMS 작성 기능에 대한 자세한 정보는 TDMS 파일 작성을 위한 VI 기반 API 문서를 참조하십시오.

미리 정의된 프로퍼티

LabVIEW 웨이브폼은 TDMS 파일에서 숫자 채널로 표시되며, 여기에서 웨이브폼 속성은 해당 채널에 프로퍼티로 추가됩니다.

  • wf_start_time–웨이브폼이 수집되거나 생성된 시간을 나타냅니다. 시간 정보가 상대적이거나 웨이브폼이 시간 영역이 아닌 경우(가령 주파수 영역인 경우) 이 프로퍼티는 제로가 될 수 있습니다.
  • wf_start_offset–LabVIEW 익스프레스 다이나믹 데이터 타입에 사용됩니다. 주파수 영역 데이터와 히스토그램 결과는 이 값을 x축의 첫번째 값으로 사용합니다.
  • wf_incrementx축에 있는 연속적인 샘플 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, kTocNewObjListkTocRawData가 설정됩니다. 첫번째 쓰기 반복을 통해 데이터 선분이 생성됩니다. 다음 테이블은 첫번째 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0E 00 00 00  69 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

두번째 쓰기 반복에서는 변경된 프로퍼티가 없으며, 채널 1과 채널 2에는 각각 3개의 값이 그대로 유지됩니다. 추가 채널은 작성되지 않습니다. 따라서 이 반복으로 메타 데이터가 작성되지 않습니다. 이전 선분의 메타 데이터가 여전히 유효한 것으로 간주됩니다. 이 반복으로는 새 선분이 작성되지 않습니다. 대신 이를 통해 원시 데이터가 기존 선분에 추가되며 도입 섹션의 다음 선분 오프셋이 업데이트됩니다. 다음 테이블은 업데이트된 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0E 00 00 00  69 12 00 00
A7 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
원시 데이터 채널 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개가 추가됩니다. 채널 1의 경우 프로퍼티 상태는 첫번째 선분에서 유효한 것으로 설정되었지만, 이제는 에러로 지정되어야 합니다. 이 반복으로 새로운 선분이 생겨나고, 이제 해당 선분의 메타 데이터 섹션에 프로퍼티의 채널, 이름, 타입 및 값에 대한 객체 경로가 포함됩니다. 향후 파일을 읽을 때 에러 값은 이전에 작성된 유효 값을 재정의합니다. 그러나 이전 유효 값의 단편화를 제거하지 않는 한 이 값은 파일에 남게 됩니다. 다음 테이블은 두번째 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0A 00 00 00  69 12 00 00
50 00 00 00  00 00 00 00  38 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 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

네번째 쓰기 반복으로 5개의 값(7,8,9,10,11)을 포함하는 별도 채널인 전압이 추가됩니다. 이 반복으로 TDMS 파일에 세번째 선분이 새롭게 생성됩니다. 이전 선분의 다른 모든 메타 데이터가 여전히 유효하기 때문에 네번째 선분의 메타 데이터 섹션에는 채널 전압에 대한 객체 경로, 프로퍼티 및 인덱스 정보만 포함됩니다. 원시 데이터 섹션은 채널 1에 대한 값 3개, 채널 2에 대한 값 3개 및 채널 전압에 대한 값 5개를 보유하게 됩니다. 다음 테이블은 세번째 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0A 00 00 00  69 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

네번째 선분에서 채널 2는 이제 27개의 값을 갖습니다. 다른 모든 채널에는 변화가 없습니다. 메타 데이터 섹션은 이제 채널 2의 프로퍼티를 제외한 객체 경로와 새로운 원시 데이터 인덱스를 포함합니다. 다음 테이블은 네번째 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0A 00 00 00  69 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

다섯번째 선분에서 어플리케이션은 채널 2에 대한 쓰기 작업을 중지합니다. 이 어플리케이션은 채널 1과 채널 전압에만 쓰기 작업을 계속합니다. 이로 인해 채널 순서가 변경되므로, 새로운 채널 경로 목록을 작성해야 합니다. ToC 비트 kTocNewObjList를 설정해야 합니다. 새로운 선분의 메타 데이터 섹션에는 모든 객체 경로의 전체 목록이 포함되어야 하지만, 프로퍼티와 원시 데이터 인덱스는 변동이 없는 한 제외됩니다. 다음 테이블은 다섯번째 선분의 2진 배치 공간을 설명합니다.

부분 2진 배치 공간(16진수)
도입 54 44 53 6D  0E 00 00 00  69 12 00 00
61 00 00 00  00 00 00 00  41 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 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 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 파일에는 *.tdms_index 옵션 인덱스 파일이 포함될 수 있습니다. 인덱스 파일은 *.tdms 파일에서 읽기 속도를 높이는 데 사용됩니다. 내쇼날인스트루먼트 어플리케이션이 인덱스 파일 없이 TDMS 파일을 열면 어플리케이션에서 자동으로 인덱스 파일을 생성합니다. LabVIEW 또는 LabWindows/CVI와 같은 내쇼날인스트루먼트 어플리케이션으로 TDMS 파일을 작성하면 어플리케이션은 이와 동시에 인덱스 파일과 기본 파일을 생성합니다.

인덱스 파일은 원시 데이터를 일체 포함하지 않고 모든 선분이 TDSm 태그 대신 TDSh 태그로 시작한다는 점을 제외하고는 *.tdms 파일의 완벽한 복사본이라 할 수 있습니다. 인덱스 파일에는 *.tdms 파일 내에서 채널 값의 위치를 정확하게 찾는 데 필요한 모든 정보가 포함되어 있습니다.

결론

한 마디로 TDMS 파일 포맷은 설명 정보의 계층적 체계를 유지하면서 측정된 데이터를 놀랍도록 빠른 속도로 쓰고 읽도록 설계되었습니다. 2진 레이아웃 자체는 다소 단순하지만, 메타 데이터를 증분식으로 작성하여 진행되는 최적화 작업으로 인해 파일 구성이 매우 복잡해질 수 있습니다.

관련 링크

Developer Zone: TDMS 파일 작성을 위한 VI 기반 API

Developer Zone: TDMS 2.0 FAQ

Developer Zone: LabWindows/CVI TDM 스트리밍 라이브러리 소개(TDMS 파일 포맷의 기능 및 사용 사례 개요)