IDL/Data Type & Format

ASDF 형식 파일의 생성 및 읽기

이상우_IDL 2023. 11. 2. 14:13
728x90

ASDF(Advanced Scientific Data Format)는 주로 천문학 분야에서 이미지 및 데이터의 교환을 위하여 많이 사용되어왔던 FITS 표준을 대체하는 역할로서 최근들어 많이 사용되고 있는 데이터 형식입니다. 제임스웹 우주망원경(James Webb Space Telescope)의 데이터 처리 파이프라인에서도 사용되고 있기도 합니다. 따라서 이러한 형식의 데이터 파일을 생성하거나 읽는 기능을 여러 프로그래밍 언어들에서 이미 지원하고 있는데, IDL의 경우도 8.9 버전부터 ASDF 형식의 파일 생성 및 읽기 기능을 지원하기 시작하였습니다. 얼마전에 IDL 8.9의 출시에 관한 게시물을 통해서도 간략하게 언급을 한 바 있는데요. 오늘은 IDL에서 ASDF 파일을 생성하고 읽는 방법에 관하여 좀 더 자세히 소개해보기로 하겠습니다.

 

 

< ASDF 파일 생성 >

 

먼저 IDL에서 정의된 데이터들을 ASDF 파일로 저장하는 예제부터 살펴보겠습니다. 먼저 다음과 같이 IDL에서 3종의 데이터를 정의해봅시다.

 

a = HANNING(768, 512)
b = 'IDL User'
c = [34, 55, 82, 63, 48]

 

이 3종의 데이터를 모두 담은 ASDF 파일을 생성하고자 하는데, 이를 위해서는 먼저 ASDF_FILE 함수를 사용하여 일종의 데이터 객체(Object)를 생성해야 합니다. IDL 도움말의 설명에 의하면, 이 객체는 ASDF_file 클래스 객체라고 할 수 있으며 내부적으로는 헤더 정보, 세부 데이터들 및 그 계층구조 등에 관한 정보들을 포함하게 됩니다. 일단 ASDF_FILE 함수를 사용하여 데이터 객체부터 먼저 다음과 같이 생성해봅시다.

 

data = ASDF_FILE('item1', a, 'item2', b, 'item3', c)

 

이렇게 하면 data라는 이름의 객체가 생성됩니다. 참고로 IDL 도움말에서 ASDF_FILE 함수를 사용하는 문법을 살펴보면 다음과 같이 소개되어 있습니다.

 

Result = ASDF_File(Key1Value1Key2Value2, ... KeynValuen)

 

즉 ASDF 파일로 저장될 데이터를 먼저 ASDF_FILE 함수에서 정의하는데 있어서는 (Key, Value) 형태의 쌍이 되도록 해야 합니다. 이것은 해쉬(Hash)와 같은 형태라고 보면 됩니다. 그래서 일단 여기서는 a는 'item1'이라는 키(Key)에 연결하고 b는 'item2'이라는 키에 그리고 c는 'item3'이라는 키에 연결한 것입니다. 그리고 이렇게 정의된 data라는 객체에 새로운 데이터를 추가할 수도 있습니다. 예를 들면 다음과 같습니다.

 

data['item4'] = !const.h

 

이렇게 하면 'item4'라는 새로운 키에 대하여 플랑크 상수에 해당되는 실수값이 부여된 쌍이 data 객체에 추가됩니다. 따라서 data 객체에는 총 4종의 데이터가 수록된 셈입니다. 이제 이 객체를 바로 ASDF 파일로 저장하면 됩니다. 이를 위해서는 ASDF_WRITE 프로시저를 다음과 같이 사용하면 됩니다.

 

ASDF_WRITE, 'myfile.asdf', data

 

이렇게 하면 data 객체에 포함된 4종의 데이터를 담은 ASDF 형식의 파일이 생성됩니다. 여기서는 파일명을 'myfile.asdf'로 정의하였습니다. 이 과정까지 정상적으로 실행되었다면 작업 디렉토리 내에 'myfile.asdf'라는 파일이 생성되어 있을 것입니다.

 

 

< ASDF 파일 읽기 >

 

이번에는 이렇게 생성된 ASDF 파일을 IDL에서 읽어서 그 안에 수록된 데이터를 추출해봅시다. 이러한 작업을 위해서는 ASDF_PARSE 함수를 사용해야 합니다. 앞서 이미 생성했던 ASDF 파일이 존재하는 상태에서 ASDF_PARSE 함수를 다음과 같이 사용해봅시다.

 

info = ASDF_PARSE('myfile.asdf')

 

이렇게 하면 대상 ASDF 파일을 읽어서 그 안에 수록된 데이터 객체부터 가져오게 됩니다. 여기서는 이 객체를 info라는 이름으로 가져왔습니다. 세부적으로는 4종의 데이터가 수록된 파일이기 때문에 이 객체를 통하여 각각의 세부 데이터를 추출해야 합니다. 이를 위해서는 데이터 객체를 각 데이터의 키(Key)로 인덱싱하는 방식으로 추출하면 됩니다. 일단 먼저 다음과 같이 'item3'이라는 키를 통하여 해당 데이터를 추출해봅시다.

 

ext = info['item3']
HELP, ext

 

이와 같이 info 객체에 대하여 'item3' 키를 통하여 추출한 데이터를 ext라는 이름으로 가져왔는데요. HELP에 의하여 출력된 내용을 보면 다음과 같습니다.

 

