Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions sotodlib/hwp/hwp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def get_hwpss(aman, signal=None, hwp_angle=None, bin_signal=True, bins=360,
lin_reg=True, modes=[1, 2, 3, 4, 5, 6, 7, 8], apply_prefilt=True,
prefilt_cfg=None, prefilt_detrend='linear', flags=None,
apodize_edges=True, apodize_edges_samps=1600,
apodize_flags=True, apodize_flags_samps=200,
apodize_flags=True, apodize_flags_samps=200, apo_type='C1',
merge_stats=True, hwpss_stats_name='hwpss_stats',
merge_model=True, hwpss_model_name='hwpss_model'):
r"""
Expand Down Expand Up @@ -52,6 +52,16 @@ def get_hwpss(aman, signal=None, hwp_angle=None, bin_signal=True, bins=360,
flags : str or RangesMatrix or Ranges, optional
Flags to be masked out before extracting HWPSS. If Default is None, and no mask will be applied.
If provided by a string, `aman.flags.get(flags)` is used for the flags.
apodize_edges : bool, optional
If True, applies an apodization window to the edges of the signal. Defaults to True.
apodize_edges_samps : int, optional
The number of samples over which to apply the edge apodization window. Defaults to 1600.
apodize_flags : bool, optional
If True, applies an apodization window based on the flags. Defaults to True.
apodize_flags_samps : int, optional
The number of samples over which to apply the flags apodization window. Defaults to 200.
apo_type: str, optional
Type of apodization, default is C1.
merge_stats : bool, optional
Whether to add the extracted HWPSS statistics to `aman` as new axes. Default is `True`.
hwpss_stats_name : str, optional
Expand Down Expand Up @@ -124,7 +134,7 @@ def get_hwpss(aman, signal=None, hwp_angle=None, bin_signal=True, bins=360,
hwp_angle_bin_centers, bin_counts, binned_hwpss, hwpss_sigma_bin = get_binned_hwpss(
aman, signal, hwp_angle=None, bins=bins, flags=flags,
apodize_edges=apodize_edges, apodize_edges_samps=apodize_edges_samps,
apodize_flags=apodize_flags, apodize_flags_samps=apodize_flags_samps,)
apodize_flags=apodize_flags, apodize_flags_samps=apodize_flags_samps, apo_type=apo_type)

# check bin count
num_invalid_bins = np.count_nonzero(np.isnan(binned_hwpss[0][:]))
Expand Down Expand Up @@ -196,7 +206,7 @@ def get_hwpss(aman, signal=None, hwp_angle=None, bin_signal=True, bins=360,
def get_binned_hwpss(aman, signal=None, hwp_angle=None,
bins=360, flags=None,
apodize_edges=True, apodize_edges_samps=1600,
apodize_flags=True, apodize_flags_samps=200):
apodize_flags=True, apodize_flags_samps=200, apo_type='C1'):
"""
Bin time-ordered data by the HWP angle and return the binned signal and its standard deviation.

