; $Id: ctm_make_datainfo.pro,v 1.21 1999/03/16 21:53:32 mgs Exp $ ;------------------------------------------------------------- ;+ ; NAME: ; CTM_MAKE_DATAINFO (function) ; ; PURPOSE: ; Create a datainfo and fileinfo structure from an ; "external" data set so that it can be used seamlessly ; within the GAMAP package. The dataset can have up to ; four dimensions (however, only the first 3 are currently ; supported). Th enew datainfo and fileinfo structures ; will be added to the global structure arrays. ; ; CATEGORY: ; GAMAP tools ; ; CALLING SEQUENCE: ; result = CTM_MAKE_DATAINFO(DATA,DATAINFO,FILEINFO [,keywords]) ; ; INPUTS: ; DATA -> A 1-D, 2-D, or 3-D data array. ; ; KEYWORD PARAMETERS: ; MODELINFO -> A modelinfo structure containing information ; about the model that generated the data (see CTM_TYPE). ; If not given, the user is prompted for a selection. ; ; GRIDINFO -> A gridinfo structure describing the grid set-up ; of the data set (see CTM_GRID). If not given, ; CTM_MAKE_DATAINFO attempts to use the MODELINFO ; structure to construct GRIDINFO. ; ; DIAGN -> A diagnostics name (category) or number that describes ; the data type. If not given, the user will be prompted. ; If DIAGN is a number that is not recognized as valid ; diagnostics by CTM_DIAGINFO, the number will be stored ; as string value. If DIAGN is a string, it does not have ; to be a valid diagnostics category. ; ; TRACER -> A tracer number or name that identifies the chemical ; species or physical quantity contained in DATA. If ; TRACER is an invalid name, it will be set to -1, and the ; string value of TRACER will be used as TRCNAME (see below). ; If not given, the user will be prompted. ; ; TRCNAME -> A tracer name. Default is to use the name associated ; with that tracer number in CTM_TRACERINFO. ; ; TAU0, TAU1 -> Beginning and end of time interval that is spanned ; by DATA (as TAU value). Default is -1 for both. ; ; SCALE -> A value that is entered in the SCALE field in DATAINFO. ; Default is 1.0. ; ; UNIT -> A unit string. Default is empty. ; ; DIM -> A 4 element vector with the DATA dimensions as ; LON, LAT, LEVEL, TIME. If not given, the dimensions ; of DATA will be entered sequentially. Use this keyword ; to properly identify e.g. a zonal mean data set as ; DIM = [ 0, 46, 20, 0 ] (for the GEOS-1). ; The order and magnitude of the dimensions in DIM must ; agree with the dimensions of the DATA array ; (e.g. if DATA(72,46) then DIM=[46,72,0,0] is not allowed). ; ; FIRSTBOX -> A 3 element vector containing IFIRST, JFIRST, and ; LFIRST, which are the starting indices for the LON, ; LAT, and LEVEL dimensions. ; ; TOPTITLE -> A user defined string that may describe the data set ; in more detail. ; ; /NO_GLOBAL -> Do not append the newly created datainfo and fileinfo ; structures to the global ones. ; ; /NO_VERTICAL (passed via _EXTRA) -> set this keyword if you only want ; to create a 2D gridfinfo structure. ; ; OUTPUTS: ; DATAINFO, FILEINFO -> The datainfo and fileinfo structures ; generated from the "external" data array. These are ; automatically appended to the global DATAINFO and FILEINFO ; structures, unless the /NO_GLOBAL keyword is set. ; ; SUBROUTINES: ; none ; ; REQUIREMENTS: ; Uses CREATE3DHSTRU, CREATE3DFSTRU, TAU2YYMMDD ; ; NOTES: ; In the current version, no error checking is made whether the ; DATA dimensions agree with the grid information. This is the ; users responsibility. ; ; EXAMPLE: ; ; create a 2D array ; DATA = dist(72,46) ; ; make a DATAINFO structure ; result = CTM_MAKE_DATAINFO(data,datainfo,fileinfo) ; ; The user will be prompted for model type, diagnostics and ; ; tracer. ; ; ; Add a zonal mean difference data set (already in DATA) ; result = CTM_MAKE_DATAINFO(data,datainfo,fileinfo, $ ; model=ctm_type('GEOS1',psurf=1013.),diagn='ZONE-AVG', $ ; tracer=2,tau0=nymd2tau(940901L),tau1=nymd2tau(940930), $ ; unit='ppbv',dim=[0,46,20,0], $ ; toptitle='Zonal mean difference in Ox CLDS/no CLDS') ; ; help,datainfo,/stru ; ; will print something like: ; ** Structure H3DSTRU, 13 tags, length=72: ; ILUN LONG -15 ; FILEPOS LONG 0 ; CATEGORY STRING 'ZONE-AVG' ; TRACER INT 2 ; TRACERNAME STRING 'Ox' ; TAU0 DOUBLE 84720.000 ; TAU1 DOUBLE 85416.000 ; SCALE FLOAT 1.00000 ; UNIT STRING 'ppbv' ; FORMAT STRING '' ; STATUS INT 1 ; DIM INT Array[4] ; OFFSET INT Array[3] ; DATA POINTER ; ; MODIFICATION HISTORY: ; mgs, 09 Oct 1998: VERSION 1.00 ; mgs, 19 Nov 1998: - bug fix. ILUN now always negative! ; - unit now "required" parameter, i.e. ; interactively asked for ; bmy, 11 Feb 1999: VERSION 1.01 ; - added OFFSET keyword so that I0, J0, and ; L0 offsets can be stored in DATAINFO ; - DATAINFO.TAU0 and DATAINFO.TAU1 are now ; stored as double precision ; - updated comments ; mgs, 16 Mar 1999: - cosmetic changes ; - OFFSET changed into FIRSTBOX ; mgs, 30 Mar 1999: - added _EXTRA keyword for ctm_grid ; (use for /NO_VERTICAL) ; ;- ; 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_make_datainfo" ;------------------------------------------------------------- function ctm_make_datainfo,data,datainfo,fileinfo, $ modelinfo=modelinfo,gridinfo=gridinfo, $ diagn=diagn,tracer=tracer,trcname=trcname, $ tau0=tau0,tau1=tau1,scale=scale,unit=unit, $ dim=dim,toptitle=toptitle, firstbox=firstbox, $ _EXTRA=e @gamap_cmn ; returns 1 if successful, 0 otherwise FORWARD_FUNCTION create3dhstru, create3dfstru, tau2yymmdd result = 0 ; for safety ; check validity of DATA argument if (n_elements(DATA) eq 0) then begin message,'No data passed!',/Cont return,result endif ; ================================================================ ; create default return structures ; ================================================================ datainfo = create3dhstru() fileinfo = create3dfstru() ; ================================================================ ; get a free "derived data" unit number (negative) ; ================================================================ if (ptr_valid(pGlobalFileInfo)) then f = *pGlobalFileInfo $ else f = fileinfo fileinfo.ilun = ( min(f.ilun) - 1 ) < ( -1 ) datainfo.ilun = fileinfo.ilun ; filename is always "derived data" fileinfo.filename = 'derived data' fileinfo.filetype = -1 ; ================================================================ ; get remaining fields for fileinfo and datainfo ; query user for fields that are not passed as keywords ; ================================================================ if (not chkstru(modelinfo,['NAME','RESOLUTION'])) then $ modelinfo = select_model() fileinfo.modelinfo = modelinfo if (DEBUG) then print,'# Modelname and resolution : ', $ modelinfo.name,modelinfo.resolution,format='(2A,2F6.2)' if (not chkstru(gridinfo,['XEDGE','YEDGE'])) then $ gridinfo = ctm_grid(modelinfo,_EXTRA=e) fileinfo.gridinfo = ptr_new(gridinfo) if (n_elements(toptitle) gt 0) then $ fileinfo.toptitle = toptitle[0] if (n_elements(diagn) eq 0) then begin diagn = '' read,diagn,prompt='Diagnostics (name or number) : ' if ( min(isdigit(diagn) eq 1) ) then diagn = fix(diagn) endif ctm_diaginfo,diagn,stru ; if not a valid diagnostics, use it anyway: pretend it's a string if (stru.index lt 0) then stru.category = strtrim(diagn,2) datainfo.category = stru.category if (DEBUG) then print,'# Category : ',datainfo.category if (n_elements(tracer) eq 0) then begin tracer = '' read,tracer,prompt='Tracer (number or name) : ' if ( min(isdigit(tracer) eq 1) ) then tracer = fix(tracer) endif else begin ; if tracer is a string and trcname is not provided, ; save tracer as trcname if (size(tracer,/TYPE) eq 7 AND n_elements(trcname) eq 0) then $ trcname = tracer endelse ctm_tracerinfo,tracer,stru,index=tracerindex datainfo.tracer = tracerindex if (n_elements(trcname) eq 0) then $ trcname = stru.name datainfo.tracername = trcname ; will be '' if unknown tracer if (DEBUG) then print,'# Tracer : ',datainfo.tracername, $ datainfo.tracer,format='(2A,3X,I4)' if (n_elements(tau0) eq 0) then tau0 = -1D datainfo.tau0 = tau0 if (n_elements(tau1) eq 0) then tau1 = -1D datainfo.tau1 = tau1 if (DEBUG) then print,'# Time range : ', $ tau0,(tau2yymmdd(tau0,/NFORMAT,/SHORT))[0], $ tau1,(tau2yymmdd(tau1,/NFORMAT,/SHORT))[0], $ format='(A,3X,2(F10.2," (=",I8,") "))' if (n_elements(scale) eq 0) then scale = 1.0 datainfo.scale = scale if (n_elements(unit) eq 0) then begin unit = '' read,unit,prompt='Unit : ' unit = strtrim(unit,2) if (unit eq '') then unit = 'UNDEFINED' endif datainfo.unit = unit datainfo.status = 1 ; since we pass data it is always "read" if (n_elements(dim) ne 4) then begin dim = size(data,/dimensions) while (n_elements(dim) lt 4) do dim = [ dim, 0 ] endif datainfo.dim = (dim > 1) if ( N_Elements( FIRSTBOX ) ne 3 ) then begin FIRSTBOX = intarr(3) ; three zero entries sd = Size( Data, /N_Dim) ; set valid entries to 1 FIRSTBOX[0:sd < 3] = 1 endif DataInfo.First = FIRSTBOX ; Make sure data dimensions agree with dim dimensions somehow !! ; be strict in the sense that the order of dimensions must be ; the same datadim = size(data,/dimensions) if (DEBUG) then print,'# DATA Dimensions : ',datadim,format='(A,4X,9I5)' if (DEBUG) then print,'# DIM Field : ',dim,format='(A,10X,4I5)' if (DEBUG) then print,'# FIRSTBOX Field : ', FIRSTBOX, Format='(A,10X,3I5)' if (n_elements(datadim) gt 4) then begin message,'Data has too many dimensions!',/Cont return,result endif j = 0 for i=0,n_elements(datadim)-1 do begin while (j lt 4 AND datadim[i] ne dim[j]) do begin j = j+1 if (j eq 4) then begin message,'Dimensions of DATA and DIM do not match!',/Cont return,result endif endwhile endfor ; Add data datainfo.data = ptr_new(data) result = 1 ; ================================================================ ; if everything went OK, we can now append the new structures ; to the global ones ; ================================================================ if (ptr_valid(pGlobalFileInfo)) then $ *pGlobalFileInfo = [ *pGlobalFileInfo, fileinfo ] $ else $ pGlobalFileInfo = ptr_new(fileinfo) if (ptr_valid(pGlobalDataInfo)) then $ *pGlobalDataInfo = [ *pGlobalDataInfo, datainfo ] $ else $ pGlobalDataInfo = ptr_new(datainfo) return,result end