【IDL程式碼庫】大資料分塊寫入HDF5檔案示例程式碼
阿新 • • 發佈:2022-05-27
IDL提供了專門針對HDF5科學資料格式的讀寫函式庫。可以參考IDL幫助的Routines (alphabetical) > Routines: H > HDF5 Routines 這個章節檢視函式列表。
如果只是簡單的讀寫HDF5檔案,可以利用下面三個函式即可:
-
H5_GETDATA
讀取資料 -
H5_LIST
檢視資料列表 -
H5_PUTDATA
寫入資料
注:上面3個函式用法非常簡單,這裡不再舉例。要求IDL最低版本為8.3。
下面介紹如何將一個大資料分塊寫入HDF5檔案。在test_write_h5d.pro原始碼中,分成了如下幾個步驟
(1)首先隨機建立一個大資料,利用了hanning函式(生成漢寧窗,主要用於快速傅立葉變換),再計算兩個維度的步長、步數。
(2)然後將第一個分塊資料寫入資料集,並進行第一個分塊資料的視覺化展示。
(3)最後是一個巢狀迴圈,將剩餘分塊資料動態寫入,併疊加展示每一個分塊資料。
下圖為視覺化結果,左側圖形為分塊效果,右側圖形為整體資料效果。
圖:視覺化效果
最後附上原始碼:
PRO test_write_h5d COMPILE_OPT idl2 ; 建立新的 HDF5檔案,可修改 file = 'D:\temp\mytest_h5_file.h5' fid = H5F_CREATE(file) ; 隨機建立初始維度 random_number1 = SORT(RANDOMU(seed, 1000)) random_number2 = SORT(RANDOMU(seed, 2000)) dim1 = random_number1[0]>500 dim2 = random_number2[0]>1000 ; 每一個維度的分塊步長 step1 = 100 step2 = 200 ; 每一個維度的分塊數目 nstep1 = dim1/step1 nstep2 = dim2/step2 ; 重新定義大資料維度,可以完美分塊 dim1 = nstep1*step1 dim2 = nstep2*step2 ; 建立一個大資料 data = hanning(dim1,dim2) ; 取出第一個分塊資料 data_segment = data[0:(step1-1),0:(step2-1)] ; 展示第一個分塊資料 s = surface(data_segment, title='分塊效果展示', $ xrange=[0,dim1-1], yrange=[0,dim2-1], layout=[2,1,1],$ dimensions=[900,500], margin=[.2,.2,.2,.2]) ; 根據資料建立一個datatype datatype_id = H5T_IDL_CREATE(data) ; 建立一個dataspace,並且可以進行擴充套件 dataspace_id = H5S_CREATE_SIMPLE([step1,step2],$ max_dimensions=[-1,-1]) ; 建立一個dataset dataset_id = H5D_CREATE(fid,'Hanning', datatype_id,$ dataspace_id, chunk_dimensions=[step1,step2]) ; 擴充套件dataset的維度,以適應第一個分塊資料 H5D_EXTEND,dataset_id,SIZE(data_segment,/dimensions) ; 將第一個分塊資料寫入dataset H5D_WRITE,dataset_id,data_segment ; 同上面操作相似,將剩下的資料分塊寫入到HDF5檔案中 FOR ind1 = 0L, nstep1-1 DO BEGIN FOR ind2 = 0L, nstep2-1 DO BEGIN ; 如果檔案dataspace已存在,則關閉 IF (ISA(iter_data_space_id)) THEN BEGIN H5S_CLOSE, iter_data_space_id ENDIF ; 如果memory dataspace已存在,則關閉 IF (ISA(iter_data_space_id2)) THEN BEGIN H5S_CLOSE, iter_data_space_id2 ENDIF ; 計算當前分塊的起始行列號 start1 = ind1 * step1 start2 = ind2 * step2 ; 獲取當前分塊資料 data_segment = data[start1:(start1+step1-1),start2:(start2+step2-1)] ; 展示當前分塊資料 s = surface(data_segment, layout=[2,1,1], $ LINDGEN(step1)+start1, LINDGEN(step2)+start2, /overplot) ; 擴充套件dataset維度,輸入維度應該是擴充套件後維度,而不是新增的維度 H5D_EXTEND, dataset_id, [start1+step1, start2+step2] ; 建立新的dataspace iter_data_space_id = H5D_GET_SPACE(dataset_id) ; 選中包含當前分塊資料的 slab H5S_SELECT_HYPERSLAB, iter_data_space_id, [start1,start2], $ [step1,step2], /RESET ; 建立memory data space iter_data_space_id2 = H5S_CREATE_SIMPLE([step1,step2]) ; 使用檔案dataspace和 Memory dataspace,將當前分塊資料寫入Dataset H5D_WRITE, dataset_id, data_segment, $ FILE_SPACE_ID=iter_data_space_id,$ MEMORY_SPACE_ID=iter_data_space_id2 ENDFOR ENDFOR ; 關閉前邊開啟的識別符號 H5S_CLOSE, iter_data_space_id H5S_CLOSE, iter_data_space_id2 H5S_CLOSE,dataspace_id H5D_CLOSE,dataset_id H5T_CLOSE,datatype_id H5F_CLOSE,fid HELP, data ; 讀取新建的HDF5資料列表 h5_list, file ; 獲取資料並進行視覺化 in_dat = H5_GETDATA(file, '/Hanning') s=surface(in_dat, layout=[2,1,2], /current, $ margin=[.2,.2,.2,.2], title='完整資料展示') END