Expand All @@ -222,6 +232,8 @@ def get_binned_hwpss(aman, signal=None, hwp_angle=None,
If True, applies an apodization window based on the flags. Defaults to True.
apodize_flags_samps : int, optional
The number of samples over which to apply the flags apodization window. Defaults to 200.
apo_type: str, optional
Type of apodization, default is C1.

Returns
-------
Expand All @@ -236,35 +248,22 @@ def get_binned_hwpss(aman, signal=None, hwp_angle=None,
if hwp_angle is None:
hwp_angle = aman['hwp_angle']

if isinstance(flags, str):
flags = aman.flags.get(flags)

weight_for_signal = None
if apodize_flags and (flags is not None):
weight_for_signal = apodize.get_apodize_window_from_flags(
aman, flags=flags, apodize_samps=apodize_flags_samps, apo_type=apo_type)

if apodize_edges:
weight_for_signal = apodize.get_apodize_window_for_ends(aman, apodize_samps=apodize_edges_samps)
if isinstance(flags, str):
flags = aman.flags.get(flags)
if (flags is not None) and apodize_flags:
flags_mask = flags.mask()
if flags_mask.ndim == 1:
flag_is_1d = True
else:
all_columns_same = np.all(np.all(flags_mask == flags_mask[0, :], axis=0))
if all_columns_same:
flag_is_1d = True
flags_mask = flags_mask[0]
else:
flag_is_1d = False
if flag_is_1d:
weight_for_signal = weight_for_signal * apodize.get_apodize_window_from_flags(aman,
flags=flags,
apodize_samps=apodize_flags_samps)
else:
weight_for_signal = weight_for_signal[np.newaxis, :] * apodize.get_apodize_window_from_flags(aman,
flags=flags,
apodize_samps=apodize_flags_samps)
else:
if (flags is not None) and apodize_flags:
weight_for_signal = apodize.get_apodize_window_from_flags(aman, flags=flags, apodize_samps=apodize_flags_samps)
edges_apodizer = apodize.get_apodize_window_for_ends(
aman, apodize_samps=apodize_edges_samps, apo_type=apo_type)
if weight_for_signal is None:
weight_for_signal = edges_apodizer
else:
weight_for_signal = None
weight_for_signal *= edges_apodizer

binning_dict = tod_ops.bin_signal(aman, bin_by=hwp_angle, range=[0, 2*np.pi],
bins=bins, signal=signal, flags=flags, weight_for_signal=weight_for_signal)

Expand Down Expand Up @@ -709,6 +708,7 @@ def get_tau_hwp(
bpf_cfg=None,
width=1000,
apodize_samps=2000,
apo_type='C1',
trim_samps=2000,
min_fhwp=1.,
max_fhwp=2.,
Expand Down Expand Up @@ -796,7 +796,7 @@ def get_tau_hwp(

tod_ops.detrend_tod(aman, signal_name=signal, method="median")
tod_ops.apodize.apodize_cosine(aman, signal_name=signal,
apodize_samps=apodize_samps)
apodize_samps=apodize_samps, apo_type=apo_type)
demod_tod(aman, signal=signal, demod_mode=demod_mode,
lpf_cfg=lpf_cfg, bpf_cfg=bpf_cfg, wrap=True)

Expand Down
1 change: 1 addition & 0 deletions sotodlib/preprocess/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,7 @@ class Apodize(_Preprocess):
signal_name: signal
apodize_samps: 2000
flags: glitch_flags
apo_type: C1

.. autofunction:: sotodlib.tod_ops.apodize.apodize_cosine
"""
Expand Down
25 changes: 18 additions & 7 deletions sotodlib/tod_ops/apodize.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import numpy as np


def get_apodize_window_for_ends(aman, apodize_samps=1600):
def get_apodize_window_for_ends(aman, apodize_samps=1600, apo_type='C1'):
"""
Generate an apodization window using a cosine taper at the beginning and end.

Args:
aman: An axismanager
apodize_samps (int): Number of samples to apply the cosine taper to at each end.
apo_type: Type of apodization, default is C1.
Comment thread
ykyohei marked this conversation as resolved.
Outdated

Returns:
numpy.ndarray: An array representing the apodization window.
"""
if apo_type == 'C1':
cosedge = 0.5 * (np.cos(np.linspace(0, np.pi, apodize_samps)) + 1)
elif apo_type == 'old_default':
cosedge = np.cos(np.linspace(0, np.pi/2, apodize_samps))

w = np.ones(aman.samps.count)
cosedge = np.cos(np.linspace(0, np.pi/2, apodize_samps))
w[-apodize_samps:] = cosedge
w[:apodize_samps] = np.flip(cosedge)
return w


def get_apodize_window_from_flags(aman, flags, apodize_samps=200):
def get_apodize_window_from_flags(aman, flags, apodize_samps=200, apo_type='C1'):
"""
Generate an apodization window based on flag values. Apply cosine tapering every
continuous portion of data between flagged region.
Expand All @@ -29,6 +34,7 @@ def get_apodize_window_from_flags(aman, flags, apodize_samps=200):
flags (str or RangesMatrix or Ranges): Flags of mask in RangesMatrix/Ranges. If provided by
a string, 'aman.flags[flags]' is used for the flags.
apodize_samps (int): Number of samples to apply the cosine taper.
apo_type: Type of apodization, default is C1.

Returns:
numpy.ndarray: An array representing the apodization window.
Expand All @@ -47,9 +53,13 @@ def get_apodize_window_from_flags(aman, flags, apodize_samps=200):
else:
flag_is_1d = False

if apo_type == 'C1':
cosedge = 0.5 * (np.cos(np.linspace(0, np.pi, apodize_samps)) + 1)
elif apo_type == 'old_default':
cosedge = np.cos(np.linspace(0, np.pi/2, apodize_samps))

apodizer = ~flags_mask
apodizer = apodizer.astype(float)
cosedge = np.cos(np.linspace(0, np.pi/2, apodize_samps))

if flag_is_1d:
idxes_left = np.where(np.diff(apodizer) == -1)[0]
Expand Down Expand Up @@ -91,7 +101,7 @@ def get_apodize_window_from_flags(aman, flags, apodize_samps=200):


def apodize_cosine(aman, signal_name='signal', apodize_samps=1600, in_place=True,
apo_axis='apodized', window=None, flags=None):
apo_axis='apodized', window=None, flags=None, apo_type='C1'):
"""
Function to smoothly filter the timestream to 0's on the ends with a
cosine function. If window is provided, multiply the window function to
Expand All @@ -105,12 +115,13 @@ def apodize_cosine(aman, signal_name='signal', apodize_samps=1600, in_place=True
apo_axis (str): Axis to store the apodized signal if not in place.
window (numpy.ndarray): Precomputed apodization window.
flags (str or RangesMatrix or Ranges): flag value to compute apodization window.
apo_type: Type of apodization, default is C1.
"""
if window is None:
if flags is not None:
window = get_apodize_window_from_flags(aman, flags, apodize_samps)
window = get_apodize_window_from_flags(aman, flags, apodize_samps, apo_type=apo_type)
else:
window = get_apodize_window_for_ends(aman, apodize_samps)
window = get_apodize_window_for_ends(aman, apodize_samps, apo_type=apo_type)

if in_place:
aman[signal_name] *= window
Expand Down
48 changes: 17 additions & 31 deletions sotodlib/tod_ops/azss.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def _valid_dets_mask(azss_stats, min_valid_bins=1):

def bin_by_az(aman, signal=None, az=None, azrange=None, bins=100, flags=None,
apodize_edges=True, apodize_edges_samps=1600,
apodize_flags=True, apodize_flags_samps=200):
apodize_flags=True, apodize_flags_samps=200, apo_type='C1'):
"""
Bins a signal by azimuth angle.

Expand Down Expand Up @@ -99,36 +99,19 @@ def bin_by_az(aman, signal=None, az=None, azrange=None, bins=100, flags=None,
* 'binned_signal': binned signal
* 'binned_signal_sigma': estimated sigma of binned signal
"""
weight_for_signal = None
if apodize_flags and (flags is not None):
weight_for_signal = apodize.get_apodize_window_from_flags(
aman, flags=flags, apodize_samps=apodize_flags_samps, apo_type=apo_type)

if apodize_edges:
weight_for_signal = apodize.get_apodize_window_for_ends(aman, apodize_samps=apodize_edges_samps)
if isinstance(flags, str):
flags = aman.flags.get(flags)
if (flags is not None) and apodize_flags:
flags_mask = flags.mask()
# check the flags dimension
if flags_mask.ndim == 1:
flag_is_1d = True
else:
all_columns_same = np.all(np.all(flags_mask == flags_mask[0, :], axis=0))
if all_columns_same:
flag_is_1d = True
flags_mask = flags_mask[0]
else:
flag_is_1d = False

if flag_is_1d:
weight_for_signal = weight_for_signal * apodize.get_apodize_window_from_flags(aman,
flags=flags,
apodize_samps=apodize_flags_samps)
else:
weight_for_signal = weight_for_signal[np.newaxis, :] * apodize.get_apodize_window_from_flags(aman,
flags=flags,
apodize_samps=apodize_flags_samps)
else:
if (flags is not None) and apodize_flags:
weight_for_signal = apodize.get_apodize_window_from_flags(aman, flags=flags, apodize_samps=apodize_flags_samps)
edges_apodizer = apodize.get_apodize_window_for_ends(
aman, apodize_samps=apodize_edges_samps, apo_type=apo_type)
if weight_for_signal is None:
weight_for_signal = edges_apodizer
else:
weight_for_signal = None
weight_for_signal *= edges_apodizer

binning_dict = bin_signal(aman, bin_by=az, signal=signal,
range=azrange, bins=bins, flags=flags, weight_for_signal=weight_for_signal)
return binning_dict
Expand Down Expand Up @@ -280,7 +263,7 @@ def fit_azss(az, azss_stats, max_mode, modes_axis_name='azss_modes', fit_range=N


def get_azss(aman, signal='signal', az=None, azrange=None, bins=100, flags=None, scan_flags=None,
apodize_edges=True, apodize_edges_samps=1600, apodize_flags=True, apodize_flags_samps=200,
apodize_edges=True, apodize_edges_samps=1600, apodize_flags=True, apodize_flags_samps=200, apo_type='C1',
apply_prefilt=True, prefilt_cfg=None, prefilt_detrend='linear',
method='interpolate', max_mode=None, modes_axis_name='azss_modes', subtract_in_place=False,
merge_stats=True, azss_stats_name='azss_stats',
Expand Down Expand Up @@ -322,6 +305,8 @@ def get_azss(aman, signal='signal', az=None, azrange=None, bins=100, flags=None,
If True, applies an apodization window based on the flags. Defaults to True.
apodize_flags_samps : int, optional
The number of samples over which to apply the flags apodization window. Defaults to 200.
apo_type: str, optional
Type of apodization, default is C1.
apply_prefilt : bool, optional
If True, applies a pre-filter to the signal before azss extraction. Defaults to True.
prefilt_cfg : dict, optional
Expand Down Expand Up @@ -401,7 +386,8 @@ def get_azss(aman, signal='signal', az=None, azrange=None, bins=100, flags=None,
# do binning
binning_dict = bin_by_az(aman, signal=signal, az=az, azrange=azrange, bins=bins, flags=flags,
apodize_edges=apodize_edges, apodize_edges_samps=apodize_edges_samps,
apodize_flags=apodize_flags, apodize_flags_samps=apodize_flags_samps,)
apodize_flags=apodize_flags, apodize_flags_samps=apodize_flags_samps,
apo_type=apo_type)
bin_centers = binning_dict['bin_centers']
bin_counts = binning_dict['bin_counts']
binned_signal = binning_dict['binned_signal']
Expand Down
2 changes: 1 addition & 1 deletion sotodlib/tod_ops/t2pleakage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
import numpy as np
from sotodlib import core
from sotodlib.tod_ops import filters, apodize
from sotodlib.tod_ops import filters
from sotodlib.tod_ops.fft_ops import calc_psd, calc_wn
from scipy.odr import ODR, Model, RealData
from lmfit import Model as LmfitModel
Expand Down