;+ ;PROCEDURE: THM_SST_ERANGE_BIN_VAL ; ;Purpose: ; This routine generates the values that will be subtracted to remove electronic noise. The actual subtraction is done by thm_sst_remove_sunpulse.pro ; A separate value will be calculated for each combination of bin and energy, but a single value will be calculated for all times(at a particular bin/energy). ; This value will be generated using one of several different functions of the values across time. The functions can be specified by the user. ; The user should never call this routine directly, but should instead provide the appropriate arguments to thm_part_moments,thm_part_moments2, & thm_part_getspec ; These routines will guarantee that this routine is called correctly. ; ;Arguments(note these arguments are generated correctly in thm_part_moments & thm_part_moments2) ; thx: a string representing a probe prefix(ie 'tha') ; ; instrument: a string representing the instrument(ie 'psif') Note that this routine will only perform an operation if ; it is passed a string representing sst full distribution data. (ie 'psif', 'psef') ; ; times: a list of times for the sst measurements, this list is generated by thm_part_dist ; ;Keywords: ; ; enoise_bins: A 0-1 array that indicates which bins should be used to calculate electronic noise. A 0 indicates that the ; bin should be used for electronic noise calculations. This is basically the output from the bins argument of edit3dbins. ; It should have dimensions 16x4. ; ; enoise_bgnd_times: This should be either a 2 element array or a 2xN element array(where n is the number of elements in enoise_bins). ; The arguments represents the start and end times over which the electronic background will be calculated for each ; bin. If you pass a 2 element array the same start and end times can be used for each bin. If you pass a 2xN element ; array, then the Ith bin in enoise_bins will use the time enoise_bgnd_time[0,I] as the start time and enoise_bgnd_time[1,I] as ; the end time for the calculation of the background for that bin. If this keyword is not set then electronic noise will not ; be subtracted. ; ; ; ; enoise_remove_method(default: 'fit_median') set the keyword to a string specifying the method you want to use to calculate the electronic noise that will be subtracted ; This function combines values across time. The allowable options are: ; 'min': Use the minimum value in the time interval for each bin/energy combination. ; 'average': Use the average value in the time interval for each bin/energy combination. ; 'median': Use the median value in the time interval for each bin/energy combination. ; 'fit_average': Fill in selected bins with a value that is interpolated across phi then subtracts the average of the difference ; between the interpolated value and the actual value from each selected bin/energy combination. ; 'fit_median' :Fill in selected bins with a value that is interpolated across phi then subtracts the median of the difference ; between the interpolated value and the actual value from each selected bin/energy combination. ; ; ;SEE ALSO: ; thm_part_moments.pro, thm_part_moments2.pro, thm_part_getspec.pro ; thm_part_dist.pro, thm_sst_psif.pro, thm_sst_psef.pro,thm_crib_sst_contamination.pro ; thm_sst_find_masking.pro, thm_sst_remove_sunpulse.pro ; ; $LastChangedBy: jimmpc $ ; $LastChangedDate: 2009-05-29 15:10:52 -0700 (Fri, 29 May 2009) $ ; $LastChangedRevision: 6004 $ ; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/thmsoc/tags/tdas_5_1/idl/themis/spacecraft/particles/SST/thm_sst_erange_bin_val.pro $ ; ; ;- ;HELPER function ;take the dat component of a structure and splits it into an array ;ordered in terms of theta = energy*angle->energy*theta*phi ;dimensions 16*64->16*4*16, phi is guaranteed to be contiguous but ;not necessarily ascending(some phi may be out of phase by 180 degrees) ;returns indices to perform this transformation function dat2angsplit,dat compile_opt idl2,hidden index = indgen(16,64) t_sort = bsort(dat.theta[0,*]) index = index[*,t_sort] return,transpose(reform(index,16,16,4),[0,2,1]) ; this magic properly reforms and orders the dimensions end function thm_sst_erange_bin_val,thx,instrument,times,enoise_bins=enoise_bins,enoise_bgnd_times=enoise_bgnd_time,enoise_remove_method=enoise_remove_method,_extra=ex compile_opt idl2 if ~strmatch(instrument,'ps?f') && ~strmatch(instrument,'pseb') then begin return,-1 endif ;Validate inputs if ~keyword_set(enoise_bins) || ~keyword_set(enoise_bgnd_time) then begin return,-1 endif d = dimen(enoise_bgnd_time) if d[0] ne 2 then begin dprint,'enoise_bgnd_time has illegal dimensions, electronic noise removal will not be performed' return,-1 endif ;fix to use 0-1 array rather than indexes enoise_bins2 = where(enoise_bins eq 0) if enoise_bins2[0] eq -1 then begin return,-1 endif n_bin = n_elements(enoise_bins2) if n_elements(d) eq 1 then begin e_times = make_array(2,n_bin,type=size(enoise_bgnd_time,/type)) e_times[0,*] = enoise_bgnd_time[0] e_times[1,*] = enoise_bgnd_time[1] endif else begin e_times = enoise_bgnd_time if d[1] ne n_bin then begin dprint,'number of enoise_bins does not match number of enoise_times, electronic noise removal will not be performed' return,-1 endif endelse ;convert to numeric format if input is not numeric if is_string(e_times) then begin e_times = time_double(e_times) endif ;Identify method if ~keyword_set(enoise_remove_method) then begin enoise_remove_method = 'fit_median' endif if strlowcase(enoise_remove_method) eq 'fit_median' then begin fit_median = 1 endif else if strlowcase(enoise_remove_method) eq 'fit_average' then begin fit_average = 1 endif else if strlowcase(enoise_remove_method) eq 'median' then begin median = 1 endif else if strlowcase(enoise_remove_method) eq 'average' then begin average = 1 endif else if strlowcase(enoise_remove_method) eq 'min' then begin min = 1 endif else begin dprint,'enoise remove method unrecognized, electronic noise removal will not be performed' return,-1 endelse format = thx+'_'+instrument out = dblarr(16,64) ;output array for i = 0,n_bin-1 do begin ; loop over angle bins trange = e_times[*,i] ; get times and bins ind = where(times ge trange[0] and times le trange[1],cnt) bin = enoise_bins2[i] if cnt eq 0 then begin dprint,'No valid times found for bin: ' + strcompress(string(bin)) continue endif n_tm = n_elements(ind) ;loop upper bound tot = dblarr(16,n_tm) ;temporary storage of processed values for j = 0, n_tm-1 do begin ; loop over times dat = thm_part_dist(format,index=ind[j],_extra=ex) ;get data for this time if is_struct(dat) then begin if keyword_set(fit_median) || keyword_set(fit_average) then begin ang_split = dat2angsplit(dat) ;indexes to turn the data from 16x64 to 16x4x64 dat.data[*,enoise_bins2] = !VALUES.F_NAN ;these bins are going to be interpolated over data = dat.data[ang_split] phi = dat.phi[ang_split] thetas = dat.theta[uniq(dat.theta,sort(dat.theta))] theta = where(dat.theta[bin] eq thetas) ;which theta is the bin in question in phi[*,[0,2],0:7] -= 360 ; make phi's monotonic for k = 0, 16-1 do begin ;loop over energy phis = reform(phi[k,theta,*]) edata = reform(data[k,theta,*]) interp_gap,phis,edata ;interpolate over enoise bins data[k,theta,*] -= edata ; data[k,theta,*] = edata endfor ;replace data inv_ang_split = bsort(ang_split) dat.data = data[inv_ang_split] endif tot[*,j] = dat.data[*,bin] ;store the data for this part of the time interval endif endfor if keyword_set(fit_median) || keyword_set(median) then begin ;perform requested processing operation out[*,bin] = median(tot,dimension = 2) endif else if keyword_set(fit_average) || keyword_set(average) then begin out[*,bin] = average(tot,2,/nan) endif else if keyword_set(min) then begin out[*,bin] = min(tot,dimension=2,/nan) endif endfor return,out end