EXT             ASDF_NDARRAY  <ID=416>  int16 [5] inline

 

그런데 앞서 우리가 처음에 데이터를 정의하고 ASDF 파일로 저장했던 과정을 돌이켜보면 'item3' 키에 대응되는 데이터는 5개의 정수값들로 구성된 1차원 배열인 c였습니다. 그런데 위의 출력 내용을 보면 뭔가 우리가 원했던 형태는 아직 아닌 것 같습니다. 실제로는 다음과 같이 추출해줘야 합니다.

 

ext = info['item3', 'data']
HELP, ext

 

이와 같이 원래 배열이었던 데이터를 추출하기 위해서는 키(Key)만으로는 부족하고 'data'라는 하위 키를 하나 더 사용해야 합니다. 이렇게 하면 HELP에 의하여 다음과 같은 내용이 출력됩니다.

 

EXT             LONG64    = Array[5]

 

이 내용을 보면 비로소 우리가 원했던 형태로 추출되었음을 확인할 수 있습니다. 이제 나머지 항목들에 대해서도 모두 확인을 해봅시다. 먼저 'item1'입니다.

 

ext = info['item1', 'data']
HELP, ext

 

EXT             FLOAT     = Array[768, 512]

 

이와 같이 'item1'이란 키에 대응되었던 2차원 배열이 제대로 추출됩니다. 그리고 'item4'를 추출해봅시다.

 

ext = info['item4']
HELP, ext

 

EXT             DOUBLE    =    6.6260696e-34

 

여기서 유의할 점은 'item4' 키에 대응된 데이터는 실수형 단일값인데, 이와 같이 단일값 형태인 데이터를 추출할 경우에는 'data'라는 하위 키의 사용이 필요없다는 것입니다. 이번에는 'item2'입니다.

 

ext = info['item2']
HELP, ext

 

EXT             STRING    = 'IDL User'

 

이것은 문자형 단일값이었기 때문에 이렇게 추출됩니다. 결국은 ASDF 파일로부터 데이터를 추출할 때에는 그 데이터의 형태 및 자료형에 따라서 인덱싱의 방식이 달라질 수 있다는 것을 유의할 필요가 있습니다.

 

 

< 계층적 구조의 데이터 >

 

그 외에도 한가지 더 주목해야 할 것은 ASDF 파일 내에 수록된 데이터가 계층적 구조를 갖는 경우입니다. 앞서 서두에서 정의했던 데이터들을 다음과 같이 myhash라는 HASH 유형의 자료로 한번 묶은 상태에서 이 해쉬에 대하여 'Set1'이라는 키를 부여하여 데이터 객체를 정의하고 ASDF 파일로 저장해봅시다.

 

myhash = HASH('item1', a, 'item2', b, 'item3', c, 'item4', !const.h)
data = ASDF_FILE('Set1', myhash)

ASDF_WRITE, 'myfile2.asdf', data

 

이렇게 생성된 'myfile2.asdf' 파일에 대하여 이제 ASDF_PARSE 함수를 사용하여 내부 데이터를 추출해봅시다. 다만 이번에는 데이터의 계층 구조를 감안하여 다음과 같이 처리해야 합니다.

 

info = ASDF_PARSE('myfile2.asdf')
ext = info['Set1', 'item2']
HELP, ext

 

EXT             STRING    = 'IDL User'

 

여기서는 ASDF_PARSE 함수로 추출한 데이터 객체 info에 대하여 키(Key)를 사용하여 인덱싱하는데 있어서 상위 키에 해당되는 'Set1'이 가장 먼저 명시되어야 한다는 것을 유의해야 합니다. 즉 위의 내용은 'Set1' 키의 하위 키들중 하나인 'item2' 키를 통하여 데이터를 가져온 경우입니다. 그리고 배열 데이터를 추출해야 할 경우에 'data'라는 하위 키가 필요한 것은 마찬가지입니다. 따라서 'item3'의 경우라면 다음과 같습니다.

 

ext = info['Set1', 'item3', 'data']
HELP, ext

 

EXT             LONG64    = Array[5]

 

그리고 'item1'의 경우는 다음과 같습니다.

 

ext = info['Set1', 'item1', 'data']
HELP, ext

 

EXT             FLOAT     = Array[768, 512]

 

이와 같이 ASDF 파일 내에 수록된 데이터가 계층적 구조를 가질 경우에는 상위 키와 하위 키를 정확히 사용하여 추출해야 한다는 것을 유념해야 합니다.

 

결론적으로 얘기한다면, ASDF 파일을 받아서 그 안에 수록된 데이터를 제대로 추출하려면 애초에 어떤 구조로 어떤 종류의 데이터들이 수록되어 있는가에 대한 세부 정보를 미리 아는 것이 중요하며, 그러한 정보는 아무래도 파일 제공자측에서 자세히 기술하여 제공하는 것이 맞을 것 같습니다. 어쨌든 IDL에서 ASDF 파일을 생성하고 읽는 방법에 관한 기본적인 내용은 이와 같습니다. 물론 실제로 유통되는 ASDF 파일들의 경우는 내부적인 정보 수록의 형태가 각양각색일 것이기 때문에, 작업자는 그 세부적인 정보를 파악하여 그에 맞는 추출 과정을 거쳐서 올바른 데이터가 추출될 수 있도록 신경써야 할 것입니다.

LIST