;----------------------------------------------------------------------------- function cdfx_file_search, pathSpec if !version.release ge '5.5' then $ return, file_search(pathSpec) return, findfile(pathSpec) ; for pre-5.5 end ;----------------------------------------------------------------------------- ; Returns true if either (A) the passed set of two strings are valid time ; specifications for 'read_myCDF', or (B) both strings are empty. function cdfx_valid_time_range, tr syntax = '[0-9]{4}(/[0-9]{2}){2} [0-9]{2}(:[0-9]{2}){2}' return, (tr[0]+tr[1] eq '') or $ (stregex(tr[0], syntax, /boolean) and stregex(tr[1], syntax, /boolean)) end ;----------------------------------------------------------------------------- ; Returns the named attribute of a given variable of a given CDF object. function cdfx_read_attr, cdfid, varname, attname ;attname = strupcase(attname) error_status = 0 ; initialize error flag catch, error_status ; set up exception handler to handle missing name if error_status ne 0 then $ return, '' $ else $ a = read_myattribute(varname, cdf_attnum(cdfid, attname), cdfid) return, a.(0) end ;----------------------------------------------------------------------------- ; Returns the minimum and maximum epoch values of the given CDF data files. function cdfx_time_range_of_files, fpaths rmin = 6.0e13 ; about 1900 rmax = 7.0e13 ; about 2200 for i = 0, n_elements(fpaths)-1 do begin cdfid = cdf_open(fpaths[i]) cdf_control, cdfid, set_zmode=2 info = cdf_inquire(cdfid) found = 0L ; initialize flag for varindex = 0, info.nzvars-1 do begin varname = (cdf_varinq(cdfid, varindex, /zvar)).name ;TJK 12/7/2006 - change this to look for range_epoch variable 1st ;since that's the only "good" epoch variable in the THEMIS cdfs ;if not found, then look for a regular epoch variable. ; if stregex(varname, 'epoch.*|range_epoch', /bool, /fold) then begin if stregex(varname, 'range_epoch', /bool, /fold) then begin found = 1L ;print, 'DEBUG, found range_epoch, varname = ',varname epoch = read_myvariable(varname, cdfid, vary, dtype, recs) emin = epoch[0] emax = epoch[n_elements(epoch)-1] ;print, emin,emax if i eq 0 then begin rmin = emin rmax = emax endif else begin rmin = min([rmin, emin]) rmax = max([rmax, emax]) endelse endif endfor if (not found) then begin ;if range_epoch variable not found, look for ;regular epochs for varindex = 0, info.nzvars-1 do begin varinfo = cdf_varinq(cdfid, varindex, /zvar) varname = varinfo.name vartype = varinfo.datatype varys = varinfo.recvar ;TJK 12/15/2006 - determine that the epoch variable we want to use has ; type cdf_epoch AND is record varying (THEMIS has ; several epochs, so you can't just take the 1st one ; that's cdf_epoch if (stregex(vartype, 'cdf_epoch', /bool, /fold) and (varys eq 'VARY')) then begin ;print, 'DEBUG, found regular epoch, varname = ',varname epoch = read_myvariable(varname, cdfid, vary, dtype, recs) emin = epoch[0] emax = epoch[n_elements(epoch)-1] ;print, 'DEBUG ',emin,emax if i eq 0 then begin rmin = emin rmax = emax endif else begin rmin = min([rmin, emin]) rmax = max([rmax, emax]) endelse endif endfor endif found = 0L; reset flag for check in next CDF. cdf_close, cdfid endfor return, [rmin, rmax] end ;----------------------------------------------------------------------------- ; Separates a list of CDF file paths into ordinary data files and ; master files. Also supplements the master file set with new ones ; generated from the data file names, looking for masters in both the ; current directory and the user-specified Masters directory. pro cdfx_separate_cdfs, fpaths, cpaths=cpaths, mpaths=mpaths common cdfxcom, CDFxwindows, CDFxprefs ; include cdfx common cpaths = [''] mpaths = [''] for i = 0, n_elements(fpaths)-1 do begin fpath = fpaths[i] if not stregex(fpath, '.*_00000000_v[0-9]+[.]cdf$', /boolean, /fold) then begin print,'This does not check for .CDF, only .cdf' ; then got data file, not a master cpaths = [cpaths, fpath] ; add it now ; Now look for data file's master CDF. ;dname = stregex(fpath, '/.*/', /extract) ;fname = stregex(fpath, '[^/]+$', /extract) ; dname = stregex(fpath, '\\.*\\', /extract) ; fname = stregex(fpath, '[^\\]+$', /extract) ;TJK 12/18/2006 - changed above to the following since above didn't ; work for directories containing '_' or various OS's if (strupcase(!version.os_family) eq 'UNIX' or $ strupcase(!version.os_family) eq 'MACOS') then $ delim = strpos(fpath, '/',/reverse_search) else $ delim = strpos(fpath, '\',/reverse_search) dname = strmid(fpath,0,delim+1) fname = strmid(fpath,delim+1, strlen(fpath)) ;TJK 12/18/2006 - change logic since it won't work w/ dataset ; names containing more than the usual fields split = strsplit(fname, '_', /extract) split[n_elements(split)-2] = '00000000' split[n_elements(split)-1] = 'v*.cdf' mname = strjoin(split, '_', /single) ; master CDF file name fpath = cdfx_file_search("{./," + dname + "," + $ CDFxprefs.masters_path + "/}" + mname) ; searches in three places if (size(fpath))[0] ne 0 then $; there is something to add mpaths = [mpaths, fpath[0]] endif endfor if n_elements(cpaths) gt 1 then $ cpaths = cpaths[1:*] if n_elements(mpaths) gt 1 then $ mpaths = cdfx_uniq_sort(mpaths[1:*]) end ;----------------------------------------------------------------------------- ; Returns whether the given set of CDF data files are structurally ; compatible with each other. Compatibility is defined by the routine ; Compare_mycdfs. function cdfx_files_compatible, cpaths n = n_elements(cpaths) if n lt 2 then return, 1 id0 = cdf_open(cpaths[0]) cdf_control, id0, set_zmode=2 for i = 1, n-1 do begin id = cdf_open(cpaths[i]) cdf_control, id, set_zmode=2 match = compare_mycdfs(id, id0) cdf_close, id if not match then begin cdf_close, id0 return, 0 endif endfor cdf_close, id0 return, 1 end ;----------------------------------------------------------------------------- pro cdfx_refine_open_event, event widget_control, event.top, get_uvalue=info widget_control, (*info).list, get_value=bvals case event.id of (*info).bSelectAll: begin bvals[*] = 1 widget_control, (*info).list, set_value=bvals end (*info).bUnselectAll: begin bvals[*] = 0 widget_control, (*info).list, set_value=bvals end (*info).bCancel: begin widget_control, event.top, /destroy end (*info).bProceed: begin widget_control, (*info).tstart, get_value=tstart widget_control, (*info).tstop, get_value=tstop trange = [tstart[0], tstop[0]] w = where(bvals eq 1, wc) if not cdfx_valid_time_range(trange) then $ resp = dialog_message(/error, "Invalid syntax in time fields!") $ else if wc lt 1 then $ resp = dialog_message(/error, 'No variables selected!') $ else begin (*info).selection = bvals (*info).trange = trange widget_control, event.top, /destroy endelse end else : ; do nothing endcase end ;----------------------------------------------------------------------------- function cdfx_opencdfs,gleader=gleader ;common cdfxcom, CDFxwindows, CDFxprefs ; include cdfx common ; Get a set of CDF files from user. paths = dialog_pickfile(title='Choose CDF(s)', $ /multiple) ;/fix_filter, filter="*.cdf" if paths[0] eq '' then $ return, -1 if !version.release ge '6' then $ if file_test(paths[0], /directory) then $ return, -1 cdfx_separate_cdfs, paths, cpaths=cpaths, mpaths=mpaths if n_elements(cpaths) lt 1 then begin resp = dialog_message(/error, 'No CDF data files selected!') return, -1 endif if not cdfx_files_compatible(cpaths) then begin resp = dialog_message(/error, $ 'The selected data files are not structurally compatible!') return, -1 endif cdfid = cdf_open(cpaths[0]) mcdfid = -1 vnames = get_allvarnames(cdfid=cdfid) ;print, vnames ;!! ;cinfo = cdf_inquire(cdfid) ; inquire about the cdf if mpaths[0] ne '' then begin mcdfid = cdf_open(mpaths[0]) vnames = [vnames, get_allvarnames(cdfid=mcdfid)] ; add master vars endif else $ resp = dialog_message(/info, 'No CDF master files found.') vnames = cdfx_uniq_sort(vnames) new_vnames = [''] vlist = [''] ;nvars = n_elements(vnames) ;vlist = strarr(nvars) ; Gather display information for the variables. for i=0, n_elements(vnames)-1 do begin ; construct the list of variables name vname = vnames[i] vtype = cdfx_read_attr(cdfid, vname, 'VAR_TYPE') if vtype eq '' and mcdfid ne -1 then $ vtype = cdfx_read_attr(mcdfid, vname, 'VAR_TYPE') fname = cdfx_read_attr(cdfid, vname, 'FIELDNAM') if fname eq '' and mcdfid ne -1 then $ fname = cdfx_read_attr(mcdfid, vname, 'FIELDNAM') + ' (M)' if vtype eq 'data' or vtype eq 'support_data' then begin vlist = [vlist, string(format='(a25,a15,a50)', vname, vtype, fname)] new_vnames = [new_vnames, vname] endif endfor cdf_close, cdfid if mcdfid ne -1 then $ cdf_close, mcdfid if n_elements(vlist) lt 2 then begin resp = dialog_message(/error, $ "No data or support variables were found in the chosen CDF file(s). The files are probably not ISTP-compliant.") return, -1 endif vlist = vlist[1:*] vnames = new_vnames[1:*] nvars = n_elements(vlist) trange = cdfx_time_range_of_files(cpaths) tstart = cdfx_time_string_of_epoch(trange[0]) tstop = cdfx_time_string_of_epoch(trange[1]) ;base = widget_base(/column, title='Select Variables and Time Interval', /frame) base = widget_base(/column, title='Select Variables and Time Interval', /frame,$ group_leader=gleader,/modal) base1 = widget_base(base, /column, /frame) base3 = widget_base(base, /row) base4 = widget_base(base3, /column, /frame) base2 = widget_base(base3, /column, /frame) w = widget_label(base4, value='Time Interval') w = widget_label(base4, value='(Format: YYYY/MM/DD hh:mm:ss)') bstart = widget_base(base4, /row) lstart = widget_label(bstart, value='Start time:') bstop = widget_base(base4, /row) lstop = widget_label(bstop, value='Stop time: ') info = ptr_new({$ selection:lonarr(nvars), $ trange:["",""], $ list:cw_bgroup(base1, vlist, /nonexclusive, scroll=(nvars>20), $ set_value = lonarr(nvars), $ label_top = strtrim(string(nvars), 2) + ' Variables', $ y_scroll = (20 * !d.y_ch_size), $ x_scroll = (95 * !d.x_ch_size)), $ tStart: widget_text(bstart, value=tstart, xsize=20, /editable), $ tStop: widget_text(bstop , value=tstop , xsize=20, /editable), $ bProceed: widget_button(base2, value='Proceed'), $ bSelectAll: widget_button(base2, value='Select All'), $ bUnselectAll: widget_button(base2, value='Unselect All'), $ bCancel: widget_button(base2, value='Cancel') }) widget_control, base, /realize, set_uvalue=info xmanager, 'cdfx_refine_open', base;, /modal ;modal is obsolete in xmanager w = where((*info).selection eq 1, wc) a = -1 if wc gt 0 then begin tstart = ((*info).trange)[0] tstop = ((*info).trange)[1] widget_control, /hourglass if mpaths[0] eq '' then $ allpaths = cpaths $ else $ allpaths = [mpaths, cpaths] if tstart eq "" or tstop eq "" then begin a = read_mycdf(vnames[w], allpaths, /nodatastruct) endif else begin a = read_mycdf(vnames[w], allpaths, /nodatastruct, $ tstart=tstart, tstop=tstop) endelse endif ptr_free, info return, a end ;-----------------------------------------------------------------------------