furax.mapmaking
Modules:
-
acquisition– -
config– -
gap_filling– -
mapmaker– -
noise– -
pixell_utils– -
preconditioner– -
results– -
templates–Template operators for fitting structured nuisance signals out of the data.
-
weight–
Classes:
-
AbstractGroundObservation–Class for interfacing with ground-based observation data.
-
AbstractLazyObservation–Deferred handle to an observation: opens its backing store only when read.
-
AbstractObservation–Abstract class for interfacing with any observation data.
-
AbstractSatelliteObservation–Class for interfacing with satellite observation data.
-
FileBackedLazyObservation–Lazy observation whose backing store is a single binary file.
-
HashedObservationMetadata–Hashed version of some metadata fields for JAX compatibility.
-
ObservationBufferShapes– -
ReaderField–Canonical names of the data fields an observation reader can load.
-
ObservationReader–Jittable reader for ground observations.
-
MapMakingConfig– -
MultiObservationMapMaker–Class for mapping multiple observations together.
-
BJPreconditioner–Block-diagonal (per-pixel) Jacobi preconditioner for Stokes sky maps.
-
MapMakingResults–
Functions:
-
gap_fill–Fill flagged time samples with a constrained noise realization, leaving good samples unchanged.
Attributes:
-
logger–
furax.mapmaking.logger = logging.getLogger('furax-mapmaking')
module-attribute
furax.mapmaking.AbstractGroundObservation
Bases: AbstractObservation[T]
Class for interfacing with ground-based observation data.
Methods:
-
get_scanning_intervals–Returns scanning intervals.
-
get_left_scan_mask–Returns boolean mask (True=valid) for selection of left-going scans.
-
get_right_scan_mask–Returns boolean mask (True=valid) for selection of right-going scans.
-
get_azimuth–Returns the azimuth of the boresight for each sample.
-
get_elevation–Returns the elevation of the boresight for each sample.
-
get_scanning_mask–Returns a boolean sample mask from scanning intervals (True=scanning).
-
get_detector_pointing_lonlat–Compute the pointing trajectory in longitude/latitude coordinates for all detectors.
Attributes:
Source code in src/furax/mapmaking/_observation.py
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
AVAILABLE_READER_FIELDS = AbstractObservation.AVAILABLE_READER_FIELDS | {ReaderField.VALID_SCANNING_MASKS, ReaderField.AZIMUTH, ReaderField.ELEVATION, ReaderField.LEFT_SCAN_MASK, ReaderField.RIGHT_SCAN_MASK, ReaderField.SCANNING_INTERVALS}
class-attribute
OPTIONAL_READER_FIELDS = AbstractObservation.OPTIONAL_READER_FIELDS | {ReaderField.VALID_SCANNING_MASKS, ReaderField.AZIMUTH, ReaderField.ELEVATION, ReaderField.LEFT_SCAN_MASK, ReaderField.RIGHT_SCAN_MASK, ReaderField.SCANNING_INTERVALS}
class-attribute
get_scanning_intervals()
abstractmethod
Returns scanning intervals.
The output is a list of the starting and ending sample indices
get_left_scan_mask()
abstractmethod
get_right_scan_mask()
abstractmethod
get_azimuth()
abstractmethod
get_elevation()
abstractmethod
get_scanning_mask()
Returns a boolean sample mask from scanning intervals (True=scanning).
Source code in src/furax/mapmaking/_observation.py
get_detector_pointing_lonlat(thin_samples=1, use_scanning_mask=True, use_degrees=True)
Compute the pointing trajectory in longitude/latitude coordinates for all detectors.
This method calculates the sky coordinates (longitude, latitude) for each detector at each time sample by combining boresight quaternions with detector offset quaternions.
Parameters:
-
thin_samples(int, default=1, default:1) –Factor by which to subsample the time axis. If > 1, only every nth sample is included in the output. Applied after scanning mask if both are used.
-
use_scanning_mask(bool, default=True, default:True) –Whether to apply the scanning mask to exclude non-scanning periods. When True, only samples during active scanning are included.
-
use_degrees(bool, default=True, default:True) –If True, return angles in degrees. If False, return in radians.
Returns:
-
alpha(Float[Array, 'det samp']) –Longitude coordinates (RA or azimuth) for each detector and sample. Shape is (n_detectors, n_samples_final) where n_samples_final depends on scanning mask and subsampling.
-
delta(Float[Array, 'det samp']) –Latitude coordinates (Dec or elevation) for each detector and sample. Shape is (n_detectors, n_samples_final).
Notes
- The coordinate system depends on the boresight quaternion convention: typically equatorial (RA/Dec) or horizontal (Az/El)
- Processing order: scanning mask is applied first, then subsampling
- The quaternion multiplication combines the boresight pointing with detector offsets to get the absolute pointing of each detector
Examples:
>>> # Get pointing in degrees for all detectors
>>> lon, lat = obs.get_detector_pointing_lonlat()
>>> print(f"Shape: {lon.shape}") # (n_dets, n_samples_scanning)
>>> # Get pointing in radians without scanning mask, subsampled by 10
>>> lon_rad, lat_rad = obs.get_detector_pointing_lonlat(
... thin_samples=10, use_scanning_mask=False, use_degrees=False
... )
Source code in src/furax/mapmaking/_observation.py
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | |
furax.mapmaking.AbstractLazyObservation
Deferred handle to an observation: opens its backing store only when read.
The default implementation is file-backed, but subclasses are free to back the
observation by any source (e.g. a preprocessing database) by overriding get_data.
Methods:
-
get_data–Loads observation data from the underlying source.
-
probe_shape–Returns the buffer dimensions for this observation.
Attributes:
-
interface_class(type[AbstractObservation[T]]) – -
name(str) –Human-readable identifier, used e.g. to report observations that failed to load.
Source code in src/furax/mapmaking/_observation.py
interface_class
instance-attribute
name
property
Human-readable identifier, used e.g. to report observations that failed to load.
get_data(requested_fields=None)
abstractmethod
Loads observation data from the underlying source.
Parameters:
-
requested_fields(Collection[str] | None, default:None) –List of data fields needed. If None, the entire observation is loaded into memory. If
[](empty list), loads only what's needed to determine buffer shapes. Otherwise, loads whatever is needed to satisfy the request.
Source code in src/furax/mapmaking/_observation.py
probe_shape(intervals=False)
Returns the buffer dimensions for this observation.
The default opens the observation with a minimal field set request; subclasses may override with a cheaper query (e.g., metadata only).
Source code in src/furax/mapmaking/_observation.py
furax.mapmaking.AbstractObservation
Abstract class for interfacing with any observation data.
This class defines what data is needed for making maps. It is meant to be
used as a base class for interfacing with different containers (e.g. toast's
Observation, sotodlib's AxisManager, litebird_sim's Observation, etc.)
Methods:
-
__init__– -
from_file–Loads the observation from a binary file.
-
get_tods–Returns the timestream data.
-
get_demodulated_tods–Returns demodulated timestream data as a Stokes pytree.
-
get_demodulated_noise_model–Returns a single noise model covering every requested Stokes leg.
-
get_detector_offset_angles–Returns the detector offset angles ('gamma').
-
get_hwp_angles–Returns the HWP angles.
-
get_hwp_frequency–Returns the average HWP rotation frequency in Hz.
-
get_sample_mask–Returns boolean sample mask (True=valid) of the TOD.
-
get_timestamps–Returns timestamps (sec) of the samples.
-
get_elapsed_times–Returns time (sec) of the samples since the observation began.
-
get_wcs_shape_and_kernel–Returns the shape and object corresponding to a WCS projection.
-
get_pointing_and_spin_angles–Obtain pointing information and spin angles from the observation.
-
get_noise_model–Load a pre-computed noise model from the data, if present. Otherwise, return None.
-
get_boresight_quaternions–Returns the boresight quaternions at each time sample.
-
get_detector_quaternions–Returns the quaternion offsets of the detectors.
Attributes:
-
AVAILABLE_READER_FIELDS(frozenset[str]) –Supported data field names for all observations
-
OPTIONAL_READER_FIELDS(frozenset[str]) –Optional data field names
-
data– -
name(str) –Observation name.
-
telescope(str) –Telescope name.
-
n_samples(int) –Returns the number of samples in the observation.
-
detectors(list[str]) –Returns a list of the detector names.
-
n_detectors(int) – -
sample_rate(float) –Returns the sampling rate (in Hz) of the data.
Source code in src/furax/mapmaking/_observation.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
AVAILABLE_READER_FIELDS = frozenset({ReaderField.METADATA, ReaderField.SAMPLE_DATA, ReaderField.VALID_SAMPLE_MASKS, ReaderField.TIMESTAMPS, ReaderField.HWP_ANGLES, ReaderField.DETECTOR_QUATERNIONS, ReaderField.BORESIGHT_QUATERNIONS, ReaderField.NOISE_MODEL_FITS})
class-attribute
Supported data field names for all observations
OPTIONAL_READER_FIELDS = frozenset({ReaderField.NOISE_MODEL_FITS})
class-attribute
Optional data field names
data = data
instance-attribute
name
abstractmethod
property
Observation name.
telescope
abstractmethod
property
Telescope name.
n_samples
abstractmethod
property
Returns the number of samples in the observation.
detectors
abstractmethod
property
Returns a list of the detector names.
n_detectors
property
sample_rate
abstractmethod
property
Returns the sampling rate (in Hz) of the data.
__init__(data)
from_file(filename, requested_fields=None)
abstractmethod
classmethod
Loads the observation from a binary file.
Parameters:
-
filename(str | Path) –The binary file.
-
requested_fields(Collection[str] | None, default:None) –List of data fields needed. If None, the entire file is loaded into memory. If
[](empty list), loads only what's needed to determine buffer shapes. Otherwise, loads whatever is needed to satisfy the request.
Source code in src/furax/mapmaking/_observation.py
get_tods()
abstractmethod
Returns the timestream data.
Returns a host (numpy) array: getters feed the reader's io_callback, which performs a single host->device transfer. Returning a device (jax) array would force a wasteful device->host->device round trip at the callback boundary.
Source code in src/furax/mapmaking/_observation.py
get_demodulated_tods(stokes='IQU')
Returns demodulated timestream data as a Stokes pytree.
Subclasses that support demodulated data should override this method.
Source code in src/furax/mapmaking/_observation.py
get_demodulated_noise_model(stokes='IQU')
Returns a single noise model covering every requested Stokes leg.
Its per-detector parameters carry a leading Stokes axis, so I/Q/U may have distinct fit values without being separate models.
Subclasses that support demodulated data should override this method.
Source code in src/furax/mapmaking/_observation.py
get_detector_offset_angles()
abstractmethod
get_hwp_angles()
abstractmethod
get_hwp_frequency()
Returns the average HWP rotation frequency in Hz.
Source code in src/furax/mapmaking/_observation.py
get_sample_mask()
abstractmethod
get_timestamps()
abstractmethod
get_elapsed_times()
Returns time (sec) of the samples since the observation began.
get_wcs_shape_and_kernel(resolution_arcmin, projection=ProjectionType.CAR)
abstractmethod
Returns the shape and object corresponding to a WCS projection.
Source code in src/furax/mapmaking/_observation.py
get_pointing_and_spin_angles(landscape)
abstractmethod
Obtain pointing information and spin angles from the observation.
get_noise_model()
abstractmethod
get_boresight_quaternions()
abstractmethod
furax.mapmaking.AbstractSatelliteObservation
Bases: AbstractObservation[T]
Class for interfacing with satellite observation data.
Source code in src/furax/mapmaking/_observation.py
furax.mapmaking.FileBackedLazyObservation
Bases: AbstractLazyObservation[T]
Lazy observation whose backing store is a single binary file.
Methods:
Attributes:
Source code in src/furax/mapmaking/_observation.py
file = Path(filename).resolve()
instance-attribute
name
property
__init__(filename)
furax.mapmaking.HashedObservationMetadata
dataclass
Hashed version of some metadata fields for JAX compatibility.
Methods:
Attributes:
-
uid(UInt32[ndarray | Array, '']) – -
telescope_uid(UInt32[ndarray | Array, '']) – -
detector_uids(UInt32[ndarray | Array, '*#dets']) –
Source code in src/furax/mapmaking/_observation.py
uid
instance-attribute
telescope_uid
instance-attribute
detector_uids
instance-attribute
from_observation(obs)
classmethod
structure_for(n_dets)
classmethod
Source code in src/furax/mapmaking/_observation.py
split_key(key)
__init__(uid, telescope_uid, detector_uids)
furax.mapmaking.ObservationBufferShapes
Bases: NamedTuple
Attributes:
-
detector_count(int) – -
sample_count(int) – -
interval_count(int) –
Source code in src/furax/mapmaking/_observation.py
detector_count
instance-attribute
sample_count
instance-attribute
interval_count = 0
class-attribute
instance-attribute
furax.mapmaking.ReaderField
Bases: StrEnum
Canonical names of the data fields an observation reader can load.
Members are plain strings (StrEnum), so they interoperate with string keys in
field dictionaries and set membership tests. Using members instead of bare literals
makes typos a name-resolution error caught by linting/type-checking.
Attributes:
-
METADATA– -
SAMPLE_DATA– -
VALID_SAMPLE_MASKS– -
VALID_SCANNING_MASKS– -
TIMESTAMPS– -
HWP_ANGLES– -
DETECTOR_QUATERNIONS– -
BORESIGHT_QUATERNIONS– -
NOISE_MODEL_FITS– -
AZIMUTH– -
ELEVATION– -
LEFT_SCAN_MASK– -
RIGHT_SCAN_MASK– -
SCANNING_INTERVALS–
Source code in src/furax/mapmaking/_observation.py
METADATA = 'metadata'
class-attribute
instance-attribute
SAMPLE_DATA = 'sample_data'
class-attribute
instance-attribute
VALID_SAMPLE_MASKS = 'valid_sample_masks'
class-attribute
instance-attribute
VALID_SCANNING_MASKS = 'valid_scanning_masks'
class-attribute
instance-attribute
TIMESTAMPS = 'timestamps'
class-attribute
instance-attribute
HWP_ANGLES = 'hwp_angles'
class-attribute
instance-attribute
DETECTOR_QUATERNIONS = 'detector_quaternions'
class-attribute
instance-attribute
BORESIGHT_QUATERNIONS = 'boresight_quaternions'
class-attribute
instance-attribute
NOISE_MODEL_FITS = 'noise_model_fits'
class-attribute
instance-attribute
AZIMUTH = 'azimuth'
class-attribute
instance-attribute
ELEVATION = 'elevation'
class-attribute
instance-attribute
LEFT_SCAN_MASK = 'left_scan_mask'
class-attribute
instance-attribute
RIGHT_SCAN_MASK = 'right_scan_mask'
class-attribute
instance-attribute
SCANNING_INTERVALS = 'scanning_intervals'
class-attribute
instance-attribute
furax.mapmaking.ObservationReader
Bases: AbstractReader, Generic[T]
Jittable reader for ground observations.
The reader is set up with a list of filenames and data field names. Individual files can be
loaded by passing an index in this list to the read method. The observation data is padded
so that all observations have the same structure.
The available data fields for ground observations are
- metadata: observation, telescope and detector uids.
- sample_data: the detector read-outs.
- valid_sample_masks: the (boolean) mask indicating which samples are valid (=True).
- valid_scanning_masks: the (boolean) mask indicating which samples are taken during scans (and not turnarounds).
- timestamps: the timestamps of the samples.
- hwp_angles: the half-wave plate angle measured at each sample.
- detector_quaternions: the detector quaternions.
- boresight_quaternions: the boresight quaternions.
- noise_model_fits: the fitted parameters for the noise model (1/f noise by default).
- azimuth, elevation: the boresight scan angles (ground observations).
- left_scan_mask, right_scan_mask: per-sample masks splitting left/right-going scans.
- scanning_intervals: per-scan [start, end) sample-index pairs (ground observations).
Methods:
-
__init__– -
from_observations–Create a reader, performing I/O to infer data structures.
Attributes:
-
demodulated– -
stokes– -
dtype–
Source code in src/furax/mapmaking/_reader.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | |
demodulated = demodulated
instance-attribute
stokes = stokes
instance-attribute
dtype = dtype
instance-attribute
__init__(*args, demodulated, stokes, dtype=jnp.float64, common_keywords=None, shapes=None, known_failures=None, **keywords)
Source code in src/furax/mapmaking/_reader.py
from_observations(observations, *, read_indices=None, requested_fields=None, demodulated=False, stokes='IQU', dtype=jnp.float64)
classmethod
Create a reader, performing I/O to infer data structures.
Parameters:
-
observations(Sequence[AbstractLazyObservation[T]]) –Full list of lazy observations.
-
read_indices(Sequence[int] | None, default:None) –Optional indices into
observations; when set, only those are opened on this process to infer shapes, and shapes are synchronised across processes (distributed-mode shortcut). -
requested_fields(Collection[str] | None, default:None) –Optional list of fields to load. If None, read all non-optional fields.
-
demodulated(bool, default:False) –Whether to read demodulated TODs.
-
stokes(ValidStokesType, default:'IQU') –Stokes components to read when demodulated.
-
dtype(DTypeLike, default:float64) –Floating-point dtype applied to every floating-point field the reader returns: sample data, noise model fits and the geometry (timestamps, HWP angles, quaternions). Use jnp.float32 to run a float32 mapmaking pipeline (MapMakingConfig.double_precision=False). Casting the geometry is also required there: under jax_enable_x64=False a float64 array is illegal, so no field may stay float64. Timestamps are rebased to a per-observation zero origin (in float64, before the downcast) so the float32 cast does not collapse the absolute POSIX epoch onto a single value; see the timestamps reader in
_get_data_field_readers.
Source code in src/furax/mapmaking/_reader.py
furax.mapmaking.MapMakingConfig
dataclass
Methods:
-
for_method–Return a default MapMakingConfig pre-configured for the given method.
-
full_defaults–Create a config with default values for all fields including optional ones.
-
load_yaml–Load and instantiate a
MapMakingConfigfrom a YAML file. -
load_dict–Load and instantiate a
MapMakingConfigfrom a dictionary. -
dump_yaml–Dump the config to a YAML file.
-
__init__–
Attributes:
-
method(Methods) – -
scanning_mask(bool) – -
sample_mask(bool) – -
hits_cut(float) – -
cond_cut(float) – -
double_precision(bool) – -
pointing(PointingConfig) – -
weighting(WeightingConfig) – -
debug(bool) – -
solver(SolverConfig) – -
gaps(GapsConfig) – -
landscape(LandscapeConfig) – -
templates(TemplatesConfig | None) – -
atop_tau(int) – -
sotodlib(SotodlibConfig | None) – -
binned(bool) – -
demodulated(bool) – -
use_templates(bool) – -
dtype(DTypeLike) –
Source code in src/furax/mapmaking/config.py
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | |
method = Methods.BINNED
class-attribute
instance-attribute
scanning_mask = False
class-attribute
instance-attribute
sample_mask = False
class-attribute
instance-attribute
hits_cut = 0.01
class-attribute
instance-attribute
cond_cut = 0.01
class-attribute
instance-attribute
double_precision = True
class-attribute
instance-attribute
pointing = field(default_factory=PointingConfig)
class-attribute
instance-attribute
weighting = field(default_factory=WeightingConfig)
class-attribute
instance-attribute
debug = True
class-attribute
instance-attribute
solver = field(default_factory=SolverConfig)
class-attribute
instance-attribute
gaps = field(default_factory=GapsConfig)
class-attribute
instance-attribute
landscape = field(default_factory=(lambda: LandscapeConfig(healpix=(HealpixConfig()))))
class-attribute
instance-attribute
templates = None
class-attribute
instance-attribute
atop_tau = 0
class-attribute
instance-attribute
sotodlib = None
class-attribute
instance-attribute
binned
property
demodulated
property
use_templates
property
dtype
property
for_method(method)
classmethod
Return a default MapMakingConfig pre-configured for the given method.
Parameters:
-
method(Methods | str) –A
Methodsenum value or its string name (e.g.'binned','ml','twostep','atop'), case-insensitive.
Source code in src/furax/mapmaking/config.py
full_defaults()
classmethod
Create a config with default values for all fields including optional ones.
load_yaml(path)
classmethod
Load and instantiate a MapMakingConfig from a YAML file.
load_dict(data)
classmethod
Load and instantiate a MapMakingConfig from a dictionary.
dump_yaml(path)
Dump the config to a YAML file.
The '.yaml' suffix is automatically added if not already present.
Source code in src/furax/mapmaking/config.py
__init__(method=Methods.BINNED, scanning_mask=False, sample_mask=False, hits_cut=0.01, cond_cut=0.01, double_precision=True, pointing=PointingConfig(), weighting=WeightingConfig(), debug=True, solver=SolverConfig(), gaps=GapsConfig(), landscape=(lambda: LandscapeConfig(healpix=(HealpixConfig())))(), templates=None, atop_tau=0, sotodlib=None)
furax.mapmaking.MultiObservationMapMaker
Class for mapping multiple observations together.
Methods:
-
__init__– -
distribute–Shard a pytree of process-local arrays along the leading 'obs' axis.
-
get_padded_read_indices– -
get_reader–Build an ObservationReader for this process's local observations.
-
run–Runs the mapmaker and return results after saving them to the given directory.
-
make_maps–Computes the mapmaker results (maps and other products).
-
build_model_and_accumulate–Build the model and accumulate the hit map and RHS in a single, sharded read pass.
-
get_system_operator– -
pixel_selection–Compute pixel selection according to hit and condition number cuts.
Attributes:
-
observations– -
config– -
logger– -
landscape– -
reader– -
mesh(Mesh) – -
sharding(NamedSharding) – -
n_observations(int) –Total number of observations across all processes.
-
obs_distribution(tuple[int, int, int]) –(start, n_owned, n_pad)for this process.
Source code in src/furax/mapmaking/mapmaker.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | |
observations = observations
instance-attribute
config = config or MapMakingConfig()
instance-attribute
logger = logger or furax_logger
instance-attribute
landscape = _static_landscape(self.config.landscape, self.config.dtype) or self._scan_wcs_footprint()
instance-attribute
reader = self.get_reader(model_fields | rhs_fields)
instance-attribute
mesh
cached
property
sharding
property
n_observations
property
Total number of observations across all processes.
obs_distribution
property
(start, n_owned, n_pad) for this process.
__init__(observations, config=None, logger=None)
Source code in src/furax/mapmaking/mapmaker.py
distribute(x)
Shard a pytree of process-local arrays along the leading 'obs' axis.
get_padded_read_indices()
get_reader(required_fields)
Build an ObservationReader for this process's local observations.
Source code in src/furax/mapmaking/mapmaker.py
run(out_dir=None)
Runs the mapmaker and return results after saving them to the given directory.
Source code in src/furax/mapmaking/mapmaker.py
make_maps()
Computes the mapmaker results (maps and other products).
Source code in src/furax/mapmaking/mapmaker.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
build_model_and_accumulate()
Build the model and accumulate the hit map and RHS in a single, sharded read pass.
Sharded over observations: each observation is read (and, for preproc-backed observations,
preprocessed) exactly once, and contributes to the model, the hit map and the RHS from that
single read. This avoids reading every observation twice (once to build the model, once to
accumulate the RHS). The hit map and RHS are reduced across all processes with psum
inside the kernel.
Observations that contribute nothing -- padding (added so every device carries the same
workload) and failed loads (the preprocessing pipeline raised) -- are gated out by zeroing
their masker inside the kernel, so they drop out of the hit map, the RHS, and the CG system
operator alike. Failed loads are reported afterwards from self.reader.failed_indices
(see make_maps).
Must run under jax.set_mesh(self.mesh).
Returns (model, hits, rhs) with the model sharded along the observation axis and the
hit map / RHS replicated (already reduced across processes).
Source code in src/furax/mapmaking/mapmaker.py
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
get_system_operator(model, *, diag=False)
Source code in src/furax/mapmaking/mapmaker.py
pixel_selection(hits, weights)
Compute pixel selection according to hit and condition number cuts.
Source code in src/furax/mapmaking/mapmaker.py
furax.mapmaking.BJPreconditioner
Bases: AbstractLinearOperator
Block-diagonal (per-pixel) Jacobi preconditioner for Stokes sky maps.
Holds one dense (n, n) block per pixel (n = len(stokes)), coupling the Stokes
components at that pixel: blocks has shape (*sky, n, n) with blocks[..., i, j] the
response of output component i to input component j. Applied by an einsum over the
Stokes axis of the map's backing array; symmetric (self-adjoint) for a symmetric operator.
Methods:
-
__init__– -
create–Assemble the per-pixel blocks from a symmetric operator acting on Stokes sky maps.
-
mv– -
inverse–
Attributes:
-
blocks(Float[Array, '*sky n n']) –
Source code in src/furax/mapmaking/preconditioner.py
blocks
instance-attribute
__init__(blocks, *, in_structure)
create(op)
classmethod
Assemble the per-pixel blocks from a symmetric operator acting on Stokes sky maps.
The operator is assumed diagonal over the pixel (map) axes. Each Stokes component is probed with a unit map; the response is that column of every pixel's block at once.
Source code in src/furax/mapmaking/preconditioner.py
mv(x)
Source code in src/furax/mapmaking/preconditioner.py
furax.mapmaking.MapMakingResults
dataclass
Methods:
Attributes:
-
map(StokesType) –The estimated sky map
-
landscape(StokesLandscape) –The landscape corresponding to the map
-
hit_map(Integer[Array, ' *dims']) –The map of hit counts per pixel
-
icov(Float[Array, 'stokes stokes *dims']) –The per-pixel inverse noise covariance matrix (H^T N^{-1} H)
-
solver_stats(dict[str, Any] | None) –Statistics from the linear solver (e.g. num_steps, max_steps)
-
noise_fits(Float[Array, ...] | None) –The fitted noise PSD parameters
-
failed_observations(list[str] | None) –Names of observations that failed to load and were excluded from the maps
Source code in src/furax/mapmaking/results.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | |
map
instance-attribute
The estimated sky map
landscape
instance-attribute
The landscape corresponding to the map
hit_map
instance-attribute
The map of hit counts per pixel
icov
instance-attribute
The per-pixel inverse noise covariance matrix (H^T N^{-1} H)
solver_stats = None
class-attribute
instance-attribute
Statistics from the linear solver (e.g. num_steps, max_steps)
noise_fits = None
class-attribute
instance-attribute
The fitted noise PSD parameters
failed_observations = None
class-attribute
instance-attribute
Names of observations that failed to load and were excluded from the maps
save(out_dir)
Source code in src/furax/mapmaking/results.py
load(out_dir, landscape, fields=None)
classmethod
Load a previously saved MapMakingResults from disk.
Parameters:
-
out_dir(str | Path) –Directory containing the saved files.
-
landscape(StokesLandscape) –The landscape used when the results were saved.
-
fields(set[str] | list[str] | None, default:None) –Fields to load. Defaults to all fields. Required fields (map, hit_map, icov) must always be included if specified.
Source code in src/furax/mapmaking/results.py
__init__(map, landscape, hit_map, icov, solver_stats=None, noise_fits=None, failed_observations=None)
furax.mapmaking.gap_fill(key, x, ninv, mask, *, rate=1.0, max_cg_steps=50, rtol=0.0001, atol=0.0, preconditioner=None, metadata=None)
Fill flagged time samples with a constrained noise realization, leaving good samples unchanged.
Replaces each flagged sample with a draw from the noise model conditioned on the surrounding good data (a constrained realization), so the gap is filled consistently with the noise correlations rather than by interpolation. The fill is a free realization \(\xi\) plus a correction that pins the good samples back to their data values:
where \(M_b\) masks the flagged samples. Three things to note:
- Good samples are returned bit-exact; only the gaps change.
- The CG solve acts only on the flagged subspace.
- \(\xi\) is drawn from \(N\), obtained as the reciprocal of the inverse-noise PSD.
For a few gaps wider than the correlation length the bare \(M_b N^{-1} M_b\) system is
ill-conditioned; passing the flagged-block covariance \(M_b N M_b\) as preconditioner,
i.e. mask.complement() @ cov @ mask.complement() with cov a cheap approximation of
\(N\) (its banded/Fourier form), then helps a lot. Its product with the system operator
differs from the identity by a boundary term of rank \(\approx 2\times\) (correlation
bandwidth) \(\times\) (number of gaps), and CG converges in roughly that many steps.
This is only worthwhile when that rank is below the iteration count of the bare system. For
the common case of many short gaps (turnarounds, glitches) the gaps are shorter than the
correlation length, the bare flagged block is already well-conditioned, and preconditioning is a
net loss -- leave preconditioner=None there. The preconditioner must be symmetric positive
definite and live in the flagged subspace (zero on the good samples).
Parameters:
-
key(Key[Array, '']) –A PRNG key generated by the user.
-
x(PyTree[Float[Array, ' *shape']]) –The time-ordered vector to be filled.
-
ninv(AbstractLinearOperator) –The inverse-noise operator \(N^{-1}\).
-
mask(MaskOperator) –The good-sample mask \(M\); its zeros are the gaps.
-
rate(ArrayLike, default:1.0) –The sampling rate of the data.
-
max_cg_steps(int, default:50) –Maximum number of CG steps for the flagged-subspace solve.
-
rtol(float, default:0.0001) –Relative convergence tolerance for the solver.
-
atol(float, default:0.0) –Absolute convergence tolerance for the solver.
-
preconditioner(AbstractLinearOperator | None, default:None) –Optional SPD preconditioner for the flagged-subspace CG (see above).
-
metadata(HashedObservationMetadata | None, default:None) –Metadata folded into the random key for reproducibility.
Returns:
-
PyTree[Float[Array, ' *shape']]–xwith its flagged samples replaced by the constrained realization.
Examples:
Gap-filling a single-detector timestream
>>> key = jax.random.key(0)
>>> ndet, nsamples = 3, 10
>>> x = jax.random.normal(key, (ndet, nsamples))
>>> in_structure = jax.ShapeDtypeStruct(x.shape, x.dtype)
>>> good = jnp.broadcast_to(
... jnp.array([1, 1, 1, 0, 0, 1, 1, 1, 1, 1], dtype=bool), x.shape
... )
>>> mask = MaskOperator.from_boolean_mask(good, in_structure=in_structure)
>>> ninv = SymmetricBandToeplitzOperator(jnp.array([1.0]), in_structure=in_structure)
>>> cov = SymmetricBandToeplitzOperator(jnp.array([1.0]), in_structure=in_structure) # N ≈ cov
>>> preconditioner = (mask.complement() @ cov @ mask.complement()).reduce()
>>> filled = gap_fill(key, x, ninv, mask, preconditioner=preconditioner)
>>> assert jnp.all(filled[good] == x[good])
Source code in src/furax/mapmaking/gap_filling.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
furax.mapmaking.acquisition
Functions:
-
build_acquisition_operator–Build an acquisition operator for a single observation. Does not include masking.
build_acquisition_operator(landscape, boresight_quaternions, detector_quaternions, hwp_angles=None, *, demodulated=False, pointing_on_the_fly=True, pointing_batch_size=16, pointing_interpolate=False, dtype=jnp.float64)
Build an acquisition operator for a single observation. Does not include masking.
Source code in src/furax/mapmaking/acquisition.py
furax.mapmaking.config
Classes:
-
Methods– -
WeightingMode– -
NoiseSource– -
GapTreatment–How flagged samples enter the correlated-noise GLS weighting.
-
SolverConfig– -
NoiseFitConfig– -
WeightingConfig–Configuration for the inverse-noise / weighting matrix used in mapmaking.
-
HealpixConfig–Configuration for a HEALPix output map.
-
SkyPatch–Explicit rectangular sky patch for WCS map construction.
-
WCSConfig–Configuration for a WCS-projected output map.
-
LandscapeConfig– -
PolynomialOrders–A polynomial order range, inclusive.
-
BinsConfig–A piecewise basis that bins a variable into
n_binsintervals. -
PolynomialConfig– -
ScanSynchronousConfig–Scan-synchronous signal on a global Legendre basis.
-
BinAzSynchronousConfig–Binned azimuth-synchronous signal, no HWP coupling.
-
HWPSynchronousConfig– -
AzHWPSynchronousConfig– -
BinAzHWPSynchronousConfig– -
SplineHWPSSConfig– -
GroundConfig– -
TemplatesConfig– -
GapFillingConfig–Specific gap-filling options.
-
NestedConfig–Inner-solver options for the nested-inverse gap weight (
GapTreatment.NESTED). -
GapsConfig–Configuration options related to the treatment of gaps.
-
PointingConfig–Configuration options for pointing computation.
-
SotodlibConfig–Configuration options specific to the sotodlib interface.
-
MapMakingConfig–
Methods
Bases: Enum
Attributes:
Source code in src/furax/mapmaking/config.py
BINNED = 'Binned'
class-attribute
instance-attribute
MAXL = 'ML'
class-attribute
instance-attribute
TWOSTEP = 'TwoStep'
class-attribute
instance-attribute
ATOP = 'ATOP'
class-attribute
instance-attribute
WeightingMode
Bases: Enum
Attributes:
Source code in src/furax/mapmaking/config.py
IDENTITY = 'identity'
class-attribute
instance-attribute
DIAGONAL = 'diagonal'
class-attribute
instance-attribute
TOEPLITZ = 'toeplitz'
class-attribute
instance-attribute
NoiseSource
Bases: Enum
Attributes:
-
FIT– -
PRECOMPUTED–
Source code in src/furax/mapmaking/config.py
FIT = 'fit'
class-attribute
instance-attribute
PRECOMPUTED = 'precomputed'
class-attribute
instance-attribute
GapTreatment
Bases: Enum
How flagged samples enter the correlated-noise GLS weighting.
For white/diagonal weights all three coincide (M W M = M W for mask M);
the distinction only matters in the correlated (Toeplitz/atmospheric) regime.
Attributes:
-
INNER_MASK– -
FILL– -
NESTED–
Source code in src/furax/mapmaking/config.py
INNER_MASK = 'inner_mask'
class-attribute
instance-attribute
FILL = 'fill'
class-attribute
instance-attribute
NESTED = 'nested'
class-attribute
instance-attribute
SolverConfig
dataclass
Methods:
-
__init__–
Attributes:
Source code in src/furax/mapmaking/config.py
rtol = 1e-06
class-attribute
instance-attribute
atol = 0
class-attribute
instance-attribute
max_steps = 1000
class-attribute
instance-attribute
__init__(rtol=1e-06, atol=0, max_steps=1000)
NoiseFitConfig
dataclass
Methods:
-
__init__–
Attributes:
-
nperseg(int) –Welch window length in samples for PSD estimation.
-
max_iter(int) –Maximum number of iterations
-
tol(float) –Relative minimiser tolerance (step size and function value change)
-
min_freq_nyquist(float) –Only use f >= min_freq * nyquist for noise fitting
-
max_freq_nyquist(float) –Only use f < max_freq * nyquist for noise fitting
-
low_freq_nyquist(float) –The PSD at f < low_freq * nyquist is assumed to be dominated by 1/f noise
-
high_freq_nyquist(float) –The PSD at f > high_freq * nyquist is assumed to be dominated by white noise
-
mask_hwp_harmonics(bool) –Mask HWP harmonics: 1f, 2f, 4f
-
mask_ptc_harmonics(bool) –Mask PTC harmonics: 1f, 2f
-
freq_mask_width(float) –Full width [Hz] of the frequency mask (if used) around HWP and PTC harmonics
-
ptc_freq(float) –PTC frequency [Hz] used for masking (if used)
Source code in src/furax/mapmaking/config.py
nperseg = 2048
class-attribute
instance-attribute
Welch window length in samples for PSD estimation.
max_iter = 100
class-attribute
instance-attribute
Maximum number of iterations
tol = 1e-10
class-attribute
instance-attribute
Relative minimiser tolerance (step size and function value change)
min_freq_nyquist = 1e-08
class-attribute
instance-attribute
Only use f >= min_freq * nyquist for noise fitting
max_freq_nyquist = 1
class-attribute
instance-attribute
Only use f < max_freq * nyquist for noise fitting
low_freq_nyquist = 0.02
class-attribute
instance-attribute
The PSD at f < low_freq * nyquist is assumed to be dominated by 1/f noise
high_freq_nyquist = 0.02
class-attribute
instance-attribute
The PSD at f > high_freq * nyquist is assumed to be dominated by white noise
mask_hwp_harmonics = True
class-attribute
instance-attribute
Mask HWP harmonics: 1f, 2f, 4f
mask_ptc_harmonics = False
class-attribute
instance-attribute
Mask PTC harmonics: 1f, 2f
freq_mask_width = 0.5
class-attribute
instance-attribute
Full width [Hz] of the frequency mask (if used) around HWP and PTC harmonics
ptc_freq = 1.4
class-attribute
instance-attribute
PTC frequency [Hz] used for masking (if used)
__init__(nperseg=2048, max_iter=100, tol=1e-10, min_freq_nyquist=1e-08, max_freq_nyquist=1, low_freq_nyquist=0.02, high_freq_nyquist=0.02, mask_hwp_harmonics=True, mask_ptc_harmonics=False, freq_mask_width=0.5, ptc_freq=1.4)
WeightingConfig
dataclass
Configuration for the inverse-noise / weighting matrix used in mapmaking.
mode selects the structure of the inverse-noise matrix:
IDENTITY: identity matrix (no weighting).DIAGONAL: diagonal white-noise weighting (default).TOEPLITZ: banded Toeplitz weighting for atmospheric (1/f) noise.
source selects where the noise model comes from: FIT (default) fits it from the
TOD power spectral density using fitting; PRECOMPUTED reads noise parameters from
the data pipeline (fitting is then ignored).
correlation_length sets the Toeplitz bandwidth (in samples) of the inverse-noise
operator. It is only used in TOEPLITZ mode and is ignored otherwise.
Methods:
-
__init__–
Attributes:
-
mode(WeightingMode) –Inverse-noise weighting matrix structure.
-
source(NoiseSource) –Where the noise model comes from: fit from the TOD PSD or read precomputed parameters.
-
correlation_length(int) –Toeplitz bandwidth in samples. Only relevant in
TOEPLITZmode. -
fitting(NoiseFitConfig) –Options for fitting the noise PSD to the data. Ignored when
sourceis PRECOMPUTED. -
diagonal_matrix(bool) –True when the inverse-noise matrix is diagonal (identity or white).
Source code in src/furax/mapmaking/config.py
mode = WeightingMode.DIAGONAL
class-attribute
instance-attribute
Inverse-noise weighting matrix structure.
source = NoiseSource.FIT
class-attribute
instance-attribute
Where the noise model comes from: fit from the TOD PSD or read precomputed parameters.
correlation_length = 1000
class-attribute
instance-attribute
Toeplitz bandwidth in samples. Only relevant in TOEPLITZ mode.
fitting = field(default_factory=NoiseFitConfig)
class-attribute
instance-attribute
Options for fitting the noise PSD to the data. Ignored when source is PRECOMPUTED.
diagonal_matrix
property
True when the inverse-noise matrix is diagonal (identity or white).
__init__(mode=WeightingMode.DIAGONAL, source=NoiseSource.FIT, correlation_length=1000, fitting=NoiseFitConfig())
HealpixConfig
dataclass
Configuration for a HEALPix output map.
Examples:
In a YAML config file:
healpix: nside: 512
Methods:
Attributes:
Source code in src/furax/mapmaking/config.py
nside = 512
class-attribute
instance-attribute
ordering = 'ring'
class-attribute
instance-attribute
__init__(nside=512, ordering='ring')
SkyPatch
dataclass
Explicit rectangular sky patch for WCS map construction.
Examples:
In a YAML config file:
patch: center: [30.0, -10.0] # ra, dec in degrees width: 20.0 height: 10.0
Methods:
-
__init__–
Attributes:
-
center(tuple[float, float]) –Center
(ra, dec)in degrees. -
width(float) –Width in degrees.
-
height(float) –Height in degrees.
Source code in src/furax/mapmaking/config.py
center
instance-attribute
Center (ra, dec) in degrees.
width
instance-attribute
Width in degrees.
height
instance-attribute
Height in degrees.
__init__(center, width, height)
WCSConfig
dataclass
Configuration for a WCS-projected output map.
projection applies to all modes except geometry_file, where it is read from the file.
The map extent is determined by exactly one of three mutually exclusive modes:
- geometry_file: read shape and WCS directly from a FITS/HDF file via
pixell.enmap.read_map_geometry. All other fields are ignored. - patch: build a rectangular patch of sky at the given
resolution. - auto (no geometry specified): scan the observations to compute each observation's
bounding box, take their union, and pixelise at the given
resolution.
Examples:
In a YAML config file:
Auto footprint at 4 arcmin resolution
car: resolution: 4.0
Explicit patch
car: resolution: 4.0 patch: center: [30.0, -10.0] width: 20.0 height: 10.0
Geometry from file
car: geometry_file: /path/to/map.fits
Methods:
Attributes:
-
projection(ProjectionType) –WCS projection type.
-
resolution(float) –Pixel resolution in arcminutes.
-
geometry_file(str | None) –Path to a FITS or HDF map file from which to read the output geometry.
-
patch(SkyPatch | None) –Explicit sky patch definition. Mutually exclusive with
geometry_file. -
has_geometry(bool) –
Source code in src/furax/mapmaking/config.py
projection = ProjectionType.CAR
class-attribute
instance-attribute
WCS projection type.
resolution = 4.0
class-attribute
instance-attribute
Pixel resolution in arcminutes.
geometry_file = None
class-attribute
instance-attribute
Path to a FITS or HDF map file from which to read the output geometry.
patch = None
class-attribute
instance-attribute
Explicit sky patch definition. Mutually exclusive with geometry_file.
has_geometry
property
__init__(projection=ProjectionType.CAR, resolution=4.0, geometry_file=None, patch=None)
LandscapeConfig
dataclass
Methods:
Attributes:
-
stokes(ValidStokesType) – -
healpix(HealpixConfig | None) – -
wcs(WCSConfig | None) –
Source code in src/furax/mapmaking/config.py
stokes = 'IQU'
class-attribute
instance-attribute
healpix = None
class-attribute
instance-attribute
wcs = None
class-attribute
instance-attribute
__init__(stokes='IQU', healpix=None, wcs=None)
PolynomialOrders
Bases: NamedTuple
A polynomial order range, inclusive.
Attributes:
Source code in src/furax/mapmaking/config.py
min_order = 0
class-attribute
instance-attribute
max_order = 3
class-attribute
instance-attribute
n_orders
property
Number of orders in the inclusive range.
BinsConfig
dataclass
A piecewise basis that bins a variable into n_bins intervals.
With interpolate = False each sample is hard-assigned to its bin. With
interpolate = True samples are spread over neighbouring bin centres using
triangular (or, if smooth, sin^2) weights.
Methods:
-
__init__–
Attributes:
Source code in src/furax/mapmaking/config.py
n_bins = 4
class-attribute
instance-attribute
interpolate = False
class-attribute
instance-attribute
smooth = False
class-attribute
instance-attribute
__init__(n_bins=4, interpolate=False, smooth=False)
PolynomialConfig
dataclass
Methods:
-
__init__–
Attributes:
-
legendre(PolynomialOrders) –Legendre orders for the polynomial drift template.
Source code in src/furax/mapmaking/config.py
legendre = PolynomialOrders(0, 3)
class-attribute
instance-attribute
Legendre orders for the polynomial drift template.
__init__(legendre=PolynomialOrders(0, 3))
ScanSynchronousConfig
dataclass
Scan-synchronous signal on a global Legendre basis.
Represents signals that depend only on the telescope's azimuth.
Methods:
-
__init__–
Attributes:
Source code in src/furax/mapmaking/config.py
legendre = PolynomialOrders(3, 7)
class-attribute
instance-attribute
__init__(legendre=PolynomialOrders(3, 7))
BinAzSynchronousConfig
dataclass
Binned azimuth-synchronous signal, no HWP coupling.
The binned counterpart of ScanSynchronousConfig.
Methods:
-
__init__–
Attributes:
-
bins(BinsConfig) –
Source code in src/furax/mapmaking/config.py
bins = field(default_factory=BinsConfig)
class-attribute
instance-attribute
__init__(bins=BinsConfig())
HWPSynchronousConfig
dataclass
AzHWPSynchronousConfig
dataclass
Methods:
-
__init__–
Attributes:
-
legendre(PolynomialOrders) – -
n_harmonics(int) – -
split_scans(bool) –
Source code in src/furax/mapmaking/config.py
legendre = PolynomialOrders(0, 3)
class-attribute
instance-attribute
n_harmonics = 4
class-attribute
instance-attribute
split_scans = False
class-attribute
instance-attribute
__init__(legendre=PolynomialOrders(0, 3), n_harmonics=4, split_scans=False)
BinAzHWPSynchronousConfig
dataclass
Methods:
-
__init__–
Attributes:
-
bins(BinsConfig) – -
n_harmonics(int) –
Source code in src/furax/mapmaking/config.py
bins = field(default_factory=BinsConfig)
class-attribute
instance-attribute
n_harmonics = 4
class-attribute
instance-attribute
__init__(bins=BinsConfig(), n_harmonics=4)
SplineHWPSSConfig
dataclass
Methods:
-
__init__– -
__post_init__– -
resolve_n_knots–Number of spline knots for
n_samplessamples (at least 2).
Attributes:
-
n_knots(int | None) –Number of spline knots. If set, takes precedence over samples_per_knot.
-
samples_per_knot(int | None) –Number of samples per knot. Defaults to 4000.
-
harmonics(tuple[int, ...]) –HWP harmonics to fit with splines. Defaults to (4,).
Source code in src/furax/mapmaking/config.py
n_knots = None
class-attribute
instance-attribute
Number of spline knots. If set, takes precedence over samples_per_knot.
samples_per_knot = 4000
class-attribute
instance-attribute
Number of samples per knot. Defaults to 4000.
harmonics = (4,)
class-attribute
instance-attribute
HWP harmonics to fit with splines. Defaults to (4,).
__init__(n_knots=None, samples_per_knot=4000, harmonics=(4,))
__post_init__()
resolve_n_knots(n_samples)
Number of spline knots for n_samples samples (at least 2).
Uses n_knots directly when set, otherwise derives it from samples_per_knot.
Source code in src/furax/mapmaking/config.py
GroundConfig
dataclass
Methods:
-
__init__–
Attributes:
Source code in src/furax/mapmaking/config.py
azimuth_resolution = 0.05
class-attribute
instance-attribute
elevation_resolution = 0.05
class-attribute
instance-attribute
__init__(azimuth_resolution=0.05, elevation_resolution=0.05)
TemplatesConfig
dataclass
Methods:
-
__init__– -
full_defaults–Create a template config with default values for all templates.
Attributes:
-
polynomial(PolynomialConfig | None) – -
scan_synchronous(ScanSynchronousConfig | None) – -
binaz_synchronous(BinAzSynchronousConfig | None) – -
hwp_synchronous(HWPSynchronousConfig | None) – -
azhwp_synchronous(AzHWPSynchronousConfig | None) – -
binazhwp_synchronous(BinAzHWPSynchronousConfig | None) – -
spline_hwpss(SplineHWPSSConfig | None) – -
ground(GroundConfig | None) – -
regularization(float) – -
empty(bool) –
Source code in src/furax/mapmaking/config.py
polynomial = None
class-attribute
instance-attribute
scan_synchronous = None
class-attribute
instance-attribute
binaz_synchronous = None
class-attribute
instance-attribute
hwp_synchronous = None
class-attribute
instance-attribute
azhwp_synchronous = None
class-attribute
instance-attribute
binazhwp_synchronous = None
class-attribute
instance-attribute
spline_hwpss = None
class-attribute
instance-attribute
ground = None
class-attribute
instance-attribute
regularization = 0.0
class-attribute
instance-attribute
empty
property
__init__(polynomial=None, scan_synchronous=None, binaz_synchronous=None, hwp_synchronous=None, azhwp_synchronous=None, binazhwp_synchronous=None, spline_hwpss=None, ground=None, regularization=0.0)
full_defaults()
classmethod
Create a template config with default values for all templates.
Source code in src/furax/mapmaking/config.py
GapFillingConfig
dataclass
Specific gap-filling options.
Methods:
-
__init__–
Attributes:
-
seed(int) –An integer seed for the noise realization
-
max_steps(int) –The maximum number of iteration steps to invert the system
-
rtol(float) –The relative tolerance of the solver for the gap-filling solve
-
precondition(bool) –Precondition the flagged-subspace solve with the covariance from the noise model.
Source code in src/furax/mapmaking/config.py
seed = 286502183
class-attribute
instance-attribute
An integer seed for the noise realization
max_steps = 50
class-attribute
instance-attribute
The maximum number of iteration steps to invert the system
rtol = 0.0001
class-attribute
instance-attribute
The relative tolerance of the solver for the gap-filling solve
precondition = False
class-attribute
instance-attribute
Precondition the flagged-subspace solve with the covariance from the noise model.
Off by default: it speeds up convergence only for few gaps wider than the correlation length, and slows the common case of many short gaps (turnarounds/glitches) where the bare system is already well-conditioned. Enable for observations dominated by a few wide gaps.
__init__(seed=286502183, max_steps=50, rtol=0.0001, precondition=False)
NestedConfig
dataclass
Inner-solver options for the nested-inverse gap weight (GapTreatment.NESTED).
Methods:
-
__init__–
Attributes:
-
max_flag_fraction(float) –Flagged-fraction budget; observations flagged above this fall back to INNER_MASK.
-
inner_steps(int) –Fixed number of inner CG iterations for the flagged-block solve.
-
rtol(float) –Relative tolerance of the inner solver (0 forces exactly
inner_stepsiterations). -
atol(float) –Absolute tolerance of the inner solver (0 forces exactly
inner_stepsiterations). -
precondition(bool) –Precondition the inner flagged-block CG with the covariance from the noise model.
Source code in src/furax/mapmaking/config.py
max_flag_fraction = 0.3
class-attribute
instance-attribute
Flagged-fraction budget; observations flagged above this fall back to INNER_MASK.
inner_steps = 20
class-attribute
instance-attribute
Fixed number of inner CG iterations for the flagged-block solve.
rtol = 0.0
class-attribute
instance-attribute
Relative tolerance of the inner solver (0 forces exactly inner_steps iterations).
atol = 0.0
class-attribute
instance-attribute
Absolute tolerance of the inner solver (0 forces exactly inner_steps iterations).
precondition = False
class-attribute
instance-attribute
Precondition the inner flagged-block CG with the covariance from the noise model.
Off by default: it helps only for few gaps wider than the correlation length, and slows the common case of many short gaps (turnarounds/glitches) where the bare inner block is already well-conditioned. Enable for observations dominated by a few wide gaps.
__init__(max_flag_fraction=0.3, inner_steps=20, rtol=0.0, atol=0.0, precondition=False)
GapsConfig
dataclass
Configuration options related to the treatment of gaps.
Methods:
-
__init__–
Attributes:
-
treatment(GapTreatment) –How flagged samples enter the weighting (see
GapTreatment). -
fill_options(GapFillingConfig) –Options to pass to the gap-filling operator (used when
treatmentisFILL). -
nested(NestedConfig) –Inner-solver options (used when
treatmentisNESTED).
Source code in src/furax/mapmaking/config.py
treatment = GapTreatment.FILL
class-attribute
instance-attribute
How flagged samples enter the weighting (see GapTreatment).
fill_options = field(default_factory=GapFillingConfig)
class-attribute
instance-attribute
Options to pass to the gap-filling operator (used when treatment is FILL).
nested = field(default_factory=NestedConfig)
class-attribute
instance-attribute
Inner-solver options (used when treatment is NESTED).
__init__(treatment=GapTreatment.FILL, fill_options=GapFillingConfig(), nested=NestedConfig())
PointingConfig
dataclass
Configuration options for pointing computation.
interpolation controls how the sky map is sampled:
'nearest': nearest-neighbor (default, fastest).'bilinear': bilinear interpolation using the four nearest pixels.
Methods:
-
__init__–
Attributes:
-
on_the_fly(bool) –Compute pointing on the fly instead of pre-computing pixel indices.
-
batch_size(int) –Detector batch size for on-the-fly pointing (set to 0 to use a full batch).
-
interpolation(Literal['nearest', 'bilinear']) –Pixel interpolation scheme used when sampling the sky map.
Source code in src/furax/mapmaking/config.py
on_the_fly = True
class-attribute
instance-attribute
Compute pointing on the fly instead of pre-computing pixel indices.
batch_size = 32
class-attribute
instance-attribute
Detector batch size for on-the-fly pointing (set to 0 to use a full batch).
interpolation = 'nearest'
class-attribute
instance-attribute
Pixel interpolation scheme used when sampling the sky map.
__init__(on_the_fly=True, batch_size=32, interpolation='nearest')
SotodlibConfig
dataclass
Configuration options specific to the sotodlib interface.
Methods:
-
__init__–
Attributes:
-
site(Literal['so', 'so_sat1', 'so_sat2', 'so_sat3', 'so_lat']) –Observatory site identifier
-
weather(Literal['toco', 'typical']) –Atmospheric condition tag for so3g sightline model
-
demodulated(bool) –Use demodulated TODs (HWP-specific data from sotodlib preprocessing).
-
wobble_correction(bool) –Apply HWP wobble correction to the line of sight.
-
noise_source(Literal['preprocess', 'mapmaking']) –Which precomputed noise model to use when fit_noise_model is False.
Source code in src/furax/mapmaking/config.py
site = 'so'
class-attribute
instance-attribute
Observatory site identifier
weather = 'toco'
class-attribute
instance-attribute
Atmospheric condition tag for so3g sightline model
demodulated = False
class-attribute
instance-attribute
Use demodulated TODs (HWP-specific data from sotodlib preprocessing).
wobble_correction = False
class-attribute
instance-attribute
Apply HWP wobble correction to the line of sight.
noise_source = 'preprocess'
class-attribute
instance-attribute
Which precomputed noise model to use when fit_noise_model is False.
'preprocess': use per-stoke noise fits (noiseT, noiseQ, noiseU) from preprocessing. 'mapmaking': use the white noise estimate from noiseQ_mapmaking.
__init__(site='so', weather='toco', demodulated=False, wobble_correction=False, noise_source='preprocess')
MapMakingConfig
dataclass
Methods:
-
__init__– -
for_method–Return a default MapMakingConfig pre-configured for the given method.
-
full_defaults–Create a config with default values for all fields including optional ones.
-
load_yaml–Load and instantiate a
MapMakingConfigfrom a YAML file. -
load_dict–Load and instantiate a
MapMakingConfigfrom a dictionary. -
dump_yaml–Dump the config to a YAML file.
Attributes:
-
method(Methods) – -
scanning_mask(bool) – -
sample_mask(bool) – -
hits_cut(float) – -
cond_cut(float) – -
double_precision(bool) – -
pointing(PointingConfig) – -
weighting(WeightingConfig) – -
debug(bool) – -
solver(SolverConfig) – -
gaps(GapsConfig) – -
landscape(LandscapeConfig) – -
templates(TemplatesConfig | None) – -
atop_tau(int) – -
sotodlib(SotodlibConfig | None) – -
binned(bool) – -
demodulated(bool) – -
use_templates(bool) – -
dtype(DTypeLike) –
Source code in src/furax/mapmaking/config.py
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | |
method = Methods.BINNED
class-attribute
instance-attribute
scanning_mask = False
class-attribute
instance-attribute
sample_mask = False
class-attribute
instance-attribute
hits_cut = 0.01
class-attribute
instance-attribute
cond_cut = 0.01
class-attribute
instance-attribute
double_precision = True
class-attribute
instance-attribute
pointing = field(default_factory=PointingConfig)
class-attribute
instance-attribute
weighting = field(default_factory=WeightingConfig)
class-attribute
instance-attribute
debug = True
class-attribute
instance-attribute
solver = field(default_factory=SolverConfig)
class-attribute
instance-attribute
gaps = field(default_factory=GapsConfig)
class-attribute
instance-attribute
landscape = field(default_factory=(lambda: LandscapeConfig(healpix=(HealpixConfig()))))
class-attribute
instance-attribute
templates = None
class-attribute
instance-attribute
atop_tau = 0
class-attribute
instance-attribute
sotodlib = None
class-attribute
instance-attribute
binned
property
demodulated
property
use_templates
property
dtype
property
__init__(method=Methods.BINNED, scanning_mask=False, sample_mask=False, hits_cut=0.01, cond_cut=0.01, double_precision=True, pointing=PointingConfig(), weighting=WeightingConfig(), debug=True, solver=SolverConfig(), gaps=GapsConfig(), landscape=(lambda: LandscapeConfig(healpix=(HealpixConfig())))(), templates=None, atop_tau=0, sotodlib=None)
for_method(method)
classmethod
Return a default MapMakingConfig pre-configured for the given method.
Parameters:
-
method(Methods | str) –A
Methodsenum value or its string name (e.g.'binned','ml','twostep','atop'), case-insensitive.
Source code in src/furax/mapmaking/config.py
full_defaults()
classmethod
Create a config with default values for all fields including optional ones.
load_yaml(path)
classmethod
Load and instantiate a MapMakingConfig from a YAML file.
load_dict(data)
classmethod
Load and instantiate a MapMakingConfig from a dictionary.
dump_yaml(path)
Dump the config to a YAML file.
The '.yaml' suffix is automatically added if not already present.
Source code in src/furax/mapmaking/config.py
furax.mapmaking.gap_filling
Functions:
-
gap_fill–Fill flagged time samples with a constrained noise realization, leaving good samples unchanged.
-
generate_noise_realization–Generates a Gaussian noise realization with the given covariance.
gap_fill(key, x, ninv, mask, *, rate=1.0, max_cg_steps=50, rtol=0.0001, atol=0.0, preconditioner=None, metadata=None)
Fill flagged time samples with a constrained noise realization, leaving good samples unchanged.
Replaces each flagged sample with a draw from the noise model conditioned on the surrounding good data (a constrained realization), so the gap is filled consistently with the noise correlations rather than by interpolation. The fill is a free realization \(\xi\) plus a correction that pins the good samples back to their data values:
where \(M_b\) masks the flagged samples. Three things to note:
- Good samples are returned bit-exact; only the gaps change.
- The CG solve acts only on the flagged subspace.
- \(\xi\) is drawn from \(N\), obtained as the reciprocal of the inverse-noise PSD.
For a few gaps wider than the correlation length the bare \(M_b N^{-1} M_b\) system is
ill-conditioned; passing the flagged-block covariance \(M_b N M_b\) as preconditioner,
i.e. mask.complement() @ cov @ mask.complement() with cov a cheap approximation of
\(N\) (its banded/Fourier form), then helps a lot. Its product with the system operator
differs from the identity by a boundary term of rank \(\approx 2\times\) (correlation
bandwidth) \(\times\) (number of gaps), and CG converges in roughly that many steps.
This is only worthwhile when that rank is below the iteration count of the bare system. For
the common case of many short gaps (turnarounds, glitches) the gaps are shorter than the
correlation length, the bare flagged block is already well-conditioned, and preconditioning is a
net loss -- leave preconditioner=None there. The preconditioner must be symmetric positive
definite and live in the flagged subspace (zero on the good samples).
Parameters:
-
key(Key[Array, '']) –A PRNG key generated by the user.
-
x(PyTree[Float[Array, ' *shape']]) –The time-ordered vector to be filled.
-
ninv(AbstractLinearOperator) –The inverse-noise operator \(N^{-1}\).
-
mask(MaskOperator) –The good-sample mask \(M\); its zeros are the gaps.
-
rate(ArrayLike, default:1.0) –The sampling rate of the data.
-
max_cg_steps(int, default:50) –Maximum number of CG steps for the flagged-subspace solve.
-
rtol(float, default:0.0001) –Relative convergence tolerance for the solver.
-
atol(float, default:0.0) –Absolute convergence tolerance for the solver.
-
preconditioner(AbstractLinearOperator | None, default:None) –Optional SPD preconditioner for the flagged-subspace CG (see above).
-
metadata(HashedObservationMetadata | None, default:None) –Metadata folded into the random key for reproducibility.
Returns:
-
PyTree[Float[Array, ' *shape']]–xwith its flagged samples replaced by the constrained realization.
Examples:
Gap-filling a single-detector timestream
>>> key = jax.random.key(0)
>>> ndet, nsamples = 3, 10
>>> x = jax.random.normal(key, (ndet, nsamples))
>>> in_structure = jax.ShapeDtypeStruct(x.shape, x.dtype)
>>> good = jnp.broadcast_to(
... jnp.array([1, 1, 1, 0, 0, 1, 1, 1, 1, 1], dtype=bool), x.shape
... )
>>> mask = MaskOperator.from_boolean_mask(good, in_structure=in_structure)
>>> ninv = SymmetricBandToeplitzOperator(jnp.array([1.0]), in_structure=in_structure)
>>> cov = SymmetricBandToeplitzOperator(jnp.array([1.0]), in_structure=in_structure) # N ≈ cov
>>> preconditioner = (mask.complement() @ cov @ mask.complement()).reduce()
>>> filled = gap_fill(key, x, ninv, mask, preconditioner=preconditioner)
>>> assert jnp.all(filled[good] == x[good])
Source code in src/furax/mapmaking/gap_filling.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
generate_noise_realization(key, cov, fsamp, metadata=None, *, inverse=False)
Generates a Gaussian noise realization with the given covariance.
Parameters:
-
key(Key[Array, '']) –A PRNG key generated by the user.
-
cov(FourierOperator | SymmetricBandToeplitzOperator | BlockDiagonalOperator) –The noise covariance operator (
N), or -- withinverse=True-- the inverse-noise operator (N⁻¹), in which case the realization is drawn from the reciprocal PSD. The operator's structure is the output structure of this function. -
metadata(HashedObservationMetadata | None, default:None) –Metadata that are folded into the random key.
-
fsamp(ArrayLike) –The sampling frequency of the data (recommended for correct normalization).
-
inverse(bool, default:False) –If
True,covisN⁻¹and the PSD is reciprocated before sampling.
Source code in src/furax/mapmaking/gap_filling.py
furax.mapmaking.mapmaker
Classes:
-
MultiObservationMapMaker–Class for mapping multiple observations together.
-
MapMaker–Class for generic mapmakers which consume GroundObservationData.
-
BinnedMapMaker–Class for mapmaking with diagonal noise covariance.
-
MLMapmaker–Class for mapmaking with maximum likelihood (ML) estimator.
-
TwoStepMapmaker–Class for binned mapmaking with templates, using the two-step estimation method.
-
ATOPMapMaker–Class for ATOP mapmaking with diagonal noise covariance.
-
IQUModulationOperator–Add the input Stokes signals into a single HWP-modulated signal.
-
QUModulationOperator–Add the input Stokes signals into a single HWP-modulated signal.
Functions:
-
get_obs_distribution_to_process–Compute this process's slice for distributed mapmaking.
Attributes:
-
T–
T = TypeVar('T')
module-attribute
MultiObservationMapMaker
Class for mapping multiple observations together.
Methods:
-
__init__– -
distribute–Shard a pytree of process-local arrays along the leading 'obs' axis.
-
get_padded_read_indices– -
get_reader–Build an ObservationReader for this process's local observations.
-
run–Runs the mapmaker and return results after saving them to the given directory.
-
make_maps–Computes the mapmaker results (maps and other products).
-
build_model_and_accumulate–Build the model and accumulate the hit map and RHS in a single, sharded read pass.
-
get_system_operator– -
pixel_selection–Compute pixel selection according to hit and condition number cuts.
Attributes:
-
observations– -
config– -
logger– -
landscape– -
reader– -
mesh(Mesh) – -
sharding(NamedSharding) – -
n_observations(int) –Total number of observations across all processes.
-
obs_distribution(tuple[int, int, int]) –(start, n_owned, n_pad)for this process.
Source code in src/furax/mapmaking/mapmaker.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | |
observations = observations
instance-attribute
config = config or MapMakingConfig()
instance-attribute
logger = logger or furax_logger
instance-attribute
landscape = _static_landscape(self.config.landscape, self.config.dtype) or self._scan_wcs_footprint()
instance-attribute
reader = self.get_reader(model_fields | rhs_fields)
instance-attribute
mesh
cached
property
sharding
property
n_observations
property
Total number of observations across all processes.
obs_distribution
property
(start, n_owned, n_pad) for this process.
__init__(observations, config=None, logger=None)
Source code in src/furax/mapmaking/mapmaker.py
distribute(x)
Shard a pytree of process-local arrays along the leading 'obs' axis.
get_padded_read_indices()
get_reader(required_fields)
Build an ObservationReader for this process's local observations.
Source code in src/furax/mapmaking/mapmaker.py
run(out_dir=None)
Runs the mapmaker and return results after saving them to the given directory.
Source code in src/furax/mapmaking/mapmaker.py
make_maps()
Computes the mapmaker results (maps and other products).
Source code in src/furax/mapmaking/mapmaker.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | |
build_model_and_accumulate()
Build the model and accumulate the hit map and RHS in a single, sharded read pass.
Sharded over observations: each observation is read (and, for preproc-backed observations,
preprocessed) exactly once, and contributes to the model, the hit map and the RHS from that
single read. This avoids reading every observation twice (once to build the model, once to
accumulate the RHS). The hit map and RHS are reduced across all processes with psum
inside the kernel.
Observations that contribute nothing -- padding (added so every device carries the same
workload) and failed loads (the preprocessing pipeline raised) -- are gated out by zeroing
their masker inside the kernel, so they drop out of the hit map, the RHS, and the CG system
operator alike. Failed loads are reported afterwards from self.reader.failed_indices
(see make_maps).
Must run under jax.set_mesh(self.mesh).
Returns (model, hits, rhs) with the model sharded along the observation axis and the
hit map / RHS replicated (already reduced across processes).
Source code in src/furax/mapmaking/mapmaker.py
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
get_system_operator(model, *, diag=False)
Source code in src/furax/mapmaking/mapmaker.py
pixel_selection(hits, weights)
Compute pixel selection according to hit and condition number cuts.
Source code in src/furax/mapmaking/mapmaker.py
MapMaker
dataclass
Class for generic mapmakers which consume GroundObservationData.
Methods:
-
__init__– -
__post_init__– -
make_map– -
run– -
from_config–Return the appropriate mapmaker based on the config's mapmaking method.
-
from_yaml– -
get_landscape–Landscape used for mapmaking with given observation.
-
get_pointing–Operator containing pointing information for given observation.
-
get_acquisition–Acquisition operator mapping sky maps to time-ordered data.
-
get_scanning_masker–Select only the scanning intervals of the given TOD.
-
get_scanning_mask_projector–Zero the values outside the scanning intervals of the given TOD.
-
get_sample_mask_projector–Zero the given TOD at masked (flagged) samples.
-
get_mask_projector–Mask operator which incorporates both the scanning and sample mask projectors.
-
get_or_fit_noise_model–Return a noise model for the observation.
-
get_pixel_selector–Select indices of map pixels satisfying the hit and condition-number cuts.
-
get_template_operator–Create a template operator from the provided name and configuration.
Attributes:
-
config(MapMakingConfig) – -
logger(Logger) –
Source code in src/furax/mapmaking/mapmaker.py
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | |
config
instance-attribute
logger = furax_logger
class-attribute
instance-attribute
__init__(config, logger=furax_logger)
__post_init__()
make_map(observation)
abstractmethod
run(observation, out_dir)
Source code in src/furax/mapmaking/mapmaker.py
from_config(config, logger=None)
classmethod
Return the appropriate mapmaker based on the config's mapmaking method.
Source code in src/furax/mapmaking/mapmaker.py
from_yaml(path, logger=None)
classmethod
get_landscape(observation)
Landscape used for mapmaking with given observation.
Source code in src/furax/mapmaking/mapmaker.py
get_pointing(observation, landscape)
Operator containing pointing information for given observation.
Source code in src/furax/mapmaking/mapmaker.py
get_acquisition(observation, landscape)
Acquisition operator mapping sky maps to time-ordered data.
Source code in src/furax/mapmaking/mapmaker.py
get_scanning_masker(observation)
Select only the scanning intervals of the given TOD.
The TOD has shape (ndets, nsamps).
Source code in src/furax/mapmaking/mapmaker.py
get_scanning_mask_projector(observation)
Zero the values outside the scanning intervals of the given TOD.
The TOD has shape (ndets, nsamps).
Source code in src/furax/mapmaking/mapmaker.py
get_sample_mask_projector(observation)
Zero the given TOD at masked (flagged) samples.
The TOD has shape (ndets, nsamps).
Source code in src/furax/mapmaking/mapmaker.py
get_mask_projector(observation)
Mask operator which incorporates both the scanning and sample mask projectors.
Source code in src/furax/mapmaking/mapmaker.py
get_or_fit_noise_model(observation)
Return a noise model for the observation.
The model type (diagonal, toeplitz, ...) is specified by the mapmaker. Attempts to load the noise model from the data if available, but otherwise fits a model to the data.
Source code in src/furax/mapmaking/mapmaker.py
get_pixel_selector(blocks, landscape)
Select indices of map pixels satisfying the hit and condition-number cuts.
Pixels must meet the minimum fractional hits (hits_cut) and condition number (cond_cut) criteria.
Source code in src/furax/mapmaking/mapmaker.py
get_template_operator(observation)
Create a template operator from the provided name and configuration.
Source code in src/furax/mapmaking/mapmaker.py
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | |
BinnedMapMaker
dataclass
Bases: MapMaker
Class for mapmaking with diagonal noise covariance.
Methods:
Source code in src/furax/mapmaking/mapmaker.py
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | |
__post_init__()
make_map(observation)
Source code in src/furax/mapmaking/mapmaker.py
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | |
MLMapmaker
dataclass
Bases: MapMaker
Class for mapmaking with maximum likelihood (ML) estimator.
Methods:
Source code in src/furax/mapmaking/mapmaker.py
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | |
__post_init__()
Source code in src/furax/mapmaking/mapmaker.py
make_map(observation)
Source code in src/furax/mapmaking/mapmaker.py
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | |
TwoStepMapmaker
dataclass
Bases: MapMaker
Class for binned mapmaking with templates, using the two-step estimation method.
Methods:
Source code in src/furax/mapmaking/mapmaker.py
1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 | |
__post_init__()
Source code in src/furax/mapmaking/mapmaker.py
make_map(observation)
Source code in src/furax/mapmaking/mapmaker.py
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 | |
ATOPMapMaker
dataclass
Bases: MapMaker
Class for ATOP mapmaking with diagonal noise covariance.
Methods:
Source code in src/furax/mapmaking/mapmaker.py
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | |
__post_init__()
Source code in src/furax/mapmaking/mapmaker.py
make_map(observation)
Source code in src/furax/mapmaking/mapmaker.py
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | |
IQUModulationOperator
Bases: AbstractLinearOperator
Add the input Stokes signals into a single HWP-modulated signal.
Similar to LinearPolarizerOperator @ QURotationOperator(hwp_angle), except that
only half of the QU rotation needs to be computed.
Methods:
Attributes:
-
cos_hwp_angle(Float[Array, ' samps']) – -
sin_hwp_angle(Float[Array, ' samps']) –
Source code in src/furax/mapmaking/mapmaker.py
cos_hwp_angle
instance-attribute
sin_hwp_angle
instance-attribute
__init__(shape, hwp_angle, dtype=jnp.float32)
Source code in src/furax/mapmaking/mapmaker.py
QUModulationOperator
Bases: AbstractLinearOperator
Add the input Stokes signals into a single HWP-modulated signal.
Similar to LinearPolarizerOperator @ QURotationOperator(hwp_angle), except that
only half of the QU rotation needs to be computed.
Methods:
Attributes:
-
cos_hwp_angle(Float[Array, ' samps']) – -
sin_hwp_angle(Float[Array, ' samps']) –
Source code in src/furax/mapmaking/mapmaker.py
cos_hwp_angle
instance-attribute
sin_hwp_angle
instance-attribute
__init__(shape, hwp_angle, dtype=jnp.float32)
Source code in src/furax/mapmaking/mapmaker.py
get_obs_distribution_to_process(n_obs, rank=None, n_proc=None, n_local=None)
Compute this process's slice for distributed mapmaking.
Distributes n_obs observations across processes as evenly as possible
(first n_obs % n_proc processes get one extra), then pads each process's
share to the next multiple of n_local so every device has a uniform
workload. All processes end up with the same number of total slots
(n_owned + n_pad), which is required for multi-process sharding.
Parameters:
-
n_obs(int) –Total number of observations across all processes.
-
rank(int | None, default:None) –Process index. Defaults to
jax.process_index(). -
n_proc(int | None, default:None) –Process count. Defaults to
jax.process_count(). -
n_local(int | None, default:None) –Local device count. Defaults to
jax.local_device_count().
Returns:
-
int–A tuple
(start, n_owned, n_pad)wherestartis the index of the -
int–first real observation owned by this process,
n_ownedis the number -
int–of real observations, and
n_padis the number of padding slots so that -
tuple[int, int, int]–n_owned + n_padis a multiple ofn_local.
Raises:
-
ValueError–If
n_obs < n_proc.
Source code in src/furax/mapmaking/mapmaker.py
furax.mapmaking.noise
Classes:
-
NoiseModel–Dataclass for noise models used for ground observation data.
-
WhiteNoiseModel–Dataclass for the white noise model used for ground observation data.
-
AtmosphericNoiseModel–Dataclass for the 1/f noise model used for ground observation data.
Functions:
-
apodization_window– -
fit_white_noise_model–Fit a white noise model to the periodogram in log space.
-
fit_atmospheric_psd_model–Fit a 1/f PSD model to the periodogram in log space.
NoiseModel
dataclass
Bases: ABC
Dataclass for noise models used for ground observation data.
Methods:
-
__init__– -
psd– -
log_psd– -
to_array– -
operator– -
inverse_operator– -
to_white_noise_model– -
to_operator_fourier–Fourier operator representation of the noise model.
-
l2_loss–l2 loss in log-log spacea with given frequency mask.
Attributes:
-
n_detectors(int) –
Source code in src/furax/mapmaking/noise.py
n_detectors
abstractmethod
property
__init__()
psd(f)
abstractmethod
log_psd(f)
abstractmethod
to_array()
abstractmethod
operator(in_structure, **kwargs)
abstractmethod
inverse_operator(in_structure, **kwargs)
abstractmethod
to_white_noise_model()
abstractmethod
to_operator_fourier(in_structure, *, sample_rate, inverse=True)
Fourier operator representation of the noise model.
Source code in src/furax/mapmaking/noise.py
l2_loss(f, Pxx, mask)
l2 loss in log-log spacea with given frequency mask.
Source code in src/furax/mapmaking/noise.py
WhiteNoiseModel
dataclass
Bases: NoiseModel
Dataclass for the white noise model used for ground observation data.
Methods:
-
__init__– -
psd– -
log_psd– -
to_array– -
operator– -
inverse_operator– -
to_white_noise_model– -
fit_psd_model–Fit a white noise model to data.
Attributes:
-
sigma(Float[Array, ' dets']) – -
n_detectors(int) –
Source code in src/furax/mapmaking/noise.py
sigma
instance-attribute
n_detectors
property
__init__(sigma)
psd(f)
log_psd(f)
to_array()
operator(in_structure, **kwargs)
Source code in src/furax/mapmaking/noise.py
inverse_operator(in_structure, **kwargs)
Source code in src/furax/mapmaking/noise.py
to_white_noise_model()
fit_psd_model(f, Pxx, sample_rate, hwp_frequency, config=None)
classmethod
Fit a white noise model to data.
Source code in src/furax/mapmaking/noise.py
AtmosphericNoiseModel
dataclass
Bases: NoiseModel
Dataclass for the 1/f noise model used for ground observation data.
Methods:
-
__init__– -
psd– -
log_psd– -
to_array– -
operator–Build a Toeplitz operator from the autocorrelation function.
-
inverse_operator–Build a Toeplitz operator from the inverse autocorrelation function.
-
to_white_noise_model– -
fit_psd_model–Fit a atmospheric (1/f) noise model to data.
Attributes:
-
sigma(Float[Array, ' dets']) – -
alpha(Float[Array, ' dets']) – -
fk(Float[Array, ' dets']) – -
f0(Float[Array, ' dets']) – -
n_detectors(int) –
Source code in src/furax/mapmaking/noise.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | |
sigma
instance-attribute
alpha
instance-attribute
fk
instance-attribute
f0
instance-attribute
n_detectors
property
__init__(sigma, alpha, fk, f0)
psd(f)
Source code in src/furax/mapmaking/noise.py
log_psd(f)
to_array()
operator(in_structure, **kwargs)
Build a Toeplitz operator from the autocorrelation function.
The autocorrelation is evaluated via inverse FFT of the noise PSD, which is apodized and cut at the given length.
Source code in src/furax/mapmaking/noise.py
inverse_operator(in_structure, **kwargs)
Build a Toeplitz operator from the inverse autocorrelation function.
The inverse autocorrelation is evaluated via inverse FFT of the noise PSD, which is apodized and cut at the given length.
Source code in src/furax/mapmaking/noise.py
to_white_noise_model()
fit_psd_model(f, Pxx, sample_rate, hwp_frequency, config=None)
classmethod
Fit a atmospheric (1/f) noise model to data.
Source code in src/furax/mapmaking/noise.py
apodization_window(size, kind='chebwin')
Source code in src/furax/mapmaking/noise.py
fit_white_noise_model(f, Pxx, sample_rate, hwp_frequency, config=None)
Fit a white noise model to the periodogram in log space.
This function fits a model of the form
PSD(f) = sigma^2
where
- sigma: white noise level
Parameters:
-
f(Float[Array, ' freqs']) –Frequency array (Hz). Shape: (n_freq,)
-
Pxx(Float[Array, 'dets freqs']) –Power spectral density values. Shape: (n_detectors, n_freq)
-
sample_rate(Array) –Sampling rate of the timestream (Hz).
-
hwp_frequency(Array) –HWP rotation frequency (Hz)
-
config(NoiseFitConfig | None, default:None) –NoiseFitConfig instance
Returns:
-
dict[str, Any]–A dictionary containing following keys: fit: Array of fitted parameters [sigma]. Shape: (n_detectors, 1)
Source code in src/furax/mapmaking/noise.py
fit_atmospheric_psd_model(f, Pxx, sample_rate, hwp_frequency, config=None)
Fit a 1/f PSD model to the periodogram in log space.
This function fits a model of the form
PSD(f) = sigma^2 * (1 + ((f + f0) / f_knee)^alpha)
where
- sigma: white noise level
- alpha: power law index (typically negative)
- f_knee: knee frequency
- f0: minimum frequency offset
Parameters:
-
f(Float[Array, ' freqs']) –Frequency array (Hz). Shape: (n_freq,)
-
Pxx(Float[Array, 'dets freqs']) –Power spectral density values. Shape: (n_detectors, n_freq)
-
sample_rate(Array) –Sampling rate (Hz)
-
hwp_frequency(Array) –HWP rotation frequency (Hz)
-
config(NoiseFitConfig | None, default:None) –NoiseFitConfig instance
Returns:
-
dict[str, Any]–A dictionary containing following keys: fit: Array of fitted parameters [sigma, alpha, f_knee, f_min]. Shape: (n_detectors, 4) loss: Array containing loss function values (-2logL) evaluated at the fitted parameters. Shape: (n_detectors,) num_iter: Array containing number of iterations spent to obtain the fit. Shape: (n_detectors,) fisher: Array containing fisher matrix values for the fitted parameters. Shape: (n_detectors, 4, 4)
Source code in src/furax/mapmaking/noise.py
furax.mapmaking.pixell_utils
Functions:
-
ndmap_from_wcs_landscape–Convert a given Stokes pytree to pixell's ndmap.
-
plot_ndmap–Visualisation function for ndmap that replaces pixell.enplot.eshow for now.
-
plot_cartview–Visualisation function for CAR projection of healpix maps.
-
get_healpix_lonlat_ranges–Find appropriate longitude and latitude ranges for a HEALPix map.
ndmap_from_wcs_landscape(map, landscape)
Convert a given Stokes pytree to pixell's ndmap.
Source code in src/furax/mapmaking/pixell_utils.py
plot_ndmap(data, title=None, vmax=None, vmin=None, cmap='RdBu_r', scale=1.0, fig=None, ax=None)
Visualisation function for ndmap that replaces pixell.enplot.eshow for now.
Inputs
title: title of the produced plot vmax: value above this are mapped to the colormap's upper end vmin: value below this are mapped to the colormap's lower end cmap: colormap name in matplotlib scale: value range scale factor of the colormap, overridden if vmin or vmax is provided fig, ax: matplotlib figure and axes
Returns: fig, ax
Source code in src/furax/mapmaking/pixell_utils.py
plot_cartview(input_maps, titles=None, lonra=(-180, 180), latra=(-90, 90), xsize=800, cmap='RdBu', vmaxs=None, vmins=None, vmax_quantile=0.999, nside=None, fig=None, axs=None)
Visualisation function for CAR projection of healpix maps.
Unlike healpy.cartview, this function returns matplotlib Axes object, and one can have more control of the plot elements such as grids and axes labels.
Parameters:
-
input_maps(NDArray[Any]) –HEALPix map(s) to plot. Can be 1D (single map) or 2D (multiple maps)
-
titles(list[str] | str | None, default:None) –Title(s) for the plot(s)
-
lonra(tuple[float, float], default:(-180, 180)) –Longitude range [min, max] in degrees
-
latra(tuple[float, float], default:(-90, 90)) –Latitude range [min, max] in degrees
-
xsize(int, default:800) –Number of pixels in longitude direction
-
cmap(str, default:'RdBu') –Colormap name
-
vmaxs(list[float] | list[None] | None, default:None) –Maximum values for color scale (one per map)
-
vmins(list[float] | list[None] | None, default:None) –Minimum values for color scale (one per map)
-
vmax_quantile(float, default:0.999) –Quantile to use for automatic vmax determination
-
nside(int | None, default:None) –HEALPix nside parameter. If None, inferred from input_maps
-
fig(Figure | None, default:None) –matplotlib figure
-
axs(Axes | None, default:None) –matplotlib axes
Returns:
Source code in src/furax/mapmaking/pixell_utils.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
get_healpix_lonlat_ranges(healpix_map, nside=None, padding_deg=5.0, hit_threshold=1e-18)
Find appropriate longitude and latitude ranges for a HEALPix map.
This function identifies the sky region covered by non-zero pixels in a HEALPix map and returns appropriate longitude and latitude ranges for visualization.
Parameters:
-
healpix_map(NDArray[Any]) –HEALPix map array
-
nside(int | None, default:None) –HEALPix nside parameter. If None, inferred from map length
-
padding_deg(float, default:5.0) –Padding in degrees to add around the data region
-
hit_threshold(float, default:1e-18) –Minimum value to consider a pixel as having data
Returns:
-
tuple(tuple[list[float], list[float]]) –(lonra, latra) where lonra=[lon_min, lon_max] and latra=[lat_min, lat_max] Ranges are in degrees, suitable for use with plot_cartview()
Examples:
>>> import healpy as hp
>>> import numpy as np
>>> # Create a small patch map
>>> nside = 64
>>> npix = hp.nside2npix(nside)
>>> hpx_map = np.zeros(npix)
>>> # Add signal in a small region
>>> theta, phi = hp.pix2ang(nside, np.arange(1000, 2000))
>>> hpx_map[1000:2000] = 1.0
>>> lonra, latra = get_healpix_lonlat_ranges(hpx_map, nside)
>>> print(f"Longitude range: {lonra}")
>>> print(f"Latitude range: {latra}")
Source code in src/furax/mapmaking/pixell_utils.py
furax.mapmaking.preconditioner
Classes:
-
BJPreconditioner–Block-diagonal (per-pixel) Jacobi preconditioner for Stokes sky maps.
BJPreconditioner
Bases: AbstractLinearOperator
Block-diagonal (per-pixel) Jacobi preconditioner for Stokes sky maps.
Holds one dense (n, n) block per pixel (n = len(stokes)), coupling the Stokes
components at that pixel: blocks has shape (*sky, n, n) with blocks[..., i, j] the
response of output component i to input component j. Applied by an einsum over the
Stokes axis of the map's backing array; symmetric (self-adjoint) for a symmetric operator.
Methods:
-
__init__– -
create–Assemble the per-pixel blocks from a symmetric operator acting on Stokes sky maps.
-
mv– -
inverse–
Attributes:
-
blocks(Float[Array, '*sky n n']) –
Source code in src/furax/mapmaking/preconditioner.py
blocks
instance-attribute
__init__(blocks, *, in_structure)
create(op)
classmethod
Assemble the per-pixel blocks from a symmetric operator acting on Stokes sky maps.
The operator is assumed diagonal over the pixel (map) axes. Each Stokes component is probed with a unit map; the response is that column of every pixel's block at once.
Source code in src/furax/mapmaking/preconditioner.py
mv(x)
Source code in src/furax/mapmaking/preconditioner.py
furax.mapmaking.results
Classes:
MapMakingResults
dataclass
Methods:
Attributes:
-
map(StokesType) –The estimated sky map
-
landscape(StokesLandscape) –The landscape corresponding to the map
-
hit_map(Integer[Array, ' *dims']) –The map of hit counts per pixel
-
icov(Float[Array, 'stokes stokes *dims']) –The per-pixel inverse noise covariance matrix (H^T N^{-1} H)
-
solver_stats(dict[str, Any] | None) –Statistics from the linear solver (e.g. num_steps, max_steps)
-
noise_fits(Float[Array, ...] | None) –The fitted noise PSD parameters
-
failed_observations(list[str] | None) –Names of observations that failed to load and were excluded from the maps
Source code in src/furax/mapmaking/results.py
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | |
map
instance-attribute
The estimated sky map
landscape
instance-attribute
The landscape corresponding to the map
hit_map
instance-attribute
The map of hit counts per pixel
icov
instance-attribute
The per-pixel inverse noise covariance matrix (H^T N^{-1} H)
solver_stats = None
class-attribute
instance-attribute
Statistics from the linear solver (e.g. num_steps, max_steps)
noise_fits = None
class-attribute
instance-attribute
The fitted noise PSD parameters
failed_observations = None
class-attribute
instance-attribute
Names of observations that failed to load and were excluded from the maps
__init__(map, landscape, hit_map, icov, solver_stats=None, noise_fits=None, failed_observations=None)
save(out_dir)
Source code in src/furax/mapmaking/results.py
load(out_dir, landscape, fields=None)
classmethod
Load a previously saved MapMakingResults from disk.
Parameters:
-
out_dir(str | Path) –Directory containing the saved files.
-
landscape(StokesLandscape) –The landscape used when the results were saved.
-
fields(set[str] | list[str] | None, default:None) –Fields to load. Defaults to all fields. Required fields (map, hit_map, icov) must always be included if specified.
Source code in src/furax/mapmaking/results.py
furax.mapmaking.templates
Template operators for fitting structured nuisance signals out of the data.
A template turns a small set of per-detector amplitudes into a time stream, so the mapmaker can fit and remove unwanted but predictable signals (slow drifts, scan-synchronous pickup, HWP-synchronous lines, T-to-P leakage).
The building block is a Basis: a small set of functions of time (Legendre
polynomials, HWP harmonics, ...). Going from amplitudes to a signal is expand;
the reverse is project. A PerDetectorTemplate then gives every detector its
own copy (or its own basis), so each detector fits its own amplitudes.
A few Basis flavours trade memory for structure:
- TensorBasis: stores every basis function value directly, as a dense array
(optionally on a coarser time grid, q > 1, to trade resolution for memory).
- KroneckerBasis: a product of independent factors (e.g. azimuth x HWP), stored
factored to save memory.
- SegmentedBasis: each sample belongs to one segment (e.g. one scan interval),
stored sparsely instead of as a mostly-zero dense array.
- WindowedBasis: each sample reads a fixed window of overlapping blocks, the
overlapping generalisation of SegmentedBasis.
Build several templates and combine them by wrapping each in a
PerDetectorTemplate and stacking with BlockRowOperator.
Classes:
-
Basis–A set of template functions of time used to model a structured signal.
-
TensorBasis–Dense basis: the matrix
Bis stored explicitly. -
KroneckerBasis–Basis whose functions factorise over independent variables.
-
SegmentedBasis–Basis partitioned into segments, each sample belonging to exactly one.
-
WindowedBasis–Basis of overlapping blocks, each sample reading a fixed-width window of them.
-
PerDetectorTemplate–Turn a single-detector
Basisinto a per-detector template operator. -
GroundTemplateOperator–Operator for ground signal templates.
-
ATOPProjectionOperator–
Basis
dataclass
Bases: AbstractLinearOperator
A set of template functions of time used to model a structured signal.
The basis functions b_k are each evaluated at the same n_points time samples.
Conceptually, we can think of them as columns of a matrix B. The modelled signal
is then a linear combination s = B a, i.e. s(t) = Σ_k a_k b_k(t) where each
a_k is the amplitude of the template function b_k. The index k may be multi
dimensional.
Two main operations:
expand(synthesis, amplitudes to signal):s = B(a).project(analysis, signal to amplitudes):a = B.T(s).
Methods:
Attributes:
-
shape(tuple[int, ...]) –Shape of the basis index.
-
n_points(int) –Number of sample points at which basis functions are evaluated.
-
size(int) –Total number of basis functions (product of
shape). -
dtype(DTypeLike) – -
out_structure(ShapeDtypeStruct) –
Source code in src/furax/mapmaking/templates.py
shape
property
Shape of the basis index.
n_points
abstractmethod
property
Number of sample points at which basis functions are evaluated.
size
property
Total number of basis functions (product of shape).
dtype
property
out_structure
property
expand(coeffs)
abstractmethod
project(signal)
abstractmethod
mv(x)
TensorBasis
dataclass
Bases: Basis
Dense basis: the matrix B is stored explicitly.
Holds values[k, t] = b_k(t) as a single dense array, with no assumed structure.
When B factorises over independent variables, KroneckerBasis
represents the same map with less memory; when each sample belongs to one interval,
SegmentedBasis avoids storing the mostly-zero per-interval blocks.
With q > 1 the values are stored on a q-times coarser time grid to save memory:
synthesis (expand) holds each coarse value over its block of q samples and analysis
(project) sums each block back down. The two are exact transposes. Hold/block-sum is a
zeroth-order resampler, exact only for content well below the coarse-grid Nyquist
frequency sample_rate / 2q, so choose q to keep that above the template's band edge.
The default q = 1 is the plain dense basis with no resampling.
Methods:
-
__post_init__– -
create– -
expand– -
project–
Attributes:
Source code in src/furax/mapmaking/templates.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
values
instance-attribute
q = field(metadata={'static': True}, default=1)
class-attribute
instance-attribute
n_full = field(metadata={'static': True}, default=0)
class-attribute
instance-attribute
n_points
property
n_dec
property
__post_init__()
Source code in src/furax/mapmaking/templates.py
create(values, q=1, n_full=None)
classmethod
Source code in src/furax/mapmaking/templates.py
expand(coeffs)
Source code in src/furax/mapmaking/templates.py
project(signal)
KroneckerBasis
dataclass
Bases: Basis
Basis whose functions factorise over independent variables.
Built from factor matrices F_i (e.g. an azimuth-polynomial set and an HWP-harmonic
set), whose rows are the factor's functions of time. The basis function for
multi-index k = (k_0, ...) is the elementwise product b_k(t) = Π_i F_i[k_i, t].
Equivalent to a TensorBasis holding the full outer product, but kept factored:
memory scales as Σ_i d_i rather than Π_i d_i columns of length n_points.
Use when the basis cleanly separates over independent variables.
Methods:
Attributes:
Source code in src/furax/mapmaking/templates.py
factors
instance-attribute
n_points
property
create(factors)
classmethod
Source code in src/furax/mapmaking/templates.py
expand(coeffs)
Source code in src/furax/mapmaking/templates.py
project(signal)
Source code in src/furax/mapmaking/templates.py
SegmentedBasis
dataclass
Bases: Basis
Basis partitioned into segments, each sample belonging to exactly one.
The amplitude index is (j, k) = segment j × shared sub-basis function k, with
b_{j,k}(t) = [segment(t) = j] · v_k(t). Since every sample lies in a single
segment, only that segment's amplitudes contribute to it.
Stored sparsely as one segment id per sample plus one shared table v_k(t), instead
of the equivalent dense per-segment array (segments × functions × samples) that would
be almost all zeros. The right choice when the segments form a partition (e.g. per-scan-interval
Legendre polynomials); KroneckerBasis does not help here, as it assumes every
factor is dense at every sample.
Samples in no segment must have their values column pre-zeroed by the builder;
their segment id is then irrelevant.
Methods:
Attributes:
Source code in src/furax/mapmaking/templates.py
segment
instance-attribute
values
instance-attribute
n_points
property
create(segment, values, n_segments)
classmethod
Source code in src/furax/mapmaking/templates.py
expand(coeffs)
Source code in src/furax/mapmaking/templates.py
project(signal)
Source code in src/furax/mapmaking/templates.py
WindowedBasis
dataclass
Bases: Basis
Basis of overlapping blocks, each sample reading a fixed-width window of them.
The amplitude index is a pair (block, sub-basis function). Every sample falls under a fixed number of consecutive blocks, weighting each by how far the sample sits inside it and each sub-basis function by its value there. The typical case is a cubic B-spline, where every sample lies under four consecutive knots.
Stored sparsely as, per sample, the index of its first block, the window weights, and the
shared sub-basis values, instead of the equivalent dense TensorBasis whose columns would
be almost all zeros. The right choice when blocks overlap by a fixed amount;
SegmentedBasis is the non-overlapping single-block-per-sample special case, kept separate
to avoid storing its trivial unit window.
The builder must keep every window inside the block range, pre-zeroing the weights of any sample whose window overhangs the ends.
Methods:
Attributes:
-
offset(Int[Array, ' samp']) – -
block_weights(Float[Array, 'O samp']) – -
sub_values(Float[Array, 'k samp']) – -
n_points(int) –
Source code in src/furax/mapmaking/templates.py
offset
instance-attribute
block_weights
instance-attribute
sub_values
instance-attribute
n_points
property
create(offset, block_weights, sub_values, n_blocks)
classmethod
Source code in src/furax/mapmaking/templates.py
expand(coeffs)
Source code in src/furax/mapmaking/templates.py
project(signal)
Source code in src/furax/mapmaking/templates.py
PerDetectorTemplate
dataclass
Bases: AbstractLinearOperator
Turn a single-detector Basis into a per-detector template operator.
Each detector is an independent block fitting its own amplitudes. Two modes:
shared_basis=True(default): all detectors use the same basis. Used by templates whose basis depends only on shared quantities (azimuth, HWP angle): polynomial, scan- and HWP-synchronous.shared_basis=False: each detector has its own basis. Used by the T2P leakage template, where detectord's basis is its own temperature stream.
Methods:
-
from_basis–Build the per-detector operator over
n_detsdetectors from a singlebasis. -
mv– -
transpose– -
scan_synchronous–Scan-synchronous (azimuth-only) template on a global Legendre basis.
-
binaz_synchronous–Binned azimuth-synchronous template, no HWP coupling.
-
hwp_synchronous–HWP-synchronous template: harmonics of the HWP angle,
k = 1..n_harmonics. -
azhwp_synchronous–Azimuth-Legendre × HWP-harmonic template (Kronecker product of the two).
-
binazhwp_synchronous–Azimuth-binned × HWP-harmonic template (azimuth is always binned).
-
polynomial–A polynomial drift template, one polynomial per scanning interval.
-
temperature–Temperature-to-polarization leakage template.
-
none–Empty template: no amplitudes, zero output.
-
bspline_hwpss–Spline-based HWP synchronous template.
Attributes:
Source code in src/furax/mapmaking/templates.py
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | |
operator
instance-attribute
shared_basis = field(default=True, metadata={'static': True})
class-attribute
instance-attribute
out_structure
property
from_basis(basis, n_dets, *, shared=True)
classmethod
Build the per-detector operator over n_dets detectors from a single basis.
shared=True uses one basis for all detectors; shared=False expects a
per-detector basis, one per detector (see the class docstring).
Source code in src/furax/mapmaking/templates.py
mv(x)
Source code in src/furax/mapmaking/templates.py
transpose()
scan_synchronous(legendre, azimuth, n_dets, dtype)
classmethod
Scan-synchronous (azimuth-only) template on a global Legendre basis.
Source code in src/furax/mapmaking/templates.py
binaz_synchronous(bins, azimuth, n_dets, dtype)
classmethod
Binned azimuth-synchronous template, no HWP coupling.
One amplitude per azimuth bin per detector.
Source code in src/furax/mapmaking/templates.py
hwp_synchronous(n_harmonics, hwp_angles, n_dets, dtype)
classmethod
HWP-synchronous template: harmonics of the HWP angle, k = 1..n_harmonics.
Source code in src/furax/mapmaking/templates.py
azhwp_synchronous(legendre, n_harmonics, azimuth, hwp_angles, n_dets, dtype, scan_mask=None)
classmethod
Azimuth-Legendre × HWP-harmonic template (Kronecker product of the two).
scan_mask optionally zeroes the azimuth leg on flagged samples (e.g. to fit
separate amplitudes per scan direction).
Source code in src/furax/mapmaking/templates.py
binazhwp_synchronous(bins, n_harmonics, azimuth, hwp_angles, n_dets, dtype)
classmethod
Azimuth-binned × HWP-harmonic template (azimuth is always binned).
Source code in src/furax/mapmaking/templates.py
polynomial(max_poly_order, intervals, times, n_dets, dtype, valid_mask=None)
classmethod
A polynomial drift template, one polynomial per scanning interval.
Each sample belongs to one interval and is fitted with Legendre orders
0..max_poly_order over that interval.
Assumes intervals are sorted, non-overlapping [start, end) rows. Samples in
gaps or past the last interval get a zero basis column. valid_mask optionally
zeroes flagged samples (1 = keep, 0 = drop) so they neither carry template
signal nor constrain the fitted amplitudes.
Source code in src/furax/mapmaking/templates.py
temperature(temperature, dtype, fit_band=None, sample_rate=1.0, decimation_factor=1)
classmethod
Temperature-to-polarization leakage template.
Each detector's basis is just its own temperature stream, so fitting one amplitude per detector estimates how much temperature leaks into its polarization.
fit_band=(f0, f1) restricts the temperature basis to that frequency band (Hz),
so the leakage is both estimated and removed only there, keeping the template a
clean linear operator.
decimation_factor=q stores the basis on a q-times coarser grid to cut memory; the
coarse-grid Nyquist frequency sample_rate / 2q must stay above f1. As a rule
of thumb keep it at a few times f1 (q ≲ sample_rate / 6·f1): the fractional
error on the fitted amplitude grows like (f1 / (sample_rate / 2q))².
Assumes temperature is already deglitched/gap-filled upstream: a glitch left in
it would smear across the band and bias the fitted amplitude.
Source code in src/furax/mapmaking/templates.py
none(n_dets, n_samps, dtype)
classmethod
Empty template: no amplitudes, zero output.
Used to leave a Stokes leg untouched in a per-leg block (e.g. the I leg of the T2P template, which acts on Q/U only).
Source code in src/furax/mapmaking/templates.py
bspline_hwpss(times, hwp_angles, n_dets, n_knots, harmonics=(4,), dtype=jnp.float32)
classmethod
Spline-based HWP synchronous template.
A cubic B-spline models the slowly time-varying amplitude of the HWP-synchronous
signal: knot j carries a (sin kχ, cos kχ) pair for each harmonic k, so the
amplitudes have shape (K, 2*n_harmonics) with K = n_knots + 2.
Parameters:
-
times(Float[Array, ' samp']) –Per-sample timestamps used to place the spline knots.
-
hwp_angles(Float[Array, ' samp']) –Per-sample HWP angle
χ(radians). -
n_dets(int) –Number of detectors; each fits its own amplitudes.
-
n_knots(int) –Number of interior spline knots (see
SplineHWPSSConfig.resolve_n_knots). -
harmonics(int | Sequence[int], default:(4,)) –HWP harmonics to model, either an int
n(the harmonics1..n) or an explicit sequence of orders. -
dtype(DTypeLike, default:float32) –Floating dtype of the basis values.
Source code in src/furax/mapmaking/templates.py
GroundTemplateOperator
dataclass
Bases: AbstractLinearOperator
Operator for ground signal templates.
The template amplitudes form a two-dimensional (elevation, azimuth) IQU map of the ground observed that is shared across detectors for the observation range. This class only contains a factory method. All argument angles should be provided in radians.
Methods:
-
create– -
get_landscape–
Source code in src/furax/mapmaking/templates.py
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | |
create(azimuth_resolution, elevation_resolution, boresight_azimuth, boresight_elevation, boresight_rotation, detector_quaternions, hwp_angles, stokes, dtype, landscape=None, batch_size=0)
classmethod
Source code in src/furax/mapmaking/templates.py
get_landscape(azimuth_resolution, elevation_resolution, boresight_azimuth, boresight_elevation, detector_quaternions, stokes, dtype)
classmethod
Source code in src/furax/mapmaking/templates.py
ATOPProjectionOperator
Bases: AbstractLinearOperator
Methods:
Attributes:
Source code in src/furax/mapmaking/templates.py
tau = field(metadata={'static': True})
class-attribute
instance-attribute
__init__(tau, *, in_structure)
mv(x)
Source code in src/furax/mapmaking/templates.py
furax.mapmaking.weight
Classes:
-
WeightOperator–Masked noise weight
M W Mas a single operator. -
NestedWeightOperator–Minimum-variance inverse-noise weighting for gappy data, using an iterative algorithm.
WeightOperator
dataclass
Bases: AbstractLinearOperator
Masked noise weight M W M as a single operator.
Methods:
Attributes:
-
weight(AbstractLinearOperator) – -
mask(MaskOperator) –
Source code in src/furax/mapmaking/weight.py
weight
instance-attribute
mask
instance-attribute
create(weight, mask)
classmethod
with_mask(mask)
NestedWeightOperator
dataclass
Bases: AbstractLinearOperator
Minimum-variance inverse-noise weighting for gappy data, using an iterative algorithm.
The minimum-variance weight for gappy data is the inverse of the good-good block of the noise
covariance, W_exact = Pᵀ N_gg⁻¹ P (with P selecting the good samples). Forming N_gg⁻¹
directly would need the covariance N; instead, block-inverse algebra moves the whole correction
onto the flagged samples, expressing the weight through N⁻¹ alone:
W_exact = N⁻¹ − N⁻¹ Qᵀ (Q N⁻¹ Qᵀ)⁻¹ Q N⁻¹,
where Q packs the flagged samples. Sketch: order the samples good/bad and split N⁻¹ into
2×2 blocks; the Schur complement of its good-good block is exactly N_gg⁻¹, and rearranging
that relation gives the line above. The correction lives entirely in the flagged subspace, whose
block Q N⁻¹ Qᵀ is small and well-conditioned; the flagged rows of the output are zeroed
automatically (no outer mask needed). Only N⁻¹ appears, so this is valid for any symmetric PSD
inverse-noise -- including det-det correlations, where forming N = (N⁻¹)⁻¹ is intractable. The
inner factor (Q N⁻¹ Qᵀ)⁻¹ is applied by a CG solve, never materialised.
Fixed flagged-subspace budget. Under jit the flagged subspace must have a static size, but
the flag count is a runtime value. We therefore pad the flagged-index set to a fixed
n_flag_max (jnp.nonzero(..., size=n_flag_max)); a validity vector v marks the real
flagged slots, and the inner system is V (Q N⁻¹ Qᵀ) V + (I − V) so padding slots act as the
identity and contribute nothing. When the flag count exceeds the budget the weight falls back
(per jax.lax.cond) to the cheap inner-mask weight M N⁻¹ M -- still unbiased, just
suboptimal -- so correctness never depends on the budget. A fully-masked input exceeds the
budget and falls back to M N⁻¹ M = 0, contributing nothing.
The inner solve runs a fixed number of iterations, so W is a constant linear operator --
identical on the RHS and on every system-operator apply. A tolerance-based inner solve would
make W depend on its input, i.e. no longer linear. Assumes a single-leaf time-ordered
structure (the SO TOD layout).
Optional preconditioner. When there are a few gaps wider than the correlation length the inner
block Q N⁻¹ Qᵀ is ill-conditioned; passing the covariance N (cov, the banded/Fourier
approximation from the noise model) builds the flagged-block preconditioner Q N Qᵀ, whose product
with the inner operator differs from the identity by a boundary term of rank ≈ 2×(correlation
bandwidth)×(number of gaps), so inner CG converges in roughly that many steps. This wins only when
that rank is below the bare inner-solve count. For the common case of many short gaps
(turnarounds/glitches) the bare block is already well-conditioned and preconditioning is a net
loss -- pass no cov there (the default). Without cov the inner solve is unpreconditioned.
Methods:
Attributes:
-
ninv(AbstractLinearOperator) – -
mask(MaskOperator) – -
max_flag_fraction(float) – -
n_flag_max(int) – -
inner_steps(int) – -
rtol(float) – -
atol(float) – -
cov(AbstractLinearOperator | None) –
Source code in src/furax/mapmaking/weight.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | |
ninv
instance-attribute
mask
instance-attribute
max_flag_fraction = field(metadata={'static': True})
class-attribute
instance-attribute
n_flag_max = field(metadata={'static': True})
class-attribute
instance-attribute
inner_steps = field(metadata={'static': True})
class-attribute
instance-attribute
rtol = field(metadata={'static': True})
class-attribute
instance-attribute
atol = field(metadata={'static': True})
class-attribute
instance-attribute
cov = None
class-attribute
instance-attribute
create(ninv, mask, config, cov=None)
classmethod
Source code in src/furax/mapmaking/weight.py
with_mask(mask)
Rebuild the weight around a new mask, re-resolving the budget.