과학기술 분야에서 자주 사용되는 특수한 데이터 포맷들 중에 netCDF라는 것이 있습니다. 이 이름은 Network Common Data Form의약자인데, 원래는 미국의 UCAR(University Corporation for Atmospheric Research)에서 주관하는 Unidata라는 프로젝트에 의하여 개발된 데이터 포맷입니다. 개발 주체가 대기과학 연구그룹이다보니, 제가 얼마전에 소개했던 GRIB와 마찬가지로 기상/해양/대기 분야에서 자주 쓰이는 데이터 포맷이기도합니다. 오늘은 IDL에서 netCDF 포맷의 파일을 읽는 기본적인 방법을 예제를 통하여 살펴보겠습니다. 그리고 다음 회차에서는 이렇게 읽은 데이터를 표출하는 과정도 이어서 소개할 예정입니다.
참고로 netCDF 파일이 주어졌을 때 이 파일 내에 포함된 정보들을 전반적으로 조회하고 데이터도 추출할 수 있는 통합적인 인터페이스 형태의 기능을 제공하는 NCDF_Browser라는 루틴이 있습니다. 이 루틴은 IDL에서 기본적으로 제공되는 것은 아니고, David Fanning의 Coyote 라이브러리에 포함된 것입니다. 당연히 Coyote 라이브러리를 별도로 설치해야 사용 가능하며, 이와 관련해서는 관련 링크의 내용을 참조하시면 됩니다. 하지만 오늘 제가 소개할 내용에서는 IDL이 자체적으로 내장하고 있는 netCDF 관련 루틴들을 사용할 것입니다. 먼저 예제로 사용할 netCDF 포맷 파일은 앞서 언급한 Unidata 웹사이트에서 받은 "rhum.2003.nc"라는 파일입니다. 웹사이트에서 직접 받으시면 됩니다(다운로드 링크).
IDL에서 지원되는 netCDF 관련 루틴들을 전반적으로 살펴보려면 IDL 도움말에서 "NCDF Overview"라는 섹션을 보면 됩니다. 오늘 제가 소개할 내용에서도 이러한 루틴들을 사용하게 됩니다. 파일을 받은 후 가장 먼저 해야 할 일은, 이 파일 내에 어떤 정보들이 포함되어 있는가를 한눈에 살펴보는 일일 것입니다. 이러한 작업을 위해서는 예제 파일을 작업 디렉토리 안에 받아놓은 후 NCDF_LIST 명령을 다음과 같이 사용하면 됩니다.
file = 'rhum.2003.nc'
NCDF_LIST, file
그러면 다음과 같이 관련 정보들이 비교적 간략하게 출력됩니다. 이 내용을 보면, 핵심 데이터는 4차원 배열의 형태이고, 변수(Variable)는 5개가 수록되어 있고, 전역속성(Global Attribute)는 6개의 항목들이 수록되어 있음을 알 수 있습니다.
data/rhum.2003.nc
# dimensions: 4
# Variables: 5
# Global attributes: 6
The unlimited dimension is 3
그런데 이보다 더 자세한 정보를 볼 필요가 있으므로 NCDF_LIST 명령을 다음과 같이 키워드와 함께 사용하는 것이 좋습니다.
NCDF_LIST, file, /VARIABLES
이와 같이 /VARIABLES 키워드와 함께 사용하면 다음과 같은 정보가 추가적으로 출력됩니다. 그러면 5개의 변수들 각각 구체적으로 어떤 정보를 담고 있는지를 알 수 있습니다. 이 내용을 보면 rhum이라는 4차원 배열이 바로 메인 데이터
Variables
0 level: FLOAT(8) = FLOAT(level)
1 lat: FLOAT(73) = FLOAT(lat)
2 lon: FLOAT(144) = FLOAT(lon)
3 time: DOUBLE(365) = DOUBLE(time)
4 rhum: INT(144,73,8,365) = INT(lon,lat,level,time)
그리고 다음과 같이 /GATT 키워드를 사용하면 전역속성들에 대한 구체적 내용도 살펴볼 수 있습니다.
NCDF_LIST, file, /GATT
그러면 다음과 같이 전역속성에 해당되는 정보들이 출력되는데, 전역속성은 일종의 메타정보와 비슷하다고 보면 됩니다. 내용을 보니 이 데이터의 날짜가 2003년 1월 1일을 기점으로 하고 있다고 나오네요.
Global Attributes
0 Conventions: COARDS
1 title: mean daily NMC reanalysis (2003)
2 base_date: 2003
2 base_date: 1
2 base_date: 1
3 history: created 03/08/18 by Hoop (netCDF2.3)
4 description: Data is from NMC initialized reanalysis
(4x/day). It consists of most variables interpolated to
pressure surfaces from model (sigma) surfaces.
5 platform: Model
그리고 다음과 같이 /VATT 키워드를 사용하면 변수속성(Variable Attribute) 정보도 볼 수 있습니다. 이 때 /VARIABLES 키워드를 함께 사용해야 합니다. 그냥 /VATT 키워드 하나만 사용해서는 정보가 제대로 나오지 않습니다.
NCDF_LIST, file, /VARIABLES, /VATT
이렇게 출력된 내용에서는 5개의 변수들(level, lat, lon, time, rhum) 각각에 대한 좀 더 구체적인 정보를 볼 수 있습니다. 예를 들어 lat이란 변수에 관하여 출력된 내용만보면 다음과 같습니다. 이 내용을 보니 데이터의 위도 범위가 -90도에서 +90도까지임을 알 수 있습니다. 물론 각각의 변수마다 해당되는 구체적인 정보가 다 출력됩니다.
1 lat: FLOAT(73) = FLOAT(lat)
0 units: degrees_north
1 actual_range: 90.0000
1 actual_range: -90.0000
2 long_name: Latitude
사실 데이터에 대한 올바른 해석을 위해서는 이러한 정보들도 유심히 볼 필요가 있습니다. 그 중요성에 대해서는 다음 회차 게시물에서 다시 언급하기로 하겠습니다. 그리고 5개의 변수 이름들을 모아서 별도의 배열로 추출하고자 할 경우에는 다음과 같이 VNAME이란 키워드를 /VARIABLES 키워드와 함께 사용하면 됩니다.
NCDF_LIST, file, /VARIABLES, VNAME=vars, /QUIET
HELP, vars
PRINT, vars
그러면 이제부터는 각 변수에 해당되는 실제 데이터를 추출해봅시다. 이러한 작업을 위해서는 가장 먼저 NCDF_OPEN 함수를 사용하여 netCDF 파일을 열고 이 파일에 대한 ID를 가져와야 합니다.
id = NCDF_OPEN(file)
그 다음에는 이 ID 정보를 이용하여 구체적인 변수 데이터를 추출해야 하는데, 이를 위해서는 NCDF_VARGET 명령을 다음과 같이 사용하면 됩니다. 다음과 같이 앞서 NCDF_OPEN으로 추출한 id라는 정보가 첫번째 인수로 그리고 추출하고자 하는 변수의 이름을 두번째 인수로 사용해야 합니다. 세번째 인수에는 추출된 데이터를 담을 변수/배열 이름을 적으면 됩니다.
NCDF_VARGET, id, 'rhum', rhum
HELP, rhum
여기서는 'rhum'이라는 변수에 해당되는 데이터를 추출하여 rhum이라는 이름의 배열로 저장하였습니다. HELP 명령으로 출력된 정보를 보면 다음과 같이 144x73x8x365의 구조를 갖는 4차원 배열로 추출되었음을 알 수 있습니다. 앞서 NCDF_LIST 명령으로 조회했던 내용과 일치합니다.
RHUM INT = Array[144, 73, 8, 365]
따라서 동일한 요령으로 나머지 변수들에 대해서도 구체적인 데이터를 추출하는 것이 가능합니다.
NCDF_VARGET, id, 'lon', lon
NCDF_VARGET, id, 'lat', lat
NCDF_VARGET, id, 'level', level
NCDF_VARGET, id, 'time', time
그래서 이와 같이 추출된 데이터들에 대하여 앞서 NCDF_LIST 명령으로 조회했던 정보들까지 참조하면, 추출된 각 데이터에 대한 구체적인 정보는 대략 다음과 같습니다.
rhum : 상대습도 값들로 구성된 144x73x8x365 구조의 배열
lon : 데이터가 커버하는 영역의 경도 방향 격자 좌표값들로서, 0도부터 357.5도까지 2.5도의 간격으로 144개의 값들로 구성됨
lat : 데이터가 커버하는 영역의 위도 방향 격자 좌표값들로서, 90도부터 -90도까지 2.5도의 간격으로 73개의 값들로 구성됨
level : 연직 방향의 각 층(layer)에 해당되는 기압고도 값들로서 1000부터 300까지 8개의 값들로 구성됨
time : 2003년 1월 1일 0시 0분을 기점으로 1일씩 증가하는 총 365개의 날짜 값들이 Julian Day의 형태로 구성됨
일단 이 정도면 예제 netCDF 파일로부터 우리가 추출하고자 했던 정보들은 충분히 확보한 것 같습니다. 사실은 속성(Attribute)들에 대해서도 NCDF_ATTNAME, NCDF_ATTGET 등을 사용하여 그 내용을 추출하는 것이 가능합니다. 만약 전역속성들 중 하나에 대해서 그 정보를 추출하고자 한다면 다음과 같이 하면 됩니다.
attn = NCDF_ATTNAME(id, /GLOBAL, 2)
PRINT, attn
NCDF_ATTGET, id, attn, value, /GLOBAL
PRINT, value
여기서는 총 6개의 전역속성들 중 세번째(인덱스로는 2) 항목에 해당되는 "base_date"에 해당되는 정보를 추출하였습니다. 이 과정을 자세히 보면, NCDF_ATTNAME 함수를 사용하여 특정 속성의 이름을 얻은 후, NCDF_ATTGET 명령을 사용하여 해당 속성의 구체적 정보를 value라는 변수로 추출하고 있습니다. 출력된 내용은 다음과 같습니다. 앞서 NCDF_LIST 명령으로 조회했던 정보와 같음을 알 수 있습니다.
base_date
2003 1 1
이외에도 다른 속성 정보들 역시 같은 요령으로 추출이 가능합니다. 물론 NCDF_ATTGET 명령을 사용할 때 다음과 같이 원하는 속성의 이름을 직접 명시해도 됩니다. 어차피 결과는 같습니다.
NCDF_ATTGET, id, 'base_date', value, /GLOBAL
PRINT, value
그래서 NCDF_ATTGET 명령의 문법은 앞서 사용했던 NCDF_VARGET 명령과 유사함을 알 수 있습니다. 추출하고자 하는 속성 또는 변수의 이름을 알면 이를 인수로 부여하면 됩니다.
자 이제 예제 netCDF 파일로부터 필요한 정보들을 추출하는 작업은 이 정도로 마무리하겠습니다. 당연한 얘기이겠지만, 어떤 netCDF 파일을 갖고 작업하느냐에 따라서 추출되는 구체적 정보들은 다를 수 밖에 없습니다. 하지만 추출하는 요령은 대략 이 정도라고 보면 될 것 같습니다. 오늘은 여기까지 하고, 다음 시간에는 오늘 추출한 데이터들을 바탕으로 실제 표출 작업으로 들어가보기로 하겠습니다.
'IDL > Data Type & Format' 카테고리의 다른 글
실수의 소수점 이하 자릿수 변경 방법 (0) | 2018.07.30 |
---|---|
netCDF 포맷의 데이터를 읽고 표출하기 [2] (0) | 2018.07.16 |
GRIB 포맷의 파일을 읽고 데이터를 표출하기 [2] (0) | 2018.07.03 |
GRIB 포맷의 파일을 읽고 데이터를 표출하기 [1] (2) | 2018.06.29 |
IDL에서 바이너리(Binary) 파일 읽기 [3] (0) | 2017.12.28 |