;------------------------------------------------------------- ;+ ; NAME: ; GTE_CONVERT ; ; PURPOSE: ; Convert a GTE ASCII data file to binary format ; thereby linking location information from the ; (binary) project data file or a (shorter) location ; file. ; ; CATEGORY: ; GTE Tools ; ; CALLING SEQUENCE: ; GTE_CONVERT,filename,data,desc,locdata,locvars [,keywords] ; ; INPUTS: ; FILENAME -> The filename of the ASCII data to convert. ; You can also use a template in which case you can select ; the file with PICKFILE. If FILENAME is a named variable ; it will return the real filename. ; ; DATA, DESC, and LOCDATA can also be used as input together ; with the /USE_DATA keyword (see below). ; ; LOCVARS -> An array of variable descriptors for LOCDATA. ; Must be passed together with LOCDATA if information shall ; be used. ; ; KEYWORD PARAMETERS: ; /P3B -> Variable names as in P3B project header ; ; LOCFILE -> A filename or template to identify the binary file ; that contains the location data. Only used if no LOCDATA ; is given. Default is '~/tmp/*.bdt' ; ; NEWFILE -> Filename or template for the new binary data file ; to be created. Default is '~/tmp/*.bdt' ; ; /PROJECT -> Set this keyword to perform extra action with project ; data before writing it out (see GTE_ADDPROJECT). The PROJECT ; keyword also sets TIMEOFFSET to +0.5 if no other value ; is specified. ; ; TIMEOFFSET -> Time values in the data sets are converted to ; use always start and stop time. Use TIMEOFFSET to correct ; times that are given as starttime although they should be ; MIDTIME (e.g. project data !) ; ; /USE_DATA -> Set this keyword to reuse the data you got from ; other operations or a prior failed attempt. DATA must be ; a valid 2D array and DESC must contain the respective ; file descriptor (see GTE_FILEDESC). ; ; /ATLANTIC or /PACIFIC -> Set either of these keywords to ; convert longitudes from 0..360 or -180..180 (see ; CONVERT_LON). Default is PACIFIC. ; ; EXPERIMENT_NAME -> A string to overwrite the experiment name ; entry of the local file (for common spelling) ; ; EXPERIMENT_DATE -> A string to overwrite the experiment date ; entry of the local file (for common spelling) ; ; CANCEL -> returns 1 if program aborted (e.g. if loc file not found) ; ; _EXTRA keywords are passed to GTE_READ, GTE_READBIN, and GTE_WRITEBIN ; (e.g. /PICKFILE, /NO_PICKFILE) ; ; OUTPUTS: ; DATA -> You can pass previously read data with this variable. ; You also have to pass the filedescriptor parameter DESC ; and you have to set the /USE_DATA keyword. Otherwise, ; DATA will always contain the data as read in and linked ; with the location information. ; ; DESC -> A named variable that will return the file descriptor ; structure (see GTE_FILEDESC) for the GTE ASCII file. If ; you want to pass dat into the routine with the USE_DATA ; keyword, this must be a valid structure to start with. ; ; LOCDATA -> The location data. If this variable contains valid ; data and LOCVARS is also present, then the information ; in these parameters is used, and the location file ; (LOCFILE keyword) is not read again. This is useful if ; you want to process several data sets from one filght. ; Make sure to set LOCDATA to 0 or undefined when switching ; to a new flight, or omit the parameter. ; ; ; SUBROUTINES: ; ; REQUIREMENTS: ; Uses OPEN_FILE, GTE_READ, GTE_WRITEBIN, GTE_READBIN. ; ; NOTES: ; Time information in the GTE file is converted to ; JDAY, STARTHOUR, STARTSEC, STOPSEC for all file types. ; This allows storage as 4 byte REAL without loss of ; timing accuracy. ; ; EXAMPLE: ; GTE_CONVERT,'/data/pem-tb/dc8/raw/*.pmb',data,desc ; ; will most often do the job ... ; ; MODIFICATION HISTORY: ; mgs, 25 Aug 1998: VERSION 1.00 ; mgs, 11 Apr 1999: VERSION 2.00 ; - lots of changes ; ;- ; Copyright (C) 1998, Martin Schultz, 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 ; with subject "IDL routine gte_convert" ;------------------------------------------------------------- pro gte_convert,filename,data,desc,locdata,locvars, $ p3b=p3b,locfile=locfile, $ newfile=newfile,project=project, $ timeoffset=timeoffset,use_data=use_data, $ atlantic=atlantic,pacific=pacific, $ experiment_name=experiment_name, $ experiment_date=experiment_date, cancel=cancel, $ _EXTRA=e FORWARD_FUNCTION gte_vardesc ; convert a GTE ASCII file to binary format and add location ; information ; 1st NOTE: USE PROJECT keyword to perform special functions on ; project data (calculate RH etc.) ; 2nd NOTE: LONgitude information will be converted to 0..360 ! ; This works only for the Pacific !! (use ATLANTIC or PACIFIC ; keywords to control this behaviour explicitely) cancel = 0 atlantic = keyword_set(atlantic) pacific = keyword_set(pacific) if ((atlantic+pacific) gt 1) then begin message,'Cannot be at Atlantic and Pacific at same time!',/CONT return endif if ((atlantic+pacific) eq 0) then pacific = 1 ; default ; set defaults if (n_elements(filename) eq 0) then filename = '' if (filename eq '') then filename = 'c:/data/gte/pem-tb/dc8/raw/*.pmb' ; '/data/pem-tb/dc8/raw/*.pmb' if (n_elements(locfile) eq 0) then locfile = 'c:/data/gte/pem-tb/*.bdt' ; '~/tmp/*.bdt' ; ********************************************************************** ; ********************************************************************** ; locationinfo = ['EVENT','LAT','LON', 'ALTP'] locationinfo = ['LAT','LON', 'ALTP'] ; ********************************************************************** ; ********************************************************************** if (n_elements(newfile) eq 0) then newfile = 'c:/data/gte/pem-tb/*.bdt' ; '~/tmp/*.bdt' ; Set time offset to + 1/2 seconds for project data if (keyword_set(project) AND n_elements(timeoffset) eq 0) then $ timeoffset = 0.5 if (n_elements(timeoffset) eq 0) then timeoffset = 0.0 ; ============================================================ ; read GTE file unless data is passed already ; ============================================================ if (n_elements(data) lt 2 OR not keyword_set(use_data)) then begin gte_read,filename,data,desc,_EXTRA=e if (n_elements(data) lt 2) then return ; unsuccessful endif ; get variable information vardesc = *desc.pvardesc print,vardesc.name ; overwrite experiment name and date if requested if (n_elements(experiment_name) gt 0) then $ desc.experiment_name = experiment_name if (n_elements(experiment_date) gt 0) then $ desc.experiment_date = experiment_date ; ============================================================ ; convert MIDTIME to STARTTIME and STOPTIME or delete MIDTIME ; Store STARTTIME and STOPTIME as STARTHOUR, STARTSEC, STOPSEC ; ============================================================ ; if filetype is negative, conversion has already been made if (desc.filetype lt 0) then goto,load_loc ; test if MIDTIME is present ind = where(vardesc.name eq 'MIDTIME') if (ind[0] lt 0) then begin message,'Cannot find MIDTIME in data set!',/CONT return endif ; Compute or extract start and stop time ; action depending on filetype if (desc.filetype eq 0 OR desc.filetype eq 1) then begin starttime = data[*,ind[0]]-0.5*desc.average_period+timeoffset stoptime = data[*,ind[0]]+0.5*desc.average_period+timeoffset ind1 = -1L ind2 = -1L endif else if (desc.filetype eq 2) then begin ind1 = where(vardesc.name eq 'STARTTIME') ind2 = where(vardesc.name eq 'STOPTIME') if (ind1[0] lt 0 OR ind2[0] lt 0) then begin message,'Cannot find STARTTIME or STOPTIME in type 2 data set!', $ /CONT return endif starttime = data[*,ind1[0]] stoptime = data[*,ind2[0]] endif else begin message,'Cannot deal with filetype '+strtrim(desc.filetype,2)+'!', $ /CONT return endelse ; Compute start hour, start sec and stop sec starthour = double(long(starttime/3600.)) startsec = starttime - 3600.*starthour stopsec = stoptime - 3600.*starthour ; delete old time variables ; (note: at least ind[0] will be ge 0!) delind = [ ind[0], ind1[0], ind2[0] ] gte_delvar,data,vardesc,delind[where(delind ge 0)] ; insert new ones starthdesc = gte_vardesc() starthdesc.name = 'STARTHOUR' starthdesc.unit = 'h' startsdesc = gte_vardesc() startsdesc.name = 'STARTSEC' startsdesc.unit = 'secs' stopsdesc = gte_vardesc() stopsdesc.name = 'STOPSEC' stopsdesc.unit = 'secs' gte_insertvar,data,vardesc,starthour,starthdesc,1 gte_insertvar,data,vardesc,startsec,startsdesc,2 gte_insertvar,data,vardesc,stopsec,stopsdesc,3 desc.filetype = -1 ; Update variable information *desc.pvardesc = vardesc ; ============================================================ ; load location data if not passed in variables AND if ; required information not already in dataset ; ============================================================ load_loc: ; Rename FMSLAT and FMSLON to LON and LAT (P3B) test = where(vardesc.name eq 'FMS_LAT') if (test[0] ge 0) then vardesc[test[0]].name = 'LAT' test = where(vardesc.name eq 'FMS_LON') if (test[0] ge 0) then vardesc[test[0]].name = 'LON' test = where(vardesc.name eq 'FMS_ALTP') if (test[0] ge 0) then vardesc[test[0]].name = 'ALTP' selind = make_selection(vardesc.name,locationinfo,/REQUIRED,/QUIET) if (selind[0] ge 0) then begin ; location information already found, i.e. no merging necessary message,'Found location information in data set.',/INFO,/NONAME ; add JDAY, STARTTIME, and STOPTIME to list and save ; location information as binary file ; use Cancel button in PICKFILE if you don't want to save it! ; Convert longitudes to 0..360 or -180..180 convert_lon,data,vardesc.name,pacific=pacific,atlantic=atlantic locselind = [0,1,2,3,selind] gte_writebin,locfile,data,vardesc,sel=locselind, $ title='Save location file', $ experiment_name=desc.experiment_name, $ experiment_date=desc.experiment_date, $ experiment_number=desc.experiment_number, $ original_file=desc.filename, $ revision_date=desc.revision_date ; extract location information for subsequent use locdata = data[*,locselind] locvars = vardesc[locselind] goto,no_merge endif if (n_elements(locdata) lt 2 OR n_elements(locvars) eq 0) then begin gte_readbin,locfile,locdata,locvars,title='Select location file' if (n_elements(locdata) lt 2) then begin message,'Must have location file in binary format!',/CONT cancel = 1 return endif endif else $ message,'Location data passed in argument list',/INFO,/NONAME failed_attempts = 0 try_matching_again: selind = make_selection(locvars.name,locationinfo) ; print,locvars.name,'===',locationinfo,'===',selind & stop if (min(selind[0]) lt 0) then begin if (failed_attempts eq 0) then begin locationinfo = ['EVENT','FMSLAT','FMSLON', 'ALTP'] ; P3B version failed_attempts = 1 goto,try_matching_again endif message,'Location information not found in location data or file!', $ /CONT print,locvars.name,'<>',locationinfo return endif ; add time information to location data selind = [0,1,2,3,selind] ; ; Rename FMSLAT and FMSLON to LON and LAT (P3B) ; test = where(locvars.name eq 'FMSLAT') ; if (test[0] ge 0) then locvars.name[test[0]] = 'LAT' ; test = where(locvars.name eq 'FMSLON') ; if (test[0] ge 0) then locvars.name[test[0]] = 'LON' ; Convert longitudes to 0..360 or -180..180 convert_lon,locdata,locvars.name,pacific=pacific,atlantic=atlantic ; ============================================================ ; merge location information with data set ; ============================================================ message,'Linking data files ...',/INFO,/NONAME retry_link: gte_link,data,vardesc,locdata[*,selind],locvars[selind],/FIRST, $ result=result if (not result) then begin ; if error was "Not the same day", then try again if ; data starts only 1 day later, and location info ; extends into that day if (!error_state.code eq -10) then begin jday = fix(data[0,0]) ljday = fix(locdata[0,0]) nloc = n_elements(locdata[*,0]) lmaxhour = locdata[nloc-1,1] if (jday eq ljday+1 AND lmaxhour gt 23) then begin ; decrement JDAY in data array and increment STARTHOUR by 24 data[*,0] = data[*,0] - 1. data[*,1] = data[*,1] + 24. message,'Retrying link with shifted time...',/INFO,/NONAME goto,retry_link endif message,'!! Time is more than 1 day shifted wrt to locdata!', $ /Continue,/NoName,/NoPref return ; time is more than 1 day apart endif else $ ; some other error message,'!! Unknown error while trying to link file with locdata!', $ /Continue,/NoName,/NoPref return endif no_merge: ; ============================================================ ; rename certain species and units ; ============================================================ ; gte_rename,vardesc ; ============================================================ ; Convert Units to (semi)standard SI ; ============================================================ ; *********** NEEDS REFINEMENT !! *********************** ; preparation: rename some ambigious units ; "nm" refers to "nautic miles (nmi)" test = where(strlowcase(vardesc.unit) eq 'nm') if (test[0] ge 0) then vardesc[test].unit = 'nmi' for i=0,n_elements(vardesc)-1 do begin ; set some to commonly used units: ; - all distances in km ; - all speeds in m/s ; - all temperatures in K ; - all pressures in hPa tmpdata = data[*,i] tmpunit = vardesc[i].unit convert_unit,tmpdata,tmpunit,to='km',/QUIET convert_unit,tmpdata,tmpunit,to='m/s',/QUIET convert_unit,tmpdata,tmpunit,to='K',/QUIET convert_unit,tmpdata,tmpunit,to='hPa',/QUIET data[*,i] = tmpdata vardesc[i].unit = tmpunit endfor ; ============================================================ ; Handle special requests for project data ; ============================================================ if (keyword_set(project)) then gte_addproject,data,vardesc ; Update variable information *desc.pvardesc = vardesc ; ============================================================ ; Write binary file ; type conversion if requested ; ============================================================ message,'Writing data ...',/INFO,/NONAME gte_writebin,newfile,data,vardesc,title='Save data', $ experiment_name=desc.experiment_name, $ experiment_date=desc.experiment_date, $ experiment_number=desc.experiment_number, $ original_file=desc.filename, $ revision_date=desc.revision_date,_EXTRA=e return end