;+ ; eis_ang_ang.pro ; ; PURPOSE: Generate angle-angle (polar versus azimuthal) plots for EIS data with overlaid pitch angle contours ; ; KEYWORDS: ; probe: value for MMS SC # ; trange: time range of interest (string, ex. ['yyyy-mm-dd','yyyy-mm-dd']) ; datatype: 'extof', 'phxtof', or 'electronenergy' ; species: depends on datatype: ; - ExTOF: 'proton', 'oxygen', 'alpha' ; - PHxTOF: 'proton', 'oxygen' ; - electronenergy: 'electron' (this will be set automatically if you specify 'electronenergy' as the datatype) ; level: data level ['l1a','l1b','l2pre','l2' (default)] ; data_units: 'flux' or 'cps' ; data_rate: instrument data rates ['brst', 'srvy' (default)] ; energy_chan: array of four energy channels (numeric, ex. [1,2,3,4]) ; avgdata: set to 1 to average values between the images when time range forces the resolution to greater than 1 (default = 0) ; i_print: set to 1 to print to PS file (default = 0) ; p_filename: string array defining filename for output .ps file ; png: string defining filename for output of .png file ; ; ; CREATED BY: J. Westlake, 2015-09-18 ; ; REVISION HISTORY: ; + 2015-09-21, I. Cohen : changed name from mms_ang_ang_crib to eis_ang_ang; added trange to keywords; added documentation; set plot window size; ; : moved loadct out of for loop; added flat field array for each probe; added trange to get_data calls ; + 2015-09-22, I. Cohen : added /time_clip to mms_load_eis call to make trange work correctly; added res keyword for plotting time resolution; ; : replaced i with correct index for timedata when plotting; change y positions in cgimage position to lower first row from top of window ; : replaced color keyword in cgcontour with c_color to get white contours; added datatype keyword; added energy_chan keyword ; + 2015-09-23, I. Cohen : changed colortable for plot from 33 to 1; changed "default" color table at the end from 13 to 39; commented out get_data for sector and midtai ; : added capability for electrons by using datatype in get_data calls ; + 2015-09-30, J. Westlake : changed polar binning from [-90,90] to [–80,80]; fixed issue with PA contours, replaced non-data 0's with NaN ; + 2015-10-15, J. Westlake : changed azimuth range from [0,360] to [-180,180] (0 sunward, GSE) ; + 2015-10-23, I. Cohen : added i_print switch for printing to PS ; + 2015-11-02, J. Westlake : changed definition of polar angle from !RADEG*acos(d.y[*,2])-90 to 90-!RADEG*acos(d.y[*,2]) to correct sign of polar angle ; + 2016-01-11, I. Cohen : added data_rate and data_units keywords ; + 2016-01-12, J. Westlake ; removed res keyword; fixed scaling issue in plotting; fixed timing (nspins & spininds) to force start and stop at first & last complete spins ; ; changed charsize to 1.5; changed number of rows to n_elements in energy_chan instead of forcing 4 ; + 2016-01-20, J. Westlake ; fixed some bugs related to the number of plots on the screen and the automatic resolution selection. Cleaned up a bit around the edges ; ; Also implemented selectable number of energy bins - as in if you only put in two energy bins in the call then you only get two in the plots ; ; Also they don't have to be energy bins that are next to each other. And I put in some stuff to make the plots a bit more informative, made the axes ; ; go to values that we care about and added titles for the lines. Updated the flat fielding. I added the keyword avgdata to allow for averaging between ; ; data points or decimating the data. Also added colorbars. ; + 2016-03-02, I. Cohen : added level keyword and defined pvalue to handle L2 data ; + 2016-03-15, I. Cohen : added p_filename keyword for general printing; added prefix definition to enable handling of burst data; removed flat fielding ; + 2016-03-23, E. Grimes : removed dependencies on cgtext, cgimage, cgconlevels, cgcontour, cgcolorbar ; : updated the date/time format to prevent overlap with the next plot ; : added png keyword, for saving output to a PNG file ; + 2016-03-24, E. Grimes : fixed issues with postscript output caused by my changes yesterday ; : set the default data_rate to 'srvy' (if not specified); request the time range (if not specified) ; : commented out !p.multi call in postscript output, so that all energy channels are included in the PS file ; + 2016-03-31, E. Grimes : removed flat fielding ; + 2016-09-19, E. Grimes : updated to support v3 L1b files, as well as integer probes ; + 2016-10-26 E. Grimes : fixed bug for burst mode data; n_azi=32 (burst), n_azi=8 (srvy) ; + 2016-11-08 E. Grimes : now programmatically getting number of azimuths from the sector variable; setting species='electron' when datatype='electronenergy'; ; : also now checking that data exists before trying to access the data ; + 2017-05-05 I. Cohen : added ability to use "helium" as species; altered EIS varformat to include look direction and magnetic field; ; : added print command to inform if data is unavailable ; ;$LastChangedBy: egrimes $ ;$LastChangedDate: 2017-06-06 10:59:40 -0700 (Tue, 06 Jun 2017) $ ;$LastChangedRevision: 23419 $ ;$URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/tags/spedas_4_0/projects/mms/eis/eis_ang_ang.pro $ ;- pro eis_ang_ang, probe=probe, trange = trange, species = species, datatype = datatype, level = level, data_units = data_units, data_rate = data_rate, $ energy_chan = energy_chan, avgdata=avgdata, i_print = i_print, p_filename = p_filename, png = png ; set defaults if not KEYWORD_SET(probe) then probe = '1' else probe = strcompress(string(probe), /rem) if not KEYWORD_SET(species) then species = 'proton' if not KEYWORD_SET(datatype) then datatype = 'extof' if not KEYWORD_SET(data_units) then data_units = 'flux' if not KEYWORD_SET(data_rate) then data_rate = 'srvy' if not KEYWORD_SET(level) then level = 'l2' if not KEYWORD_SET(energy_chan) then energy_chan = [1,2,3,4] if not KEYWORD_SET(i_print) then i_print = 0 if not KEYWORD_SET(avgdata) then avgdata = 0 if not KEYWORD_SET(trange) && n_elements(trange) eq 2 $ then trange = timerange(trange) $ else trange = timerange() ; species should always be 'electron' for 'electronenergy' datatypes if datatype eq 'electronenergy' then species = 'electron' if species eq 'helium' then species = 'alpha' date_dir = strmid(trange(0),0,10) date_filename = strmid(trange(0),0,4)+strmid(trange(0),5,2)+strmid(trange(0),8,2) start_time_filename = strmid(trange(0),11,2)+strmid(trange(0),14,2) end_time_filename = strmid(trange(1),11,2)+strmid(trange(1),14,2) nenergies = n_elements(energy_chan) if (data_rate eq 'brst') then prefix = 'mms'+probe+'_epd_eis_brst_' else prefix = 'mms'+probe+'_epd_eis_' ; load EIS data: mms_load_eis, probes=probe, trange=trange, datatype=datatype, level = level, data_rate = data_rate, data_units=data_units, /time_clip, varformat = ['*'+species+'_P*_'+data_units+'_t*','*spin*','*sector*','*pitch_angle*','*look*','*_b'] get_data, prefix+datatype+'_look_t0', data = d ; check if there's valid data before continuing if ~is_struct(d) then begin print,'No valid data found' return endif azi = dblarr(6,n_elements(d.x)) pol = dblarr(6,n_elements(d.x)) pa = dblarr(6,n_elements(d.x)) cps = dblarr(6,nenergies,n_elements(d.x)) ; use wild cards to figure out what this variable name should be for telescope 0 this_variable = tnames(prefix + datatype + '_' + species + '*_' + data_units + '_t0') if level eq 'l2' || level eq 'l1b' then begin ; get the P# value from the name of telescope 0: pval_num_in_name = data_rate eq 'brst' ? 6 : 5 pvalue = (strsplit(this_variable, '_', /extract))[pval_num_in_name] if pvalue ne data_units then pvalue = pvalue + '_' else pvalue = '' endif else begin pvalue = '' endelse for t=0, 5 do begin get_data, prefix+datatype+'_look_t'+STRTRIM(t, 1), data = d azi[t,*] = !RADEG*atan(d.y[*,1],d.y[*,0]) ;; Domain [-180,180], 0 = sunward (GSE) pol[t,*] = 90-!RADEG*acos(d.y[*,2]) ;; Domain [-90,90], Positive is look direction northward get_data, prefix+datatype+'_pitch_angle_t'+STRTRIM(t, 1), data = d pa[t,*] = d.y get_data, prefix+datatype+'_'+species+'_'+pvalue+data_units+'_t'+STRTRIM(t, 1), data = d for i=0, nenergies-1 do cps[t,i,*] = d.y[*,energy_chan(i)-1] endfor get_data, prefix+datatype+'_b', data = magfield get_data, prefix+datatype+'_spin', data = spin get_data, prefix+datatype+'_sector', data = sector spininds = uniq(spin.y) spin_test = where(spin.y eq spin.y[spininds[0]],count) ;; Check to see if we have a complete first spin if count ne 8 then spininds = spininds[1:n_elements(spininds)-1] ;; If not then go to the second spin spin_test = where(spin.y eq spin.y[spininds[n_elements(spininds)-1]],count) ;; Check to see if the last one is complete if count ne 8 then spininds = spininds[0:n_elements(spininds)-2] ;; If not then go to the second spin nspins = n_elements(spininds) n_pol = 6 min_pol_edges = -80 + 160*findgen(n_pol)/n_pol ;;Minus 80 plus max_pol_edges = -80 + 160*(findgen(n_pol)+1)/n_pol ;if data_rate eq 'brst' then n_azi = 32 else n_azi = 8 n_azi = n_elements(uniq(sector.Y, sort(sector.Y))) min_azi_edges = -180 + 360*findgen(n_azi)/n_azi max_azi_edges = -180 + 360*(findgen(n_azi)+1)/n_azi angangdata = dblarr(n_azi,n_pol,nspins,nenergies) padata = fltarr(n_azi,n_pol,nspins) ind = where(padata eq 0.0) padata[ind] = !VALUES.F_NAN ;; Start the array with NAN timedata = strarr(nspins) polarangs = -80+findgen(160) aziangs = findgen(360) for i=0, nspins-1 do begin thisSpin = spin.y[spininds[i]] timeinds = where(spin.y eq thisSpin) timedata[i] = time_string(spin.x[spininds[i]], tformat='YYYY-MM-DD!Chh:mm:ss') for j=0, n_elements(timeinds)-1 do begin for t=0, 5 do begin thisAzi = where((azi[t,timeinds[j]] gt min_azi_edges) and (azi[t,timeinds[j]] lt max_azi_edges)) thisPol = where((pol[t,timeinds[j]] gt min_pol_edges) and (pol[t,timeinds[j]] lt max_pol_edges)) for k=0, nenergies-1 do angangdata[thisAzi,thisPol,i,k] = cps[t,k,timeinds[j]] padata[thisAzi,thisPol,i] = pa[t,timeinds[j]] endfor endfor endfor ;; set color table specific to each species if species eq 'proton' then loadct,1 if species eq 'alpha' then loadct,8 if species eq 'oxygen' then loadct,3 if species eq 'electron' then loadct,7 ;; set number of columns in plot !p.multi=0 if nspins le 16 then begin res=1. !p.multi = [0,nspins,nenergies] nplots = nspins endif else begin res = fix(nspins/16) !p.multi=[0,16,nenergies] nplots = 16 endelse ;; Scale the plots for the maximum size that the screen can handle scsize = get_screen_size() nxsize = nplots*150 nysize = nenergies*200 if nxsize gt scsize[0] then nxsize=scsize[0] if nysize gt scsize[1] then nysize=scsize[1] window, 0, xsize=nxsize, ysize=nysize !X.OMargin = [3,12] !Y.OMargin = [2,5] ;; Reformat axes axis_format = {XTicks:3, YTicks:4} ;; plot for j=0,nenergies-1 do begin angangdata_bytscl = bytscl(alog10(angangdata[*,*,*,j]),min=0.01) for i=0,nplots-1 do begin if i eq nplots-1 then xyouts, 10, (nysize-10)-(nysize/nenergies-8)*j, species+', Energy Bin Number: '+strcompress(string(energy_chan(j))),/device, color=0 thisind = i*res if (res gt 1) and (avgdata eq 1) and (i gt 0) then thisangangdata = total(angangdata_bytscl[*,*,(thisind-res):thisind],3)/res $ else thisangangdata = angangdata_bytscl[*,*,thisind] ; setup the plot with margins and axes contour, padata[*,*,thisind], min_azi_edges + 180./n_azi, min_pol_edges + 90./n_pol,$ YSTYLE=1, xstyle=1, XRANGE=[-180, 180], YRANGE=[-80, 80], xmargin=2, ymargin=[7, 2], charsize=1.5, $ title=timedata[thisind], yticks=4, xticks=3 ; setup the contour levels num_levels = 6 contourLevels = 180*indgen(num_levels+1)/num_levels c_levels_str = strcompress(string(contourLevels), /rem) ; add the data tvimage, thisangangdata, /axes, margin=0.33,xrange=[-180,180],yrange=[-80,80],$ background=255,Position= [0.1, 0.2, 0.98, 0.88] , title=timedata[thisind],charsize=1.5,$ AXKEYWORDS=axis_format, xstyle=1, ystyle=1, /overplot, /nointerpolation ; draw the contours contour, padata[*,*,thisind], min_azi_edges + 180./n_azi, min_pol_edges + 90./n_pol, $ Levels=contourLevels,C_Colors=255, /overplot, c_labels=c_levels_str if i eq nplots-1 then draw_color_scale, range=[0.01, max(angangdata[*,*,*,j])], charsize=2.0, /log endfor endfor if keyword_set(png) then makepng, png ;; print copy of plot to file if i_plot keyword set to 1 if (i_print eq 1) then begin !p.charsize=0.6 popen,p_filename,land=1 if species eq 'proton' then loadct,1 if species eq 'alpha' then loadct,8 if species eq 'oxygen' then loadct,3 if species eq 'electron' then loadct,7 ; !p.multi=[0,16,4] for j=0,nenergies-1 do begin angangdata_bytscl = bytscl(alog10(angangdata[*,*,*,j]),min=0.01) for i=0,nplots-1 do begin if i eq nplots-1 then xyouts, 0.025, 1.-(float(j)/nenergies)+0.004*j, species+', Energy Bin Number: '+strcompress(string(energy_chan(j))),/normal, color=0 thisind = i*res ;800 + i*res if (res gt 1) and (avgdata eq 1) and (i gt 0) then thisangangdata = total(angangdata_bytscl[*,*,(thisind-res):thisind],3)/res $ else thisangangdata = angangdata_bytscl[*,*,thisind] ; setup the plot with margins and axes contour, padata[*,*,thisind], min_azi_edges + 180./n_azi, min_pol_edges + 90./n_pol,$ YSTYLE=1, xstyle=1, XRANGE=[-180, 180], YRANGE=[-80, 80], xmargin=2, ymargin=[7, 2], $ title=timedata[thisind], yticks=4, xticks=3, c_charsize=0.4 ; setup the contour levels num_levels = 6 contourLevels = 180*indgen(num_levels+1)/num_levels c_levels_str = strcompress(string(contourLevels), /rem) ; add the data tvimage, thisangangdata, /axes, margin=0.33,xrange=[-180,180],yrange=[-80,80],$ background=255,Position= [0.1, 0.2, 0.98, 0.88] , title=timedata[thisind],$ AXKEYWORDS=axis_format, xstyle=1, ystyle=1, /overplot, /nointerpolation ; draw the contours contour, padata[*,*,thisind], min_azi_edges + 180./n_azi, min_pol_edges + 90./n_pol, $ Levels=contourLevels,C_Colors=255, /overplot, c_labels=c_levels_str, c_charsize=0.4 ; draw the colorbar if i eq nplots-1 then draw_color_scale, range=[0.01, max(angangdata[*,*,*,j])], charsize=1.2, /log endfor endfor pclose endif loadct,39 end