Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding AZSS correction per subscan #1065

Open
wants to merge 33 commits into
base: master
Choose a base branch
from

Conversation

susannaaz
Copy link
Contributor

Addresses remaining part of issue #1009, i.e. adding AZSS correction per subscan, as a continuation of the PR in #1064.

@susannaaz susannaaz marked this pull request as draft December 10, 2024 21:37
@susannaaz susannaaz force-pushed the 20241210_preproc_mapmaking_azsssubscan branch from 71891d7 to 6d888d9 Compare December 16, 2024 18:04
…stimation from get_azss with flag subscan, TODO: azss subtraction per subscan still problematic
@msilvafe msilvafe assigned msilvafe and unassigned msilvafe Dec 17, 2024
@msilvafe msilvafe self-assigned this Dec 17, 2024
@susannaaz susannaaz assigned susannaaz and msilvafe and unassigned msilvafe Dec 17, 2024
@susannaaz susannaaz marked this pull request as ready for review December 18, 2024 21:00
@susannaaz susannaaz requested a review from chervias December 18, 2024 21:46
Copy link
Contributor

@msilvafe msilvafe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some inline comments.

sotodlib/preprocess/processes.py Show resolved Hide resolved
Comment on lines +1686 to +1687
proc_aman.flags.wrap("left_scan", aman.flags.left_scan)
proc_aman.flags.wrap("right_scan", aman.flags.right_scan)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These have to exist in the axis manager first which means that FlagTurnarounds must be run first with the argument merge_lr = True which is the default but can be overwritten. Not sure what the right path is here, perhaps if those don't exist then look in proc_aman for them and if they're not in either place then run the the get_turnaround_flags fn w/ merge_lr = True.

def calc_and_save(self, aman, proc_aman):
if 'flags' not in proc_aman._fields:
from sotodlib.core import FlagManager
proc_aman.wrap('flags', FlagManager.for_tod(proc_aman))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically we don't wrap into proc_aman directly in calc_and_save instead we make one new AxisManager here (say bss_aman--bad sub scan aman), wrap everything into that, and then pass that to save (in the field typically called calc_aman) and the save method wraps that into proc_aman so that everything for this one preprocess step is in a single field in proc_aman. Here you wrap into proc_aman directly and also wrap ss_aman, and det_aman all into separate fields of proc_aman. Let's put everything in one aman and send just that one to save.

sotodlib/preprocess/processes.py Show resolved Hide resolved
Comment on lines +1689 to +1691
subscan_stats_T = proc_aman[self.stats_name+"_T"]
subscan_stats_Q = proc_aman[self.stats_name+"_Q"]
subscan_stats_U = proc_aman[self.stats_name+"_U"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this requires that you run GetStats three times wrapping in the same name but appending _T, _Q, and _U to the end? That's a pretty specific prerequisite. Plus I think 90% of the time we are running GetStats it'll be to achieve what BadSubscanFlags is achieving (probably the other 10% of the time is getting some stats on the full TOD or PSD I guess). So why don't we instead check if self.stats_name+"_T" exists and if not call tod_ops.flags.get_stats to get the info you need.

sotodlib/tod_ops/flags.py Show resolved Hide resolved
@@ -998,3 +1021,73 @@ def noise_fit_flags(aman, low_wn, high_wn, high_fk):
return flag_valid_fk
else:
return None

def get_noisy_subscan_flags(aman, subscan_stats_T, subscan_stats_Q, subscan_stats_U,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this require T, Q, and U simultaneously makes this a very restrictive function (i.e. can only be run for the SATs not LAT and only after demodulation). Maybe we can make this take just one signal (i.e. signal = subscan_stats_T) and produce one dets x subscan boolean mask/RangesMatrix per signal then the preprocess method could choose how to combine these i.e. if there's one use 1, if there's >1 use logical and or logical or, etc. Thoughts?

raise ValueError(f"Flag name {name} already exists in aman.flags")
aman.flags.wrap(name, noisy_subscan_flags)

return noisy_subscan_flags, noisy_detector_flags
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix newline

sotodlib/preprocess/processes.py Show resolved Hide resolved
def process(self, aman, proc_aman):
subtract = self.process_cfgs.get('subtract', False)
if self.proc_aman_turnaround_info:
_f = attergetter(self.proc_aman_turnaround_info)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: attrgetter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

if 'flags' not in proc_aman._fields:
from sotodlib.core import FlagManager
proc_aman.wrap('flags', FlagManager.for_tod(proc_aman))
proc_aman.flags.wrap("left_scan", aman.flags.left_scan)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left_scan and right_scan are already in the proc_aman after FlagTurnarounds, just top-level not under "flags". We probably want to agree on one place for them and just look there

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nominally we shouldn't be wrapping anything into aman unless it's explicitly intended to be done in a process step and then merged into proc_aman in the calc_and_save step. However the wrapping into aman is happening in calc_and_save for FlagTurnarounds which should not be allowed. Long story short we should have all of the merge options hard coded false in the call to get_turnaround_flags in calc_and_save and any functions that look for info from TurnaroundFlags should look for it in proc_aman.

sotodlib/tod_ops/azss.py Show resolved Hide resolved
right_mask = turnaround_info.right_scan
else:
print("")
print("HEREEEEEEE")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover debug statement

Copy link
Contributor

@mmccrackan mmccrackan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor comments/questions on formatting and organization.

tod_ops.azss.get_azss(aman, azss_stats_name=self.azss_stats_name,
turnaround_info=turnaround_info,
merge_stats = True, merge_model=False,
subtract_in_place=subtract, **self.calc_cfgs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably has already been discussed so feel free to ignore this, but this is using calc_cfgs within process which seems a bit counter-intuitive. I think it might be unavoidable given the way this needs to be run, but maybe these would make more sense as process_cfgs since process is always going to be run and will run first.

@@ -313,15 +435,31 @@ def subtract_azss(aman, signal='signal', azss_template_name='azss_model',
else:
raise TypeError("Signal must be None, str, or ndarray")

azss_stats, model_left, model_right = get_model_sig_tod(aman, azss_stats, az=None)

if in_place:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional, but I think this logic can be simplified by assigning to a temporary variable, i.e.:

if in_place:
   if signal_name is None:
       sig = signal
   else:
     sig = aman[signal_name]
else:
   if signal_name is None:
       sig = signal.copy()
   else:
       sig = aman[signal_name].copy()

As long as you use sig -= mask, the non-copy ones should stay as references.

if self.azss_stats_name in proc_aman:
if subtract:
tod_ops.azss.subtract_azss(aman, proc_aman[self.azss_stats_name],
signal = self.calc_cfgs.get('signal'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor formatting on signal = self.calc_cfgs.get('signal') (space not needed).

sotodlib/tod_ops/azss.py Show resolved Hide resolved
else:
tod_ops.azss.get_azss(aman, azss_stats_name=self.azss_stats_name,
turnaround_info=turnaround_info,
merge_stats = True, merge_model=False,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want merge_model hardcoded to False here (or elsewhere)? Is there any case where we'd want to be able to look at the model after fitting or interpolation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes because it wraps in a n_dets x n_samps copy of the data, we can use get_model_sig_tod to reconstruct it from the info in azss_stats if we need to look at it later.

else:
tod_ops.azss.get_azss(aman, azss_stats_name=self.azss_stats_name,
turnaround_info=turnaround_info,
merge_stats = True, merge_model=False,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor formatting with unneeded spaces on merge_stats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants