def perform_spectral_analysis(self):
# FIX: Consolidate with map analysis
# Performs same analysis functions as the map, but just on the single (1D) total spectrum
# Smoothing (presently performed for individual detectors)
sigma_spec = self.settings['spectral_smooth_gauss_sigma'] # In terms of frames?
width_spec = self.settings['spectral_smooth_savgol_width'] # In terms of frames?
order_spec = self.settings['spectral_smooth_savgol_order']
if self.settings['spectral_smooth_type'] == 'Gaussian':
print('spectral smoothing...')
self.total_spec = gaussian_filter(self.total_spec, sigma_spec)
elif self.settings['spectral_smooth_type'] == 'Savitzky-Golay':
# Currently always uses 4th order polynomial to fit
print('spectral smoothing...')
self.total_spec = savgol_filter(self.total_spec, 1 + 2*width_spec, order_spec)
# Background subtraction (implemented detector-wise currently)
# NOTE: INSUFFICIENT SPATIAL SMOOTHING MAY GIVE INACCURATE OR EVEN INF RESULTS
if not(self.settings['subtract_ke1'] == 'None'):
print('Performing background subtraction...')
# Fit a power law to the background
# get background range
ke_min = self.settings['ke1_start']
ke_max = self.settings['ke1_stop']
fit_map = (self.ke_interp > ke_min) * (self.ke_interp < ke_max)
ke_to_fit = self.ke_interp[fit_map]
spec_to_fit = self.total_spec[fit_map]
if self.settings['subtract_ke1'] == 'Power Law':
# Fit power law
A, m = self.fit_powerlaw(ke_to_fit, spec_to_fit)
bg = A * self.ke_interp**m
elif self.settings['subtract_ke1'] == 'Linear':
# Fit line (there may be an easier way for 1D case)
m, b = self.fit_line(ke_to_fit, spec_to_fit)
bg = m * self.ke_interp + b
self.total_spec -= bg
if self.settings['subtract_tougaard']:
R_loss = self.settings['R_loss']
E_loss = self.settings['E_loss']
dE = self.ke_interp[1] - self.ke_interp[0]
# Always use a kernel out to 3 * E_loss to ensure enough feature size
ke_kernel = np.arange(0, 3*E_loss, abs(dE))
if not np.mod(len(ke_kernel),2) == 0:
ke_kernel = np.arange(0, 3*E_loss+dE, abs(dE))
self.K_toug = (8.0/np.pi**2)*R_loss*E_loss**2 * ke_kernel / ((2.0*E_loss/np.pi)**2 + ke_kernel**2)**2
# Normalize the kernel so the its area is equal to R_loss
self.K_toug /= (np.sum(self.K_toug) * dE)/R_loss
self.total_spec -= dE * correlate1d(self.total_spec, self.K_toug,
mode='nearest', origin=-len(ke_kernel)//2, axis=0)
评论列表
文章目录