;+
;PROCEDURE:	mvn_sta_get_c6_co2
;PURPOSE:	
;	Returns APID c6 data structure at a single time from common generated by mvn_sta_prod_cal.pro
;INPUT:		
;	time:		dbl		time of data to be returned
;
;KEYWORDS:
;	start:		0,1		if set, gets first time in common block
;	en:		0,1		if set, gets last time in common block
;	advance		0,1		if set, gets next time in common block
;	retreat		0,1		if set, gets previous time in common block
;	index		long		gets data at the index value "ind" in common block
;	calib:		0,1		not working yet, allows alternate calibration
;	times		0,1		returns an array of times for all the data, returns 0 if no data
;
;
;CREATED BY:	J. McFadden
;VERSION:	1
;LAST MODIFICATION:  13/11/12
;MOD HISTORY:
;
;NOTES:	  
;	Data structures can be used as inputs to functions such as n_4d.pro, v_4d.pro
;	Or used in conjunction with iterative programs such as get_2dt.pro, get_en_spec.pro
;-
FUNCTION mvn_sta_get_c6_co2,time,START=st,EN=en,ADVANCE=adv,RETREAT=ret,index=ind,calib=calib,times=times

common mvn_c6,get_ind,all_dat
common mvn_sta_c6_co2,co2_valid

if n_elements(get_ind) eq 0 then begin
	if keyword_set(times) then return,0
	dat = 	{project_name:'MAVEN',valid:0}
	print,' ERROR - mvn c6 data not loaded'
	return,dat
endif else if get_ind eq -1 then begin
	dat = 	{project_name:'MAVEN',valid:0}
	print,' ERROR - mvn c6 data not loaded'
	return,dat
endif else if keyword_set(times) then begin
	dat=(all_dat.time+all_dat.end_time)/2.
	return,dat
endif else begin

if (n_elements(time) eq 0) and (not keyword_set(st)) and (not keyword_set(en)) $
        and (not keyword_set(adv)) and (not keyword_set(ret)) and (n_elements(ind) eq 0) $
	then ctime,time,npoints=1

if keyword_set(st) then ind=0l 						$
	else if keyword_set(en) then ind=n_elements(all_dat.time)-1 	$
	else if keyword_set(adv) then ind=get_ind+1 			$
	else if keyword_set(ret) then ind=get_ind-1 			$
	else if n_elements(ind) ne 0 then ind=ind 			$
	else tmpmin = min(abs(all_dat.time-time),ind)

; this routine only valid for static mode 1,2,7 at this time
; you can bypass this default for testing by declaring common mvn_sta_c6_co2,co2_valid and setting co2_valid=1
; energy-anode dependence of ion straggling in carbon foils needed for other modes
	mode = all_dat.mode[ind]

if ind lt 0 or ind ge n_elements(all_dat.time) or not ((mode eq 1) or (mode eq 2) or (mode eq 7) or keyword_set(co2_valid)) then begin

dat = 		{project_name:		all_dat.project_name,		$
		spacecraft:		all_dat.spacecraft, 		$
		data_name:		all_dat.data_name+' co2', 	$
		apid:			all_dat.apid,			$
		valid: 			0}

	return,dat

