;+ ; PROCEDURE: ; makecdf, datavary, datanovary=datanovary, filename=filename, status=status, $ ; gattributes=gattr, vattributes=vattr, tagsvary=tagsvary, $ ; tagsnovary=tagsnovary, overwrite=overwrite ; ; PURPOSE: ; Creates a CDF file given an array of structures ; ; KEYWORDS: ; filename: ; Name of file to be created. ; datanovary: ; a structure containing the time invariant data to be written to CDF (like ; array descriptors). ; tagsvary: ; array of strings that will be used as the CDF variable names for the values ; stored in the datavary structure. Default CDF variable names are the names ; of the tags of the datavary structure. ; Note that, since IDL internally capitalizes all variable and tag names, ; the CDF variable names will be all caps in the default, so the tagsvary ; keyword should generally be used to control capitalization of the CDF variable ; names. ; tagsnovary: ; array of strings that will be used as the CDF variable names for the values ; stored in the datanovary structure. Default CDF variable names are the names ; of the tags of the datanovary structure. ; Note that, since IDL internally capitalizes all variable and tag names, ; the CDF variable names will be all caps in the default, so the tagsnovary ; keyword should generally be used to control capitalization of the CDF variable ; names. ; gattributes: ; a structure specifying the names, entry numbers, and values of the global ; CDF attributes that will be written to the CDF file. ; The tagnames of the gattributes structure are actually dummy placeholders ; which are not used (but must all be unique, or course). ; The value of each field is a struture containing three fields, 'name', ; which contains the name of the attribute, 'entry', which contains the entry ; number (many attributes contain just a single entry, generally just entry 0, ; and some contain several entries, generally entries 0,1,2,3, etc), and ; 'value' which contains the value of the attribute for the specified entry. ; (see the example below) ; vattributes: ; a structure specifying, for each CDF variable that has variable attributes, ; the names and values of the variable CDF attributes that will be written to ; the CDF file. The tagnames of the vattributes structure are actually dummy ; placeholders and are not used. The values of the fields of the vattributes ; structure should each be a structure, with a 'varname' field containing the ; name of a CDF variable, and an 'attrlist' field which contains a structure ; containing the set of attribute names and values for the specified variable. ; (see the example below) ; overwrite: ; if set, overwrite any existing CDF file with the specified name (default ; is to not overwrite any such existing file). ; status: ; status is 0 on successful return, nonzero on unsuccessful return. ; A routine that calls makecdf should in general use the status keyword parameter ; and verify that the CDF write has completed successfully. ; ; INPUT: ; datavary: ; an array of structures containing the time variant data to be written to CDF. ; Each element of the array is a structure containing the values for one time. ; Datavary must have a tag named 'time' that contains the time in seconds since ; 01-01-1970/00:00:00 UT. An additional CDF variable named 'Epoch', of type ; CDF_EPOCH, will be written to the CDF, and will be computed from 'time'. ; ; EXAMPLE: ; To make a CDF file named 'foo.cdf' containing tplot variables 'el_0' and 'el_high', ; and with two global attributes, named 'foo' (with one entry with value 'bar') and ; 'goo' (with two entries, one with value 1.0, and one with value 2.0), ; and with two variable attributes, 'VALIDMIN' and 'VALIDMAX', with VALIDMIN for el_0 ; to be set to 1.0, and VALIDMAX of el_0 to be set to 2.0, and VALIDMIN of el_high to ; be set to 1.0 and VALIDMAX of el_high to be set to 2.0, ; give the following IDL commands: ; ; > make_cdf_structs, ['el_0', 'el_high'], datavary, datanovary ; > gattr = {foo0: {name:'foo', entry:0, value:'bar'}, $ ; goo0: {name:'goo', entry:0, value:1.0 }, $ ; goo1: {name:'goo', entry:1, value:2.0 }} ; > vattr_el_0 = {VALIDMIN:1.0, VALIDMAX:2.0} ; > vattr_el_high = {VALIDMIN:1.0, VALIDMAX:2.0} ; > vattr = {el_0: {varname:'el_0', attrlist:vattr_el_0}, $ ; el_high: {varname:'el_high', attrlist:vattr_el_high}} ; > makecdf, file='foo', datavary, datanovary=datanovary, $ ; tagsvary=['time', 'el_0', 'el_high'], tagsnovary=['el_0_en', 'el_high_pa'], $ ; gattr=gattr, vattr=vattr ; ; Note that, in the above specification of vattr, the names of the CDF variables (el_0 ; and el_high in this example), appear to be repeated in two places each. The first ; occurrence of each, in the tagname, is actually just an unused dummy, and the second ; occurrence of each, in the string value of varname, is the CDF variable name. This ; is because IDL variable names and tag names can't be used to specify the more general ; strings that CDF variable names can have. Similarly with gattr. ; ; The resulting CDF file will contain an Epoch variable (computed from the time), ; a time variable (taken by default from the 'x' component of the first named tplot ; variable, but specifiable otherwise by the 'times' keyword to 'make_cdf_structs'), ; and, for each tplot variable named in the argument list to 'make_cdf_structs', the ; 'y' component, with a name taken from 'tagsvary', and the 'v' component, with a ; name taken from 'tagsnovary'. ; Thus the CDF file from the above commands will contain the CDF variables ; Epoch: ; This is of type CDF_EPOCH, and is calculated from the time variable below ; time: ; by default, the 'x' tag from the tplot variable 'el_0' ; el_0: ; the 'y' tag from the tplot variable 'el_0' ; el_high: ; the 'y' tag from the tplot variable 'el_high' ; el_0_en: ; the 'v' tag from the tplot variable 'el_0' ; el_high_pa: ; the 'v' tag from the tplot variable 'el_high' ; ; ; SEE ALSO: ; "loadcdf", "loadcdfstr" ; "make_cdf_structs.pro", "strarr_to_arrstr.pro" ; ; VERSION: @(#)makecdf.pro 1.6 08/13/98 ;- pro makecdf , datavary, datanovary=datanovary, filename=filename, status=status, $ tagsvary=tagsvary, tagsnovary=tagsnovary, overwrite=overwrite, $ gattributes=gattr, vattributes=vattr status = -1 if not keyword_set(filename) then begin message, "keyword 'filename' must be set" return endif if keyword_set(overwrite) then begin on_ioerror, create id = cdf_open(filename) cdf_delete,id create: on_ioerror,null endif id = cdf_create(filename, /single) ; ; Create and write the values of the global attributes ; if keyword_set(gattr) then begin for i = 0, n_tags(gattr) - 1 do begin attrname = gattr.(i).name attrentry = gattr.(i).entry attrvalue = gattr.(i).value if not cdf_attr_exists(id, attrname) then begin attr_id = cdf_attcreate(id, attrname, /GLOBAL_SCOPE) endif cdf_attput, id, attr_id, attrentry, attrvalue endfor endif ; ; Write out all the record variant data ; if keyword_set(tagsvary) then begin if n_elements(tagsvary) ne n_tags(datavary) then begin message, 'tagsvary has wrong number of elements', /continue cdf_delete,id return endif endif else tagsvary=tag_names_r(datavary) ntags = n_elements(tagsvary) nrecs = n_elements(datavary) ;help,datavary,/str for n=0,ntags-1 do begin d0 = datavary(0) dat0=0 str_element,d0,tagsvary(n),dat0 ;help,tagsvary(n),dat0,/str nd = ndimen(dat0) dim = dimen(dat0) type = data_type(dat0) dat = 0 str_element,datavary,tagsvary(n),dat ;help,tagsvary(n),dat,/str if nd ne 0 then begin case data_type(dat) of 1: zid = cdf_varcreate(id,tagsvary(n),dim ne 0,dim=dim,/cdf_uchar) 2: zid = cdf_varcreate(id,tagsvary(n),dim ne 0,dim=dim,/cdf_int2) 3: zid = cdf_varcreate(id,tagsvary(n),dim ne 0,dim=dim,/cdf_int4) 4: zid = cdf_varcreate(id,tagsvary(n),dim ne 0,dim=dim,/cdf_float) 5: zid = cdf_varcreate(id,tagsvary(n),dim ne 0,dim=dim,/cdf_double) endcase endif else begin case data_type(dat) of 1: zid = cdf_varcreate(id,tagsvary(n),/zvar,/cdf_uchar) 2: zid = cdf_varcreate(id,tagsvary(n),/zvar,/cdf_int2) 3: zid = cdf_varcreate(id,tagsvary(n),/zvar,/cdf_int4) 4: zid = cdf_varcreate(id,tagsvary(n),/zvar,/cdf_float) 5: zid = cdf_varcreate(id,tagsvary(n),/zvar,/cdf_double) endcase endelse cdf_varput,id,tagsvary(n),dat endfor ; ; Write out all the non record variant data ; if keyword_set(datanovary) then begin if keyword_set(tagsnovary) then begin if n_elements(tagsnovary) ne n_tags(datanovary) then begin message, 'tagsnovary has wrong number of elements', /continue cdf_delete,id return endif endif else tagsnovary=tag_names(datanovary) ntags = n_elements(tagsnovary) nrecs = n_elements(datanovary) for n=0,ntags-1 do begin d0 = datanovary(0) nd = ndimen(d0.(n)) dim = dimen(d0.(n)) type = data_type(d0.(n)) dat = datanovary.(n) if nd ne 0 then begin case data_type(dat) of 1: zid = cdf_varcreate(id,tagsnovary(n),dim ne 0,dim=dim,/cdf_uchar,/rec_novary) 2: zid = cdf_varcreate(id,tagsnovary(n),dim ne 0,dim=dim,/cdf_int2,/rec_novary) 3: zid = cdf_varcreate(id,tagsnovary(n),dim ne 0,dim=dim,/cdf_int4,/rec_novary) 4: zid = cdf_varcreate(id,tagsnovary(n),dim ne 0,dim=dim,/cdf_float,/rec_novary) 5: zid = cdf_varcreate(id,tagsnovary(n),dim ne 0,dim=dim,/cdf_double,/rec_novary) endcase endif else begin case data_type(dat) of 1: zid = cdf_varcreate(id,tagsnovary(n),/zvar,/cdf_uchar,/rec_novary) 2: zid = cdf_varcreate(id,tagsnovary(n),/zvar,/cdf_int2,/rec_novary) 3: zid = cdf_varcreate(id,tagsnovary(n),/zvar,/cdf_int4,/rec_novary) 4: zid = cdf_varcreate(id,tagsnovary(n),/zvar,/cdf_float,/rec_novary) 5: zid = cdf_varcreate(id,tagsnovary(n),/zvar,/cdf_double,/rec_novary) endcase endelse cdf_varput,id,tagsnovary(n),dat endfor endif ; ; Write out the variable attributes for all variables, creating each when necessary ; if keyword_set(vattr) then begin for i = 0, n_tags(vattr) - 1 do begin varname = vattr.(i).varname attrlist = vattr.(i).attrlist for j = 0, n_tags(attrlist) - 1 do begin attrname = (tag_names(attrlist))(j) attrvalue = attrlist.(j) if not cdf_attr_exists(id, attrname) then begin attr_id = cdf_attcreate(id, attrname, /variable) endif cdf_attput, id, attrname, varname, attrvalue endfor endfor endif epoch0 = 719528.d * 24.* 3600. * 1000. ;Jan 1, 1970 epoch = datavary.time * 1000. + epoch0 zid = cdf_varcreate(id,'Epoch',/CDF_EPOCH) cdf_varput,id,'Epoch',epoch cdf_close,id status = 0 return end