API reference¶
Camera¶
getframes.camera.Camera
¶
A camera that generates realistic synthetic frames.
A :class:Camera wraps a :class:~getframes.config.CameraConfig and exposes
high-level frame-generation methods. Construct one directly from a config, or
load a built-in preset:
import getframes as gf cam = gf.Camera.from_preset("andor_ikon_m934") frame = cam.dark_frame(exposure=30.0, temperature=-60.0, seed=0) frame.shape (1024, 1024)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CameraConfig
|
The detector configuration. |
required |
default_temperature_c
|
float | None
|
Temperature (deg C) used when a frame method is called without an explicit temperature. Defaults to the config's dark-current reference temperature. |
None
|
seed
|
int | None
|
Optional seed for this camera's internal random generator, giving reproducible output across calls when no per-call seed is supplied. |
None
|
precision
|
str
|
Working floating-point precision of the signal chain: |
'float64'
|
Source code in src/getframes/camera.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 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 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 | |
from_preset(name, **kwargs)
classmethod
¶
Create a camera from a built-in preset (see :func:getframes.available_presets).
Source code in src/getframes/camera.py
92 93 94 95 | |
from_dict(data, **kwargs)
classmethod
¶
Create a camera from a plain configuration dictionary.
Source code in src/getframes/camera.py
97 98 99 100 | |
with_config(**changes)
¶
Return a new camera with configuration fields overridden.
Source code in src/getframes/camera.py
117 118 119 120 121 122 123 | |
dark_frame(exposure, temperature=None, *, seed=None)
¶
Generate a single dark frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
exposure
|
float
|
Integration time in seconds. |
required |
temperature
|
float | None
|
Sensor temperature in degrees Celsius. Defaults to the camera's
:attr: |
None
|
seed
|
int | None
|
If given, use a fresh generator seeded with this value, producing a fully reproducible frame independent of prior calls. If omitted, the camera's internal generator advances. |
None
|
Returns:
| Type | Description |
|---|---|
Frame
|
The simulated frame (ADU) with descriptive metadata. |
Source code in src/getframes/camera.py
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 | |
dark_series(exposure, n_frames, temperature=None, *, seed=None)
¶
Yield n_frames independent dark frames (e.g. for building a master dark).
When seed is given the series is reproducible; each frame uses a distinct
derived seed so the frames are independent but the whole series is repeatable.
Source code in src/getframes/camera.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
expose(photon_rate, exposure, temperature=None, *, background=0.0, quantum_efficiency=None, extra_electrons=0.0, seed=None, include_truth=True)
¶
Expose the sensor to an incident photon rate and return a frame.
This is the general signal path; :meth:dark_frame, :meth:flat_frame,
and :meth:bias_frame are convenience wrappers around it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
photon_rate
|
PhotonRate
|
Incident photon rate in photons/s/pixel, as a scalar (uniform
illumination) or a 2-D array matching :attr: |
required |
exposure
|
float
|
Integration time in seconds. |
required |
temperature
|
float | None
|
Sensor temperature in degrees Celsius. Defaults to
:attr: |
None
|
background
|
PhotonRate
|
Additive background (sky/thermal) photon rate in photons/s/pixel. |
0.0
|
quantum_efficiency
|
float | None
|
Overrides the config's scalar QE for this exposure. Spectral mode uses
this with an already-photoelectron map and |
None
|
extra_electrons
|
PhotonRate
|
Additive noise-free signal in electrons (scalar or array) injected
before shot noise. Used by :meth: |
0.0
|
seed
|
int | None
|
If given, use a fresh generator seeded with this value for a fully reproducible frame. |
None
|
include_truth
|
bool
|
If |
True
|
Source code in src/getframes/camera.py
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 | |
flat_frame(photon_rate, exposure, temperature=None, *, background=0.0, seed=None, include_truth=True)
¶
A uniformly (or per-pixel) illuminated flat-field frame.
Equivalent to :meth:expose; provided as a named entry point for
flat-field/photon-transfer workflows. Pass a scalar photon_rate for a
uniform flat.
Source code in src/getframes/camera.py
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 | |
bias_frame(temperature=None, *, seed=None)
¶
A zero-exposure bias frame (bias pedestal + read noise only).
Source code in src/getframes/camera.py
294 295 296 297 298 299 300 301 302 303 | |
observe(scene, exposure, temperature=None, *, seed=None, include_truth=True)
¶
Observe a :class:~getframes.scene.Scene and return a science frame.
Renders the scene to an incident photon-rate map, then exposes the sensor
to it (adding the scene's sky as a uniform background). The scene's
shape must match this camera's :attr:resolution.
Spectral mode activates automatically when this camera's config has a
:attr:~getframes.config.CameraConfig.qe_curve and the scene's band
carries a spectral response: each source then gets a colour-dependent
effective QE from its SED, instead of the scalar quantum_efficiency.
Source code in src/getframes/camera.py
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 | |
expose_series(photon_rate, exposure, n_frames, temperature=None, *, background=0.0, seed=None, include_truth=True)
¶
Yield n_frames independent illuminated frames (the :meth:expose series).
The light-frame analogue of :meth:dark_series. When seed is given the
series is reproducible; each frame uses a distinct derived seed so the
frames are independent but the whole series repeats.
Source code in src/getframes/camera.py
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 | |
observe_series(scene, exposure, n_frames, temperature=None, *, cadence=None, pointing=None, jitter_arcsec=0.0, seed=None, include_truth=True)
¶
Observe scene over time, returning a reproducible :class:Observation.
Produces a time-ordered stack of science frames. Frame i is exposed at
timestamp t_i = i * cadence (the start of its exposure); sources
carrying a :class:~getframes.scene.sources.LightCurve vary accordingly,
and a :class:~getframes.observation.Pointing model shifts the field per
frame. If the detector has a non-zero
:attr:~getframes.config.CameraConfig.persistence_fraction, latent charge
is carried across frames.
The returned :class:Observation is iterable over its frames (so
for f in cam.observe_series(...) still works) and carries the per-frame
timestamps, realised pointing offsets, and the ground-truth light curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
scene
|
Scene
|
As in :meth: |
required |
exposure
|
Scene
|
As in :meth: |
required |
temperature
|
Scene
|
As in :meth: |
required |
n_frames
|
int
|
Number of frames in the series. |
required |
cadence
|
float | None
|
Seconds between successive frame start times. Defaults to |
None
|
pointing
|
Pointing | None
|
A :class: |
None
|
jitter_arcsec
|
float
|
Convenience for the common case: the RMS of a per-frame Gaussian
pointing jitter (ignored if |
0.0
|
seed
|
int | None
|
When given, the series is reproducible; each frame draws a distinct derived seed (independent frames) and the pointing jitter uses its own derived stream, so the whole observation repeats exactly. |
None
|
include_truth
|
bool
|
Whether to attach per-frame :class: |
True
|
Source code in src/getframes/camera.py
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 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | |
master_bias(n_frames, temperature=None, *, seed=None, method='median')
¶
Combine n_frames bias frames into a master bias (see :func:getframes.combine).
Source code in src/getframes/camera.py
560 561 562 563 564 565 566 567 568 569 570 571 572 | |
master_dark(exposure, n_frames, temperature=None, *, seed=None, method='median')
¶
Combine n_frames dark frames into a master dark.
The result still contains the bias pedestal, so it is subtracted directly
from an exposure-matched science frame (calibrate(sci, dark=master)).
Source code in src/getframes/camera.py
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | |
master_flat(photon_rate, exposure, n_frames, temperature=None, *, background=0.0, bias=None, seed=None, method='median')
¶
Combine n_frames flat frames into a master flat.
If bias is given it is subtracted, yielding a pedestal-free flat whose
pixel-to-pixel structure is the detector's response — the form
:func:getframes.calibrate expects to normalise and divide by.
Source code in src/getframes/camera.py
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 | |
CameraConfig¶
getframes.config.CameraConfig
dataclass
¶
Physical and electronic parameters of a camera/detector.
All electron quantities are in electrons (e-); all digital quantities are
in analog-to-digital units (ADU, sometimes called counts or DN).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Human-readable identifier (e.g. |
required |
sensor_type
|
SensorType
|
One of :class: |
required |
resolution
|
tuple[int, int]
|
Sensor size as |
required |
pixel_size_um
|
float
|
Physical pixel pitch in microns. Informational; not used for dark frames. |
required |
quantum_efficiency
|
float
|
Band-averaged quantum efficiency in |
required |
qe_curve
|
QE | None
|
Optional wavelength-resolved quantum efficiency
(:class: |
None
|
full_well_e
|
float
|
Full-well capacity in electrons. Signal saturates here before digitization. |
required |
bit_depth
|
int
|
ADC resolution in bits. The output saturates at |
required |
gain_e_per_adu
|
float
|
Camera conversion gain in electrons per ADU. Electrons reaching the ADC are divided by this to produce counts. |
required |
bias_offset_adu
|
float
|
Electronic offset (pedestal) added to every pixel, in ADU. |
required |
read_noise_e
|
float
|
RMS read noise in electrons. For sCMOS this is the median; see
|
required |
read_noise_nonuniformity
|
float
|
Fractional pixel-to-pixel spread of the read-noise RMS (e.g. |
0.0
|
nonlinearity
|
float
|
Fractional signal compression at full well, in |
0.0
|
nonlinearity_coeffs
|
tuple[float, ...] | None
|
Optional polynomial generalisation of |
None
|
cti
|
float
|
Charge-transfer inefficiency (CTI) of a CCD, the fraction of charge left
behind per pixel-to-pixel transfer during readout, in |
0.0
|
blooming
|
bool
|
When |
False
|
ipc_coupling
|
float
|
Inter-pixel capacitance (IPC): the fraction of each pixel's signal that
couples capacitively into each of its four nearest neighbours at readout,
in |
0.0
|
reset_noise_e
|
float
|
kTC / reset noise RMS in electrons: an independent per-pixel, per-frame
Gaussian charge uncertainty from resetting the sense node, added alongside
read noise. |
0.0
|
amplifier_layout
|
tuple[int, int]
|
Multi-amplifier readout as |
(1, 1)
|
amp_gain_nonuniformity
|
float
|
Fractional RMS spread of per-amplifier gain about |
0.0
|
amp_offset_spread_adu
|
float
|
RMS spread of per-amplifier bias offset in ADU, about |
0.0
|
cosmic_ray_track_length_px
|
float
|
Mean length in pixels of cosmic-ray tracks. |
0.0
|
bad_column_fraction
|
float
|
Fraction of columns that are defective (dead): a fixed, deterministic set of
whole columns forced to zero signal in every frame — the bad columns a flat
cannot rescue. |
0.0
|
dead_pixel_fraction
|
float
|
Fraction of individual pixels that are dead (zero response), a fixed map.
|
0.0
|
bias_structure_amplitude_adu
|
float
|
Peak amplitude in ADU of a fixed, structured bias pattern (a smooth gradient
plus per-column offsets) added on top of the flat |
0.0
|
cosmic_ray_rate_per_cm2_s
|
float
|
Cosmic-ray hit rate in events per cm^2 per second (sea level is ~5). The number of hits scales with sensor area and exposure; each deposits a burst of charge in a random pixel. |
0.0
|
prnu
|
float
|
Photo-response non-uniformity: fractional pixel-to-pixel variation in
sensitivity (e.g. |
0.0
|
dark_current_e_per_s
|
float
|
Dark current in electrons per pixel per second, specified at
|
required |
detector_glow_e_per_s
|
float
|
Detector self-emission ("glow") in electrons per pixel per second, added to
the dark signal (it scales with exposure and so is removed by an
exposure-matched master dark). A uniform model of amplifier/array glow,
relevant for IR arrays alongside the thermal background. |
0.0
|
dark_current_ref_temp_c
|
float
|
Temperature (deg C) at which |
20.0
|
dark_current_doubling_temp_c
|
float
|
Temperature increase (deg C) that doubles the dark current. Typical CCD/CMOS silicon values are 5-8 C. |
6.3
|
em_gain
|
float
|
Mean gain of the stochastic multiplication stage: the EM register of an
EMCCD or the avalanche gain of an eAPD. |
1.0
|
excess_noise_factor
|
float | None
|
Excess noise factor |
None
|
clock_induced_charge_e
|
float
|
Clock-induced charge (spurious charge) in electrons per pixel per frame. Relevant mainly for EMCCD. |
0.0
|
persistence_fraction
|
float
|
Fraction of a frame's collected charge captured into traps as a latent
image (image persistence), in |
0.0
|
persistence_decay
|
float
|
Fraction of the trapped charge released each subsequent frame, in
|
0.5
|
dark_current_nonuniformity
|
float
|
Fractional pixel-to-pixel dark-signal non-uniformity (DSNU), e.g. |
0.0
|
hot_pixel_fraction
|
float
|
Fraction of pixels that are "hot" (anomalously high dark current). |
0.0
|
hot_pixel_factor
|
float
|
Multiplicative dark-current factor applied to hot pixels. |
100.0
|
fixed_pattern_seed
|
int
|
Seed for the sensor's fixed-pattern noise (PRNU, DSNU, and the hot-pixel
map). These patterns are a property of the physical sensor, so they are the
same in every frame this camera produces --- which is exactly what lets a
master flat or dark capture and remove them. Two configs with the same seed
and shape share a pattern; change it to mint a different sensor. Independent
of the per-frame |
0
|
manufacturer
|
str | None
|
Optional provenance metadata. |
None
|
model
|
str | None
|
Optional provenance metadata. |
None
|
notes
|
str | None
|
Optional provenance metadata. |
None
|
Source code in src/getframes/config.py
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 | |
max_adu
property
¶
The saturation value of the ADC output.
has_gain_stage
property
¶
Whether a stochastic multiplication stage (EM/avalanche) is active.
gain_excess_noise_factor
property
¶
The effective excess noise factor F of the gain stage.
Returns :attr:excess_noise_factor if set, else a sensible default for the
sensor type: sqrt(2) for EMCCD (the high-gain limit) and 1.0
(noiseless) otherwise.
dark_current_at(temperature_c)
¶
Dark current (e-/pixel/s) scaled to temperature_c.
Uses the standard doubling-temperature model::
D(T) = D_ref * 2 ** ((T - T_ref) / T_double)
Source code in src/getframes/config.py
352 353 354 355 356 357 358 359 360 361 | |
replace(**changes)
¶
Return a copy with the given fields overridden (like dataclasses.replace).
Source code in src/getframes/config.py
363 364 365 366 367 | |
to_dict()
¶
Serialise to a plain dict (sensor_type rendered as its string value).
Source code in src/getframes/config.py
369 370 371 372 373 374 375 376 377 378 | |
from_dict(data)
classmethod
¶
Build a config from a dict, ignoring unknown keys (stashed in extra).
A qe_curve may be given as a :class:~getframes.spectral.QE or as a
mapping {"wavelength_nm": [...], "qe": [...]} (the form used in preset
TOML files).
Source code in src/getframes/config.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | |
SensorType¶
getframes.config.SensorType
¶
Bases: str, Enum
The detector architecture, which selects the noise model used.
Source code in src/getframes/config.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | |
coerce(value)
classmethod
¶
Accept either a :class:SensorType or a case-insensitive string.
Source code in src/getframes/config.py
28 29 30 31 32 33 34 35 36 37 | |
Frame¶
getframes.frame.Frame
dataclass
¶
A single simulated image plus the metadata describing how it was made.
The pixel values live in :attr:data as a 2-D NumPy array in ADU. The object
is array-like: np.asarray(frame) and most NumPy operations work directly.
Attributes:
| Name | Type | Description |
|---|---|---|
data |
NDArray[floating[Any] | integer[Any]]
|
2-D array of pixel values in ADU, shaped |
metadata |
dict[str, Any]
|
Free-form dictionary describing the simulation (camera name, exposure, temperature, frame type, etc.). Suitable for writing to a FITS header. |
truth |
FrameTruth | None
|
Optional :class: |
Source code in src/getframes/frame.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 | |
stats()
¶
Common summary statistics of the pixel values (mean/median/std/min/max).
Source code in src/getframes/frame.py
73 74 75 76 77 78 79 80 81 82 | |
to_fits(path, overwrite=False)
¶
Write the frame to a FITS file (requires astropy).
Metadata keys are written to the FITS header where they fit the 8-character keyword and value-type constraints.
Source code in src/getframes/frame.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
getframes.frame.FrameTruth
dataclass
¶
Noise-free ground truth a :class:Frame was generated from.
Useful for validating analysis pipelines against exactly what went in. All arrays are in electrons unless noted, shaped like the frame.
Attributes:
| Name | Type | Description |
|---|---|---|
mean_electrons |
NDArray[float64]
|
Noise-free total signal (photo + dark) per pixel, in electrons. This is the expectation value before shot noise, gain, and read noise. |
mean_photoelectrons |
NDArray[float64]
|
Noise-free photo signal per pixel, in electrons (i.e. excluding dark). |
photon_rate |
NDArray[float64] | float
|
The incident photon rate the frame was exposed to, in photons/s/pixel, as provided by the caller (a scalar for uniform illumination, else an array). |
Source code in src/getframes/frame.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Calibration¶
getframes.calibrate
¶
Calibration: combine frames into masters and reduce raw frames against them.
These helpers close the loop the library is built for: generate raw frames (each
optionally carrying :class:~getframes.frame.FrameTruth), then reduce them with
master calibration frames and compare the result to the ground truth.
The reduction follows the standard, exposure-matched CCD equation::
reduced = (raw - dark) / normalised(flat)
where dark is an exposure-matched master dark (which still contains the bias
pedestal, so subtracting it removes bias and dark current together) and flat is
a pedestal-free master flat (see :meth:getframes.Camera.master_flat). Pass
bias instead of dark to subtract only the bias pedestal.
combine(frames, *, method='median', sigma=3.0)
¶
Combine a stack of frames pixel-wise into a single master frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frames
|
Iterable[FrameLike]
|
An iterable of :class: |
required |
method
|
str
|
|
'median'
|
sigma
|
float
|
Clipping threshold for |
3.0
|
Returns:
| Type | Description |
|---|---|
Frame
|
The master frame (ADU, |
Source code in src/getframes/calibrate.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 | |
calibrate(raw, *, bias=None, dark=None, flat=None, dark_scale=1.0)
¶
Reduce a raw frame with master calibration frames.
Performs, in order: subtract the additive pedestal (an exposure-matched master
dark if given, else a bias), then divide by the normalised flat::
out = raw - dark_scale * dark # or raw - bias if no dark
out = out / (flat / mean(flat))
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
raw
|
FrameLike
|
The frame to reduce (a :class: |
required |
bias
|
FrameLike | None
|
Master bias. Subtracted only when |
None
|
dark
|
FrameLike | None
|
Exposure-matched master dark (including bias). Subtracted from |
None
|
flat
|
FrameLike | None
|
Pedestal-free master flat. Divided out after normalising it to unit mean, so only its relative pixel-to-pixel response remains. |
None
|
dark_scale
|
float
|
Multiplier applied to |
1.0
|
Returns:
| Type | Description |
|---|---|
Frame
|
The reduced frame ( |
Source code in src/getframes/calibrate.py
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 | |
Presets¶
getframes.presets
¶
Built-in library of camera/detector presets.
Presets are stored as TOML files in :mod:getframes.presets.data. They are loaded
lazily and cached. Add a new camera by dropping a <name>.toml file into that
directory (see the existing files for the schema) — no code changes required.
available_presets()
¶
Return the sorted list of available preset names.
from getframes import available_presets "andor_ikon_m934" in available_presets() True
Source code in src/getframes/presets/__init__.py
38 39 40 41 42 43 44 45 | |
preset_info()
¶
Return lightweight descriptors (name, manufacturer, model, sensor_type) for each preset.
Source code in src/getframes/presets/__init__.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | |
load_preset(name)
¶
Load a preset by name and return a :class:~getframes.config.CameraConfig.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A preset slug, e.g. |
required |
Source code in src/getframes/presets/__init__.py
75 76 77 78 79 80 81 82 83 84 85 86 87 | |
Scene & optics¶
getframes.scene.scene.Scene
dataclass
¶
A focal-plane scene that renders to an incident photon-rate map.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shape
|
tuple[int, int]
|
Output size as |
required |
optics
|
Telescope
|
The :class: |
required |
psf
|
PSF
|
The :class: |
required |
sources
|
Sequence[Source]
|
The sources in the field (point, extended, catalog, or uniform). |
tuple()
|
sky
|
Sky | None
|
Optional uniform sky background. |
None
|
thermal
|
Thermal | None
|
Optional :class: |
None
|
wcs
|
WCSInfo | None
|
Optional :class: |
None
|
Source code in src/getframes/scene/scene.py
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 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 | |
is_spectral_capable
property
¶
Whether this scene's band carries a spectral response for spectral mode.
add(*sources)
¶
Append one or more sources to the scene.
Source code in src/getframes/scene/scene.py
68 69 70 | |
photon_rate_map(time_s=None, offset_xy=(0.0, 0.0), dtype=np.float64)
¶
Render the sources through the PSF into a photons/s/pixel map.
This is the incident rate at the detector before quantum efficiency; the camera applies QE, dark current, and noise when it exposes the scene.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time_s
|
float | None
|
Optional observation time in seconds. When set, sources carrying a
:class: |
None
|
offset_xy
|
tuple[float, float]
|
A whole-field pointing offset |
(0.0, 0.0)
|
dtype
|
DTypeLike
|
Output (and working) floating-point dtype. |
float64
|
Source code in src/getframes/scene/scene.py
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 | |
sky_photon_rate()
¶
Uniform sky background in photons/s/pixel (0 if no sky is set).
Source code in src/getframes/scene/scene.py
141 142 143 144 145 | |
thermal_photon_rate()
¶
Uniform thermal (graybody) background in photons/s/pixel (0 if unset).
Source code in src/getframes/scene/scene.py
147 148 149 150 151 | |
photoelectron_rate_map(qe_curve, time_s=None, offset_xy=(0.0, 0.0), dtype=np.float64)
¶
Render sources to a photoelectron-rate map (e-/s/pixel) in spectral mode.
Like :meth:photon_rate_map, but each source's incident photon rate is
multiplied by the colour-dependent effective QE for its SED (folding the
detector qe_curve with the band's spectral response). The result is
already in photoelectrons, so the camera applies a unit QE downstream.
time_s and offset_xy behave as in :meth:photon_rate_map.
Requires a band with a spectral response (see :attr:is_spectral_capable).
Source code in src/getframes/scene/scene.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
sky_electron_rate(qe_curve)
¶
Uniform sky background in photoelectrons/s/pixel for spectral mode.
Source code in src/getframes/scene/scene.py
181 182 183 184 185 186 187 188 | |
thermal_electron_rate(qe_curve)
¶
Uniform thermal background in photoelectrons/s/pixel for spectral mode.
Source code in src/getframes/scene/scene.py
190 191 192 193 194 195 196 197 | |
background_photon_rate()
¶
Total uniform background (sky + thermal) in photons/s/pixel.
Source code in src/getframes/scene/scene.py
199 200 201 | |
background_electron_rate(qe_curve)
¶
Total uniform background (sky + thermal) in photoelectrons/s/pixel (spectral).
Source code in src/getframes/scene/scene.py
203 204 205 | |
getframes.scene.sources.PointSource
dataclass
¶
Bases: Source
An unresolved point source (e.g. a star) at pixel position (x, y).
Specify the brightness in exactly one of two ways:
magnitude--- converted to a photon rate by the telescope's bandpass, orphoton_rate--- photons/s already arriving at the detector (post-optics, pre-quantum-efficiency), handy when you know the flux directly (e.g. an AO sub-aperture).
x is the column and y the row, in pixels; sub-pixel positions are fine.
sed is an optional spectral energy distribution
(:class:~getframes.spectral.SED). It is used only in spectral mode, to give
the source a colour-dependent effective QE; it has no effect on the integrated
photon rate (the magnitude sets that). Defaults to a flat photon spectrum.
brightness is an optional :class:LightCurve. When set, the source's
photon rate is multiplied by brightness(t) at each timestamp sampled by
:meth:getframes.Camera.observe_series, making the source variable in time.
A static :meth:getframes.Camera.observe (no time) ignores it.
name is an optional label used to key the source in an observation's
per-frame truth light curve.
flux_sed is an alternative to magnitude/photon_rate: an absolute
:class:~getframes.spectral.SED (SED.from_flux_density) whose integral over
the band sets the photon rate directly (true spectral flux integration). When
given it also serves as the colour SED for spectral mode.
Source code in src/getframes/scene/sources.py
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 | |
getframes.scene.sources.ExtendedSource
dataclass
¶
Bases: Source
A resolved source rendered from an analytic Sersic profile or a pixel array.
Place it by pixel (x, y) or, with a scene :class:~getframes.scene.wcs.WCSInfo,
by sky (ra_deg, dec_deg). Total brightness is set by magnitude or an
explicit photon_rate (exactly one), as for :class:PointSource; the profile
distributes that total flux over pixels and is normalised to conserve it.
Construct via :meth:sersic (a Sersic surface-brightness profile, optionally
elliptical) or :meth:from_array (an arbitrary normalised image, e.g. a galaxy
cutout). The profile is rendered directly to the focal plane and is not
additionally convolved with the scene PSF --- supply a pre-convolved array, or
rely on the profile being broad compared with the PSF.
Source code in src/getframes/scene/sources.py
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 | |
position_angle
property
¶
Position angle of the major axis, in degrees (alias of the field).
sersic(*, x=None, y=None, ra=None, dec=None, magnitude=None, photon_rate=None, n=1.0, r_eff_arcsec, ellipticity=0.0, position_angle_deg=0.0, sed=None, brightness=None, name=None, flux_sed=None)
classmethod
¶
A Sersic profile I(r) ~ exp(-b_n[(r/r_eff)^(1/n) - 1]).
n=1 is an exponential disk, n=4 a de Vaucouleurs bulge. ellipticity
(1 - b/a) and position_angle_deg (of the major axis, measured
counter-clockwise from the +x axis) shape an elliptical isophote.
Source code in src/getframes/scene/sources.py
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 | |
from_array(image, *, x=None, y=None, ra=None, dec=None, magnitude=None, photon_rate=None, sed=None, brightness=None, name=None, flux_sed=None)
classmethod
¶
An arbitrary 2D image (e.g. a galaxy cutout) used as the profile.
The array is normalised to unit sum and pasted centred on the source position at detector-pixel resolution, then scaled to the total flux.
Source code in src/getframes/scene/sources.py
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 | |
getframes.scene.sources.UniformIllumination
dataclass
¶
Bases: Source
A spatially flat illumination of photon_rate photons/s/pixel.
A clean, PSF-free flat field --- the natural input for a photon-transfer curve
(PTC) or for building synthetic flats. brightness and sed behave as for
other sources (time variability and spectral effective QE).
Source code in src/getframes/scene/sources.py
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 | |
getframes.scene.sources.Catalog
dataclass
¶
Bases: Source
Many point sources sharing a PSF, SED, and optional light curve.
Build one from a table with :meth:from_table. Entries may be placed by pixel
(x, y) or by sky (ra, dec); sky coordinates are projected to pixels
through the scene's :class:~getframes.scene.wcs.WCSInfo, so a Gaia/2MASS-style
catalogue drops straight into a WCS-tagged scene. The whole catalogue is keyed
by a single :attr:name in observation truth (its summed flux).
Source code in src/getframes/scene/sources.py
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 | |
from_table(table, *, magnitude=None, photon_rate=None, x=None, y=None, ra=None, dec=None, sed=None, brightness=None, name=None)
classmethod
¶
Build a catalogue from column names of table.
table is anything column-indexable by name (an astropy Table, a
pandas DataFrame, or a dict of arrays). Give the brightness column as
magnitude or photon_rate, and the position columns as either
(x, y) pixels or (ra, dec) degrees.
Source code in src/getframes/scene/sources.py
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 | |
getframes.scene.sources.Sky
dataclass
¶
A uniform sky background of a given surface brightness.
The :class:~getframes.scene.scene.Scene treats the sky specially: it is added
by the camera as a uniform background rather than deposited into the rendered
source map, and is therefore not affected by vignetting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
surface_brightness_mag_arcsec2
|
float
|
Sky brightness in magnitudes per square arcsecond (fainter = larger). |
required |
sed
|
SED | None
|
Optional spectral energy distribution for the sky, used only in spectral mode for the sky's effective QE. Defaults to a flat photon spectrum. |
None
|
Source code in src/getframes/scene/sources.py
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 | |
getframes.scene.thermal.Thermal
dataclass
¶
A graybody thermal background from warm optics/enclosure.
Models the thermal emission seen by the detector as a graybody of emissivity
:attr:emissivity at temperature :attr:temperature_k, integrated over the
telescope band into a per-pixel photon rate. Attach it to a
:class:~getframes.scene.scene.Scene (scene.thermal = Thermal(...)) and it
is added as a uniform background by :meth:getframes.Camera.observe, like the
sky but dominant in the thermal infrared.
Computing the rate requires the telescope band to carry a spectral
response (the graybody is integrated over it).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
temperature_k
|
float
|
Graybody temperature in kelvin (e.g. ~273--293 K for a warm enclosure). |
required |
emissivity
|
float
|
Effective emissivity in |
1.0
|
Source code in src/getframes/scene/thermal.py
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 | |
photon_rate(optics)
¶
Thermal background in photons/s/pixel reaching the detector through optics.
emissivity * Omega_pixel * A_collect * int L_ph(lambda, T) T_band(lambda)
dlambda, with Omega_pixel the per-pixel solid angle and A_collect
the collecting area. Requires a band with a spectral response.
Source code in src/getframes/scene/thermal.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | |
photon_sed(wavelength_min_nm=300.0, wavelength_max_nm=3000.0, n_samples=256)
¶
A relative SED of the graybody photon spectrum (for spectral effective QE).
Source code in src/getframes/scene/thermal.py
102 103 104 105 106 107 108 109 110 111 | |
getframes.scene.optics.Telescope
dataclass
¶
An optical system that turns source magnitudes into photon rates at the focal plane.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aperture_diameter_m
|
float
|
Primary aperture diameter in metres. |
required |
plate_scale_arcsec_per_pixel
|
float
|
Angular size of one detector pixel, in arcseconds. |
required |
throughput
|
float
|
End-to-end fraction of photons transmitted (optics x filter x atmosphere),
in |
1.0
|
central_obstruction
|
float
|
Diameter of the central obstruction as a fraction of the aperture diameter
(e.g. the secondary mirror); |
0.0
|
band
|
Bandpass | None
|
The :class: |
None
|
vignetting
|
Vignetting | None
|
Optional :class: |
None
|
distortion
|
RadialDistortion | None
|
Optional :class: |
None
|
Source code in src/getframes/scene/optics.py
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 | |
collecting_area_m2
property
¶
Unobstructed collecting area in square metres.
pixel_solid_angle_arcsec2
property
¶
Solid angle subtended by one pixel, in square arcseconds.
illumination_map(shape)
¶
Relative illumination map for shape (None if no vignetting set).
Source code in src/getframes/scene/optics.py
121 122 123 124 125 | |
unit(plate_scale_arcsec_per_pixel=1.0)
classmethod
¶
A trivial 1 m, unit-throughput telescope.
Handy when you supply source photon rates directly (already at the detector) and only need a plate scale --- e.g. AO sub-aperture simulations.
Source code in src/getframes/scene/optics.py
127 128 129 130 131 132 133 134 135 136 137 138 | |
photon_rate_from_magnitude(magnitude)
¶
Photons/s reaching the detector from a point source of this magnitude.
Source code in src/getframes/scene/optics.py
151 152 153 154 155 156 157 158 | |
photon_rate_from_sed(sed)
¶
Photons/s at the detector from a source described by an absolute SED.
Integrates the SED over the band's spectral response
(:meth:~getframes.scene.photometry.Bandpass.photon_flux_from_sed) and
scales by collecting area and throughput --- the spectral-flux-integration
counterpart of :meth:photon_rate_from_magnitude. Requires a band with a
spectral response and an absolute SED
(:meth:getframes.spectral.SED.from_flux_density).
Source code in src/getframes/scene/optics.py
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
surface_brightness_photon_rate(surface_brightness_mag_arcsec2)
¶
Photons/s/pixel from a uniform sky of the given surface brightness.
Source code in src/getframes/scene/optics.py
177 178 179 180 | |
getframes.scene.optics.Vignetting
dataclass
¶
A radial illumination falloff toward the edges of the field.
Relative illumination is 1 - strength * (r / r_corner)^power, where r is
the distance from the optical centre and r_corner is the distance to the
farthest corner. strength is the fractional light loss at that corner;
power=2 gives a gentle quadratic roll-off (power=4 approximates the cos^4
law). The map is clipped to [0, 1].
Source code in src/getframes/scene/optics.py
20 21 22 23 24 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 | |
illumination_map(shape)
¶
Relative illumination in [0, 1] for a frame of (height, width).
Source code in src/getframes/scene/optics.py
40 41 42 43 44 45 46 47 48 49 50 51 | |
getframes.scene.optics.RadialDistortion
dataclass
¶
A simple radial (barrel/pincushion) distortion about the field centre.
A source at pixel distance r from the centre is displaced to
r * (1 + k1 r^2 + k2 r^4). k1 < 0 gives barrel distortion, k1 > 0
pincushion; both coefficients carry inverse-pixel-power units (k1 is small,
e.g. 1e-7 per pixel^2 for a 2k detector).
Source code in src/getframes/scene/optics.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |
apply(x, y, cx, cy)
¶
Map pixel (x, y) to its distorted position about centre (cx, cy).
Source code in src/getframes/scene/optics.py
67 68 69 70 71 72 | |
getframes.scene.photometry.Bandpass
dataclass
¶
A photometric band, summarised by its photon zero point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Human-readable label, e.g. |
required |
photon_zeropoint
|
float
|
Photons per second per square metre, above the atmosphere, from a magnitude-0 source integrated over the band. |
required |
response
|
SpectralBandpass | None
|
Optional spectral transmission curve for the band. Enables spectral mode
(colour-dependent effective QE); |
None
|
Source code in src/getframes/scene/photometry.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 | |
johnson(band, *, spectral=True)
classmethod
¶
Return a standard Johnson-Cousins band (one of U, B, V, R, I).
By default the band also carries a tophat spectral response so spectral
mode works out of the box; pass spectral=False for the bare zero point.
Source code in src/getframes/scene/photometry.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
ab(band)
classmethod
¶
Return an AB-system band for a common survey filter.
The AB system references every band to a flat :math:f_\nu = 3631
Jy source, so the zero point is computed from the band's transmission
shape (see :func:_ab_photon_zeropoint) rather than tabulated. Supported
band names (case-insensitive): SDSS u g r i z, Gaia
gaia_g gaia_bp gaia_rp (also G BP RP), and 2MASS J H Ks. Each
carries a tophat spectral response, so spectral mode works out of the box;
supply a measured curve via :meth:SpectralBandpass.from_file for rigour.
Gaia bands are gaia_g, gaia_bp, gaia_rp (bp/rp also
accepted); g is SDSS g. Use :meth:johnson for the Vega system instead.
Source code in src/getframes/scene/photometry.py
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 | |
photon_flux(magnitude)
¶
Photons/s/m^2 above the atmosphere for a source of the given magnitude.
Source code in src/getframes/scene/photometry.py
154 155 156 | |
photon_flux_from_sed(sed)
¶
Photons/s/m^2 above the atmosphere from an absolute SED through this band.
Integrates int S(lambda) T(lambda) dlambda over the band's spectral
response, where S is the absolute photon flux density
(photons/s/m^2/nm) of an SED built with
:meth:getframes.spectral.SED.from_flux_density. This is the "true spectral
flux integration" path: the spectrum itself sets the rate, rather than a
magnitude. Requires a spectral :attr:response.
Source code in src/getframes/scene/photometry.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
effective_qe(qe, sed=None)
¶
Photon-weighted effective QE for a source of SED sed seen through this band.
Requires a spectral :attr:response. sed defaults to a flat photon
spectrum (the bandpass-weighted mean QE). See
:func:getframes.spectral.effective_qe.
Source code in src/getframes/scene/photometry.py
179 180 181 182 183 184 185 186 187 188 189 190 191 | |
getframes.scene.photometry.Extinction
dataclass
¶
Interstellar extinction (reddening) by intervening dust.
A Cardelli, Clayton & Mathis (1989) extinction curve, parameterised by the
visual extinction a_v (magnitudes of attenuation in V) and the total-to-
selective ratio r_v (3.1 for the diffuse Galactic ISM). It dims and reddens a
source: redder dust passes more light, so a blue source is attenuated more.
Use :meth:transmission for the wavelength-dependent throughput
10**(-0.4 A(lambda)), :meth:redden to apply it to an
:class:~getframes.spectral.SED, or :meth:band_attenuation_mag for the
band-integrated magnitude shift to add to a source magnitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a_v
|
float
|
Visual extinction |
required |
r_v
|
float
|
Total-to-selective extinction ratio |
3.1
|
Source code in src/getframes/scene/photometry.py
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 | |
attenuation_mag(wavelength_nm)
¶
Extinction A(lambda) in magnitudes at each wavelength (nm).
Wavelengths outside the CCM89 range (~303--3333 nm) are clamped to the nearest valid value.
Source code in src/getframes/scene/photometry.py
267 268 269 270 271 272 273 274 275 276 | |
transmission(wavelength_nm)
¶
Fractional transmission 10**(-0.4 A(lambda)) at each wavelength (nm).
Source code in src/getframes/scene/photometry.py
278 279 280 | |
transmission_curve(wavelength_nm)
¶
The transmission as a :class:~getframes.spectral.Spectrum (for :func:product).
Source code in src/getframes/scene/photometry.py
282 283 284 285 | |
redden(sed)
¶
Apply extinction to sed, returning a reddened copy (units preserved).
Source code in src/getframes/scene/photometry.py
287 288 289 290 | |
band_attenuation_mag(band, sed=None)
¶
Band-integrated extinction in magnitudes through band for a source sed.
The photon-weighted mean attenuation,
-2.5 log10(int S T 10^{-0.4 A} dl / int S T dl), evaluated on the band's
response grid. sed defaults to a flat photon spectrum. Add the result to
a source magnitude to dim it by the dust column. Requires a spectral
:attr:~Bandpass.response.
Source code in src/getframes/scene/photometry.py
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | |
getframes.scene.wcs.WCSInfo
dataclass
¶
A tangent-plane (TAN) world coordinate system for a detector frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
crval_ra_deg
|
float
|
Sky coordinates (degrees) of the reference point. |
required |
crval_dec_deg
|
float
|
Sky coordinates (degrees) of the reference point. |
required |
crpix_x
|
float
|
Pixel coordinates of the reference point, in 0-based array convention
( |
required |
crpix_y
|
float
|
Pixel coordinates of the reference point, in 0-based array convention
( |
required |
plate_scale_arcsec_per_pixel
|
float
|
Angular pixel size, matching the telescope's plate scale. |
required |
rotation_deg
|
float
|
Position angle of the y-axis east of north, in degrees ( |
0.0
|
Source code in src/getframes/scene/wcs.py
21 22 23 24 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 | |
header_cards()
¶
FITS WCS header cards for a TAN projection (8-char keywords, no astropy).
RA increases to the left (east), so CD1_1 carries the sign flip. The
rotation is folded into the CD matrix.
Source code in src/getframes/scene/wcs.py
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
to_astropy()
¶
Build an :class:astropy.wcs.WCS (requires astropy).
Source code in src/getframes/scene/wcs.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | |
pixel_to_world(x, y)
¶
Convert a 0-based pixel (x, y) to (ra_deg, dec_deg) (needs astropy).
Source code in src/getframes/scene/wcs.py
99 100 101 102 | |
world_to_pixel(ra_deg, dec_deg)
¶
Convert (ra_deg, dec_deg) to a 0-based pixel (x, y) (needs astropy).
Source code in src/getframes/scene/wcs.py
104 105 106 107 | |
getframes.scene.psf
¶
Point-spread functions: how a point source's flux is spread over pixels.
Each PSF knows how to add a source of a given total flux at a sub-pixel position into an image, conserving flux. Models are evaluated on a small stamp around the source for efficiency. The Gaussian uses the exact per-pixel integral (via the error function) so it is flux-conserving to machine precision; the Moffat is sampled on a stamp and normalised.
PSF
¶
Base class for point-spread functions.
Source code in src/getframes/scene/psf.py
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 | |
add_source(image, x, y, flux, plate_scale_arcsec_per_pixel)
¶
Add flux photons/s of a point source at sub-pixel (x, y) into image.
Source code in src/getframes/scene/psf.py
43 44 45 46 47 48 49 50 51 52 | |
add_sources(image, xs, ys, fluxes, plate_scale_arcsec_per_pixel)
¶
Add many point sources at once (vectorised where the PSF supports it).
xs, ys, fluxes are equal-length 1-D arrays of sub-pixel column,
row, and total flux. The generic implementation loops over
:meth:add_source; subclasses (e.g. :class:GaussianPSF) override it with a
batched, chunked evaluation so a large :class:~getframes.scene.sources.Catalog
does not pay a Python-level per-source loop.
Source code in src/getframes/scene/psf.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | |
GaussianPSF
dataclass
¶
Bases: PSF
A circular Gaussian PSF specified by its full width at half maximum.
Source code in src/getframes/scene/psf.py
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 | |
add_sources(image, xs, ys, fluxes, plate_scale_arcsec_per_pixel)
¶
Vectorised, chunked deposition of many Gaussian point sources.
Builds every source's exact per-pixel error-function integral on a common
stamp in one batched NumPy expression and scatter-adds it into image,
replacing the Python per-source loop. Identical pixel values to repeated
:meth:add_source calls (flux off the frame is clipped the same way). Work
is chunked over sources to keep the intermediate (chunk, stamp, stamp)
buffer bounded for very large catalogues.
Source code in src/getframes/scene/psf.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 | |
MoffatPSF
dataclass
¶
Bases: PSF
A Moffat PSF, a better match to seeing-limited stars than a Gaussian.
The beta parameter controls the wings: smaller beta gives broader wings
(beta -> infinity approaches a Gaussian). beta ~ 3 is typical for
atmospheric seeing.
Source code in src/getframes/scene/psf.py
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 | |
EllipticalGaussianPSF
dataclass
¶
Bases: PSF
An elliptical Gaussian PSF with independent major/minor widths and an angle.
position_angle_deg is the angle of the major axis, measured counter-clockwise
from the +x axis. The profile is sampled on a stamp and normalised (not the exact
error-function integral the circular :class:GaussianPSF uses), so flux is
conserved to the sampling accuracy.
Source code in src/getframes/scene/psf.py
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 | |
AiryPSF
dataclass
¶
Bases: PSF
The diffraction-limited Airy pattern of a circular aperture.
Models a space- or AO-corrected diffraction-limited core: the intensity is
[2 J1(x)/x]^2 with x = pi * D * theta / lambda, optionally including a
central obstruction of fractional diameter obstruction. The first dark ring
sits at theta = 1.22 lambda / D. Sampled on a stamp and normalised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aperture_diameter_m
|
float
|
Aperture diameter in metres (sets the angular scale of the pattern). |
required |
wavelength_m
|
float
|
Observing wavelength in metres. |
required |
obstruction
|
float
|
Central-obstruction diameter as a fraction of the aperture, in |
0.0
|
Source code in src/getframes/scene/psf.py
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 | |
ArrayPSF
dataclass
¶
Bases: PSF
A user-supplied PSF kernel, e.g. straight from an AO/optics simulation.
The kernel is a 2D array sampled at detector-pixel resolution; it is
normalised to unit sum on construction. Sub-pixel source positions are handled by
a first-order (bilinear) shift of the kernel before it is pasted, so the centroid
lands at the requested location. Flux falling off the frame is clipped.
Source code in src/getframes/scene/psf.py
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 | |
Time series¶
getframes.scene.sources.LightCurve
dataclass
¶
A time-varying brightness multiplier for a source.
A light curve maps a time t (seconds, measured from the start of an
observation) to a dimensionless factor that multiplies the source's baseline
brightness. A constant 1.0 leaves the source unchanged; 0.99 during a
transit dims it by 1%.
Time variability is owned by the source (see :attr:PointSource.brightness):
:meth:getframes.Camera.observe_series samples the curve at each frame's
timestamp, so the injected signal is reproducible and recorded in the
observation's per-frame truth.
Construct one with a factory (:meth:box, :meth:sinusoidal,
:meth:constant) or wrap any callable with :meth:from_function. The instance
itself is callable: lc(t) returns the multiplier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[[float], float]
|
Callable mapping time in seconds to a non-negative brightness multiplier. |
required |
Source code in src/getframes/scene/sources.py
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 | |
constant(level=1.0)
classmethod
¶
A flat light curve at level (default 1.0, i.e. no variation).
Source code in src/getframes/scene/sources.py
119 120 121 122 | |
box(depth, t0, t1, baseline=1.0)
classmethod
¶
A box-shaped dip of fractional depth between times t0 and t1.
Outside [t0, t1) the multiplier is baseline; inside it is
baseline * (1 - depth). A simple model of a flat-bottomed transit
(depth=0.01 for a 1% transit).
Source code in src/getframes/scene/sources.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
sinusoidal(amplitude, period_s, *, phase=0.0, baseline=1.0)
classmethod
¶
A sinusoid: baseline + amplitude * sin(2*pi*t/period + phase).
Models a pulsating or rotating variable. amplitude is in the same units
as baseline (i.e. a fraction of the unit baseline); keep
amplitude <= baseline to stay non-negative.
Source code in src/getframes/scene/sources.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | |
from_function(func)
classmethod
¶
Wrap an arbitrary t -> multiplier callable as a light curve.
Source code in src/getframes/scene/sources.py
166 167 168 169 | |
getframes.observation.Observation
dataclass
¶
A reproducible stack of frames of one scene over time.
Returned by :meth:getframes.Camera.observe_series. It is iterable and
indexable over its :attr:frames, so existing for frame in obs: style code
keeps working, while :attr:truth, :attr:times_s, and :attr:offsets_pixels
expose the time and pointing information.
Attributes:
| Name | Type | Description |
|---|---|---|
frames |
list[Frame]
|
The realised science :class: |
times_s |
NDArray[float64]
|
Frame timestamps in seconds, shape |
offsets_pixels |
NDArray[float64]
|
The realised pointing offset |
truth |
ObservationTruth | None
|
The :class: |
Source code in src/getframes/observation.py
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 | |
getframes.observation.ObservationTruth
dataclass
¶
The noise-free ground truth of an :class:Observation.
Attributes:
| Name | Type | Description |
|---|---|---|
times_s |
NDArray[float64]
|
The frame timestamps, in seconds from the start of the observation,
shape |
light_curve |
dict[str, NDArray[float64]]
|
Per-source injected signal: a mapping from source name to an array of the
noise-free incident photons collected from that source in each frame
(photon rate x exposure, post-optics, pre-quantum-efficiency), shape
|
Source code in src/getframes/observation.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
getframes.observation.Pointing
dataclass
¶
A per-frame pointing model: jitter, slow drift, and a programmed dither.
The three components combine additively into a whole-field offset applied to every source in the scene at each frame. Offsets are specified in arcseconds (converted to pixels with the scene's plate scale) so the model is independent of the detector sampling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
jitter_arcsec
|
float
|
RMS of a per-frame Gaussian offset drawn independently for each axis and
each frame. Models random tracking jitter and atmospheric tip-tilt / image
motion (e.g. for AO sub-apertures). |
0.0
|
drift_arcsec_per_s
|
tuple[float, float]
|
A constant |
(0.0, 0.0)
|
dither_arcsec
|
Sequence[tuple[float, float]] | None
|
An optional sequence of programmed |
None
|
Source code in src/getframes/observation.py
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 | |
is_static
property
¶
Whether this model never moves the field (a no-op pointing).
offset_pixels(frame_index, time_s, plate_scale_arcsec_per_pixel, rng)
¶
The realised (dx, dy) offset in pixels for one frame.
Combines drift (deterministic in time_s), the cycled dither entry, and a
fresh Gaussian jitter draw, then converts arcseconds to pixels.
Source code in src/getframes/observation.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | |
Spectral mode¶
getframes.spectral
¶
Wavelength-resolved primitives for the opt-in spectral mode.
The band-integrated model (a scalar quantum efficiency and a single photon zero point per band) is accurate enough for exposure planning, but it cannot capture how a detector's response colour interacts with a source's spectral energy distribution (SED). Spectral mode adds that, additively, through three tabulated curves on a shared wavelength axis (nanometres):
- :class:
SED--- a source's spectral photon flux density (shape only; the absolute level is still set by the source magnitude), - :class:
SpectralBandpass--- a filter/optics transmission response in[0, 1], - :class:
QE--- a detector quantum-efficiency curve in[0, 1].
The single physical quantity spectral mode computes is the effective quantum efficiency a source sees,
.. math::
\mathrm{QE}_\mathrm{eff} =
\frac{\int S(\lambda)\,T(\lambda)\,\mathrm{QE}(\lambda)\,d\lambda}
{\int S(\lambda)\,T(\lambda)\,d\lambda},
a photon-weighted average of :math:\mathrm{QE}(\lambda) over the band. It is a
ratio, so it is invariant to the absolute normalisation of both the SED and the
bandpass --- which is why spectral mode needs no absolute reference spectrum and
leaves the magnitude-to-photon-rate conversion (governed by the band zero point)
untouched. Only the photon-to-electron conversion is refined.
Everything here is pure NumPy and free of randomness.
Spectrum
dataclass
¶
A tabulated, non-negative curve value(wavelength_nm).
Values are linearly interpolated within the sampled range and treated as zero
outside it. The wavelength axis is in nanometres and must be strictly
increasing. This base class carries the shared sampling/integration machinery;
:class:SED, :class:SpectralBandpass, and :class:QE add units and
constructors.
Source code in src/getframes/spectral.py
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 | |
__call__(wavelength_nm)
¶
Interpolate the curve at wavelength_nm (zero outside the sampled range).
Source code in src/getframes/spectral.py
112 113 114 115 | |
from_file(path, *, wavelength_to_nm=1.0, delimiter=None, skiprows=0, usecols=(0, 1))
classmethod
¶
Load a two-column (wavelength, value) curve from a text file.
Reads path with :func:numpy.loadtxt. The first column is scaled by
wavelength_to_nm to nanometres (e.g. 0.1 for angstroms, 1000 for
microns); the second is taken verbatim. Handy for measured filter, QE, or
atmospheric-transmission curves --- combine several with :func:product or
:meth:SpectralBandpass.from_product.
Source code in src/getframes/spectral.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |
integrate()
¶
Trapezoidal integral of the curve over wavelength (nm).
Source code in src/getframes/spectral.py
140 141 142 | |
SED
dataclass
¶
Bases: Spectrum
A source's spectral photon flux density.
Two flavours, distinguished by :attr:is_absolute:
- Relative (the default; :meth:
from_arraysand the parametric shapes). Only the shape matters: spectral mode uses it to colour-weight the quantum efficiency, a calculation invariant to overall scale (the source magnitude still sets the absolute photon rate). - Absolute (:meth:
from_flux_density): values are a true photon flux density inphotons/s/m^2/nmabove the atmosphere. Such an SED can set the integrated photon rate directly --- pass it to a source asflux_sedand the telescope integrates it over the band (see :meth:getframes.scene.photometry.Bandpass.photon_flux_from_sed), instead of deriving the rate from a magnitude.
Source code in src/getframes/spectral.py
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 | |
from_arrays(wavelength_nm, photon_flux)
classmethod
¶
A relative SED sampled at wavelength_nm with photon flux density (shape only).
Source code in src/getframes/spectral.py
223 224 225 226 | |
from_flux_density(wavelength_nm, photon_flux_density)
classmethod
¶
An absolute SED: photon_flux_density in photons/s/m^2/nm.
Unlike :meth:from_arrays, the absolute scale is meaningful: integrated over
a band it yields a photon rate, so a source carrying this as flux_sed has
its brightness set by the spectrum itself (no magnitude needed). Wavelengths
and flux may be plain arrays (nm and photons/s/m^2/nm) or astropy.units
quantities, which are converted.
Source code in src/getframes/spectral.py
228 229 230 231 232 233 234 235 236 237 238 | |
flat(wavelength_min_nm=_DEFAULT_WL_MIN_NM, wavelength_max_nm=_DEFAULT_WL_MAX_NM)
classmethod
¶
A flat photon spectrum (equal photons per unit wavelength).
The neutral default: with a flat SED the effective QE is simply the
bandpass-weighted mean of QE(lambda).
Source code in src/getframes/spectral.py
240 241 242 243 244 245 246 247 248 249 250 251 252 | |
blackbody(temperature_k, wavelength_min_nm=_DEFAULT_WL_MIN_NM, wavelength_max_nm=_DEFAULT_WL_MAX_NM, n_samples=256)
classmethod
¶
A blackbody photon spectrum at temperature_k (relative units).
Photon spectral radiance ~ lambda**-4 / (exp(hc / lambda k T) - 1) --- the
Planck law expressed per photon rather than per unit energy. Good for giving
a star a colour (e.g. 5800 K for a sun-like source, 3500 K for a cool
M dwarf, 10000 K for a hot blue star).
Source code in src/getframes/spectral.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
power_law(index, reference_wavelength_nm=550.0, wavelength_min_nm=_DEFAULT_WL_MIN_NM, wavelength_max_nm=_DEFAULT_WL_MAX_NM, n_samples=64)
classmethod
¶
A power-law photon spectrum (lambda / lambda_ref)**index (relative).
Source code in src/getframes/spectral.py
278 279 280 281 282 283 284 285 286 287 288 289 | |
QE
dataclass
¶
Bases: Spectrum
A detector quantum-efficiency curve, QE(lambda) in [0, 1].
Source code in src/getframes/spectral.py
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 | |
from_arrays(wavelength_nm, qe)
classmethod
¶
A QE curve sampled at wavelength_nm with values in [0, 1].
Source code in src/getframes/spectral.py
300 301 302 303 | |
constant(value, wavelength_min_nm=_DEFAULT_WL_MIN_NM, wavelength_max_nm=_DEFAULT_WL_MAX_NM)
classmethod
¶
A flat QE curve --- equivalent to the scalar quantum_efficiency.
Source code in src/getframes/spectral.py
305 306 307 308 309 310 311 312 313 314 315 316 | |
SpectralBandpass
dataclass
¶
A filter/optics transmission response T(lambda) in [0, 1].
Carries the spectral shape of a band, used to colour-weight the effective QE.
It does not replace a :class:~getframes.scene.photometry.Bandpass's scalar
photon zero point (which still sets the magnitude-to-photon conversion); it
refines the photon-to-electron step.
Source code in src/getframes/spectral.py
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 | |
pivot_wavelength_nm
property
¶
The pivot wavelength: sqrt(int T dl / int T l^-2 dl) (nm).
mean_wavelength_nm
property
¶
The throughput-weighted mean wavelength (nm).
from_arrays(wavelength_nm, throughput)
classmethod
¶
A response curve sampled at wavelength_nm with throughput in [0, 1].
Source code in src/getframes/spectral.py
331 332 333 334 335 336 337 | |
from_file(path, **kwargs)
classmethod
¶
Load a two-column (wavelength, throughput) response from a text file.
Thin wrapper over :meth:Spectrum.from_file (same wavelength_to_nm,
delimiter, skiprows, usecols options); throughput must be in
[0, 1].
Source code in src/getframes/spectral.py
339 340 341 342 343 344 345 346 347 348 349 350 | |
from_product(*items)
classmethod
¶
Fold several transmission curves into one combined band response.
Each item is a :class:SpectralBandpass or a bare :class:Spectrum (e.g. a
:class:QE curve or an atmospheric-transmission curve); their pointwise
product over the common wavelength support becomes the new response. This is
how a real filter x QE x atmosphere transmission product is assembled.
Source code in src/getframes/spectral.py
352 353 354 355 356 357 358 359 360 361 362 363 364 365 | |
tophat(center_nm, width_nm, peak=1.0)
classmethod
¶
A flat-topped band of full width width_nm centred on center_nm.
Soft (one-sample) shoulders keep the curve continuous for integration.
Source code in src/getframes/spectral.py
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | |
johnson(band)
classmethod
¶
A tophat approximation of a Johnson-Cousins band (one of U, B, V, R, I).
Source code in src/getframes/spectral.py
395 396 397 398 399 400 401 402 403 | |
overlap_integral(*spectra)
¶
Integrate the pointwise product of several spectra over their common range.
Returns 0.0 when the spectra do not overlap (the product is zero there).
Source code in src/getframes/spectral.py
171 172 173 174 175 176 177 178 179 180 181 182 | |
product(*spectra)
¶
Pointwise product of several spectra as a new :class:Spectrum.
The result is sampled on the union of the inputs' knots within their common wavelength support, where the product of piecewise-linear curves is exact --- outside that support at least one factor is zero. The natural way to fold a measured filter transmission, detector QE, and atmospheric transmission into a single response curve. Raises if the inputs do not overlap.
Source code in src/getframes/spectral.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | |
effective_qe(qe, bandpass, sed=None)
¶
Photon-weighted effective quantum efficiency a source sees through a band.
Computes int S T QE dl / int S T dl over the wavelength range common to the
SED, bandpass, and QE curve. sed defaults to a flat photon spectrum, giving
the bandpass-weighted mean QE. The result is a dimensionless number in
[0, 1] and is invariant to the absolute scale of both S and T.
Source code in src/getframes/spectral.py
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
Analysis helpers¶
getframes.analysis.apertures
¶
Lightweight photometry helpers used by the examples and for quick analysis.
These are intentionally minimal (pure NumPy, no extra dependencies). For serious
photometry on real pipelines, reach for photutils; these exist so the bundled
examples stay self-contained and readable.
aperture_sum(image, center, r, *, annulus=None)
¶
Background-subtracted sum within radius r of center = (x, y).
The background level is the median of a surrounding annulus (default: from
r + 2 to r + 5 pixels), scaled to the number of aperture pixels. Pass
annulus=(inner, outer) to control it, or annulus=(0, 0) to skip
background subtraction.
Source code in src/getframes/analysis/apertures.py
24 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 | |
centroid(image, *, center=None, r=None, background=None)
¶
Intensity-weighted centroid (x, y) of image (or a region of it).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
center
|
tuple[float, float] | None
|
If both are given, only pixels within radius |
None
|
r
|
tuple[float, float] | None
|
If both are given, only pixels within radius |
None
|
background
|
float | None
|
Level subtracted before weighting, so the pedestal doesn't bias the centroid. Defaults to the image median, which works well for a small spot on a flat background. |
None
|
Returns:
| Type | Description |
|---|---|
(x, y):
|
Sub-pixel centroid. Returns the geometric centre if there is no positive signal after background subtraction. |
Source code in src/getframes/analysis/apertures.py
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 | |
getframes.analysis.ptc
¶
Photon transfer curve (PTC): characterise a camera from synthetic flats.
The PTC is the standard way to measure a detector's conversion gain. This module
generates flat pairs at a range of light levels, builds the variance-vs-mean
curve, and fits the gain --- turning the workflow in
examples/06_photon_transfer_curve.py into a one-liner.
PTCResult
dataclass
¶
The outcome of :func:photon_transfer_curve.
Attributes:
| Name | Type | Description |
|---|---|---|
mean_adu, variance_adu2 |
The measured photon transfer curve: per-level mean signal and noise variance, both in ADU. |
|
gain_e_per_adu |
float
|
Conversion gain fitted from the shot-noise-limited region (slope = 1/gain). |
read_noise_e |
float
|
Read noise measured from a pair of bias frames. |
full_well_adu |
float | None
|
Mean signal at which the variance peaks (onset of saturation), or |
Source code in src/getframes/analysis/ptc.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
photon_transfer_curve(camera, levels, exposure=1.0, *, temperature=None, seed=0)
¶
Measure a photon transfer curve for camera over the given flux levels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
Camera
|
The camera to characterise. |
required |
levels
|
NDArray[float64]
|
Incident photon rates (photons/s/pixel) to sample, ascending. Span from a few electrons up past saturation to capture the full curve. |
required |
exposure
|
float
|
Exposure time for each flat, in seconds. |
1.0
|
temperature
|
float | None
|
Sensor temperature; defaults to the camera's operating temperature. |
None
|
seed
|
int
|
Base seed; each flat uses a distinct derived seed for reproducibility. |
0
|
Source code in src/getframes/analysis/ptc.py
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 | |
Datasets & scale¶
getframes.dataset
¶
Scalable raw + ground-truth dataset generation (roadmap phase 1.6).
The library's reason to exist is paired data: a realistic raw frame and the
noise-free signal it was drawn from. :func:pairs turns a camera and a stream of
:class:~getframes.scene.scene.Scene objects into a reproducible sequence of
{"raw": ADU, "truth": electrons} pairs — training data for denoising,
deconvolution, or calibration networks — and streams it to disk in float32
without ever holding the whole set in memory.
:func:random_star_fields is a convenience generator of random star-field scenes
to feed it, but any iterable of scenes (matching the camera's resolution) works.
import getframes as gf cam = gf.Camera.from_preset("andor_ikon_m934", precision="float32") scenes = gf.dataset.random_star_fields(n=4, shape=cam.resolution, seed=0) ds = gf.dataset.pairs(camera=cam, scenes=scenes, exposure=10.0, seed=1) pair = next(iter(ds)) sorted(pair) ['raw', 'truth']
RandomStarFields
¶
A reproducible, re-iterable stream of random star-field :class:Scene objects.
Each scene is a field of uniformly placed point sources with magnitudes drawn
uniformly from mag_range and an optional uniform sky. The number of stars per
field is fixed (int) or drawn per field from a (low, high) range. The
stream is deterministic for a given seed (each field gets its own derived
seed) and can be iterated more than once.
Construct via :func:random_star_fields.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of scenes in the stream. |
required |
shape
|
tuple[int, int]
|
Scene size |
required |
optics
|
Telescope | None
|
The :class: |
None
|
psf
|
Telescope | None
|
The :class: |
None
|
n_stars
|
int | tuple[int, int]
|
Stars per field — a fixed count, or a |
(20, 200)
|
mag_range
|
tuple[float, float]
|
|
(16.0, 22.0)
|
sky_mag_arcsec2
|
float | None
|
Optional uniform sky surface brightness (mag/arcsec^2); |
21.0
|
seed
|
int | None
|
Base seed; field |
None
|
Source code in src/getframes/dataset.py
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 | |
PairDataset
¶
A lazy, reproducible sequence of raw + truth pairs (see :func:pairs).
Iterating yields {"raw": ADU, "truth": electrons} dicts, one per input
scene, each cast to :attr:dtype. The stream is single-pass when its scenes are
a one-shot iterator; pass a re-iterable scene source (e.g.
:class:RandomStarFields) to iterate more than once. Materialise to disk with
:meth:to_npz or into stacked arrays with :meth:to_arrays.
Source code in src/getframes/dataset.py
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 | |
to_npz(directory, *, prefix='pair', compress=False)
¶
Write each pair to {directory}/{prefix}_{i:06d}.npz and return the paths.
Each archive holds raw (ADU) and truth (electrons) arrays in
:attr:dtype. Streams pair by pair, so the whole set is never resident in
memory. compress uses :func:numpy.savez_compressed.
Source code in src/getframes/dataset.py
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | |
to_arrays()
¶
Stack the whole dataset into (raw, truth) arrays of shape (N, H, W).
Convenient for small sets; holds everything in memory, unlike :meth:to_npz.
Source code in src/getframes/dataset.py
241 242 243 244 245 246 247 248 249 250 251 252 253 | |
random_star_fields(n, shape, *, optics=None, psf=None, n_stars=(20, 200), mag_range=(16.0, 22.0), sky_mag_arcsec2=21.0, seed=None)
¶
Build a reproducible :class:RandomStarFields stream of n star-field scenes.
A convenience source of scenes for :func:pairs; see :class:RandomStarFields
for the parameters.
Source code in src/getframes/dataset.py
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 | |
pairs(*, camera, scenes, exposure, temperature=None, dtype=np.float32, seed=None)
¶
Build a :class:PairDataset of raw + truth pairs from a camera and scenes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
Camera
|
The :class: |
required |
scenes
|
Iterable[Scene]
|
Any iterable of :class: |
required |
exposure
|
float
|
Integration time in seconds for every frame. |
required |
temperature
|
float | None
|
Sensor temperature (deg C); defaults to the camera's. |
None
|
dtype
|
DTypeLike
|
Storage dtype for the |
float32
|
seed
|
int | None
|
Base seed; frame |
None
|
Source code in src/getframes/dataset.py
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 | |
Command line¶
getframes.cli
¶
The getframes command-line interface (roadmap phase 1.6).
A thin wrapper that turns a TOML configuration file into frames or an ML dataset, so an experiment is a file you can share and run without writing Python. Three subcommands:
getframes presets— list the built-in camera presets.getframes generate config.toml -o frame.fits— generate one frame (or a short series) of a given type (dark/bias/flat/light).getframes dataset config.toml -o train/— stream raw + truth pairs to disk.
See :func:main. Run getframes --help for the full usage.
build_parser()
¶
Construct the getframes argument parser.
Source code in src/getframes/cli.py
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
main(argv=None)
¶
Entry point for the getframes command. Returns a process exit code.
Source code in src/getframes/cli.py
202 203 204 205 206 207 208 209 210 | |
Noise models¶
getframes.noise
¶
Physical noise models that turn a :class:CameraConfig into pixel values.
The models here are deliberately small, composable, and well-documented so that
the physics is auditable. Each function takes a configuration, exposure, and a
seeded :class:numpy.random.Generator, and returns electrons or ADU.
Signal chain (:func:simulate_frame)
- Mean photo signal:
(photon_rate + background) * t_exp * QEelectrons, modulated per pixel by photo-response non-uniformity (PRNU). - Mean dark signal:
D(T) * t_expelectrons (temperature-scaled), modulated by dark-signal non-uniformity (DSNU) and hot pixels. - Shot noise: the total electrons are Poisson-distributed about that mean.
- Clock-induced charge (EMCCD) adds a small Poisson term.
- Cosmic rays (single pixels or extended tracks).
- Charge-transport artifacts: blooming along saturated columns, CCD charge-transfer inefficiency (CTI), and inter-pixel capacitance (IPC).
- Detector nonlinearity (single-parameter or polynomial).
- EM register / avalanche multiplication with its stochastic excess noise.
- kTC/reset noise and read noise: Gaussian in electrons, at the output amplifier.
- Conversion to ADU via (optionally per-amplifier) gain, plus the bias pedestal and any structured-bias pattern; dead pixels/columns read as defects.
- Saturation at full well / ADC range and quantisation to integers.
A dark frame is simply the special case photon_rate = 0.
SimulationResult
¶
Bases: NamedTuple
The output of :func:simulate_frame: the digitised frame plus ground truth.
Source code in src/getframes/noise.py
488 489 490 491 492 493 494 | |
dark_signal_map(config, exposure_s, temperature_c, float_dtype=DEFAULT_FLOAT_DTYPE)
¶
Per-pixel mean dark signal in electrons, including fixed-pattern structure.
This is the noise-free expectation per pixel; shot noise is applied separately.
The fixed-pattern structure (DSNU and hot pixels) is deterministic for a given
sensor (keyed on :attr:~getframes.config.CameraConfig.fixed_pattern_seed), so
it repeats across frames and can be calibrated out with a master dark. A uniform
detector-glow term (detector_glow_e_per_s) is added on top, also
exposure-scaled and dark-removable.
float_dtype selects the working precision (float64 exact default, or
float32 for the memory-light fast path).
Source code in src/getframes/noise.py
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 | |
photo_signal_map(config, photon_rate, exposure_s, background_photon_rate, quantum_efficiency=None, float_dtype=DEFAULT_FLOAT_DTYPE)
¶
Per-pixel mean photo-generated signal in electrons (noise-free).
Converts an incident photon rate (photons/s/pixel, plus an additive
background) to photoelectrons via the quantum efficiency, then imprints a
fixed multiplicative PRNU pattern. photon_rate may be a scalar (uniform
illumination) or a 2-D array matching the sensor resolution.
The PRNU pattern is deterministic for a given sensor (keyed on
:attr:~getframes.config.CameraConfig.fixed_pattern_seed), so it repeats across
frames and is removable with a master flat.
quantum_efficiency overrides config.quantum_efficiency when given. The
spectral path uses this with a pre-multiplied (already-photoelectron) map and
quantum_efficiency = 1.0. float_dtype selects the working precision
(float64 default, or float32 for the memory-light fast path).
Source code in src/getframes/noise.py
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 | |
apply_gain_stage(electrons, gain, excess_noise_factor, rng)
¶
Apply a stochastic multiplication stage (EM register or APD avalanche).
A single model covers both EMCCDs and avalanche photodiodes, parameterised by
the mean gain G and the excess noise factor F. For n input
electrons the multiplied output is drawn from a Gamma distribution:
.. math::
\text{out} \sim \mathrm{Gamma}(\text{shape}=n\alpha,\ \text{scale}=\theta),
\quad \alpha = \frac{1}{F^2 - 1}, \quad \theta = G\,(F^2 - 1).
Then :math:E[\text{out}] = nG and, with Poisson input of mean :math:\mu, the
total output variance is :math:G^2 F^2 \mu --- i.e. the model reproduces the
requested excess noise factor exactly. Special cases:
F = sqrt(2)givesalpha = 1--- the classic EMCCDGamma(n, G)model.F -> 1is noiseless multiplication (deterministicn * G).
Pixels with zero input electrons produce zero output.
Source code in src/getframes/noise.py
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 | |
apply_em_gain(electrons, em_gain, rng)
¶
Backwards-compatible EMCCD multiplication (F = sqrt(2) gain stage).
Thin wrapper over :func:apply_gain_stage; prefer that for new code.
Source code in src/getframes/noise.py
204 205 206 207 208 209 210 211 212 213 | |
apply_nonlinearity(electrons, config)
¶
Bend the charge response near full well (detector nonlinearity).
Two models, both deterministic (no randomness):
- Polynomial (when
config.nonlinearity_coeffsis set): withu = q / full_welland coefficients(c1, c2, ...), the response multiplier is1 + c1 u + c2 u**2 + ..., so an arbitrary measured curve or look-up can be reproduced. - Single-parameter (the default):
q -> q * (1 - nonlinearity * q / full_well), a smooth, monotonic compression so a pixel near full well reads slightly low.
The polynomial model takes precedence when both are configured.
Source code in src/getframes/noise.py
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 | |
apply_blooming(electrons, full_well_e)
¶
Bleed charge above full well along columns (CCD blooming).
Charge exceeding full_well_e in a pixel floods symmetrically into the
vacant pixels of the same column (axis=0): half the excess sweeps toward
higher rows and half toward lower rows, each filling successive pixels up to
full well until the charge is absorbed or runs off the array edge. Deterministic
and charge-conserving except for charge that bleeds off the top/bottom edge.
Source code in src/getframes/noise.py
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 | |
apply_cti(electrons, cti)
¶
Smear charge by charge-transfer inefficiency (CTI) during readout.
A first-order, charge-conserving model: the readout register is row 0, so a
pixel r rows away undergoes r transfers and defers a fraction
cti * r of its charge into the trailing pixel one row farther from the
register (axis=0), producing the characteristic CTI tail. Charge deferred
past the final row is lost into overscan. Deterministic.
Source code in src/getframes/noise.py
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | |
apply_ipc(electrons, coupling)
¶
Couple a fraction of each pixel into its four neighbours (inter-pixel capacitance).
Convolves with the charge-conserving 3x3 kernel whose centre is
1 - 4*coupling and whose four edge-adjacent taps are coupling each
(corners zero). Models the capacitive crosstalk of CMOS / IR hybrid arrays.
Charge coupling past the array boundary is lost. Deterministic.
Source code in src/getframes/noise.py
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | |
add_cosmic_rays(electrons, config, exposure_s, rng)
¶
Deposit cosmic-ray charge bursts into random pixels.
The number of hits is Poisson with mean rate * area * exposure; each hit
carries a broad charge burst of order ten thousand electrons. When
config.cosmic_ray_track_length_px is zero the charge lands in a single
pixel; when positive, each hit draws an exponential track length and a random
in-plane direction (a glancing muon) and spreads its charge evenly along the
track --- the extended morphology a real rejection pipeline must handle.
Source code in src/getframes/noise.py
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 | |
digitize(electrons, config, rng)
¶
Add read/reset noise, convert electrons to ADU, then saturate and quantise.
Read noise is referenced to the sensor output amplifier. When
read_noise_nonuniformity is set (sCMOS), each pixel gets its own read-noise
RMS drawn from a log-normal distribution about read_noise_e.
Detector-depth structure is folded in here: dead pixels/columns collect no charge; kTC/reset noise adds a per-pixel Gaussian; a multi-amplifier layout applies per-block conversion gain and offset; and a fixed structured-bias pattern rides on the flat pedestal.
Source code in src/getframes/noise.py
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 | |
frame_electrons(config, mean_electrons, rng, exposure_s=0.0)
¶
Apply shot noise, CIC, cosmic rays, nonlinearity, and any gain stage.
Takes the noise-free expected electrons per pixel and returns a realised
electron frame prior to read noise and digitisation. exposure_s is needed
only to scale the cosmic-ray rate. The working dtype follows mean_electrons
(float64 exact, or float32 for the memory-light fast path).
Source code in src/getframes/noise.py
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 | |
simulate_frame(config, photon_rate, exposure_s, *, temperature_c, background_photon_rate=0.0, quantum_efficiency=None, extra_electrons=0.0, rng=None, seed=None, float_dtype=DEFAULT_FLOAT_DTYPE)
¶
Simulate one frame end-to-end, returning ADU and the noise-free truth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
CameraConfig
|
The detector configuration. |
required |
photon_rate
|
PhotonRate
|
Incident photon rate in photons/s/pixel, as a scalar (uniform) or a 2-D
array. Use |
required |
exposure_s
|
float
|
Integration time in seconds ( |
required |
temperature_c
|
float
|
Sensor temperature in degrees Celsius. |
required |
background_photon_rate
|
PhotonRate
|
Additive background (sky/thermal) photon rate in photons/s/pixel. |
0.0
|
quantum_efficiency
|
float | None
|
Overrides |
None
|
extra_electrons
|
PhotonRate
|
Additive noise-free signal already in electrons (scalar or 2-D array), injected before shot noise and the gain stage. Used to carry latent charge from image persistence across the frames of an observation; it is real charge in the well, so it picks up shot noise and any EM/avalanche gain. |
0.0
|
rng
|
Generator | None
|
Provide an existing generator, or a seed to build a fresh one. |
None
|
seed
|
Generator | None
|
Provide an existing generator, or a seed to build a fresh one. |
None
|
float_dtype
|
DTypeLike
|
Working floating-point precision of the per-pixel arrays: |
DEFAULT_FLOAT_DTYPE
|
Source code in src/getframes/noise.py
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 | |
generate_dark_frame(config, exposure_s, temperature_c, rng=None, seed=None)
¶
End-to-end dark frame in ADU (the photon_rate = 0 case of simulate_frame).
Source code in src/getframes/noise.py
597 598 599 600 601 602 603 604 605 606 607 | |
dark_frame_electrons(config, exposure_s, temperature_c, rng)
¶
Electron-domain dark frame prior to digitisation (kept for convenience).
Source code in src/getframes/noise.py
610 611 612 613 614 615 616 617 618 | |