Source code for pyxel.models.photon_collection.stripe_pattern
# Copyright (c) European Space Agency, 2020.
#
# This file is subject to the terms and conditions defined in file 'LICENCE.txt', which
# is part of this Pyxel package. No part of the package, including
# this file, may be copied, modified, propagated, or distributed except according to
# the terms contained in the file ‘LICENCE.txt’.
"""Stripe pattern illumination model."""
from typing import TYPE_CHECKING
import numpy as np
import skimage.transform as tr
if TYPE_CHECKING:
from pyxel.detectors import Detector
def square_signal(n: int, lw: int, start_with: int = 0) -> list[int]:
"""Compute a 1D periodic square signal.
Parameters
----------
n : int
Length of the signal.
lw
Width of a pulse.
start_with
1 to start with high level or 0 for 0.
Returns
-------
list
Output list.
"""
if lw > n // 2:
raise ValueError("Line too wide.")
start: list[int] = [start_with] * lw
second: list[int] = [1 - start_with] * lw
pair = start + second
num = n // len(pair)
out = pair * num
return out
def compute_pattern(
detector_shape: tuple,
period: int = 2,
level: float = 1,
angle: float = 0,
start_with: int = 0,
) -> np.ndarray:
"""Return an array of a periodic pattern.
Parameters
----------
detector_shape : tuple
Detector shape.
period : int
Period of the periodic pattern in pixels.
level : float
Amplitude of the periodic pattern.
angle : int
Angle of the pattern in degrees.
start_with : int
1 to start with high level or 0 for 0.
Returns
-------
ndarray
Output stripe pattern.
"""
if period < 2:
raise ValueError("Can not set a period smaller than 2 pixels.")
elif (period % 2) != 0:
raise ValueError("Period should be a multiple of 2.")
if start_with not in (0, 1):
raise ValueError("")
y, x = detector_shape
n = max(y, x) * 2
m = max(y, x) * 2
sx = slice(n // 2 - y // 2, n // 2 + y // 2)
sy = slice(m // 2 - x // 2, m // 2 + x // 2)
signal_lst: list[int] = square_signal(n=n, lw=period // 2, start_with=start_with)
new_signal_lst: list[int] = signal_lst + ([1] * (n - len(signal_lst)))
signal = np.array(new_signal_lst)[::-1]
out = np.ones((n, m))
for i in range(m):
out[:, i] = signal
out = level * out
if angle:
out = tr.rotate(out, angle=angle)
out = out[sx, sy]
return out
[docs]
def stripe_pattern(
detector: "Detector",
period: int = 10,
level: float = 1.0,
angle: int = 0,
startwith: int = 0,
time_scale: float = 1.0,
) -> None:
"""Stripe pattern model.
Parameters
----------
detector : Detector
Detector object.
period : int
Period of the periodic pattern in pixels.
level : float
Amplitude of the periodic pattern.
angle : int
Angle of the pattern in degrees.
startwith : int
1 to start with high level or 0 for 0.
time_scale : float
Time scale of the photon flux, default is 1 second. 0.001 would be ms.
"""
photon_array = compute_pattern(
detector_shape=(detector.geometry.row, detector.geometry.col),
period=period,
level=level,
start_with=startwith,
angle=angle,
)
photon_array = photon_array * (detector.time_step / time_scale)
detector.photon += photon_array