;+ ; Purpose: ; Find the sun direcion vector if requested ; ;- function thm_part_dist_array_getsun, probe=probe, times=times, fail=fail compile_opt idl2, hidden ctn = '2dslice_temp_sundir' nt = n_elements(times) ; Caculation needed for dsl dprint, dlevel=4, 'Finding sun direction in DSL...' thm_load_state, probe=probe, trange=minmax(times) + 120*[-1,1], suffix='_'+ctn, $ /get_support_data ;Transform GSE x-axis (defined by sun) store_data, ctn, data = {x: times, $ y: [1.,0,0] ## replicate(1,nt) } thm_cotrans, ctn, probe=probe, in_coord='gse', out_coord='dsl', $ support_suffix='_'+ctn, out_suff='_dsl' ;Return array of transformed vectors get_data, ctn+'_dsl', data=ctd if size(ctd,/type) ne 8 then begin fail = 'Could not obtain coordinate transform from GSE -> DSL'+ $ ', check for error from THM_COTRANS.' dprint, dlevel=0, fail return, -1 endif sundir = ctd.y ;Delete temporary tplot data store_data, '*'+ctn+'*', /delete return, sundir end ;+ ; ;Procedure: ; thm_part_dist_array ; ;Purpose: ; Returns an array of pointers to ESA or SST particle distributions.(One pointer for new mode in the time series) This routine ; is a wrapper for thm_part_dist, which returns single distributions. ; ; ;Required Keywords: ; PROBE: The THEMIS probe, 'a','b','c','d','e'. ; DATATYPE: Four character string denoting the type of data that you need. ; ESA Ions (full/reduced/burst) ; 'peif' - Full mode ; 'peir' - Reduced mode ; 'peib' - Burst mode ; ESA Electrons ; 'peef' - Full ; 'peer' - Reduced ; 'peeb' - Burst ; SST Ions ; 'psif' - Full ; 'psir' - Reduced ; SST Electrons ; 'psef' - Full ; 'pser' - Reduced ; 'pseb' - Burst ; TRANGE: Time range of interest (2 element array, string or numerical). ; *This keyword may be ommitted if 'timespan is set. If neither ; TRANGE nor 'timespan' is set the user will be prompted. ; ; ;Optional Keywords: ; MAG_DATA: Tplot variable containing magnetic field data. The data will be ; interpolated to the cadence of the requested particle distribution ; and added to the returned structures under the tag 'MAGF'. ; VEL_DATA: Tplot variable containing velocity data. The data will be ; interpolated to the cadence of the requested particle distribution ; and added to the returned structures under the tag 'VELOCITY'. ; If not set V_3D_NEW.PRO will be used instead. ; GET_SUN_DIRECTION: Adds sun direction vector to the returned structures ; under the tag 'SUN_VECTOR' ; FRACTIONAL_COUNTS: Flag to keep the ESA unit conversion routine from rounding ; to an even number of counts when removing the dead time ; correction (no effect if input data already in counts, ; no effect on SST data). This will only be used by this ; code when calculating the bulk velocity with V_3D_NEW.PRO ; ;ESA Keywords: ; BGND_REMOVE: Flag to turn on ESA background removal. ; BGND_TYPE: String naming removal type, e.g. 'angle','omni', or 'anode'. ; BGND_NPOINTS: Number of lowest values points to average over when determining background. ; BGND_SCALE: Scaling factor that the background will be multiplied by before it is subtracted. ; ;SST Keywords: ; SST_CAL: Flag to use newest SST calibrations ; ; ;Examples: ; dist_array = thm_part_dist_array(probe='b',datatype='pseb', $ ; trange='2008-2-26/04:'+['50:00','55:00']) ; ; timespan, '2008-2-26/04:50:00', 5, /min ; dist_array = thm_part_dist_array(probe='b',datatype='psif', $ ; vel_data='tplot_vel', $ ; mag_data='tplot_mag') ; ; ;See Also: thm_crib_part_product, thm_part_products ; thm_crib_part_slice2d, thm_part_slice2d ; thm_crib_esa_bgnd_remove, thm_esa_bgnd_remove, ; ; ;Created by Bryan Kerr ;Modified by A. Flores ; ; $LastChangedBy: aaflores $ ; $LastChangedDate: 2014-02-24 18:05:51 -0800 (Mon, 24 Feb 2014) $ ; $LastChangedRevision: 14423 $ ; $URL $ ;- function thm_part_dist_array, format=format, trange=trange, type=type, datatype=datatype, $ probe=probe, mag_data=mag_data, vel_data=vel_data, $ get_sun_direction=get_sun_direction, $ suffix=suffix, err_msg=err_msg, $ forceload=forceload, $ gettimes=gettimes, sst_cal=sst_cal, $ _extra = _extra compile_opt idl2 if keyword_set(type) && ~keyword_set(datatype) then datatype=type if keyword_set(probe) && keyword_set(datatype) then begin probe = strlowcase(probe) dtype = strlowcase(datatype) format = 'th'+probe+'_'+dtype endif else if keyword_set(format) then begin format = strlowcase(format) probe = strmid(format,2,1) dtype = strmid(format,4,4) endif else begin err_msg = 'Must provide PROBE and DATATYPE keywords.' dprint, dlevel=1, err_msg return, -1 endelse inst = strmid(dtype,1,1) species = strmid(dtype,2,1) ; check requested probe dummy = where(probe eq ['a','b','c','d','e'], yes_probe) if yes_probe lt 1 then begin dprint, dlevel=1, 'Invalid probe: ' + probe return, -1 endif ; check requested instrument type if inst ne 'e' && inst ne 's' then begin dprint, dlevel=1, 'Invalid instrument type: ' + inst return, -1 endif ; check requested species if species ne 'e' && species ne 'i' then begin dprint, dlevel=1, 'Invalid species: ' + species return, -1 endif ; check time range if keyword_set(trange) then begin trd = minmax(time_double(trange)) tr = time_string(trd) endif else begin trd = timerange() tr = time_string(trd) endelse ; This warning should probabably be in thm_part_load if inst eq 's' && keyword_set(sst_cal) then begin if stregex(dtype, 'ps[ei]r', /bool) then begin err_msg = 'Beta SST calibrations only available for full and burst data' dprint, dlevel=1, err_msg return, -1 endif endif ; load L0 data thm_part_load, probe=probe, datatype=dtype, trange=tr, $ forceload=forceload, sst_cal=sst_cal, _extra=_extra ; get time indexes of data in requested time range times = thm_part_dist(format, /times, sst_cal=sst_cal) if size(times,/type) eq 8 then begin err_msg = 'Unable to retrieve times for th'+probe+'_'+dtype+ $ ' between ' +tr[0]+ ' and ' +tr[1]+ '.' dprint, err_msg return, -1 endif ;time correction to point at bin center is applied for ESA, but not for SST if inst eq 's' then begin times += 1.5 endif ;return times if requested if keyword_set(gettimes) then return, times ; check that data exists in requested range time_ind = where(times ge trd[0] and times le trd[1], n_times) if (size(times,/type) ne 5) or (n_times lt 1) then begin err_msg = 'No '+format+' data for time range '+tr[0]+ $ ' to '+tr[1]+'.' dprint, err_msg return, -1 endif ;interpolate mag data if keyword_set(mag_data) then begin tinterpol_mxn, mag_data, times[time_ind], /nan_extrapolate, error=success if success then begin get_data, mag_data+'_interp', data=d mag = d.y add_mag_data = 1b endif else begin err_msg = 'Unable to interpolate B field data from "'+ mag_data + $ '". Variable may not exist or may not cover the requested time range.' dprint, dlevel=1, err_msg return, -1 endelse endif ;interpolate velocity data if keyword_set(vel_data) then begin tinterpol_mxn, vel_data, times[time_ind], /nan_extrapolate, error=success if success then begin get_data, vel_data+'_interp', data=d vel = d.y add_vel_data = 1b endif else begin err_msg = 'Unable to interpolate velocity data from "'+ vel_data + $ '". Variable may not exist or may not cover the requested time range.' dprint, dlevel=1, err_msg return, -1 endelse endif ;get sun vector (in DSL) if requested if keyword_set(get_sun_direction) then begin sundir = thm_part_dist_array_getsun(probe=probe, times=times[time_ind], fail=fail) endif ; Find all mode changes. This will allow pre-allocation of memory ; for the data structure arrays and bypass costly concatenations ; in the following for loop. midx = thm_part_getmodechange(probe, dtype, time_ind, sst_cal=sst_cal, n=nsamples) if nsamples[0] eq 0 then begin dprint, dlevel=0, 'Unknown error determining mode changes.' return, -1 end ;Initialize array of pointers to be returned dist_ptrs = replicate( ptr_new(), n_elements(midx) ) ; Loop to create array for i=0L,n_times-1 do begin dat = thm_part_dist(format, index=time_ind[i], sst_cal=sst_cal,mask_tot=mask_tot,enoise_tot=enoise_tot, _extra=_extra) ; add mag data to dat structure if keyword_set(add_mag_data) then begin str_element, /add, dat, 'magf', reform(mag[i,*]) endif ; add velocity data to dat structure if keyword_set(add_vel_data) then begin ; add user specified velocity data to data structure str_element, /add, dat, 'velocity', reform(vel[i,*]) endif else begin ; calculate velocity if not specified vel=v_3d_new(dat,_extra=_extra) ;*1000. use km/s str_element, /add, dat, 'velocity', vel endelse ;add sun direction vector if keyword_set(sundir) && n_elements(sundir) gt 1 then begin str_element, /add, dat, 'sun_vector', reform(sundir[i,*]) endif ;Assign pointer to pre-allocated structure array for new mode; ;otherwise, place structure into existing array. mode = where(i eq midx,n) if n gt 0 then begin dprint, dlevel=2,'New mode encountered at '+time_string(dat.time) current_mode = mode[0] ;create new pointer with pre-allocated array dist_ptrs[current_mode] = ptr_new( replicate(dat, nsamples[current_mode]), /no_copy ) dist_count = 1 endif else begin ;place this structure into the current mode's array ( *(dist_ptrs[current_mode]) )[dist_count] = temporary(dat) dist_count++ endelse endfor return, dist_ptrs end