function rbsp_interp_spin_phase_integration, per, tarr, t0, phi0, time_array
compile_opt idl2, hidden
omega = 2d * !dpi / per
dt = tarr[1:*] - tarr
dphi = omega * dt
nt = n_elements(tarr)
phase = dblarr(nt)
for i = 1L, nt - 1 do phase[i] = phase[i-1] + dphi[i-1]
phase = phase * !radeg
phase_out = interpol(phase, tarr, time_array)
if n_elements(time_array) gt 1 then begin
phase0 = interpol(phase_out, time_array, t0)
endif else begin
phase0 = phase_out[0]
endelse
offset = phase0 - phi0
phase_out -= offset
nfold = abs(round(-min(phase_out) / 360d)) + 1L
phase_out += nfold * 360d
phase_out = phase_out mod 360
return, phase_out
end
function rbsp_interp_spin_phase, sc, time_array, $
newname = newname $
, tper = tper $
, tphase = tphase $
, tumbra_sta = tumbra_sta $
, tumbra_end = tumbra_end $
, umbra_pad = umbra_pad
compile_opt idl2
if n_elements(sc) eq 0 or size(sc, /type) ne 7 then begin
dprint, 'Invalid spacecraft name argument. Abort.'
return, -1
endif
rbx = 'rbsp' + strlowcase(sc[0]) + '_'
if n_elements(umbra_pad) eq 0 then umbra_pad = [-20d, 20d] * 60d
if n_elements(tper) eq 0 then tper = rbx + 'spinper'
if ~thm_check_tvar(tper) then begin
dprint, 'Spin period data not available. Abort.'
return, -1
endif
get_data, tper, data = dat_per
tspan = timerange()
tr = minmax(time_array)
if tr[0] lt tspan[0] or tr[1] gt tspan[1] then begin
dprint, 'The input time array exceeds the coverage of time span. Abort.'
return, -1
endif
if n_elements(tphase) eq 0 then tphase = rbx + 'spinphase'
if ~thm_check_tvar(tphase) then begin
dprint, 'Spin phase data not available. Abort.'
return, -1
endif
get_data, tphase, data = dat_ph
if max(dat_ph.x - dat_per.x) - min(dat_ph.x - dat_per.x) gt 1e-6 then begin
dprint, 'Spin period and spin phase data do not have the same time tags.' + $
' Abort.'
return, -1
endif
nt = n_elements(dat_per.x)
ind = where(dat_per.x gt tr[0] and dat_per.x lt tr[1], nind)
if nind eq 0 then begin
dprint, 'Time array very short. Be cautious about the interpolation results!'
if tr[1] lt dat_per.x[0] then begin
tarr = interpol([tr[0], dat_per.x[0]], 1e2)
per = tarr * 0d + dat_per.y[0]
t0 = dat_per.x[0]
phi0 = dat_ph.y[0]
phase_out = rbsp_interp_spin_phase_integration(per, tarr, t0, phi0, $
time_array)
if size(newname, /type) eq 7 then begin
store_data, newname, data = {x:time_array, y:phase_out}
options, newname, ysubtitle = '[degree]'
endif
return, phase_out
endif
if tr[0] gt dat_per.x[nt-1] then begin
tarr = interpol([dat_per.x[nt-1], tr[1]], 1e2)
per = tarr * 0d + dat_per.y[nt-1]
t0 = dat_per.x[nt-1]
phi0 = dat_ph.y[nt-1]
phase_out = rbsp_interp_spin_phase_integration(per, tarr, t0, phi0, $
time_array)
if size(newname, /type) eq 7 then begin
store_data, newname, data = {x:time_array, y:phase_out}
options, newname, ysubtitle = '[degree]'
endif
return, phase_out
endif
i0 = value_locate(dat_per.x, tr[0])
t0 = dat_per.x[i0]
t1 = dat_per.x[i0+1]
tarr = interpol([t0, t1], 1e2)
per = interpol(dat_per.y, dat_per.x, tarr)
phi0 = dat_ph.y[i0]
phase_out = rbsp_interp_spin_phase_integration(per, tarr, t0, phi0, $
time_array)
if size(newname, /type) eq 7 then begin
store_data, newname, data = {x:time_array, y:phase_out}
options, newname, ysubtitle = '[degree]'
endif
return, phase_out
endif
if n_elements(tumbra_sta) eq 0 then tumbra_sta = rbx + 'umbra_sta'
if n_elements(tumbra_end) eq 0 then tumbra_end = rbx + 'umbra_end'
if ~thm_check_tvar(tumbra_sta) or ~thm_check_tvar(tumbra_end) then begin
seg_tr = dblarr(5, 2)
dt_seg = (tspan[1] - tspan[0]) / 5d
seg_tr[*, 0] = tspan[0] + dindgen(5) * dt_seg
seg_tr[*, 1] = tspan[0] + (dindgen(5) + 1d) * dt_seg
endif else begin
get_data, tumbra_sta, data = udat_sta
get_data, tumbra_end, data = udat_end
umbra_tr = [[udat_sta.x + umbra_pad[0]], [udat_end.x + umbra_pad[1]]]
n_umbra = n_elements(udat_sta.x)
seg_tr = dblarr(n_umbra*2+1, 2)
for i = 0, n_umbra-1 do begin
seg_tr[i*2+1, *] = umbra_tr[i, *]
if i eq 0 then seg_tr[i*2,0] = dat_per.x[0] else $
seg_tr[i*2,0] = umbra_tr[i-1,1]
seg_tr[i*2,1] = umbra_tr[i,0]
endfor
seg_tr[2*n_umbra, 0] = umbra_tr[n_umbra-1,1]
seg_tr[2*n_umbra, 1] = tspan[1]
endelse
nseg = n_elements(seg_tr[*,0])
phase_out = time_array
for i = 0, nseg-1 do begin
tmptr = seg_tr[i,*]
ind = where(time_array ge tmptr[0] and time_array lt tmptr[1], nind)
if nind eq 0 then continue
ista = ind[0]
iend = ind[nind-1]
tsta = tmptr[0]
tend = tmptr[1]
dum = minmax(time_array[ista:iend])
tmp_ind = where(dat_per.x ge dum[0] and dat_per.x le dum[1], tmp_nind)
if tmp_nind eq 0 then begin
dprint, 'No spin period data covered by time_array. Something is off.'
stop
return, -1
endif
i0 = tmp_ind[0]
t0 = dat_per.x[i0]
phi0 = dat_ph.y[i0]
dt = 0.2d
nt = (tend - tsta) / dt + 1L
tarr = tsta + dindgen(nt) * dt
per = interpol(dat_per.y, dat_per.x, tarr)
phase_out[ista:iend] = $
rbsp_interp_spin_phase_integration(per, tarr, t0, phi0, $
time_array[ista:iend])
endfor
if size(newname, /type) eq 7 then begin
store_data, newname, data = {x:time_array, y:phase_out}
options, newname, ysubtitle = '[degree]'
endif
return, phase_out
end