;+ ;PROCEDURE: store_data,name,DATA=data,LIMITS=limits,DLIMITS=dlimits, ; NEWNAME=newname,DELETE=delete ;PURPOSE: ; Store time series structures in static memory for later retrieval ; by the tplot routine. Three structures can be associated with the ; string 'name': a data structure (DATA) that typically contains the x and ; y data. A default limits structure (DLIMITS) and a user limits structure ; (LIMITS) that will typically contain user defined limits and options ; (typically plot and oplot keywords). The data structure and the default ; limits structure will be ; over written each time a new data set is loaded. The limit structure ; is not over-written. ;INPUT: ; name: string name to be associated with the data structure and/or ; the limits structure. Also, can enter tplot index as name. ; The name should not contain spaces or the characters '*' and '?' ;KEYWORDS: ; DATA: variable that contains the data structure. ; LIMITS; variable that contains the limit structure. ; DLIMITS; variable that contains the default limits structure. ; NEWNAME: new tplot handle. Use to rename tplot names. ; DELETE: array of tplot handles or indices to delete from common block. ; MIN: if set, data values less than this value will be made NaN. (obsolete) ; MAX: if set, data values greater than this value will be made NaN. (obsolete) ; NOSTRSW: if set, do not transpose multidimensional data arrays in ; structures. The default is to transpose. ; ERROR: if set returns error code for store_data, values are: ; 0=NO ERROR ; 1=INVALID HANDLE ERROR ; 2=OTHER ERROR ; ;SEE ALSO: "GET_DATA", "TPLOT_NAMES", "TPLOT", "OPTIONS" ; ;CREATED BY: Davin Larson ; $LastChangedBy: davin-win $ ; $LastChangedDate: 2012-02-22 17:15:46 -0800 (Wed, 22 Feb 2012) $ ; $LastChangedRevision: 9829 $ ; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/ssl_general/trunk/tplot/store_data.pro $ ;- pro store_data,name, time,ydata,values, $ data = data, $ append=append, $ limits= limits, $ dlimits = dlimits, $ newname = newname, $ min=min, max=max, $ delete = delete, $ clear = clear, $ verbose = verbose, $ nostrsw = nostrsw,$ except_ptrs = except_ptrs, $ error=error @tplot_com.pro error = 0 ;if n_params() ge 3 then begin ; if keyword_set(data) then dprint,'Warning! Data keyword ignored!' ; data = {x:time, y:ydata} ; if keyword_set(values) then data = create_struct(data,'v',values) ;endif if size(verbose,/type) eq 0 then begin str_element,tplot_vars,'options.verbose',verbose ; get default verbose value if it exists endif dprint,dlevel=5,verbose,/phelp if keyword_set(clear) then begin names = tnames(name,n) for i=0,n-1 do begin index = find_handle(names[i]) if index gt 0 then begin dq = data_quants[index] ptr = *dq.dh dprint,dlevel=2,verbose=verbose,'Clearing: ',names[i] if size(/type,ptr) eq 8 then tags = tag_names(ptr) else undefine,tags for j=0,n_elements(tags)-1 do begin if size(ptr.(j),/type) eq 10 then *(ptr.(j)) = 0 $ else (*dq.dh).(j) = 0 endfor dq.trange = !values.d_nan dq.create_time = systime(1) data_quants[index] = dq endif else message,'This should never occur' endfor return endif if keyword_set(delete) then begin if n_elements(name) ne 0 then delete=name delnames = tnames(delete,cnt) if cnt ne 0 then begin au = array_union(data_quants.name,delnames) savevars = where(au eq -1) delevars = where(au ne -1) saveptrs = ptr_extract(except_ptrs) saveptrs = [saveptrs,ptr_extract(data_quants[savevars])] delptrs = ptr_extract(data_quants[delevars],except=saveptrs) data_quants=data_quants[savevars] ptr_free,delptrs dprint,dlevel=1,verbose=verbose,'Deleted ',cnt,' variables' endif else dprint,dlevel=1,verbose=verbose,'No matching variables to delete' return endif dt = size(name,/type) if size(name,/n_dimen) ne 0 then begin dprint,verbose=verbose,'Input name must be scalar!' error=1 return endif if dt eq 7 then begin if name eq '' then begin dprint, verbose=verbose, 'Invalid name: Cannot use empty string to name tplot variable' error=1 return endif if total( array_union(byte(name),byte(' *?[]\')) ge 0) then begin dprint,verbose=verbose,'Invalid name: "'+name+'"; Name may not contain spaces, or the characters: "* ? [ ] \"' error=1 return endif if n_elements(data_quants) eq 0 then index = 0 else index = find_handle(name) endif else if (dt ge 1) and (dt le 3) then begin index = name name = data_quants(index).name endif else if not keyword_set(delete) then begin dprint,verbose=verbose,'Invalid handle name or index' error=1 return endif dq = {tplot_quant} if n_elements(data_quants) eq 0 then data_quants = [dq] if index eq 0 then begin ; new variable orig_name = name+'x' ; required due to compile bug in early versions of IDL dq.name = strmid(orig_name,0,strlen(name)) ; if keyword_set(verbose) then print,'Creating new tplot variable: ',dq.name verb = 'Creating' dq.dh = ptr_new(0) ;/allocate) dq.lh = ptr_new(0) ;/allocate) dq.dl = ptr_new(0) ;/allocate) data_quants = [data_quants,dq] index = n_elements(data_quants) - 1 dq.trange = !values.d_nan dq.create_time = systime(1) endif else begin dq = data_quants(index) if keyword_set(append) then verb = 'Appending' else verb = 'Altering' endelse if n_params() ge 3 then begin if keyword_set(append) && keyword_set( *dq.dh ) && keyword_set(*(*dq.dh).x) then begin ; dqdh = (*dq.dh) ; oldind= dqdh.x_ind if append eq 2 then begin append_array,*(*dq.dh).x, !values.d_nan , index=(*dq.dh).x_ind ,new_index=ind ,/fillnan & (*dq.dh).x_ind = ind append_array,*(*dq.dh).y, fill_nan(ydata), index=(*dq.dh).y_ind ,new_index=ind ,/fillnan & (*dq.dh).y_ind = ind ; dprint,dlevel=2,'Data gap in ',dq.name,ind endif append_array,*(*dq.dh).x, time , index=(*dq.dh).x_ind ,new_index=ind ,/fillnan & (*dq.dh).x_ind = ind append_array,*(*dq.dh).y, ydata, index=(*dq.dh).y_ind ,new_index=ind ,/fillnan & (*dq.dh).y_ind = ind ; dprint,dlevel=3,'Normal in ',dq.name,ind ; if keyword_set(values) then append_array,*dqdh.v,values,index = *dqdy.v_ind,/fill_nan ; dprint,dlevel=4,verbose=verbose,'Appending to ',name dq.trange = minmax([dq.trange,time]) data_quants[index] = dq ; tplot_panel,time,ydata,var= name,psym=-3 ; real time plotting return endif if keyword_set(data) then dprint,'Warning! Data keyword ignored!' data = {x:time, y:ydata} ; First time appending uses normal method if keyword_set(values) then data = create_struct(data,'v',values) endif if keyword_set(min) then begin bad = where(data.y lt min,c) if c ne 0 then data.y(bad) = !values.f_nan endif if keyword_set(max) then begin bad = where(data.y gt max,c) if c ne 0 then data.y(bad) = !values.f_nan endif ; set values: if n_elements(newname) ne 0 then begin if total( array_union(byte(newname),byte(' *?[]\')) ge 0) then begin dprint,verbose=verbose,dlevel=0,'Invalid name: "'+name+'"; Name may not contain spaces, or the characters: "* ? [ ] \"' error=2 return endif nindex = where(data_quants.name eq newname, count) if count gt 0 then begin dprint,verbose=verbose,dlevel=0,'New name must not already be in use! error=2 return endif else dq.name = newname endif if n_elements(limits) ne 0 then *dq.lh = limits if n_elements(dlimits) ne 0 then *dq.dl = dlimits if n_elements(data) ne 0 then begin save_ptrs = ptr_extract(except_ptrs) save_ptrs = [save_ptrs, ptr_extract(limits) ] save_ptrs = [save_ptrs, ptr_extract(dlimits)] save_ptrs = [save_ptrs, ptr_extract(data)] save_ptrs = [save_ptrs, ptr_extract( data_quants[where(data_quants.name ne dq.name)])] dprint,verbose=verbose,dlevel=2,verb+' tplot variable: ',strtrim(index,2),' ',dq.name dq.create_time = systime(1) if size(/type,data) eq 8 then begin ; structures mytags = tag_names(data) myptrstr = 0 for i = 0, n_elements(mytags) - 1 do begin newv = data.(i) ; faster than: str_element,data,mytags(i),foo dim_newv = size(/dimension,newv) oldp = ptr_new() ; this line is not necessary str_element,*dq.dh,mytags[i],oldp if size(/type,newv) ne 10 then begin ; newv is not a pointer ptr_free,ptr_extract(oldp,except=save_ptrs) ; free old stuff (if any exist) newv = ptr_new([newv],/no_copy) endif else begin ; newv is a pointer if oldp ne newv then ptr_free,ptr_extract(oldp,except=save_ptrs) endelse str_element,/add_replace,myptrstr,mytags[i],newv str_element,/add_replace,myptrstr,mytags[i]+'_ind',dim_newv[0] > 1 endfor *dq.dh = myptrstr endif else *dq.dh = data endif ;if n_elements(data) ne 0 then if data_type(data) eq 10 then $ ; dq.dh = data else *dq.dh = data extract_tags,dstr,data ; this command can be extremely time consuming and should be removed extract_tags,dstr,dlimits extract_tags,dstr,limits str_element,dstr,'x',value=x str_element,dstr,'y',value=y if size(/type,x) eq 10 then if ptr_valid(x) then x=*x if size(/type,y) eq 10 then if ptr_valid(y) then y=*y if n_elements(x) ne 0 and n_elements(y) ne 0 then begin dq.dtype = 1 dq.trange = minmax(x) endif str_element,dstr,'time',value=time0 if size(/type,time0) eq 10 then time0=*time0 if n_elements(time0) ne 0 then begin ; obsolete format of passing in an array of structures dq.dtype = 2 dprint,'Obsolete storage method. type .cont to continue' ; stop dq.trange = minmax(time0) dqtags = tag_names(*dq.dh) data_quants(index) = dq for i=0,n_elements(dqtags)-1 do if dqtags(i) ne 'TIME' then begin subname = dq.name+'.'+dqtags(i) str_element,*dq.dh,dqtags(i),foo if size(foo,/type) eq 10 then begin if ndimen(*foo) ne 1 then $ if dimen((*foo)[0]) ne n_elements(time0) then $ if keyword_set(nostrsw) eq 0 then $ *foo = transpose(*foo) store_data,subname,data={x: time0, y:foo}, $ dlimits=*dq.dl, limits=*dq.lh endif endif endif if size(/type,data) eq 7 then begin dq.dtype = 3 names = tnames(data,trange=tr) dprint,verbose=verbose,dlevel=2,'Multi-'+' tplot variable: ',strtrim(index,2),' ',dq.name,' : ' ,names dq.trange = minmax(tr) endif data_quants[index] = dq ;pos = strpos(name,'.') ;if (pos gt 0) then begin ; names = strarr(2) ; names(0) = strmid(name,0,pos) ; names(1) = strmid(name,pos+1,100) ; superind = find_handle(names(0)) ; dq.trange = data_quants(superind).trange ;endif end