;------------------------------------------------------------- ;+ ; NAME: ; CTM_READ3DB_HEADER ; ; PURPOSE: ; retrieve header information and file positions of data ; blocks from binary global 3D model output. This is a ; twin of CTM_READ3DP_HEADER which digests the header ; information from ASCII punch files. ; ; CATEGORY: ; CTM tools ; ; CALLING SEQUENCE: ; test = CTM_READ3DB_HEADER(LUN,FILEINFO,DATAINFO [,keywords]) ; ; INPUTS: ; LUN --> logical file unit of the binary punch file. The file ; must be open (see CTM_OPEN_FILE or OPEN_FILE) ; ; FILEINFO --> a (single) fileinfo structure containing information ; about the (open) file (see CREATE3DFSTRU). FILEINFO also ; contains information about the model which generated ; the output (see CTM_TYPE) ; ; DATAINFO --> a named variable that will contain an array of ; structures describing the file content (see ; CREATE3DHSTRU) ; ; KEYWORD PARAMETERS: ; PRINT -> if activated, print all headers found in the file ; ; OUTPUTS: ; The function returns 1 if successful, and 0 otherwise. ; ; FILEINFO --> toptitle and modelinfo tags will be set ; ; DATAINFO --> contains an array of named structures ; (see CREATE3DHSTRU) with all relevant information ; from the punch file header and what is needed to find ; and load the data. ; ; SUBROUTINES: ; ; REQUIREMENTS: ; uses CREATE3DHSTRU function to create header structure ; uses CHKSTRU to test FILEINFO structure ; uses CTM_TYPE to create modelinfo structure ; needs gamap_cmn.pro to access global common block ; ; NOTES: ; This routine uses the new binary file format introduced ; first to the GEOS/Harvard CTM. ; ; EXAMPLE: ; fileinfo = create3dfstru() ; not required ! ; fname = '~bmy/terra/CTM4/results/ctm.bpch' ; open_file,fname,ilun,/F77_UNFORMATTED ; <=== !! ; if (ilun gt 0) then $ ; result = CTM_READ3DB_HEADER(ilun,fileinfo,datainfo) ; print,result ; ; To get e.g. all scaling factors, type ; print,datainfo[*].scale ; ; To retrieve the header structure for one data block, type ; blocki = datainfo[i] ; ; MODIFICATION HISTORY: ; mgs, 15 Aug 1998: VERSION 1.00 ; - derived from CTM_READ3DP_HEADER ; mgs, 21 Sep 1998: - changed gamap.cmn to gamap_cmn.pro ; mgs, 14 Jan 1999: - now expects diag category name instead ; of number ; bmy, 11 Feb 1999: - change TAU0, TAU1 to double-precision, ; in accordance w/ new binary file format ; - clean up some POINT_LUN calls ; bmy, 22 Feb 1999: VERSION 1.01 ; - now store I0, J0, L0 from binary file ; in new FIRST field from CREATE3DHSTRU ; - comment out assignment statement for ; SKIP; now use value from binary file ; mgs, 16 Mar 1999: - cosmetic changes ; ;- ; Copyright (C) 1998, 1999, Martin Schultz and Bob Yantosca, ; Harvard University ; This software is provided as is without any warranty ; whatsoever. It may be freely used, copied or distributed ; for non-commercial purposes. This copyright notice must be ; kept with any copy of this software. If this software shall ; be used commercially or sold as part of a larger package, ; please contact the author to arrange payment. ; Bugs and comments should be directed to mgs@io.harvard.edu ; or bmy@io.harvard.edu with subject "IDL routine CTM_READ3DB_HEADER" ;------------------------------------------------------------- function CTM_READ3DB_HEADER,ilun,fileinfo,datainfo, $ print=pprint FORWARD_FUNCTION chkstru, ctm_type, create3dhstru ; if we ever need to include global common block ... ; @gamap_cmn.pro ; initialize return variables datainfo = -1 ; ======================================== ; retrieve punch file name ; ======================================== if (chkstru(fileinfo,'filename')) then $ thisfilename = fileinfo.filename $ else $ thisfilename = '' ; ======================================== ; read general file information ; (reset file pointer to 0 and re-read ; file type identifier) ; ======================================== fti = bytarr(40) toptitle = bytarr(80) modelname = bytarr(20) modelres = fltarr(2) on_ioerror,readerr point_lun,ilun,0L readu,ilun,fti if (keyword_set(pprint)) then print,'>> ',string(fti) readu,ilun,toptitle if (keyword_set(pprint)) then print,'Title:',string(toptitle) readu,ilun,modelname,modelres if (keyword_set(pprint)) then $ print,'Model and resolution: ',string(modelname),modelres ; get model type structure modelname = strtrim(modelname,2) modelinfo = ctm_type(string(modelname),resolution=modelres) ; ======================================== ; initialize the datainfo structure array ; ======================================== MAXENTRIES = 4096 struc = create3dhstru(MAXENTRIES) ; ... and a line counter count = -1 ; line counter ; get file size and current file position fsize = (fstat(ilun)).size point_lun,-ilun,newpos ; ======================================== ; read in header information of each data ; block ; ======================================== while (newpos lt fsize-1) do begin diagc = bytarr(40) tracer = 0L tau0 = 0.D tau1 = 0.D skip = 0L on_ioerror,headererr point_lun,ilun,newpos ; set file pointer to next header line readu, ilun, diagc, tracer, tau0, tau1, skip diagc = strtrim(diagc,2) ; compute position of next header line point_lun,-ilun,newpos ; read dimensional information dim = [ 0L,0L,0L,0L,0L,0L ] ; NI, NJ, NL, I0, J0, L0 readu,ilun,dim ; FILEPOS pointer now points to beginning of data block point_lun,-ilun,filepos ; NEWPOS pointer now points to the first header ; line of the next data block newpos = filepos + skip ;### note: SKIP value is determined in CTM as follows: ;### skip = 4L * ( dim[0]*dim[1]*dim[2] + 6 ) + 16L count = count + 1 ; sort information into structure struc(count).ilun = ilun struc(count).filepos = filepos struc(count).category = diagc struc(count).tracer = fix(tracer) struc(count).tau0 = tau0 struc(count).tau1 = tau1 struc(count).format = 'BINARY' struc(count).dim = [ fix(dim[0:2]), 0 ] struc(count).first = [ fix(dim[3:5]) ] if (keyword_set(PPRINT)) then begin print,' category : ',diagc print,' tracer : ',tracer print,' time (from,to) : ',tau0,tau1 print,' dimensions : ',dim print,' first indices : ',first print,' newpos : ',newpos endif next_header: ; check if MAXENTRIES is exceeded, if so, create another structure ; array and concatenate if (count ge MAXENTRIES) then begin tmpstru = create3dhstru(4096) struc = [ temporary(struc), tmpstru ] MAXENTRIES = MAXENTRIES+4096 endif endwhile ; (end of file) end_of_file: ; ======================================== ; prepare information to be returned ; ======================================== ; if count is less than 0, nothing was read in if (count lt 0) then begin dum = dialog_message(['No information read from file', $ thisfilename+'!'] ) free_lun,ilun return,0 endif ; enter toptitle in fileinfo structure if (chkstru(fileinfo,'TOPTITLE')) then $ fileinfo.toptitle = string(toptitle) ; get model information and enter in fileinfo structure modelinfo = ctm_type(modelname,resolution=modelres) if (chkstru(fileinfo,'MODELINFO')) then $ fileinfo.modelinfo = modelinfo ; truncate struc array and pass it as datainfo datainfo = struc(0:count) return,1 ; successful ! ; ======================================== ; error messages for IO errors ; ======================================== ; error while reading data from the file readerr: dum = dialog_message(['Error ('+strtrim(!ERR,2)+ $ ') reading file ', $ thisfilename, $ ' in block '+strtrim(count,2), $ strcompress(!ERR_STRING) ], $ /ERROR ) ; for error -221 (unexpected end of file) return what we got if (!ERR eq -221 AND count ge 0) then goto,end_of_file ; otherwise close file and return as unsuccessful free_lun,ilun return,0 ; error while parsing a header line headererr: ; print error and exit print,'while reading header information ...' goto,readerr end