;+
;Procedure: THM_CAL_FIT
;
;Purpose:  Converts raw FIT parameter data into physical quantities.
;keywords:
;   /VERBOSE or VERBOSE=n ; set to enable diagnostic message output.
;		higher values of n produce more and lower-level diagnostic messages.
;   /ALL
;
;Example:
;   thm_cal_fit, /all
;
;Notes:
;	-- FGM range changes are not handled properly; RANGE=0 is assumed.
;	-- fixed, nominal calibration pars used, rather than proper time-dependent parameters.
;   -- time-dependent spinn axis offset implemented Hannes 05/25/2007
;   -- fixed trouble reading cal files with extra lines at the end,
;      jmm, 8-nov-2007
; $LastChangedBy: jimm $
; $LastChangedDate: 2007-11-08 15:27:30 -0800 (Thu, 08 Nov 2007) $
; $LastChangedRevision: 1996 $
; $URL $
;-
pro thm_cal_fit, probe=probe, datatype=datatype, files=files,trange=trange, coord=coord,valid_names=valid_names,verbose=verbose,in_suf=in_suf,out_suf=out_suf


thm_init
if not keyword_set(datatype) then datatype=['fgs','efs','fgs_sigma','efs_sigma']
if n_params() eq 0 then begin
   vprobes = ['a','b','c','d','e']
   vdatatypes = ['fgs', 'efs', 'fit_efit', 'fit_bfit', 'fgs_sigma', 'efs_sigma', 'fit', 'efs_0', 'efs_dot0']
   if keyword_set(valid_names) then begin
      probe = vprobes
      datatypes = vdatatypes
      return
   endif
   if n_elements(probe) eq 1 then if probe eq 'f' then vprobes = ['f']
   if not keyword_set(probe) then probes = vprobes $
   else probes = thm_check_valid_name(strlowcase(probe), vprobes, /include_all)
   if not keyword_set(probes) then return

   dts = 'fit'
  dt_output = thm_check_valid_name(strlowcase(datatype), vdatatypes, $
                                         /include_all)

   if not keyword_set(in_suf) then in_suf = ''
   if not keyword_set(out_suf) then out_suf = ''

