opticks.imaging_model.detector

Classes

AbsorptionData(**data)

Reference to an external absorption coefficient data file.

Channel(**data)

Create a new model by parsing and validating input data from keyword arguments.

Detector(**data)

Class containing generic Detector parameters.

DetectorType(*values)

Detector type enumeration.

Noise(**data)

Noise parameters for a Detector.

SensorParams(**data)

Image sensor physical parameters (diffusion MTF, CTE, crosstalk).

Timings(**data)

Timing parameters for a Detector.

class AbsorptionData(**data)[source]

Reference to an external absorption coefficient data file.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • file (str)

  • csv_separator (str | None)

csv_separator: str | None
file: str
model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class Channel(**data)[source]

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • name (str)

  • horizontal_pixels (Annotated[int, Gt(gt=0)])

  • vertical_pixels (Annotated[int, Gt(gt=0)])

  • binning (int)

  • tdi_stages (int)

  • read_blocks (Annotated[int, Gt(gt=0)])

  • cuton_wvl (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • cutoff_wvl (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • is_binned (bool)

  • frame_duration (Quantity | None)

  • frame_rate (Quantity | None)

  • integration_duration (Quantity | None)

  • max_integration_duration (Quantity | None)

  • total_tdi_col_duration (Quantity | None)

property bandwidth: Quantity

Computes the bandwidth of the channel (the difference between the cut-off and cut-on wavelengths).

Returns:

Quantity – Bandwidth of the channel (in wavelengths)

binning: int
property centre_wavelength: Quantity

Computes the centre wavelength of the channel.

Returns:

Quantity – Centre wavelength of the channel

cutoff_wvl: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
cuton_wvl: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
frame_duration: Quantity | None
frame_rate: Quantity | None
horizontal_pixels: Annotated[int, Gt(gt=0)]
integration_duration: Quantity | None
is_binned: bool
max_integration_duration: Quantity | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Return type:

None

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

name: str
nyquist_freq(with_binning=True)[source]

Returns Nyquist Frequency / Limit parameter with or without binning.

Nyquist frequency is defined as: 1 / (2 x pix pitch), which translates to one line pair per two pixels (e.g., one pixel white, next one black). This is the absolute maximum limiting resolution of the sensor.

Return type:

Quantity

Parameters:

with_binning (bool) – Return the value with binning or not

Returns:

nyquist_limit (Quantity) – Nyquist limit in cycles/mm

pix_read_rate(frame_rate, with_binning=True, with_tdi=False, with_read_blocks=True)[source]

Pixel read rate.

Return type:

Quantity

Parameters:
Computed as:
  • Pushbroom type: horiz pix (binned) x TDI stages x read blocks x line rate

  • Full frame type: horiz pix (binned) x vert pix (binned) x frame rate

Parameters:
  • frame_rate (Quantity) – Frame or line rate (in Hz)

  • with_binning (bool) – Return the value with binning or not

  • with_tdi (bool) – Return the value with TDI or not (valid for pushbroom only)

  • with_read_blocks (bool) – Return the value with read blocks or not (valid for pushbroom only)

Returns:

Quantity – Pixel read rate with or without binning (Mpixel/s)

Return type:

Quantity

pixel_area(with_binning=True)[source]

Pixel geometric area.

Computed as the square of pixel pitch. The effective pixel area is smaller, even for a pixel with a single sensing element.

Return type:

Quantity

Parameters:

with_binning (bool) – Return the value with binning or not

Returns:

Quantity – Pixel area with or without binning

pixel_count_frame(with_binning=True)[source]

Computes the total number of pixels in the channel with/without binning.

Return type:

Quantity

Parameters:

with_binning (bool) – Return the value with binning or not

Returns:

Quantity – Total number of pixels for the requested configuration

pixel_count_line(with_binning=True)[source]

Computes the total number of pixels in the detector line with/without binning.

Return type:

Quantity

Parameters:

with_binning (bool) – Return the value with binning or not

Returns:

Quantity – Total number of pixels for the requested configuration (in Mpixels)

pixel_pitch(with_binning=True)[source]

Returns pixel pitch parameter with or without binning.

This corresponds to an effective pixel pitch.

Return type:

Quantity

Parameters:

with_binning (bool) – Return the value with binning or not

Returns:

Quantity – Pixel pitch with or without binning

read_blocks: Annotated[int, Gt(gt=0)]
tdi_stages: int
total_tdi_col_duration: Quantity | None
vertical_pixels: Annotated[int, Gt(gt=0)]
class Detector(**data)[source]

Class containing generic Detector parameters.

A Detector has one or more Channel objects.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • name (str)

  • detector_type (DetectorType)

  • pixel_pitch (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • horizontal_pixels (Annotated[int, Gt(gt=0)])

  • vertical_pixels (Annotated[int, Gt(gt=0)])

  • channels (dict[str, Channel])

  • full_well_capacity (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • noise (Noise | None)

  • timings (Timings)

  • sensor_params (SensorParams | None)

channels: dict[str, Channel]
detector_type: DetectorType
full_well_capacity: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
get_channel(band_id)[source]

Gets the channel with the ‘band_id’.

Return type:

Channel

Parameters:

band_id (str) – band ID corresponding to the requested channel

Returns:

Channel – Requested channel with the ‘band_id’

get_channels(band_ids)[source]

Gets the list of channels with the ‘band_id’.

Return type:

list[Channel]

Parameters:

band_ids (Iterable[str]) – band IDs corresponding to the requested channels

Returns:

list[Channel] – Requested channels with the ‘band_id’

get_crosstalk_mtf_1d(channel_id, with_binning=True)[source]

Generate crosstalk MTF model for this detector.

Uses the crosstalk coefficients from sensor_params and the pixel pitch for the given channel.

Return type:

MTF_Model_1D

Parameters:
  • channel_id (str) – Channel identifier.

  • with_binning (bool, optional) – If True (default), use the channel’s effective pitch accounting for binning. If False, use the native pixel pitch.

Returns:

MTF_Model_1D – Crosstalk MTF model.

Raises:

ValueError – If sensor_params or crosstalk_xs is not configured.

get_cte_mtf_1d(num_pixels, channel_id, with_binning=True, tdi_stages=None)[source]

Generate CTE MTF model for this detector.

Uses cte_num_phases and cte_value from sensor_params and the pixel pitch for the given channel.

num_pixels is a required runtime argument: the number of pixel shifts from the target pixel to the readout register, which is both position-dependent and direction-dependent. cte_tdi_stages from sensor_params is used unless overridden by the tdi_stages argument (pass tdi_stages=0 for the ACT direction on a TDI sensor without modifying sensor_params).

Return type:

MTF_Model_1D

Parameters:
  • num_pixels (int) – Number of pixels between the target pixel and the readout register.

  • channel_id (str) – Channel identifier.

  • with_binning (bool, optional) – If True (default), use the channel’s effective pitch accounting for binning. If False, use the native pixel pitch.

  • tdi_stages (int, optional) – Override for the number of on-chip analog TDI stages. If None, falls back to sensor_params.cte_tdi_stages (or 0 if unset).

Returns:

MTF_Model_1D – CTE MTF model.

Raises:

ValueError – If sensor_params, cte_num_phases, or cte_value is not configured.

get_det_sampling_mtf_1d(channel_id, with_binning=True)[source]

Generate detector sampling MTF model for this detector.

The sampling MTF is a sinc function of the effective pixel pitch for the given channel.

Return type:

MTF_Model_1D

Parameters:
  • channel_id (str) – Channel identifier.

  • with_binning (bool, optional) – If True (default), use the channel’s effective pitch accounting for binning. If False, use the native pixel pitch.

Returns:

MTF_Model_1D – Detector sampling MTF model.

get_diffusion_mtf_1d(wavelength)[source]

Generate diffusion MTF model for this detector at the given wavelength.

The diffusion MTF is isotropic (same in ALT and ACT directions).

Looks up the absorption coefficient from the sensor_params absorption table, then delegates to MTF_Model_1D.detector_diffusion() or MTF_Model_1D.detector_diffusion_preset().

Return type:

MTF_Model_1D

Parameters:

wavelength (Quantity) – Wavelength at which to compute the diffusion MTF.

Returns:

MTF_Model_1D – Diffusion MTF model.

Raises:

ValueError – If sensor_params or absorption_data is not configured.

horizontal_pixels: Annotated[int, Gt(gt=0)]
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_Detector__context)[source]

Initialises derived parameters after Pydantic validation.

Overrides the abstract pydantic method to perform additional initialization after __init__ and model_construct.

name: str
noise: Noise | None
pix_read_rate(band_id, with_binning=True, with_tdi=True, with_read_blocks=True)[source]

Pixel read rate.

Return type:

Quantity

Parameters:
Computed as:
  • Pushbroom type: horiz pix (binned) x TDI stages x read blocks x line rate

  • Full frame type: horiz pix (binned) x vert pix (binned) x frame rate

If a list of channels is given, then the returned result is the sum of all the requested channels.

Parameters:
  • band_id (str or Iterable[str]) – band ID to compute the readout

  • with_binning (bool) – Return the value with binning or not

  • with_tdi (bool) – Return the value with TDI or not (valid for pushbroom only)

  • with_read_blocks (bool) – Return the value with read blocks or not (valid for pushbroom only)

Returns:

Quantity – Pixel read rate with or without binning (Mpixels)

Return type:

Quantity

property pixel_count: Quantity

Computes the total number of pixels in the detector.

Returns:

Quantity – Total number of pixels for the requested configuration (in Mpixels)

pixel_pitch: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
sensor_params: SensorParams | None
timings: Timings
vertical_pixels: Annotated[int, Gt(gt=0)]
class DetectorType(*values)[source]

Detector type enumeration.

FULL_FRAME = 'full frame'
PUSHBROOM = 'pushbroom'
class Noise(**data)[source]

Noise parameters for a Detector.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • dark_current (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • temporal_dark_noise (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

dark_current: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

temporal_dark_noise: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
class SensorParams(**data)[source]

Image sensor physical parameters (diffusion MTF, CTE, crosstalk).

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • diffusion_model (str | None)

  • diffusion_preset (str | None)

  • diffusion_length (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • field_free_depth (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • depletion_depth (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=~opticks.utils.parser_helpers._validate_positive_quantity), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • surface_recomb_velocity (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • diffusion_coeff (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • crosstalk_xs (float | None)

  • crosstalk_xd (float | None)

  • cte_num_phases (int | None)

  • cte_value (float | None)

  • cte_tdi_stages (int | None)

  • absorption_data (AbsorptionData | None)

absorption_data: AbsorptionData | None
crosstalk_xd: float | None
crosstalk_xs: float | None
cte_num_phases: int | None
cte_tdi_stages: int | None
cte_value: float | None
depletion_depth: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
diffusion_coeff: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
diffusion_length: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
diffusion_model: str | None
diffusion_preset: str | None
field_free_depth: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), AfterValidator(func=_validate_positive_quantity), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
get_absorption_coeff(wavelength)[source]

Return the absorption coefficient at the given wavelength.

Return type:

Quantity

Parameters:

wavelength (Quantity) – Wavelength at which to interpolate α.

Returns:

Quantity – Absorption coefficient with units from the data file.

load_absorption_data()[source]

Load absorption coefficient data from the external file.

Resolves the file path relative to the current working directory. The file is self-describing: comment lines start with #, the first non-comment line is the header declaring column names and units (e.g. wavelength (nm)  alpha (1/um)), and subsequent lines are data rows.

Return type:

None

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Return type:

None

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

surface_recomb_velocity: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
class Timings(**data)[source]

Timing parameters for a Detector.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Parameters:
  • frame_rate (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)] | None)

  • integration_duration (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • frame_overhead_duration (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • frame_overlap_duration (Annotated[Quantity, BeforeValidator(func=~opticks.utils.parser_helpers._parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=~opticks.utils.parser_helpers._serialize_quantity, return_type=str, when_used=always)])

  • frame_duration (Quantity | None)

frame_duration: Quantity | None
frame_overhead_duration: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
frame_overlap_duration: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
frame_rate: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)] | None
integration_duration: Annotated[Quantity, BeforeValidator(func=_parse_quantity, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_quantity, return_type=str, when_used=always)]
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].