- This topic has 3개 답변, 2명 참여, and was last updated 10 years, 2 months 전에 by chobo.
-
글쓴이글
-
-
chobo회원
안녕하세요.
바이너리 포맷 읽기 관련하여 문의드립니다.
기상레이더의 한 포맷인 dorade 자료를 읽을려고 합니다.
아래처럼 코드를 작성해봤는데, id만 “RYIB”으로 제대로 읽힌것 같고, 나머지는 모두 조금 이상해 보입니다. nbytes(크기)는 44 가 맞으나, 조금 이상해 보이구요. 아마도 제가 자료형의 이해를 잘 못 하고 있는 것 같아서 발생한 초보적인 문제인 것 같은데, 무엇이 잘 못 된 것일까요?
감사합니다.pro dorade_io
FP = ‘F:/DORADE/080529/’
file=’swp.1080529010200.SPOLRVP8.0.1.0_’
data = READ_BINARY( fp+file)
rm=!null
for i = 0L, n_elements(data)-4L do begin
if string(data[i:i+3L]) eq ‘RYIB’ then rm = [[rm], [i, i+3L]]
endfor; ******** Data Format *************************************
;Offset-bytes Data type Bytewidth Count Item
;———– ——— ——— ——— ———-
;0 char 1 4 id
;4 integer 4 1 nbytes
;8 integer 4 1 sweep_num
;12 integer 4 1 julian_day
;16 integer 2 1 hour
;18 integer 2 1 minute
;20 integer 2 1 second
;22 integer 2 1 millisecond
;24 float 4 1 azimuth angle in degree
;28 float 4 1 elevation angle in degree
;32 float 4 1 peak_power
;36 float 4 1 true_scan_rate
;40 integer 4 1 ray_status
;************************************************************for i = 0, n_elements(rm[0, *])-1 do begin
offset = rm[i]
id = string(data[offset+0L:offset+3]) & print, ‘id:’, id
nbyte= fix(data[offset+4L:offset+7L]) & print, ‘nbyte:’, nbyte
sweep_num = fix(data[offset+8L:offset+11L]) & print, ‘sweep_num:’, sweep_num
juluday = fix(data[offset+12L:offset+15L]) & print, ‘juluday:’, juluday
hour = fix(data[offset+16L:offset+17L]) & print, ‘hour:’, hour
minute = fix(data[offset+18L:offset+19L]) & print, ‘minute:’, minute
second = fix(data[offset+20L:offset+21L]) & print, ‘second:’, second
milisecond = fix(data[offset+22L:offset+23L]) & print, ‘milisecond:’, milisecond
az = float(data[offset+24L:offset+27L]) & print, ‘az:’, az
el = float(data[offset+28L:offset+31L]) & print, ‘el:’, el
peak_power= float(data[offset+32L:offset+35L]) & print, ‘peak_power:’, peak_power
scan_rate = float(data[offset+36L:offset+39L]) & print, ‘scan_rate:’, scan_rate
ray_status= fix(data[offset+40L:offset+43L]) & print, ‘ray_status:’, ray_status
stop
endfor====== IDL printed ======
IDL> dorade_io
% Compiled module: DORADE_IO.
id:RYIB
nbyte: 44 0 0 0
sweep_num: 1 0 0 0
juluday: 150 0 0 0
hour: 1 0
minute: 2 0
second: 0 0
milisecond: 0 0
az: 34.0000 148.000 160.000 67.0000
el: 26.0000 81.0000 122.000 63.0000
peak_power: 176.000 51.0000 161.000 77.0000
scan_rate: 0.000000 0.000000 0.000000 199.000
ray_status: 0 0 0 0
% Stop encountered: DORADE_IO 53 F:\DORADE\dorade_io.pro
IDL> -
chobo회원
위 코드 에서 offset = rm[i]를 offset = rm[0, i] 로 수정합니다.
-
코드 내에서 잘못된 점은 fix나 float등이 배열들의 개별값을 변환하는 함수라는 점입니다.
nbyte= fix(data[offset+4L:offset+7L]) & print, ‘nbyte:’, nbyte
에서 출력이
nbyte: 44 0 0 0
라고 되는데요.
보시면 data라는 byte array의 data[offset+4L:offset+7L]의 결과가 배열이 됩니다.따라서 nbyte를 포함한 fix,float로 변환하는 변수들을 help로 확인하면
<Expression> INT = Array[4]
등으로 출력이 됩니다. (fix를 이용했으면 int, float를 이용하면 float)단 string은 byte를 char로 판단하기 때문에 byte array를 넣으면 정상적으로 출력됩니다. 따라서 id는 제대로 출력이 된 것이지요.
참고로 byte array로 출력된 데이터를 다른형으로 맞춰서 변환하는 것이 힘들기 때문에 처음 파일을 읽을 때 데이터형에 따라서
char형은 bytarr(4) [예)id = bytarr(4)]
integer4형은 IDL의 long [예) nbyte=0L]
integer2형은 IDL의 int
float4형은 IDL의 float와 같이 변수를 우선 생성하고,
openr,1,fp+file
로 파일을 열어서
readu,id,nbyte,sweep_num …
식으로 파일을 읽으면 될 것 같습니다.
-
chobo회원
매번 감사합니다.
덕분에 실마리를 찾은 것 같습니다. ^^
-
-
글쓴이글