for s=0L,n_elements(probes)-1L do begin
     sc = probes[s]
     case 1 of				; vassilis 4/28 establish probe number in cal tables
		sc eq 'a' : scn=0   ; vassilis 4/28 establish probe number in cal tables
		sc eq 'b' : scn=1   ; vassilis 4/28 establish probe number in cal tables
		sc eq 'c' : scn=2   ; vassilis 4/28 establish probe number in cal tables
		sc eq 'd' : scn=3   ; vassilis 4/28 establish probe number in cal tables
		sc eq 'e' : scn=4   ; vassilis 4/28 establish probe number in cal tables
	 endcase				; vassilis 4/28 establish probe number in cal tables


     ;start Hannes 05/25/2007
     ;get the calfile
     thx = 'th' + sc
     cal_relpathname = thx+'/l1/fgm/0000/'+thx+'_fgmcal.txt'
     cal_file = file_retrieve(cal_relpathname, _extra=!themis)


	;read the calibration file
	PRINT,'read calibration file:'
	PRINT,cal_file

	ncal=file_lines(cal_file)
	calstr=strarr(ncal)
	openr,2,cal_file
	readf,2,calstr
	close,2
        ok_cal = where(calstr Ne '', ncal) ;jmm, 8-nov-2007, cal files have carriage returns at the end
        calstr = calstr[ok_cal]
        
	;define variables
	spinperi=dblarr(ncal)
	offi=dblarr(ncal,3)
	cali=dblarr(ncal,9)
	offi2=dblarr(ncal,3)
	spinperii=dblarr(1)
	offii=dblarr(3)
	calii=dblarr(9)
	utci='2006-01-01T00:00:00.000Z'
	utc=dblarr(ncal)
	utcStr=strarr(ncal)

	for i=0,ncal-1 DO BEGIN
    	calstri=calstr(i)
    	utci=strmid(calstr(i),0,25)
    	reads,strmid(calstr(i),26),offii,calii,spinperii;
    	offi(i,*)=offii
    	cali(i,*)=calii
    	spinperi(i)=spinperii
    	utcStr(i)=utci
    	;translate time information
    	STRPUT, utci, '/', 10
    	utc(i)=time_double(utci)
	ENDFOR
	PRINT,'done reading calibration file'
    ;end Hannes 05/25/2007






     for n=0L, n_elements( dts)-1L do begin
        name = dts[ n]
     	; this call to string should be replaced with a call to the function used to generate the TPLOT variable name in the first place.
		tplot_var = thm_tplot_var( sc, name)
		if keyword_set( verbose) then $
			message, /info, string( tplot_var, format='("working on TPLOT variable",X,A)')

		get_data, tplot_var+in_suf, data=d, limit=l, dlim=dl
		get_data, tplot_var+'_hed'+in_suf, data=d_hed, limit=l_hed, dlim=dl_hed
		store_data,delete=tplot_var+'_hed'+in_suf
		store_data,tplot_var+'_hed',data=d_hed,limit=l_hed,dlim=dl_hed
		; get_data, tplot_var+'_code', data=d_code, limit=l_code, dlim=dl_code
		; stop

		; check that returned data and hed structures are structures (get_data returns 0 if no TPLOT variable exists).
		if (size( d, /type) eq 8) and (size( d_hed, /type) eq 8) then begin
        ;check that data has not already been calibrated
            if thm_data_calibrated(tplot_var+in_suf) then begin
              message, tplot_var+in_suf, " has already been calibrated."
            endif
            ;search fgm calibration for selected time interval ...
            ; start Hannes 05/25/2007
			count=n_elements(d.X)
			Bzoffset=dblarr(count)

			PRINT,'search fgm calibration for selected time interval ...'
			compTime=utc(0)
			refTime=d.X(0)
			i=0
			WHILE ((compTime lt reftime) && (i lt ncal-1)) DO BEGIN
		    	i=i+1
		    	compTime=utc(i)
		    	IF (compTime gt reftime) THEN BEGIN
		       		i=i-1
		       		BREAK
		    	ENDIF
			ENDWHILE
			istart=i
			compTime=utc(i)
			refTime=d.X(count-1L)
			;i=0
			WHILE ((compTime lt reftime) && (i lt ncal-1)) DO BEGIN
		    	i=i+1
		    	compTime=utc(i)
		    	IF (compTime gt reftime) THEN BEGIN
		       		i=i-1
		        	BREAK
		    	ENDIF
			ENDWHILE
			istop=i
			PRINT, 'Select calibrations from:'
			FOR i=istart,istop DO BEGIN
				PRINT, utcStr(i)
			ENDFOR
			;end search fgm calibration for selected time interval ...'

			;build the calibrations vector (offset only at this point)
			;we still need to implement:
			;Gz,Gxy,phi1
			flipxz=[[0,0,-1.],[0,-1.,0],[-1.,0,0]]

			IF (istart eq istop) THEN BEGIN
			    offi2=invert(transpose([cali[istart,0:2],cali[istart,3:5],cali[istart,6:8]]) ## flipxz)##offi(istart,*)
				Bzoffset(0L:count-1L)=offi2(2) ;
			ENDIF ELSE BEGIN
				FOR ii=istart,istop DO BEGIN
					IF (ii eq istart) THEN BEGIN
						indcal=WHERE(d.X lt utc(ii+1))
						if (indcal(0) gt -1) THEN BEGIN
						    offi2=invert(transpose([cali[ii,0:2],cali[ii,3:5],cali[ii,6:8]]) ## flipxz)##offi(ii,*)
							Bzoffset(indcal)=offi2(2)
						ENDIF
					ENDIF ELSE BEGIN
						IF (ii eq istop) THEN BEGIN
							indcal=WHERE(d.X ge utc(ii))
							if (indcal(0) gt -1) THEN BEGIN
								offi2=invert(transpose([cali[ii,0:2],cali[ii,3:5],cali[ii,6:8]]) ## flipxz)##offi(ii,*)
								Bzoffset(indcal)=offi2(2)
							ENDIF
						ENDIF ELSE BEGIN
							indcal=WHERE((d.X ge utc(ii)) AND (d.X lt utc(ii+1)))
							if (indcal(0) gt -1) THEN BEGIN
							    offi2=invert(transpose([cali[ii,0:2],cali[ii,3:5],cali[ii,6:8]]) ## flipxz)##offi(ii,*)
								Bzoffset(indcal)=offi2(2)
							ENDIF
						ENDELSE
					ENDELSE
				ENDFOR
			ENDELSE
			;Bzoffset is an array (for vectoriced processing)
            ;end Hannes 05/25/2007

			hed_data = thm_unpack_hed( 'fit', d_hed.y)


			adc2nT=50000./2.^24 ; vassilis 2007-04-03
			rotBxy_angles=[29.95,29.95,29.95,29.95,29.95] ; vassilis 6/2/2007: deg to rotate FIT on spin plane to match DSL on 5/4
			rotBxy=rotBxy_angles(scn) ;  vassilis 4/28: probably should be part of CAL table as well...
			cs=cos(rotBxy*!PI/180.) ;  vassilis
			sn=sin(rotBxy*!PI/180.) ;  vassilis

			;Bz_offset_table = [4.93,6.14,5.03,8.02,2.99] ; vassilis 4/28
			; vassilis 4/28: note the above must be read from 3rd (Z) offset in FGM cal files
			;Bzoffset = Bz_offset_table(scn) ;  vassilis 4/28
            str_element, dl, 'data_att', data_att, success=has_data_att
            if has_data_att then begin
               str_element, data_att, 'data_type', 'calibrated', /add
            endif else data_att = { data_type: 'calibrated' }
            str_element, data_att, 'coord_sys',  'dsl', /add

            lv12=49.6 ;m
            lv34=40.4 ;m
            lv56=5.6  ;m

			cpar = { $
				e:{ cal_par_time:'2002-01-01/00:00:00', Ascale:-15000.0/(lv12*2.^15), Bscale:-15000.0/(lv12*2.^15), Cscale:-15000.0/(lv12*2.^15), theta:0.0, sigscale:15000./(lv12*2.^15), Zscale:15000./(lv56*2.^15), units:'mV/m'}, $
				b:{ cal_par_time:'2002-01-01/00:00:00', Ascale:1.e0, Bscale:1.e0, Cscale:1.e0, theta:0.0, sigscale:1.e0, Zscale:1.e0, units:'nT'} $
			} ; vassilis 2007-04-03, changed b scales

			; E-field fit (EFI).
			idx = 0L
			dqd = 'efit'
			units = cpar.e.units
			tplot_var_efit = string( tplot_var, dqd, format='(A,"_",A)')
			str_element, dl, 'ytitle', string( tplot_var_efit, units, format='(A,"!C!C[",A,"]")'), /add
			str_element, dl, 'labels', [ 'A', 'B', 'C', 'Sig', '<Ez>'], /add
			str_element, dl, 'labflag', 1, /add
			str_element, dl, 'colors', [ 1, 2, 3, 4, 5], /add
			str_element, data_att, 'cal_par_time', cpar.e.cal_par_time, /add
			str_element, data_att, 'units', units, /add
            str_element, dl, 'data_att', data_att, /add
			d.y[ *, 0, idx] = cpar.e.Ascale*d.y[ *, 0, idx]
			d.y[ *, 1, idx] = cpar.e.Bscale*d.y[ *, 1, idx]
			d.y[ *, 2, idx] = cpar.e.Cscale*d.y[ *, 2, idx]
			d.y[ *, 3, idx] = cpar.e.sigscale*d.y[ *, 3, idx]
			d.y[ *, 4, idx] = cpar.e.Zscale*d.y[ *, 4, idx]

			; store the spin fit parameters.
			if (where(dt_output eq 'fit_efit') ne -1)  then begin
			store_data, tplot_var_efit, $
				data = { x:d.x, y:reform( d.y[ *, *, idx])}, $
				lim=l, dlim=dl
            endif


			dqd = 'efs'+out_suf
			tplot_var_efs = string( strmid(tplot_var,0,3), dqd, format='(A,"_",A)')
			str_element, dl, 'ytitle', string( tplot_var_efs, units, format='(A,"!C!C[",A,"]")'), /add
			str_element, dl, 'labels', [ 'Ex', 'Ey', 'Ez'], /add
			str_element, dl, 'colors', [ 2, 4, 6], /add
            efs=reform(d.y[*,[1,2,4],idx])
			; store the spin fit E-field vector (only the B, C, and <Ez> parameters).
            if (where(dt_output eq 'efs') ne -1) then begin
			store_data, tplot_var_efs, $
				data = { x:d.x, y:efs}, $
				lim=l, dlim=dl
				if keyword_set(coord) && strlowcase(coord) ne 'dsl' then begin
               thm_cotrans, tplot_var_efs, out_coord = coord
                options, tplot_var_efs, 'ytitle', /def, $
                      string( tplot_var_efs, units, format='(A,"!C!C[",A,"]")'), /add
              endif
            endif
			if (where(dt_output eq 'efs_sigma') ne -1) then $
			store_data,tplot_var_efs+'_sigma',data={x:d.x,y:d.y[*,3,idx]}

			; B-field fit (FGM).
			idx = 1L
			dqd = 'bfit'
			units = cpar.b.units
			tplot_var_bfit = string( tplot_var, dqd, format='(A,"_",A)')
			str_element, dl, 'ytitle', string( tplot_var_bfit, units, format='(A,"!C!C[",A,"]")'), /add
			str_element, dl, 'labels', [ 'A', 'B', 'C', 'Sig', '<Ez>'], /add
			str_element, dl, 'labflag', 1, /add
			str_element, dl, 'colors', [ 1, 2, 3, 4, 5], /add
			str_element, data_att, 'cal_par_time', cpar.b.cal_par_time, /add
			str_element, data_att, 'units', units, /add
            str_element, dl, 'data_att', data_att, /add
			; punt on handling FGM range changes for the moment.
			b_range = 0.
			b_range_fac = 1./2.^b_range
			str_element, dl, 'b_range', b_range, /add
			str_element, dl, 'b_range_fac', b_range_fac, /add

			d.y[ *, 0, idx] = b_range_fac*cpar.b.Ascale*d.y[ *, 0, idx]*adc2nT ;  vassilis
			d.y[ *, 1, idx] = b_range_fac*cpar.b.Bscale*d.y[ *, 1, idx]*adc2nT ;  vassilis
			d.y[ *, 2, idx] = b_range_fac*cpar.b.Cscale*d.y[ *, 2, idx]*adc2nT ;  vassilis
			d.y[ *, 3, idx] = b_range_fac*cpar.b.sigscale*d.y[ *, 3, idx]*adc2nT ;  vassilis
			d.y[ *, 4, idx] = b_range_fac*cpar.b.Zscale*d.y[ *, 4, idx]*adc2nT ;  vassilis
            if (where(dt_output eq 'fit_bfit') ne -1) then begin
			store_data, tplot_var_bfit, $
				data = { x:d.x, y:reform( d.y[ *, *, idx])}, $
				lim=l, dlim=dl
            endif
			dqd = 'fgs'+out_suf
			tplot_var_fgs = string( strmid(tplot_var,0,3), dqd, format='(A,"_",A)')
			str_element, dl, 'ytitle', string( tplot_var_fgs, units, format='(A,"!C!C[",A,"]")'), /add
			str_element, dl, 'units', units, /add
			str_element, dl, 'labels', [ 'Bx', 'By', 'Bz'], /add
			str_element, dl, 'colors', [ 2, 4, 6], /add
			Bxprime= cs*d.y[ *,1,idx]+sn*d.y[ *,2,idx]
			Byprime=-sn*d.y[ *,1,idx]+cs*d.y[ *,2,idx]
			Bzprime=-d.y[ *,4,idx]-Bzoffset ; vassilis 4/28 (SUBTRACTING offset from spinaxis POSITIVE direction)
			dprime=d
			dprime.y[ *,1,idx]=Bxprime ; vassilis DSL
			dprime.y[ *,2,idx]=Byprime ; vassilis DSL
			dprime.y[ *,4,idx]=Bzprime ; vassilis DSL
			fgs=reform(dprime.y[*,[1,2,4],idx])


            if (where(dt_output eq 'fgs') ne -1) then begin
			store_data, tplot_var_fgs, $
				data = { x:d.x, y:fgs}, $
				lim=l, dlim=dl
				if keyword_set(coord) && strlowcase(coord) ne 'dsl' then begin
               thm_cotrans, tplot_var_fgs, out_coord = coord
                options, tplot_var_fgs, 'ytitle', /def, $
                      string( tplot_var_fgs, units, format='(A,"!C!C[",A,"]")'), /add
            	endif
			endif

			if (where(dt_output eq 'fgs_sigma') ne -1) then begin
			store_data,tplot_var_fgs+'_sigma',data={x:d.x,y:d.y[*,3,idx]}
            endif


           thx_efs_0=efs
            thx_efs_0[*,2]=0

			str_element, dl, 'labels', [ 'Ex', 'Ey', 'Ez'], /add
			str_element, dl, 'colors', [ 2, 4, 6], /add
			str_element, data_att, 'cal_par_time', cpar.e.cal_par_time, /add
			str_element, data_att, 'units', 'mV/m',/add
            str_element, dl, 'data_att', data_att, /add
            str_element, dl, 'ytitle', string( thx+'_efs_0', units, format='(A,"!C!C[",A,"]")'), /add
            if where(dt_output eq 'efs_0') ne -1 then $
      store_data,thx+'_efs_0'+out_suf,data={x:d.x,y:thx_efs_0},limit=l, dlimit=dl

      Ez=(efs[*,0]*fgs[*,0] + efs[*,1]*fgs[*,1])/(-1*fgs[*,2])
      angle=acos(fgs[*,2]/(fgs[*,0]^2+fgs[*,1]^2+fgs[*,2]^2)^.5)*180/!dpi
      angle80=where(angle gt 80)
      if size(angle80,/dim) ne 0 then Ez[where(angle gt 80)]='NaN'
      thx_efs_dot0=efs
      thx_efs_dot0[*,2]=Ez
      str_element, dl, 'ytitle', string( thx+'_efs_dot0', units, format='(A,"!C!C[",A,"]")'), /add
			if where(dt_output eq 'efs_dot0') ne -1 then $
      store_data,thx+'_efs_dot0'+out_suf,data={x:d.x,y:thx_efs_dot0},limit=l, dlimit=dl

	endif


	endfor	; loop over names.

endfor	; loop over spacecraft.
endif
end