Skip to content
Open
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
6a10d5b
initial commit
Mar 19, 2024
0af181a
add combine_focal_planes.py
Mar 19, 2024
32e24af
resolve wrong git operations
Mar 19, 2024
7cb9ac2
Merge branch 'master' into pointing_workflow
Apr 29, 2024
18dfb22
Merge branch 'mat_polfilt' into pointing_workflow
Apr 29, 2024
1689165
Merge remote-tracking branch 'origin/new_preprocess_methods' into poi…
Apr 29, 2024
76db4c5
using a new preprocess style in map_based pointing reconstruction
Apr 30, 2024
dba66bf
Merge remote-tracking branch 'origin' into pointing_workflow
Apr 30, 2024
20b522c
added except method in flags.reduce
Apr 30, 2024
2063544
Merge branch 'mat_polfilt' into pointing_workflow
Apr 30, 2024
4ca1ef9
Merge branch 'mat_polfilt' into pointing_workflow
Apr 30, 2024
740f1e3
added ReduceFlags function in preprocessing
Apr 30, 2024
2a9dcdb
Merge branch 'mat_polfilt' into pointing_workflow
Apr 30, 2024
7b403a7
new fitting code
May 2, 2024
4525865
Merge branch 'mat_polfilt', remote-tracking branch 'origin' into poin…
May 2, 2024
5101736
added argument save_normal_roll
May 7, 2024
d708edb
tod based fitting is automated
May 7, 2024
3d03e68
Merge branch 'iir_default' into pointing_workflow
tterasaki May 7, 2024
34481e7
main function is done
tterasaki May 9, 2024
2da7965
removed combine_focal_plane.py which is no longer used
tterasaki May 10, 2024
a26283a
Merge branch 'master' into pointing_workflow
tterasaki May 30, 2024
8d8fae4
removed planets.close()
tterasaki May 30, 2024
59f55ce
tuning for master branch
tterasaki May 31, 2024
6b8fce3
Merge branch 'master' into pointing_workflow
tterasaki May 31, 2024
5b80e50
fix preprocessing stuff
tterasaki May 31, 2024
6e91879
Added script that solves satv1 pointing model parameters.
Oct 11, 2024
51093ed
Make solve_pointing_model match site_pipeline standards.
Oct 21, 2024
0e5ef43
Edits to documentation
Oct 21, 2024
63308fd
Trying again with docs syntax.
Oct 21, 2024
fd14407
Edit docs syntax. Surely it is getting close by now.
Oct 21, 2024
b8c6ed9
Edit documentation. Fingers crossed.
Oct 21, 2024
2071000
Added lmfit to list of modules to mock import.
Oct 21, 2024
2247003
Small change to logger output for outliers after iteration.
Oct 21, 2024
64a9696
Made changes to log file and diagnostic plots.
Oct 23, 2024
89ec639
Renamed map_based_pointing and update pointing to get_brightsrc_point…
elle-shaw May 23, 2025
03ed8e9
Merge remote-tracking branch 'origin/master' into pointing_workflow
May 27, 2025
4ac7e45
Major update to solve_pointing_model.py to include per-detector fitti…
elle-shaw Jul 15, 2025
8042065
Fixed issue so now works for fitting LAT parameters. Minor changes to…
elle-shaw Aug 4, 2025
a7120c2
fixed conflicts in conf.py
elle-shaw Aug 4, 2025
dde4236
Added plotting capabilities to show effect of solved pointing paramet…
elle-shaw Aug 4, 2025
41aa7f1
feat: add joint fitting and some db fixes
skhrg Aug 6, 2025
be21499
Merge pull request #1320 from simonsobs/pm_joint_time
elle-shaw Aug 6, 2025
f601872
Added just_test_params functionality to only test initial params aga…
elle-shaw Aug 6, 2025
994081a
Merge remote-tracking branch 'origin/master' into pointing_workflow
elle-shaw Aug 25, 2025
954bdd5
Made small changes to make code be compatible with latest master branch.
elle-shaw Aug 25, 2025
e1e3dbc
Merge remote-tracking branch 'origin/master' into pointing_workflow
elle-shaw Aug 28, 2025
092b2ab
Removed offensive square brackets in a get_obs call
elle-shaw Aug 29, 2025
951de7a
add saturn to possible source objects
elle-shaw Sep 3, 2025
2a38cb3
removed obsolete logger entry
elle-shaw Sep 11, 2025
35adb2d
Merge remote-tracking branch 'origin/master' into solve_pointing
elle-shaw Nov 14, 2025
512d4eb
fixed bug on including a list of detectors to debug with
elle-shaw Nov 19, 2025
9560831
Merge remote-tracking branch 'origin/master' into solve_pointing
elle-shaw Nov 21, 2025
a7fef70
fix: fix supplying only some init pars and plotting when culled
skhrg Oct 27, 2025
f3cf323
Merge branch 'solve_pointing' of github.com:simonsobs/sotodlib into s…
elle-shaw Dec 19, 2025
458aafd
updating to current master changes
elle-shaw Jan 20, 2026
e7f007f
Updated rst documentation with example NERSC submission script
elle-shaw Jan 20, 2026
2de0b16
Changes according to requested comments. Condensed ReduceFlags into C…
elle-shaw Feb 16, 2026
f3befaa
Fixed issues with lonlat quat rotations and hacky negative xi solutions
elle-shaw Feb 25, 2026
e70d68a
Merge with master
elle-shaw Mar 3, 2026
76ae8df
Find boresight azimuth and elevation during detector crossings.
elle-shaw Mar 4, 2026
81ac886
propagate addition of az and el and roll to result set output in dumm…
elle-shaw Mar 18, 2026
5879bf3
Added ability to pass az el and roll values from get_brightsrc datase…
elle-shaw Mar 25, 2026
2601e0b
Merge remote-tracking branch 'origin/master' into pointing_workflow
elle-shaw Mar 25, 2026
3dbb7ed
Pre-fill detector pointing with central values from obs_info if per d…
elle-shaw Mar 26, 2026
c6f3612
Lat pmchanges (#1605)
skhrg Apr 14, 2026
e0de726
Merge branch 'pointing_workflow' into solve_pointing such that the
elle-shaw Apr 14, 2026
9838573
Refactoring of code to handle per-detector azimuth data. Implements s…
elle-shaw Apr 20, 2026
5b8780f
Fix bugs and typos. Handle measured vs template options in calculatio…
elle-shaw Apr 22, 2026
0288873
Remove breakpoint(). Error remains on float_ots == True
elle-shaw Apr 22, 2026
51b1ba7
fix: handle nans in OT float and catch some edge cases
skhrg Apr 23, 2026
4eb0d48
fix: minor plotting stuff
skhrg Apr 23, 2026
f7f919c
Pulling in final changes from pointing_workflow and master onto this …
elle-shaw Apr 25, 2026
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
395 changes: 393 additions & 2 deletions docs/site_pipeline.rst

Large diffs are not rendered by default.

518 changes: 518 additions & 0 deletions sotodlib/coords/brightsrc_pointing.py

Large diffs are not rendered by default.

33 changes: 30 additions & 3 deletions sotodlib/coords/fp_containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class FocalPlane:
id_strs: NDArray[np.str_] # (ndet,)
avg_fp: NDArray[np.floating] # (ndim, ndet)
weights: NDArray[np.floating] # (ndet,)
det_boresight: NDArray[np.floating] # (ndim, ndet)
transformed: NDArray[np.floating] # (ndet, ndim)
center: NDArray[np.floating] # (1, ndim)
center_transformed: NDArray[np.floating] # (1, ndim)
Expand Down Expand Up @@ -219,6 +220,7 @@ def empty(cls, template, stream_id, wafer_slot, n_aman, config=""):
tot_weight = np.zeros((len(template.det_ids), 2))
avg_fp = np.full_like(template.fp, np.nan)
weight = np.zeros((len(template.det_ids), 2))
det_boresight = np.zeros((len(template.det_ids), 3)) + np.nan # az, el, roll
transformed = template.fp.copy()
center = template.center.copy()
center_transformed = template.center.copy()
Expand All @@ -232,6 +234,7 @@ def empty(cls, template, stream_id, wafer_slot, n_aman, config=""):
template.id_strs,
avg_fp,
weight,
det_boresight,
transformed,
center,
center_transformed,
Expand Down Expand Up @@ -260,8 +263,17 @@ def map_by_det_id(self, aman):
xi = aman.pointing.xi[msk][srt][mapping]
eta = aman.pointing.eta[msk][srt][mapping]
r2 = np.nan + np.zeros_like(eta)
az = np.deg2rad(aman.obs_info.az_center) * np.ones_like(eta)
el = np.deg2rad(aman.obs_info.el_center) * np.ones_like(eta)
roll = np.deg2rad(aman.obs_info.roll_center) * np.ones_like(eta)
if "R2" in aman.pointing:
r2 = aman.pointing.R2[msk][srt][mapping]
if "az" in aman.pointing:
az = aman.pointing.az[msk][srt][mapping]
if "el" in aman.pointing:
el = aman.pointing.el[msk][srt][mapping]
if "roll" in aman.pointing:
roll = aman.pointing.roll[msk][srt][mapping]
if "polarization" in aman:
# name of field just a placeholder for now
gamma = aman.polarization.polang[msk][srt][mapping]
Expand All @@ -270,14 +282,16 @@ def map_by_det_id(self, aman):
else:
gamma = np.full(len(xi), np.nan)
fp = np.column_stack((xi, eta, gamma))
return fp, r2, template_msk
det_boresight = np.column_stack((az, el, roll))
return fp, r2, det_boresight, template_msk

def add_fp(self, i, fp, weights, template_msk):
if self.full_fp is None or self.tot_weight is None:
def add_fp(self, i, fp, weights, det_boresight, template_msk):
if self.full_fp is None or self.tot_weight is None or self.det_boresight is None:
raise ValueError("full_fp or tot_weight not initialized")
self.full_fp[template_msk, :, i] = fp * weights[:, 0][..., None]
weights = np.nan_to_num(weights)
self.tot_weight[template_msk] += weights
self.det_boresight[template_msk, :] = det_boresight

def save(self, f, db_info, group):
logger.info("Saving %s", self.stream_id)
Expand Down Expand Up @@ -323,6 +337,9 @@ def save(self, f, db_info, group):
("gamma_m", np.float32),
("weights", np.float32),
("r2", np.float32),
("az", np.float32),
("el", np.float32),
("roll", np.float32),
("n_point", np.int8),
("n_gamma", np.int8),
]
Expand All @@ -333,6 +350,7 @@ def save(self, f, db_info, group):
*(self.transformed.T),
*(self.avg_fp.T),
*(self.weights.T),
*(self.det_boresight.T),
self.n_point,
self.n_gamma,
),
Expand Down Expand Up @@ -378,6 +396,14 @@ def load(cls, group, include_cm=None):
np.array(fp_full["gamma_m"]),
)
)

