本帖最后由 lianyi_dyq 于 2009-11-2 16:05 編輯
1 輸入與輸出 IDL中輸入輸出的基本原則是:“只要有數(shù)據(jù),就可以將其讀進(jìn)IDL”,IDL對數(shù)據(jù)的格式?jīng)]有要求,也就是任何數(shù)據(jù)格式都能自由的解析,這使得IDL成為目前功能最強(qiáng)、最靈活的科學(xué)可視化分析語言。 1.1 標(biāo)準(zhǔn)輸入輸出 1.1.1 輸入輸出函數(shù) IDL中讀寫ASCII碼文本是很重要的一部分。標(biāo)準(zhǔn)輸入是鍵盤輸入,標(biāo)準(zhǔn)輸出指的是屏幕輸出顯示。表1-1中列出了標(biāo)準(zhǔn)輸入輸出的幾個函數(shù)。 1.1.2 格式化輸出 數(shù)據(jù)的格式化輸出是按照設(shè)計的格式進(jìn)行輸出。IDL支持“%”和“\”。 標(biāo)準(zhǔn)的輸入輸出時可以進(jìn)行格式的自由控制,格式化控制的格式為:[n]FC[+][-][width],各個字段代表的含義見表1-2
如下面的
例子 PRO Test_format COMPILE_OPT idl2 ; PRINT, FORMAT = '(A6)', '123456789' PRINT, FORMAT = '(I2,$)', INDGEN(6) ; PRINT, FORMAT = '("First", 20X, "Last", T10, "Middle")' PRINT, FORMAT = '("First", 20X, "Last", T4, "Middle")' ; PRINT, FORMAT = '("First", 5X, "Last", TL2, "Middle")' ; PRINT, SYSTIME(/JULIAN) PRINT, FORMAT='(C())', SYSTIME(/JULIAN) PRINT, FORMAT='(C(CMOI,"/",CDI))',SYSTIME(/JULIAN) PRINT, FORMAT='(C(CHI2.2,":",CMI2.2,":",CSF05.2))',SYSTIME(/JULIAN) ; PRINT, FORMAT='(%"I have %d monkeys, %s,", " and ", I0, " parrots.")', 10, 'Scott', 5 PRINT, format='(%"I have \xb1%d monkeys [url=file://%22)]\\")'[/url], 5 ; print,'0F'X ; 十六進(jìn)制轉(zhuǎn)十進(jìn)制 print,"17 ; 八進(jìn)制轉(zhuǎn)十進(jìn)制 print, 119, format='(B)';十進(jìn)制轉(zhuǎn)二進(jìn)制的 print, 119, format='(O)';十進(jìn)制轉(zhuǎn)到八進(jìn)制 print, 119, format='(Z)';十進(jìn)制轉(zhuǎn)到十六進(jìn)制 END
|
1.2 文件讀寫 1.2.1 打開文件 IDL從磁盤上的文件讀寫數(shù)據(jù),必須首先把一個邏輯設(shè)備號連接到一個特定的文件,然后進(jìn)行文件操作如打開、關(guān)閉和讀取等。IDL中的邏輯設(shè)備號范圍是-2—128,其中1--99是可以用戶任意指定的,100-128是根據(jù)get_lun和free_lun來管理的,其他是特殊函數(shù)專用的。 0是常規(guī)標(biāo)準(zhǔn)輸入流,一般是鍵盤。也就是說下面命令是一致的:
-1是常規(guī)標(biāo)準(zhǔn)輸出流,一般是顯示屏幕,下面命令的功能是一致的:
IDL> PRINTF, -1, X IDL> PRINTF, -1, X |
-2是錯誤流,一般是顯示屏幕。 文件操作相關(guān)的函數(shù)見表1-4。
1.2.2 讀寫ASCII碼文件 IDL在讀寫該文件分為有兩種格式化文件:自由文件格式和確定的文件格式。 自由文件格式是用逗號或空白(tab鍵和空格鍵)分開文件中的每個元素的ASCII文件。確定的格式文件是用格式說明按照給定的規(guī)范進(jìn)行編排的。二者相比后者比前者更正規(guī)一些。 1.2.2.1 讀寫自由文件格式 IDL下用ReadF從文件中讀入自由格式數(shù)據(jù),Printf寫入自由格式數(shù)據(jù)到文件中。IDL中讀寫自由格式文件遵循下面的幾個規(guī)則: 1) 如果讀入到字符串變量中,那么,在當(dāng)前行剩下的所有字符都將讀入該變量中。 2) 輸入數(shù)據(jù)必須用逗號或空白分隔(空格鍵或tab鍵)。 3) 輸入通過數(shù)字變量完成。數(shù)組和結(jié)構(gòu)都可作為數(shù)字變量的集合。 4) 如果當(dāng)前讀入行是空的,并且還有變量要求輸入,則讀取另一行。 5) 如果當(dāng)前讀入行不是空的,但是沒有變量要求輸入,則忽略此行剩下的數(shù)。 6) 盡量將數(shù)據(jù)轉(zhuǎn)換為變量所希望的數(shù)據(jù)類型。 7) 復(fù)數(shù)數(shù)據(jù)必須有實數(shù)和虛數(shù)兩部分,用逗號分隔,并用括號括起來。 1.2.2.2 讀寫確定的文件格式 讀寫確定文件格式可同樣用ReadF和PrintF命令,它們剛才已用于自由格式文件,但現(xiàn)在文件格式已由Format關(guān)鍵字明確聲明。(在讀寫標(biāo)準(zhǔn)輸入和輸出時,也可將Format關(guān)鍵字用于Read 和Print命令)。 1.2.2.2.1 通用的格式說明符 通用格式說明符Format關(guān)鍵字的語法參考1.1.2. 1.2.2.2.2 逗號分隔的確定格式 有時數(shù)據(jù)文件必須用確定格式書寫,以方便它們被其它軟件讀取。用逗號分隔的數(shù)據(jù)文件就是這類文件的典型代表。 Format=’(F10.3, A1, 2x, F10.3, A1, 2x, F10.3)’ 1.2.2.2.3 字符串中讀取格式數(shù)據(jù) ReadS是一個有用的IDL命令,可以從字符串變量而不是從文件中為自由格式或確定格式讀取數(shù)據(jù)。ReadS運用了和命令Read和ReadF相同的讀取格式數(shù)據(jù)規(guī)則。也就是說,使用ReadS 就象從數(shù)據(jù)文件中讀取一樣,所不同的是所讀的對象是一個字符串變量。 當(dāng)大量信息需從文件頭部讀取時,此命令特別有用。例如,假設(shè)ASCII 數(shù)據(jù)文件的第一行說明了數(shù)據(jù)文件的行數(shù)和列數(shù),此文件頭可以從文件中讀取,并且可創(chuàng)建一個大小正確的數(shù)組來讀取數(shù)據(jù)。
IDL> firstLine=' 10 24500 12 June 1996' IDL> columns=0 IDL> rows=0 IDL> date='' IDL> reads,firstline,columns,rows,date 10 24500 12 June 1996 IDL> print,columns;,rows,date 10 IDL> print,rows;,date 24500 IDL> print,date 12 June 1996 |
1.2.2.3 向?qū)阶x取函數(shù) IDL中提供了ASCII_TEMPLATE,QUERY_ASCII和READ_ASCII函數(shù)。
asciiFile =currentPath+'\data\ascii.txt' ;依次讀取 OPENR,lun,asciifile,/get_lun IF lun EQ -1 THEN RETURN; tmp = '' WHILE(~EOF(lun)) DO BEGIN READF,lun,tmp ENDWHILE FREE_LUN,lun ;分塊讀取 tmp = STRARR(3) data = FLTARR(2,4) fdata = INTARR(20) OPENR,lun,asciifile,/get_lun READF,lun,tmp READF,lun,data FREE_LUN,lun ;自定義格式讀取 tmp ='' row =0 columns =0 type =0 OPENR,lun,asciifile,/get_lun ; READF,lun,tmp READS,tmp,row,columns,type data =MAKE_ARRAY(row,columns,type = type) READF,lun,tmp READF,lun,tmp READF,lun,data FREE_LUN,lun template =Ascii_template(asciiFile) data = Read_ascii(asciiFile,TEMPLATE=template,count = yNum) help,data print,data.(0)
|
1.2.2.4 綜合應(yīng)用舉例 針對上面介紹的三種讀取方式,對同一個數(shù)據(jù)采用了不同的讀取方式進(jìn)行了讀取,附代碼。 1.2.3 讀寫二進(jìn)制文件 二進(jìn)制數(shù)據(jù)文件基本是以一長串的二進(jìn)制字節(jié)存在文件中,這些字節(jié)的含義(也就是說,這些字節(jié)如何翻譯成特定數(shù)據(jù)類型和結(jié)構(gòu)的)很難描述的,除非剛開始就知道文件寫入的是什么內(nèi)容。二進(jìn)制數(shù)據(jù)比格式化數(shù)據(jù)緊湊得多,經(jīng)常用于存儲大數(shù)據(jù)文件。有兩種命令讀寫二進(jìn)制數(shù)據(jù),它們與前面用來讀取格式數(shù)據(jù)文件的ReadF和 Print 命令等效。它們是ReadU和WriteU命令。 要讀取非格式數(shù)據(jù)文件,簡單定義變量,打開文件讀取,并用ReadU命令將字節(jié)一個接一個地讀入變量中。如果給定了變量的數(shù)據(jù)類型和組織結(jié)構(gòu),每個變量按其要求從文件中讀出相應(yīng)的字節(jié)數(shù)。 1.2.3.1 讀寫常規(guī)二進(jìn)制文件
IDL> B = BYTARR(192, 192, /NOZERO) IDL> ; Read the data into B: IDL> READU, 1, B IDL> ; Close the file: IDL> CLOSE, 1 IDL> ; Display the image: IDL> TV, B |
1.2.3.2 讀寫帶頭文件的二進(jìn)制文件 當(dāng)數(shù)據(jù)中含有特定的頭文件時,讀取的時候有時希望直接跳過,此時需要用Point_Lun函數(shù),該函數(shù)支持對文件進(jìn)行字節(jié)定位。 調(diào)用格式為POINT_LUN, Unit, Position,其中Unit是文件打開后的lun,Position一般是需要跳轉(zhuǎn)的字節(jié)數(shù)。 1.2.3.3 關(guān)聯(lián)變量讀寫二進(jìn)制文件 IDL關(guān)聯(lián)變量是把一個IDL數(shù)組或結(jié)構(gòu)變量的組織結(jié)構(gòu)映射到數(shù)據(jù)文件的內(nèi)容上。文件被看作是這些重復(fù)單元的一個數(shù)組。 第一個單元的索引號是0,第二個單元的索引號1等等。關(guān)聯(lián)變量不象常規(guī)變量那樣將整個數(shù)據(jù)組都存儲在內(nèi)存里。而是當(dāng)一關(guān)聯(lián)變量被引用時,IDL僅對需要的部分?jǐn)?shù)據(jù)執(zhí)行相關(guān)的輸入或輸出請求,這部分?jǐn)?shù)據(jù)就是要讀入內(nèi)存的。 有時候大型的二進(jìn)制數(shù)據(jù)文件都由一系列的重復(fù)單元組成。一個IDL關(guān)聯(lián)變量通常是處理這種數(shù)據(jù)形式的最好方式(有時候是唯一的方式)。 關(guān)聯(lián)變量有下面的幾個優(yōu)點: 當(dāng)該變量被用于表達(dá)式時,才產(chǎn)生文件的輸入和輸出動作。不需要單獨的讀或?qū)懨睢?br> 數(shù)據(jù)集的大小不受內(nèi)存容量的限制,因為有時它可處理大型的數(shù)據(jù)集。對于物理存儲器來說是太大的數(shù)據(jù),通過把此數(shù)據(jù)分成塊就能很容易地處理。 不必提前聲明用于映射該數(shù)據(jù)的數(shù)組或結(jié)構(gòu)的數(shù)量。 關(guān)聯(lián)變量是效率最高的I/O形式。 1.2.3.4 向?qū)阶x取函數(shù) READ_BINARY和BINARY_TEMPLATE Read_Binary是直接讀取二進(jìn)制文件的函數(shù),用法可參考下面的語句:
vHeadData = READ_BINARY(FILEPATH('head.dat', $ SUBDIRECTORY=['examples', 'data']), DATA_DIMS=[80,100,57]) IVOLUME, vHeadData |
1.2.3.5 例子 讀FY-3的9210AWX文件,F(xiàn)Y-2C的衛(wèi)星黑體亮度溫度產(chǎn)品,下面的格式說明是參考國家衛(wèi)星氣候中心的《風(fēng)云二號C衛(wèi)星業(yè)務(wù)產(chǎn)品使用手冊》。
PRO test_ReadBinAWX ; currentPath = sourceroot() file = currentPath+'data\FY2C_TBB_IR1_OTG_20061130_AOAD.AWX' ; OpenR, file_lun, file ,/Get_Lun ;定位到信息部分 point_lun,file_lun,20 HeadLine =indgen(3) readu,file_lun,HeadLine ;HeadLine[0]-數(shù)據(jù)的頭文件長度 $ ;HeadLine[]-文件頭文件記錄數(shù) $ ;HeadLine[2]-數(shù)據(jù)的記錄數(shù) point_lun,file_lun,58 ;定位到信息部分 BeginDate=indgen(5) ;依次為年月日時分 EndDate =indgen(5) ;依次為年月日時分 LatLong=indgen(4) ;依次為左上角緯度經(jīng)度右下角經(jīng)度緯度 readu,file_lun,BeginDate readu,file_lun,EndDate readu,file_lun,LatLong ; data = bytarr(HeadLine[2],(HeadLine[0])) ;定位到數(shù)據(jù)部分 point_lun,file_lun,HeadLine[0]*HeadLine[1] readu,file_lun,data Free_Lun,lun END
|
1.3 讀寫通用格式文件 IDL可以讀寫許多常用文件格式,這些文件格式已在表1-5中列出。
1.3.1 圖像文件信息查詢 IDL中提供了常用圖像文件格式的查詢程序。這些程序允許在沒有真正讀取其數(shù)據(jù)的情況下,就可以查詢圖像文件,并可以存取隨著圖像數(shù)據(jù)文件一起存儲在文件里的元數(shù)據(jù)(關(guān)于數(shù)據(jù)的一些信息)。 下面是新的圖像查詢程序列表: Query_BMP Query_DICOM Query_GIF Query_JPEG Query_PICT Query_PNG Query_PPM Query_SRF Query_TIFF 所有這些查詢命令都是以同樣的方式工作。它們都是返回0或1的函數(shù),通過返回值確定是否成功地(返回值為1)讀取了圖像文件里的元數(shù)據(jù)。如果它們成功地讀取了文件,將保存文件信息的IDL結(jié)構(gòu)變量作為輸出命令返回給用戶。用戶通過存取這個結(jié)構(gòu)里面的字段從而獲取文件的有關(guān)信息。 1.3.2 JPEG文件操作 1.3.2.1 JPEG讀操作 用Read_JPEG命令就可以讀取并顯示一個JPEG文件。 假設(shè)正在8位顯示器上顯示24位的圖像,應(yīng)該使用TV命令里的關(guān)鍵字True: IDL> TV, thisimage, true=1 1.3.2.2 JPEG寫操作 對圖形窗口進(jìn)行拍照可以用TVRD函數(shù)。 IDL> image3D=TVRD(true=1) 最后,用Write_JPEG命令,將圖像用輸出為JPEG文件,運行命令: IDL> Write_JPEG, ‘test.jpg’, image3D, true=1, quality=75 1.3.2.3 舉例 對一個jpg文件進(jìn)行查詢及讀取操作。
PRO test_CommonImg currentPath =file_dirname(routine_file_path(“test_CommonImg”)) imgFile =currentPath+'\data\idl.jpg' ;文件信息查詢 queryStatus = QUERY_IMAGE(imgFile, imageInfo,type = type) HELP,imageInfo,/str IF queryStatus EQ 1 THEN BEGIN CASE type OF 'BMP': BEGIN END 'JPEG': BEGIN jpgStatus=QUERY_JPEG(imgFile, fileinfo) IF jpgStatus THEN BEGIN HELP,fileInfo,/str READ_JPEG,imgFile,data TV,data,/true image=TVRD(0,0,127,287,/true) Write_Jpeg,currentPath+'\data\result.jpg', image,true=1, quality=75 ENDIF END ELSE: BEGIN END ENDCASE ENDIF END |
1.3.3 HDF數(shù)據(jù)讀入 HDF有兩種基本對象—組(Group)和數(shù)據(jù)集(Dataset),同時也有一些其他的輔助對象,如數(shù)據(jù)類型(Datatype)、數(shù)據(jù)空間(Dataspace)、屬性(Attribute)。HDF組織結(jié)構(gòu)有些類似于Windows 中的文件結(jié)構(gòu),組相當(dāng)于一個文件夾,數(shù)據(jù)集相當(dāng)于一個數(shù)據(jù)文件,文件夾里面可以包含數(shù)據(jù)文件,也可以包含其他的組對象,這樣嵌套下去,就形成了一個復(fù)雜的數(shù)據(jù)對象,這點正好的對應(yīng)于HDF邏輯結(jié)構(gòu)的層次性。 HDF文件的操作 讀取-編輯 HDF_OPEN: 這個過程首先要打開HDF文件,通過create關(guān)鍵字來確定是讀取文件還是創(chuàng)建一個新的文件。 HDF_DFAN_ADDFDS: 添加文件描述;Optionally, add a file description. HDF_DFAN_ADDFID: 添加文件Optionally, add a file annotation. 對HDF 文件添加數(shù)據(jù)用到的過程: 添加8位圖像,用HDF_DFR8_ADDIMAGE 或DFR8_PUTIMAGE; 添加顏色表,用HDF_DFP_ADDPAL或HDF_DFP_PUTPAL; 添加24位圖像,用HDF_DF24_ADDIMAGE 或HDF_DF24_PUTIMAGE; 添加多數(shù)據(jù)時,需要用下面的命令: HDF_SD_CREATE 或 HDF_SD_SELECT 建立一個SDS或選擇一個現(xiàn)有的SDS; HDF_SD_DIMSET 設(shè)置維數(shù)信息; HDF_SD_ATTRSET 設(shè)置屬性信息; HDF_SD_SETINFO 添加一個數(shù)據(jù)信息; HDF_SD_ADDDATA 添加數(shù)據(jù); HDF_SD_SETEXTFILE移動數(shù)據(jù)到外部存儲文件; HDF_SD_ENDACCESS 結(jié)束讀取SDS; 添加數(shù)據(jù)表(vData)時需要用下面的命令: HDF_VD_ATTACH 獲取一個數(shù)據(jù)表的標(biāo)識;to get a Vdata identifier. HDF_VD_SETINFO寫入數(shù)據(jù)表的信息; HDF_VD_FDEFINE to prepare non-trivial fields (optional). HDF_VD_WRITE 寫入數(shù)據(jù)表; 將數(shù)據(jù)表(Vdata)添加到數(shù)據(jù)組合(Vgroup)中時,用下面的命令: HDF_VG_ATTACH to get a Vgroup identifier. HDF_VG_SETINFO to set the Vgroup name and class (optional). HDF_VG_INSERT to add the Vdata to a Vgroup. HDF_VG_DETACH to close the Vgroup. HDF_CLOSE to close the file 示例數(shù)據(jù) |