; ; PP2spectrogram is a helper function that takes a structure of the ; form ; TIME DOUBLE Array[19686] ; MASS FLOAT Array[19686] ; SCRIPT STRING Array[19686] ; COUNTS_PER_SECOND ; FLOAT Array[19686] ; MODE STRING Array[19686] ; CS_FIL1_EMISSION ; FLOAT Array[19686] ; CS_FIL2_EMISSION ; FLOAT Array[19686] ; OS_FIL1_EMISSION ; FLOAT Array[19686] ; OS_FIL2_EMISSION ; FLOAT Array[19686] ; EM1_VOLTAGE FLOAT Array[19686] ; EM2_VOLTAGE FLOAT Array[19686] ; and returns a structure of counts_per_second(nmass, ntimes), with ; one minute time resolution that can be plotted easily. Set the time ; range if you need for all spectrograms to end up on the same time ; array. Function pp2spectrogram, pp, time_range = time_range ;Get a mass array m0 = min(fix(pp.mass), max = m1) mass_arr = m0+indgen(m1-m0+1) nmass = n_elements(mass_arr) ;masses out from 1 to 150 nout = 150 mass_arr_out = 1+indgen(150) ;Get a time array, 10 second time resolution ntx = 6 dt = 60.0/float(ntx) If(n_elements(time_range) Eq 2) Then Begin t00 = time_range[0] t01 = time_range[1] Endif Else t00 = min(pp.time, max = t01) t0 = double(long64(t00)) nt = ceil((t01-t0)/dt) time_array = t0+dt*dindgen(nt) tmid = 0.5*(time_array+time_array[1:*]) ntmid = n_elements(tmid) ;Output array otp = fltarr(ntmid, nout) For j = 0, nmass-1 Do Begin k = where(mass_arr_out Eq (mass_arr[j] mod 150), nk) If(nk Eq 0) Then Continue ;Here all you need is to interpolate for each mass this_mass = where(pp.mass Eq mass_arr[j], nj) If(nj Eq 0) Then Continue ;degap the data first xdegap, 600.0, 10.0, pp.time[this_mass], pp.counts_per_second[this_mass], ct_out, y_out, /twonanpergap If(y_out[0] Eq -1 && ct_out[0] Eq -1) Then Continue otpj = interpol(y_out, ct_out, tmid) ;Apply attenuation here: If(mass_arr[j] Le 150.0) Then att = 1.0 $ Else If(mass_arr[j] Gt 150.0 And mass_arr[j] Le 300.0) Then att = 10.0 $ Else att = 100.0 otpj = otpj*att otp[*, k] = otp[*, k]+otpj Endfor Return, {x:tmid, y:otp, v:mass_arr_out} End ;+ ;NAME: ; mvn_ngi_read_csv ;PURPOSE: ; Reads an NGIMS csv file ;CALLING SEQUENCE: ; p = mvn_ngi_read_csv(filename) ;INPUT: ; filename = the input file name, full path. ;OUTPUT: ; p = a structure with tags corresponding to the columns in the file ; tplot_vars = an array of tplot var names, one for each column ; Currently: ; TIME, MASS, SCRIPT, COUNTS_PER_SECOND, MODE, CS_FIL1_EMISSION, ; CS_FIL2_EMISSION, OS_FIL1_EMISSION, OS_FIL2_EMISSION, ; EM1_VOLTAGE, EM2_VOLTAGE ; The column names are encoded in the file. ; tplot_spec = the name of the tplot mass spectrogram variable ;NOTES: ;NGIMS CSV file notes (via Mehdi) ; ;four operation modes: ; - csn = closed source neutrals ; - osnt = open source neutrals thermal (grid at 0 V) ; - osnb = open source neutrals beam (grid at ~1 V) ; - osi = open source ion ; ;modes are typically combined on a periapsis pass: ; csn/osnb, csn/osi ; ;masses are in amu, modulo 150: ; - 0 < mass <= 150 --> attenuation factor = 1 ; - 150 < mass <= 300 --> attenuation factor = 10 ; - 300 < mass <= 450 --> attenuation factor = 100 ; ;masses can come in any order ;a given mass can be present with multiple attenuation factors ; ;Noete that the most recent test file has masses up to the ;400's so I assumet aht this is fixed... jmm, 2014-09-22 ;masses can come with 1-amu resolution or fractional (~0.1-amu) resolution ; - for fractional resolution, take all masses within 0.5 amu of an ; integer, and take the peak count rate in that range ;*** changed to 0.3 amu, for ovelap issues at m= 27, 28 boundary, jmm, ; 2014-08-20 *** ; ;Corrected Rate = Raw Rate * Attenuation Factor * Emission Gain ; ;Maybe 3 panels: CSN, OSN, OSI ; - OSN and OSI can be combined, since they cannot be done ; simultaneously, but this might be confusing ; ;Build up spectrograms one pixel at a time? ;HISTORY: ; 2014-07-28, jmm, jimm@ssl.berkeley.edu ; $LastChangedBy: jimm $ ; $LastChangedDate: 2015-03-06 16:33:35 -0800 (Fri, 06 Mar 2015) $ ; $LastChangedRevision: 17101 $ ; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/tags/spedas_5_0/projects/maven/quicklook/mvn_ngi_read_csv.pro $ ;- Function mvn_ngi_read_csv, filename, tplot_vars, tplot_spec filex = file_search(filename) If(~is_string(filex)) Then Begin dprint, 'File: '+filename+' Not found.' Return, -1 Endif p0 = read_csv(filex, header = h0) If(~is_struct(p0)) Then Begin dprint, 'Bad File: '+filex Return, -1 Endif ;Extract the file date, and set a timespan filex0 = file_basename(filex, '.csv') alpx = strsplit(filex0[0], '_', /extract) date = time_string(alpx[3], precision = -3) timespan, date, 1 ;New version, now read_csv returns a header, and has numbers in the ;first column, the structure tags will come from the header now ;Assume that the first column is 'TIME', and get the columns ;definitions ; xstart = where(strupcase(p0.field01) Eq 'TIME') ;Just build up the output structure using str_element tags0 = tag_names(p0) ntags = n_elements(tags0) varcount = 0 For j = 0, ntags-1 Do Begin tagj = p0.(j) ; tj_name = strupcase(tagj[xstart]) tj_name = h0[j] tj_val = tagj;[xstart:*] If(tj_name Eq 'TIME') Then Begin tj_val = mvn_spc_met_to_unixtime(double(tj_val)) Endif Else If(tj_name Ne 'SCRIPT' And tj_name Ne 'MODE') Then Begin tj_val = float(tj_val) Endif If(j Eq 0) Then Begin p = create_struct(tj_name, tj_val) Endif Else str_element, p, tj_name, tj_val, /add_replace ;create tplot variables here too If(j Eq 0) Then Begin time = tj_val Endif Else Begin tj_vname = 'mvn_ngi_'+strlowcase(tj_name[0]) nj = n_elements(tj_val) If(tj_name Eq 'SCRIPT' Or tj_name Eq 'MODE') Then Begin ss = bsort(tj_val) x2 = tj_val[ss] ssu = uniq(x2) uvals = x2[ssu] all_flag = bytarr(nj) For k = 0, n_elements(uvals)-1 Do Begin one_flag = bytarr(nj) okk = where(tj_val Eq uvals[k]) one_flag[okk] = 1b all_flag = all_flag+(2b^k)*one_flag Endfor store_data, tj_vname, data = {x:time, y:all_flag} options, tj_vname, 'tplot_routine', 'bitplot' options, tj_vname, 'labels', uvals Endif Else Begin store_data, tj_vname, data = {x:time, y:tj_val} Endelse If(varcount eq 0) Then tplot_vars = tj_vname $ Else tplot_vars = [tplot_vars, tj_vname] varcount = varcount+1 Endelse Endfor ;Here create the spectrogram tplot variable ;First get rid of fractional masses: ; xxx = where(p.mass Gt 0 and p.mass mod long(p.mass) Ne 0) yyy = where(p.mass Gt 0 and p.mass mod long(p.mass) Eq 0, nyyy) tags = tag_names(p) ntags = n_elements(tags) ;pnew only has integer mass values pnew = p For i = 0, ntags-1 Do Begin tagi = p.(i) str_element, pnew, tags[i], tagi[yyy], /add_replace Endfor ntimes = n_elements(p.time) For j = 0, nyyy-1 Do Begin ;If there are fractional masses above and below, then assign a value jj = yyy[j] jm1 = (jj-1) > 0 jp1 = (jj+1) < (ntimes-1) If((p.mass[jj]-p.mass[jm1]) Lt 0.5 And $ (p.mass[jp1]-p.mass[jm1]) Lt 0.5) Then Begin jm3 = (jj-3) > 0 jp3 = (jj+3) < (ntimes-1) counts_temp = max(p.counts_per_second[jm3:jp3]) pnew.counts_per_second[j] = counts_temp Endif Endfor ;split into modes, and create a tplot spectrogram for each mode modes = ['csn', 'osnt', 'osnb', 'osion'] pcsn = -1 & posnt = -1 & posnb = -1 & posi = -1 dl = {units:'CPS', ztitle:'CPS', ysubtitle:'amu', spec:1, log:1, ylog:0, zlog:1} oti = minmax(pnew.time) For j = 0, n_elements(modes)-1 Do Begin this_mode = where(pnew.mode Eq modes[j], nj) If(nj Eq 0) Then continue pp = pnew For i = 0, ntags-1 Do Begin tagi = pnew.(i) str_element, pp, tags[i], tagi[this_mode], /add_replace Endfor Case modes[j] Of 'csn': Begin pcsn = pp2spectrogram(temporary(pp)) store_data, 'mvn_ngi_csn', data = pcsn, dlimits = dl options, 'mvn_ngi_csn', 'ytitle', 'ngi_csn' End 'osnt': Begin posnt = pp2spectrogram(temporary(pp)) store_data, 'mvn_ngi_osnt', data = posnt, dlimits = dl options, 'mvn_ngi_osnt', 'ytitle', 'ngi_osnt' End 'osnb': Begin posnb = pp2spectrogram(temporary(pp)) store_data, 'mvn_ngi_osnb', data = posnb, dlimits = dl options, 'mvn_ngi_osnb', 'ytitle', 'ngi_osnb' End 'osion': Begin posi = pp2spectrogram(temporary(pp)) store_data, 'mvn_ngi_osi', data = posi, dlimits = dl options, 'mvn_ngi_osi', 'ytitle', 'ngi_osi' End Endcase Endfor Return, pnew End