def process_vis(self, vis_range=(390, 720), min_scan=None, max_scan=None, sigma=2.3, para_angle=45): data_file = self.file wls = self.vis_wls() t = data_file['t'] d = -data_file['data_Stresing CCD'][min_scan:max_scan, ...] if 'rot' in data_file: rot = data_file['rot'][min_scan:max_scan] para_idx = (abs(np.round(rot) - para_angle) < 3) else: n_ir_cwl = data_file['wl_Remote IR 32x2'].shape[0] para_idx = np.repeat(np.array([False, True], dtype='bool'), n_ir_cwl) dpm = sigma_clip(d[para_idx, ...], axis=0, sigma=sigma, max_iter=10) dsm = sigma_clip(d[~para_idx, ...], axis=0, sigma=sigma, max_iter=10) dp = dpm.mean(0) dps = dpm.std(0) ds = dsm.mean(0) dss = dsm.std(0) para = TimeResSpec(wls, t, dp[0, :, 0, ...], freq_unit='nm', disp_freq_unit='nm') perp = TimeResSpec(wls, t, ds[0, :, 0, ...], freq_unit='nm', disp_freq_unit='nm') pol = PolTRSpec(para, perp) pol = pol.cut_freq(*vis_range, invert_sel=True) return pol.para, pol.perp, pol
def process_ir(self, t0=0, min_scans=0, max_scans=None, subtract_background=True, center_ch=16, disp=14, sigma=3) -> PolTRSpec: data_file = self.file t = data_file['t'] - t0 wli = data_file['wl_Remote IR 32x2'] print(wli[:, 16, None]) wli = -(disp * (np.arange(32) - center_ch)) + wli[:, 16, None] wli = 1e7 / wli d = data_file['data_Remote IR 32x2'][min_scans:max_scans] print(d.shape) dp = sigma_clip(d[1::2, ...], axis=0, sigma=sigma) dpm = dp.mean(0) ds = sigma_clip(d[0::2, ...], axis=0, sigma=sigma) dsm = ds.mean(0) if subtract_background: dsm -= dsm[:, :10, ...].mean(1, keepdims=True) dpm -= dpm[:, :10, ...].mean(1, keepdims=True) para = TimeResSpec(wli[0], t, dpm[0, :, 0, ...], freq_unit='cm', disp_freq_unit='cm') perp = TimeResSpec(wli[0], t, dsm[0, :, 0, ...], freq_unit='cm', disp_freq_unit='cm') para.plot.spec(1, n_average=20) for i in range(1, wli.shape[0]): para_t = TimeResSpec(wli[i], t, dpm[i, :, 0, ...], freq_unit='cm', disp_freq_unit='cm') para_t.plot.spec(1, n_average=20) para = para.concat_datasets(para_t) perp = perp.concat_datasets( TimeResSpec(wli[i], t, dsm[i, :, 0, ...], freq_unit='cm', disp_freq_unit='cm')) both = PolTRSpec(para, perp) return both
def bin_times(self, n, start_index=0) -> 'TimeResSpec': """ Bins down the dataset by binning `n` sequential spectra together. Parameters ---------- n : int How many spectra are binned together. start_index : int Determines the starting index of the binning Returns ------- TimeResSpec Binned down `TimeResSpec` """ out = [] out_t = [] m = len(self.t) for i in range(start_index, m, n): end_idx = min(i + n, m) out.append( sigma_clip(self.data[i:end_idx, :], sigma=2.5, max_iter=1, axis=0).mean(0)) out_t.append(self.t[i:end_idx].mean()) new_data = np.array(out) new_t = np.array(out_t) out = self.copy() out.t = new_t out.data = new_data return out
def bin_times(self, n, start_index=0) -> "TimeResSpec": """ Bins down the dataset by binning `n` sequential spectra together. Parameters ---------- n : int How many spectra are binned together. start_index : int Determines the starting index of the binning Returns ------- TimeResSpec Binned down `TimeResSpec` """ out = [] out_t = [] m = len(self.t) for i in range(start_index, m, n): end_idx = min(i + n, m) out.append( sigma_clip(self.data[i:end_idx, :], sigma=2.5, max_iter=1, axis=0).mean( 0 ) ) out_t.append(self.t[i:end_idx].mean()) new_data = np.array(out) new_t = np.array(out_t) out = self.copy() out.t = new_t out.data = new_data return out
def average_scans(self, sigma=3, max_iter=3, min_scan=0, max_scan=None, disp_freq_unit=None): """ Calculate the average of the scans. Uses sigma clipping, which also filters nans. For polarization resolved measurements, the function assumes that the polarisation switches every scan. Parameters ---------- sigma : float sigma used for sigma clipping. max_iter: int Maximum iterations in sigma clipping. min_scan : int or None All scans before min_scan are ignored. max_scan : int or None If `None`, use all scan, else just use the scans up to max_scan. disp_freq_unit : 'nm', 'cm' or None Sets `disp_freq_unit` of the created datasets. Returns ------- dict or TimeResSpec TimeResSpec or Dict of DataSets containing the averaged datasets. If the first delay-time are identical, they are interpreted as background and their mean is subtracted. """ if max_scan is None: sub_data = self.data else: sub_data = self.data[..., min_scan:max_scan] num_wls = self.data.shape[0] t = self.t if disp_freq_unit is None: disp_freq_unit = "nm" if self.wl.shape[0] > 32 else "cm" kwargs = dict(disp_freq_unit=disp_freq_unit) if not self.is_pol_resolved: data = sigma_clip(sub_data, sigma=sigma, max_iter=max_iter, axis=-1) mean = data.mean(-1) std = data.std(-1) err = std / np.sqrt((~data.mask).sum(-1)) if self.valid_channel in [0, 1]: mean = mean[..., self.valid_channel] std = std[..., self.valid_channel] err = err[..., self.valid_channel] out = {} if num_wls > 1: for i in range(num_wls): ds = TimeResSpec(self.wl[:, i], t, mean[i, ..., :], err[i, ...], **kwargs) out[self.pol_first_scan + str(i)] = ds else: out = TimeResSpec(self.wl[:, 0], t, mean[0, ...], err[0, ...], **kwargs) return out else: raise NotImplementedError("TODO") elif self.is_pol_resolved and self.valid_channel in [0, 1]: assert self.pol_first_scan in ["para", "perp"] data1 = sigma_clip(sub_data[..., self.valid_channel, ::2], sigma=sigma, max_iter=max_iter, axis=-1) mean1 = data1.mean(-1) std1 = data1.std(-1, ddof=1) err1 = std1 / np.sqrt(np.ma.count(data1, -1)) data2 = sigma_clip(sub_data[..., self.valid_channel, 1::2], sigma=sigma, max_iter=max_iter, axis=-1) mean2 = data2.mean(-1) std2 = data2.std(-1, ddof=1) err2 = std2 / np.sqrt(np.ma.count(data2, -1)) out = {} for i in range(num_wls): wl, t = self.wl[:, i], self.t if self.pol_first_scan == "para": para = mean1[i, ...] para_err = err1[i, ...] perp = mean2[i, ...] perp_err = err2[i, ...] elif self.pol_first_scan == "perp": para = mean2[i, ...] para_err = err2[i, ...] perp = mean1[i, ...] perp_err = err1[i, ...] para_ds = TimeResSpec(wl, t, para, para_err, **kwargs) perp_ds = TimeResSpec(wl, t, perp, perp_err, **kwargs) out["para" + str(i)] = para_ds out["perp" + str(i)] = perp_ds iso = 1/3*para + 2/3*perp out["iso" + str(i)] = TimeResSpec(wl, t, iso, **kwargs) self.av_scans_ = out return out else: raise NotImplementedError("Iso correction not supported yet.")
def average_scans(self, sigma=3, max_scan=None, disp_freq_unit=None): """ Calculate the average of the scans. Uses sigma clipping, which also filters nans. For polarization resolved measurements, the function assumes that the polarisation switches every scan. Parameters ---------- sigma : float sigma used for sigma clipping. max_scan : int or None If `None`, use all scan, else just use the scans up to max_scan. disp_freq_unit : 'nm', 'cm' or None Sets `disp_freq_unit` of the created datasets. Returns ------- dict or TimeResSpec TimeResSpec or Dict of DataSets containing the averaged datasets. If the first delay-time are identical, they are interpreted as background and their mean is subtracted. """ if max_scan is None: sub_data = self.data else: sub_data = self.data[..., :max_scan] num_wls = self.data.shape[0] t = self.t if disp_freq_unit is None: disp_freq_unit = 'nm' if self.wl.shape[0] > 32 else 'cm' kwargs = dict(disp_freq_unit=disp_freq_unit) if not self.is_pol_resolved: data = sigma_clip(sub_data, sigma=sigma, axis=-1) mean = data.mean(-1) std = data.std(-1) err = std / np.sqrt((~data.mask).sum(-1)) if self.valid_channel in [0, 1]: mean = mean[..., self.valid_channel] std = std[..., self.valid_channel] err = err[..., self.valid_channel] out = {} if num_wls > 1: for i in range(num_wls): ds = TimeResSpec(self.wl[:, i], t, mean[i, ..., :], err[i, ...], **kwargs) out[self.pol_first_scan + str(i)] = ds else: out = TimeResSpec(self.wl[:, 0], t, mean[0, ...], err[0, ...], **kwargs) return out else: raise NotImplementedError('TODO') elif self.is_pol_resolved and self.valid_channel in [0, 1]: assert (self.pol_first_scan in ['para', 'perp']) data1 = sigma_clip(sub_data[..., self.valid_channel, ::2], sigma=sigma, axis=-1) mean1 = data1.mean(-1) std1 = np.ma.std(-1) err1 = std1 / np.sqrt(np.ma.count(data1, -1)) data2 = sigma_clip(sub_data[..., self.valid_channel, 1::2], sigma=sigma, axis=-1) mean2 = data2.mean(-1) std2 = data2.std(-1) err2 = std2 / np.sqrt(np.ma.count(data2, -1)) out = {} for i in range(num_wls): wl, t = self.wl[:, i], self.t if self.pol_first_scan == 'para': para = mean1[i, ...] para_err = err1[i, ...] perp = mean2[i, ...] perp_err = err2[i, ...] elif self.pol_first_scan == 'perp': para = mean2[i, ...] para_err = err2[i, ...] perp = mean1[i, ...] perp_err = err1[i, ...] para_ds = TimeResSpec(wl, t, para, para_err, **kwargs) perp_ds = TimeResSpec(wl, t, perp, perp_err, **kwargs) out['para' + str(i)] = para_ds out['perp' + str(i)] = perp_ds iso = 1/3 * para + 2 / 3 * perp out['iso' + str(i)] = TimeResSpec(wl, t, iso, **kwargs) self.av_scans_ = out return out else: raise NotImplementedError("Iso correction not supported yet.")