endif else begin

	while (all_dat.valid[ind] eq 0 and ind+1 lt n_elements(all_dat.time)) do ind=ind+1

	mode	= all_dat.mode[ind]
	rate	= all_dat.rate[ind]
	swp_ind	= all_dat.swp_ind[ind]
	mlut_ind= all_dat.mlut_ind[ind]
	eff_ind	= all_dat.eff_ind[ind]
	att_ind	= all_dat.att_ind[ind]
		str_element,all_dat,'gf_corr',success=success
		if success then gf_corr=reform(all_dat.gf_corr[ind,*])#replicate(1.,all_dat.nmass) else gf_corr=1.
	gf2	= (reform(all_dat.gf[swp_ind,*,att_ind])#replicate(1.,all_dat.nmass))*gf_corr
;	gf2	= reform(all_dat.gf[swp_ind,*,att_ind])#replicate(1.,all_dat.nmass)

dat = 		{project_name:		all_dat.project_name,			$
		spacecraft:		all_dat.spacecraft, 			$
		data_name:		all_dat.data_name+' co2', 		$
		apid:			all_dat.apid,				$
		units_name: 		'counts', 				$
		units_procedure: 	all_dat.units_procedure, 		$
		valid: 			all_dat.valid[ind], 			$
		quality_flag: 		all_dat.quality_flag[ind], 		$

		time: 			all_dat.time[ind], 			$
		end_time: 		all_dat.end_time[ind], 			$
		delta_t: 		all_dat.delta_t[ind],			$
		integ_t: 		all_dat.integ_t[ind],			$

;		eprom_ver:		all_dat.eprom_ver[ind],			$
;		header:			all_dat.header[ind],			$
		mode:			mode,					$
		rate:			rate,					$
		swp_ind:		swp_ind,				$
		mlut_ind:		mlut_ind,				$
		eff_ind:		eff_ind,				$
		att_ind:		att_ind,				$

		nenergy: 		all_dat.nenergy, 			$
		energy: 		reform(all_dat.energy[swp_ind,*,*]), 	$
		denergy: 		reform(all_dat.denergy[swp_ind,*,*]),   $

		nbins: 			all_dat.nbins,	 			$
		bins: 			all_dat.bins, 				$
		ndef:			all_dat.ndef,				$
		nanode:			all_dat.nanode,				$

		theta: 			reform(all_dat.theta[swp_ind,*,*]),  	$
		dtheta: 		reform(all_dat.dtheta[swp_ind,*,*]),  	$
		phi: 			reform(all_dat.phi[swp_ind,*,*]),  	$
		dphi: 			reform(all_dat.dphi[swp_ind,*,*]),	$
		domega: 		reform(all_dat.domega[swp_ind,*,*]),  	$

		gf: 			gf2,					$
		eff: 			reform(all_dat.eff[eff_ind,*,*]),	$

		geom_factor: 		all_dat.geom_factor, 			$
		dead1: 			all_dat.dead1,				$
		dead2: 			all_dat.dead2,				$
		dead3: 			all_dat.dead3,				$

		nmass:			all_dat.nmass,				$
		mass: 			all_dat.mass, 				$
		mass_arr: 		reform(all_dat.mass_arr[swp_ind,*,*]), 	$
		tof_arr: 		reform(all_dat.tof_arr[mlut_ind,*,*]), 	$
		twt_arr: 		reform(all_dat.twt_arr[mlut_ind,*,*]), 	$

		charge: 		all_dat.charge, 			$
		sc_pot: 		all_dat.sc_pot[ind], 			$
		magf:	 		reform(all_dat.magf[ind,*]), 		$
		quat_sc:	 	reform(all_dat.quat_sc[ind,*]), 	$
		quat_mso:	 	reform(all_dat.quat_mso[ind,*]), 	$
		bins_sc:		reform(all_dat.bins_sc[ind,*]),		$
		pos_sc_mso:		reform(all_dat.pos_sc_mso[ind,*]),	$

		bkg:	 		reform(all_dat.bkg[ind,*,*]),		$
		dead:	 		reform(all_dat.dead[ind,*,*]),		$
		cnts:	 		reform(all_dat.data[ind,*,*]),		$

		data: 			reform(all_dat.data[ind,*,*])}

get_ind=ind

; remove everything but co2

	dat2=dat 

	mass_arr=reform(dat.mass_arr[31,*])
	ms3 = 40.
	ms4 = 60.
;	mass_scale=8.0 & cnts_scale=1.05 & ms1=27.0 & ms2=40.0			; this works best for ram anode to get sc_pot agreement and no flow
;	mass_scale=8.0 & cnts_scale=0.66 & ms1=29.2 & ms2=35.6			; this works best for ram anode to get sc_pot agreement and no flow
	mass_scale=8.0 & cnts_scale=0.85 & ms1=29.2 & ms2=37.9			; modified 20170521
;	mass_scale=8.0 & cnts_scale=0.90 & ms1=29.2 & ms2=37.9			; testing - works better for 20170712 for along-track near zero
;	mass_scale=8.0 & cnts_scale=0.80 & ms1=29.2 & ms2=37.9			; testing - not that good for 201805 co2 mode - .85 still best

;	mass_scale=7.5 & cnts_scale=0.70 & ms1=29.2 & ms2=37.9			; testing 20180922, used nightside O2+ for calibration (very little CO2+) 20180908/0357UT

;	mass_scale=7.5 & cnts_scale=0.55 & ms1=29.2 & ms2=37.9			; testing 20181212, on 20180526 data


	ind32 = where(mass_arr ge ms1 and mass_arr le ms2,count)		 

;  o2+ straggling changes with time, likely due to thinning of the foils
;  this corrects the linear straggling term based on observations on the days listed
	t0=dat.time
	t1=time_double('2018-04-24')
	t2=time_double('2022-09-13')
	cnts1_scale = 0.90 + 0.15*(t0-t1)/(t2-t1)  & cnts2_scale=2000.
	cnts1 = total(dat.cnts[*,ind32]-dat.bkg[*,ind32],2)
	cnts0 = total(dat.cnts,2)
	dead0 = reform(dat.dead[*,0])

;  the non-linear term, or mass peak shift to higher mass with rate, depends on rate squared 
;  c6 data is averaged over deflectors, so use c8 data product to correct for rate changes with deflection
	c8 = mvn_sta_get_c8(dat.time)

	normc8 = reform(c8.cnts*c8.dead)/(.000001+total(reform(c8.cnts*c8.dead),2)#replicate(1.,16))

	cnts2 = total(((cnts0#replicate(1.,16))*normc8)*((cnts1#replicate(1.,16))*normc8),2)

; assume similar power law variation of o2+ stragglers for linear and non-linear terms
;  bkg1 is the linear straggling term
	bkg1 = (cnts1#replicate(1.,64)/cnts1_scale)*(dat.mass_arr gt ms3)*exp(-dat.mass_arr/mass_scale)*dat.twt_arr 
;  bkg2 is the non-linear straggling term
	bkg2 = (cnts2#replicate(1.,64)/cnts2_scale)*(dat.mass_arr gt ms3)*exp(-dat.mass_arr/mass_scale)*dat.twt_arr 

;  add all the bkg together
	dat.bkg = dat.bkg+bkg1+bkg2

;  removal all mass bins outside co2+ mass range
	mask = (dat.mass_arr gt ms3)*(dat.mass_arr lt ms4)
	dat.bkg = dat.bkg*mask
	dat.cnts = dat.cnts*mask

;  remove all counts in an energy bin if the total counts in an energy bin is less than zero
	ind33 = where(total(dat.cnts,2) lt 0.,count)
	if count ge 1 then dat.cnts[ind33,*]=0.
	dat.data=dat.cnts

; fix the dat.dead for co2 by adjusting it for differences in efficiency between o2 and co2.
; note that dat.dead tof efficiency was determined for all ions at that energy based on start/stop efficiency
; so dat.dead corrects for the average efficiency with rate (droop, deadtime) but not relative efficiency which depends on mass
; the average efficiency will depend on the dominant ion and relative efficiency variations of minor ions create small errors w/o this correction
; the below code corrects for efficiency variations with a mixture of o2+ and co2+, ignoring other ions by treating them as having same eff as o2+
; note that dat.eff is the same constant for all ions, since rate dependence of efficiencies (due to mcp droop and deadtime) dominate
; since o2+ dominates at periapsis, this corrects for the relative efficiency of co2+ being different by 1.25 (lower efficiency)
	mass_arr=reform(dat2.mass_arr(16,*))
	ind_o2 = where(mass_arr lt 40.)
	cnt_o2 = total(dat2.cnts[*,ind_o2],2)>10.
;	co2_eff_corr = 1.6				; ground calibrations indicated this was ~1.6, perhaps foil outgassing increased co2+ penetration
	co2_eff_corr = 1.25				; determined from inflight calibration using apid d9 - program plot_d9r.pro - checked several days during mission
	cnt_co2 = total(dat.data,2)>10.
	eff_corr = (cnt_o2*co2_eff_corr+cnt_co2)/(cnt_o2+cnt_co2)
	dat.dead = dat.dead*(eff_corr#replicate(1.,64))

endelse
endelse

return,dat

end