det_boresight = np.column_stack(
(
np.array(fp_full["az"]),
np.array(fp_full["el"]),
np.array(fp_full["roll"]),
)
)
# For backwards compatibility
weights = np.array(fp_full["weights"])
if "r2" in fp_full.keys:
Expand Down Expand Up @@ -424,6 +450,7 @@ def load(cls, group, include_cm=None):
np.array(id_strs),
avg_fp,
np.array(weights),
det_boresight,
transformed,
center,
center_transformed,
Expand Down
4 changes: 3 additions & 1 deletion sotodlib/core/flagman.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def reduce(self, flags=None, method='union', wrap=False, new_flag=None,
flags: List of flags to collapse together. Uses their names.
If flags is None then all flags are reduced
method: How to collapse the data. Accepts 'union','intersect',
or function.
'except', or function.
wrap: if True, add reduced flag to self
new_flag: name of new flag, required if wrap is True
remove_reduced: if True, remove all reduced flags from self
Expand All @@ -198,6 +198,8 @@ def reduce(self, flags=None, method='union', wrap=False, new_flag=None,
op = lambda x, y: x+y
elif method == 'intersect':
op = lambda x, y: x*y
elif method == 'except':
op = lambda x, y: x*~y
else:
op = method
out = reduce(op, to_reduce)
Expand Down
29 changes: 17 additions & 12 deletions sotodlib/preprocess/processes.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pdb
import numpy as np
from operator import attrgetter
import copy
Expand Down Expand Up @@ -1832,6 +1833,7 @@ class SourceFlags(_Preprocess):
.. autofunction:: sotodlib.tod_ops.flags.get_source_flags
"""
name = "source_flags"

def __init__(self, step_cfgs):
self.source_flags_name = step_cfgs.get('source_flags_name', 'source_flags')
self.save_name = self.source_flags_name
Expand Down Expand Up @@ -1881,7 +1883,7 @@ def calc_and_save(self, aman, proc_aman):
source_aman.wrap(source + '_inv',
RangesMatrix.ones([aman.dets.count, aman.samps.count]),
[(0, 'dets'), (1, 'samps')])

self.save(proc_aman, source_aman)

return aman, proc_aman
Expand Down Expand Up @@ -2102,8 +2104,7 @@ def process(self, aman, proc_aman, sim=False, data_aman=None):
aman.samps.offset + aman.samps.count - trim))
proc_aman.restrict('samps', (proc_aman.samps.offset + trim,
proc_aman.samps.offset + proc_aman.samps.count - trim))
return aman, proc_aman

return aman, proc_aman

class DetcalNanCuts(_Preprocess):
"""
Expand Down Expand Up @@ -2696,9 +2697,9 @@ def process(self, aman, proc_aman, sim=False, data_aman=None):
aman['flags'].wrap(self.process_cfgs['total_flags_label'], total_flags)

return aman, proc_aman

class CombineFlags(_Preprocess):
"""Do the conbine of relevant flags for mapping
"""Do the combination of relevant flags for mapping


Saves results for aman under the "flags.[total_flags_label]" field.
Expand All @@ -2709,8 +2710,11 @@ class CombineFlags(_Preprocess):
process:
flag_labels: ['glitches.glitch_flags', 'source_flags.jupiter_inv']
total_flags_label: 'glitch_flags'
method: 'union' # You can select a method from ['union', '+', 'intersect', '*'].
#method: ['+', '*'] # Or you can pass individual method for each flags as a list. Lentgh must match the length of flag_labels.
method: 'union' # You can select a method from ['union', '+', 'intersect', '*', 'except', '-'].
#method: ['+', '*'] # Or you can pass individual method for each flags as a list.
# Length of list must match the length of flag_labels.
# If a list, the first method must be '+', as if adding the first flag set to an empty flag set.
# Operations are performed strictly from Left to Right, '*' are not performed first.

"""
name = "combine_flags"
Expand All @@ -2727,13 +2731,12 @@ def process(self, aman, proc_aman, sim=False, data_aman=None):
if isinstance(self.process_cfgs['method'], list):
if len(self.process_cfgs['flag_labels']) != len(self.process_cfgs['method']):
raise ValueError("The length of method does not match to the length of flag_labels")
elif any(method not in ['+', 'union', '*', 'intersect'] for method in self.process_cfgs['method']):
raise ValueError("The method provided does not match one of '+', '*', 'union', or 'intersect'")
elif self.process_cfgs['method'] in ['+', 'union', '*', 'intersect']:
elif any(method not in ['+', 'union', '*', 'intersect', '-', 'except'] for method in self.process_cfgs['method']):
raise ValueError("One or more methods in list are not valid")
elif self.process_cfgs['method'] in ['+', 'union', '*', 'intersect', '-', 'except']:
self.process_cfgs['method'] = ['+'] + (len(self.process_cfgs['flag_labels']) - 1)*[self.process_cfgs['method']]
else:
raise ValueError("The method matches neither list nor the one of the ['+', 'union', '*', 'intersect']")

raise ValueError("The method matches neither list nor the one of the valid operations")
total_flags = RangesMatrix.zeros([proc_aman.dets.count, proc_aman.samps.count]) # get an empty flags with shape (Ndets,Nsamps)
for i, (method, label) in enumerate(zip(self.process_cfgs['method'], self.process_cfgs['flag_labels'])):
_label = attrgetter(label)
Expand All @@ -2746,6 +2749,8 @@ def process(self, aman, proc_aman, sim=False, data_aman=None):
total_flags += _label(proc_aman) # The + operator is the union operator in this case
elif method in ['*', 'intersect']:
total_flags *= _label(proc_aman) # The * operator is the intersect operator in this case
elif method in ['-', 'except']:
total_flags *= ~ _label(proc_aman) # The - operator is the except operator in this case

if 'flags' not in aman._fields:
from sotodlib.core import FlagManager
Expand Down
4 changes: 3 additions & 1 deletion sotodlib/site_pipeline/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def main(obs_id=None, config_file=None, logger=None):
update_obsdb_ancil,
make_coadd_atomic_map,
make_cosamp_hk,
solve_pointing_model,
)

# Dictionary matching element name to a submodule (which must have
Expand All @@ -81,7 +82,8 @@ def main(obs_id=None, config_file=None, logger=None):
'update-obsdb': update_obsdb,
'update-obsdb-ancil': update_obsdb_ancil,
'make-cosamp-hk': make_cosamp_hk,
'make-coadd-atomic-map': make_coadd_atomic_map
'make-coadd-atomic-map': make_coadd_atomic_map,
'solve-pointing-model': solve_pointing_model,
}

CLI_NAME = 'so-site-pipeline'
Expand Down
10 changes: 7 additions & 3 deletions sotodlib/site_pipeline/finalize_focal_plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
from importlib import import_module
from typing import List, Optional

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

import git
import h5py
import megham.transform as mt
Expand Down Expand Up @@ -403,7 +407,7 @@ def _mk_pointing_config(telescope_flavor, tube_slot, wafer_slot, config):
def _restrict_inliers(aman, focal_plane):
# TODO: Use gamma as well
# Map to template
fp, _, template_msk = focal_plane.map_by_det_id(aman)
fp, _, _, template_msk = focal_plane.map_by_det_id(aman)
fp = fp[:, :2]
inliers = np.ones(len(fp), dtype=bool)

Expand Down Expand Up @@ -779,7 +783,7 @@ def main():
_restrict_inliers(aman, focal_plane)

# Mapping to template
fp, r2, template_msk = focal_plane.map_by_det_id(aman)
fp, r2, det_boresight, template_msk = focal_plane.map_by_det_id(aman)
focal_plane.template.add_wafer_info(aman, template_msk)

# Try an initial alignment and get weights
Expand Down Expand Up @@ -816,7 +820,7 @@ def main():

# Store weighted values
weights = np.column_stack((weights, r2))
focal_plane.add_fp(i, fp, weights, template_msk)
focal_plane.add_fp(i, fp, weights, det_boresight, template_msk)

n_obs += 1

Expand Down
Loading