Misc (pyobs.images.processors.misc)
AddMask
- class AddMask(masks: dict[str, dict[str, ndarray[tuple[Any, ...], dtype[floating[Any]]] | str]], **kwargs: Any)
Attach a precomputed mask to an image based on instrument and binning.
This processor selects a mask from a user-provided dictionary keyed by instrument name and binning, and assigns it to
image.maskin a returned copy of the image. Masks can be provided directly as NumPy arrays or as paths to FITS files, which are loaded viaastropy.io.fits.getdata().- Parameters:
masks (dict[str, dict[str, numpy.ndarray | str]]) –
Mapping of instrument name (matching
INSTRUME) to a mapping of binning strings (e.g.,"1x1","2x2") to either:a NumPy array mask, or
a string path to a FITS file containing the mask array.
The selected mask must match the image shape for the given instrument and binning.
kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
Builds an internal lookup of masks during initialization:
If a value is a NumPy array, it is stored as-is.
If a value is a string, loads the mask array using
fits.getdata(path).Otherwise, raises
ValueError("Unknown mask format.").
On processing:
Reads
INSTRUME,XBINNING, andYBINNINGfrom the FITS header.Constructs the binning key as
"%dx%d" % (XBINNING, YBINNING).Retrieves a copy of the corresponding mask and assigns it to
output_image.mask.If no mask is found for the instrument/binning, logs a warning and returns the image unchanged.
Returns a copy of the input image; pixel data are not modified.
Input/Output
Input:
pyobs.images.Imagewith FITS header keysINSTRUME,XBINNING, andYBINNING.Output:
pyobs.images.Image(copied) withmaskset when available; pixel data and other headers are unchanged.
Configuration (YAML)
Provide masks for multiple instruments and binning modes, mixing arrays and files:
class: pyobs.images.processors.misc.AddMask masks: CAM_A: "1x1": "/path/to/cam_a_1x1_mask.fits" "2x2": "/path/to/cam_a_2x2_mask.fits" CAM_B: "1x1": "/path/to/cam_b_1x1_mask.fits"
Notes
Ensure mask arrays have the same shape as the image data for the selected instrument and binning. If your images are color/multi-plane, provide masks matching the plane used downstream, or adapt prior processing accordingly.
Mask dtype can be boolean or numeric; downstream code typically treats non-zero values as masked. Use boolean masks for clarity.
The binning key must match the exact
"%dx%d"format built fromXBINNINGandYBINNINGin the image header.Loaded FITS masks use the primary data returned by
fits.getdata; if your mask resides in a different HDU, adjust accordingly.
CatalogCircularMask
- class CatalogCircularMask(radius: float, center: Tuple[int, int] | Tuple[float, float] | Tuple[str, str] = ('CRPIX1', 'CRPIX2'), exclude_circle: bool = False, **kwargs: Any)
Filter a source catalog by keeping only entries inside a central circle (or outside it).
This processor applies a circular spatial filter to the catalog attached to a
pyobs.images.Image. It either retains sources whose positions fall within a specified radius of a chosen center, or excludes them ifexclude_circleis set. Pixel data are not modified; only the image catalog is filtered in place.- Parameters:
radius (float) – Radius of the circle in pixels used for filtering. Default: required.
center (tuple[int, int] | tuple[float, float] | tuple[str, str]) – Center of the circle. Either a pair of numeric pixel coordinates
(x, y), or a pair of FITS header keywords whose values define the center (default:("CRPIX1", "CRPIX2")). The center must use the same coordinate convention as the catalog (typically FITS 1-based indices in pyobs catalogs).exclude_circle (bool) – If
False, keep only sources inside the circle. IfTrue, exclude sources inside the circle and keep those outside. Default:False.kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
If the image has no catalog (
image.safe_catalog is None), the image is returned unchanged.Determines the circle center:
If
centeris a pair of strings, reads their values from the FITS header.If
centeris numeric, uses those pixel coordinates directly.
Builds a boolean mask on the catalog using Euclidean distance in pixel units:
Inside selection:
(x - cx)^2 + (y - cy)^2 <= radius^2.Outside selection (if
exclude_circle): the inequality is reversed.
Applies the mask to the catalog and assigns the filtered catalog back to
image.catalog.Returns the original image object with a filtered catalog; pixel data and header are unchanged.
Input/Output
Input:
pyobs.images.Imagewith a source catalog containingxandycolumns, and optionally header keys for the center ifcenteris given as strings.Output:
pyobs.images.Imagewith its catalog filtered by the circular criterion. Pixel data are unchanged.
Configuration (YAML)
Keep sources within 300 pixels of CRPIX center:
class: pyobs.images.processors.misc.CatalogCircularMask radius: 300 center: ["CRPIX1", "CRPIX2"] exclude_circle: false
Exclude a 100-pixel radius around a specified pixel center:
class: pyobs.images.processors.misc.CatalogCircularMask radius: 100 center: [1024, 1024] exclude_circle: true
Notes
Ensure the center coordinates and catalog positions use the same origin and units. Pyobs catalogs often store positions in FITS 1-based convention.
radiusis interpreted in pixel units of the catalog/image.The filtering operates solely on the catalog; it does not mask pixels in the image data.
CircularMask
- class CircularMask(radius: float, center: Tuple[str, str] = ('CRPIX1', 'CRPIX2'), **kwargs: Any)
Mask an image by keeping only pixels inside a central circle of a given radius.
This processor reads the circle center from two FITS header keywords (e.g., CRPIX1/CRPIX2) and constructs a circular mask in pixel coordinates. Pixels outside the circle are set to zero by in-place multiplication; pixels inside the circle are preserved. The modified image is returned.
- Parameters:
radius (float) – Radius of the circular pass region in pixels. Pixels with squared distance to the center less than or equal to
radius**2are kept.center (tuple[str, str]) – Names of the FITS header keywords whose values give the x and y pixel coordinates of the circle center (default:
("CRPIX1", "CRPIX2")).kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
Reads the circle center from
image.header[center[0]]andimage.header[center[1]].Builds a boolean circular mask on the 2D pixel grid and applies it to
image.databy element-wise multiplication, zeroing pixels outside the circle and keeping those inside (boundary inclusive).Returns the same image object with modified pixel data; the FITS header and catalog are not changed.
Input/Output
Input:
pyobs.images.Imagewith 2D pixel data and FITS header containing the specified center keywords.Output:
pyobs.images.Imagewith pixel data masked outside the circle.
Configuration (YAML)
Keep only pixels within a 500-pixel radius around CRPIX:
class: pyobs.images.processors.misc.CircularMask radius: 500 center: ["CRPIX1", "CRPIX2"]
Use custom center keywords:
class: pyobs.images.processors.misc.CircularMask radius: 250 center: ["CX", "CY"]
Notes
The center values must use the same pixel coordinate convention as the mask grid. FITS CRPIX values are typically 1-based; if your image indices are 0-based, ensure consistency to avoid off-by-one shifts.
The implementation operates on 2D images. Multi-plane/color images are not supported by this processor as written.
Masking is performed in place; if you need to preserve the original image data, copy the image before applying this processor.
CreateFilename
- class CreateFilename(pattern: str | None, **kwargs: Any)
Format and set a filename for the image using a pattern, storing it in the FNAME header.
This processor uses a
pyobs.utils.filenames.FilenameFormatterto render a filename string from image metadata and writes it into the FITS header keyFNAMEon a copy of the image. If no pattern is provided, a built-in default pattern is used.The default pattern is:
{SITEID}{TELID}-{INSTRUME}-{DAY-OBS|date:}-{FRAMENUM|string:04d}-{IMAGETYP|type}01.fitsThis pattern typically expands to a string like:
XXYY-CAM-20240130-0007-L101.fits- Parameters:
pattern (str | None) –
A filename pattern understood by
pyobs.utils.filenames.FilenameFormatter. IfNone, a default pattern is used. The pattern is a template with placeholders of the form{KEY}or{KEY|filter:params}, where KEY is usually a FITS header keyword and optional filters control formatting. Common filters include:date:...: format a date/time value (e.g., fromDATE-OBSorDAY-OBS) according to formatter defaults or supplied parameters.string:fmt: format using a Python-style format specification (e.g.,04dto zero-pad integers).type: map image type values to standardized tokens.
See the FilenameFormatter documentation for the full set of supported filters and parameters.
kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
Creates a
FilenameFormatterfrom the given pattern during initialization (or from the built-in default pattern if none was provided).On call, creates a copy of the input image and invokes
Image.format_filename(formatter)()to compute the filename and store it in the FITS header underFNAME.Returns the modified copy; pixel data and other metadata remain unchanged.
Input/Output
Input:
pyobs.images.Imagewith FITS header fields referenced by the chosen pattern (e.g.,SITEID,TELID,INSTRUME,DAY-OBSorDATE-OBS,FRAMENUM,IMAGETYP).Output:
pyobs.images.Image(copied) with theFNAMEheader set to the formatted filename.
Configuration (YAML)
Use the default pattern:
class: pyobs.images.processors.misc.CreateFilename pattern: null
Custom pattern with zero-padded sequence and date:
class: pyobs.images.processors.misc.CreateFilename pattern: "{SITEID}-{DAY-OBS|date:%Y%m%d}-{FRAMENUM|string:05d}.fits"
Notes
Ensure the FITS header contains all keywords required by the pattern; otherwise the formatter may raise an error or leave fields empty, depending on its behavior.
The exact syntax and capabilities of filters (
date,string,type, etc.) are defined byFilenameFormatter.
ImageSourceFilter
- class ImageSourceFilter(min_dist_to_border: float, num_stars: int, min_pixels: int, max_ellipticity: float = 0.4, min_weber_contrast: float = 1.5, max_saturation: int = 50000)
Filter a source catalog by border distance, quality metrics, and brightness, selecting the top N stars.
This processor operates on the source catalog attached to a
pyobs.images.Imageafter SEP-based detection. It removes sources too close to the image borders, rejects saturated or low-quality detections based on several criteria, and then keeps the brightest remaining sources by flux. Pixel data are not modified; the catalog is replaced in a returned copy of the image.- Parameters:
min_dist_to_border (float) – Minimum allowed distance from any image border, in pixels. Sources closer than this threshold on either axis are removed. Default: required.
num_stars (int) – Number of brightest sources to keep. If set to a positive value smaller than the number of valid sources, the catalog is truncated to that many entries; otherwise all valid sources are kept. Default: required.
min_pixels (int) – Minimum number of pixels (
tnpix) required for a source to be considered valid. Default: required.max_ellipticity (float) – Maximum allowed source ellipticity. Sources with
ellipticity > max_ellipticityare removed. Default:0.4.min_weber_contrast (float) – Minimum required Weber contrast relative to the local background, computed as
(peak - background) / background. Sources with contrast less than or equal to this value are removed. Default:1.5.max_saturation (int) – Saturation threshold in ADU. Sources with
peak >= max_saturationare considered saturated and removed. Default:50000.kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
Works on a copy of the input image and its catalog.
Removes sources near the borders:
Computes distance to the nearest border along both axes from the catalog coordinates
xandyand the image shape.Keeps sources whose minimum border distance exceeds
min_dist_to_border.
Removes low-quality sources using these criteria:
Saturation:
peak >= max_saturation.Too small:
tnpix < min_pixels.Too large:
tnpix > median(tnpix) + 2 * std(tnpix)(to reject extended artifacts).High ellipticity:
ellipticity > max_ellipticity.Non-positive background:
background <= 0.Low contrast: Weber contrast
(peak - background) / background <= min_weber_contrast.
Selects the brightest sources by sorting on
fluxin descending order and truncating tonum_starsif positive and less than the number of remaining sources.Returns the modified copy with the filtered catalog assigned.
Input/Output
Input:
pyobs.images.Imagewith a source catalog containing at leastx,y,flux,peak,tnpix,ellipticity, andbackground. The catalog is expected to use pixel coordinates consistent with the image shape.Output:
pyobs.images.Image(copied) with a filtered catalog. Pixel data and headers are unchanged.
Configuration (YAML)
Keep 20 high-quality stars, at least 10 pixels each, away from 25-pixel borders:
class: pyobs.images.processors.misc.ImageSourceFilter min_dist_to_border: 25 num_stars: 20 min_pixels: 10 max_ellipticity: 0.4 min_weber_contrast: 1.5 max_saturation: 50000
Notes
Coordinate convention: pyobs catalogs often store
x/yin FITS-like 1-based pixel coordinates. If necessary, convert to NumPy 0-based indexing before applying geometric filters; a helper method_fits2numpyis provided to subtract 1 from common pixel keys but is not invoked automatically here.The border-distance calculation uses the image shape and source positions on each axis; ensure consistency between catalog coordinates and image dimensions.
The “too large” criterion uses a robust size cutoff based on
tnpixmedian and standard deviation to reject extended artifacts or blends.Weber contrast requires a positive background; sources with non-positive background are removed prior to contrast evaluation.
RemoveBackground
- class RemoveBackground(sigma: float = 3.0, box_size: Tuple[int, int] = (50, 50), filter_size: Tuple[int, int] = (3, 3), **kwargs: Any)
Estimate and subtract the background from an image using a DAOPhot-style method.
This processor applies robust background estimation and removes it from the image, producing a background-corrected result. The background is estimated on a grid with sigma-clipping and optional smoothing, then subtracted from the pixel data. The implementation delegates to
pyobs.images.processors.detection._DaoBackgroundRemover.- Parameters:
sigma (float) – Sigma for kappa–sigma clipping used in background estimation. Default:
3.0.box_size (tuple[int, int]) – Size of the grid boxes (ny, nx) in pixels over which the background is estimated. Default:
(50, 50).filter_size (tuple[int, int]) – Size (ny, nx) of the smoothing filter applied to the coarse background map. Default:
(3, 3).kwargs – Additional keyword arguments forwarded to
pyobs.images.processor.ImageProcessor.
Behavior
Builds a background model using kappa–sigma clipping within tiles of size
box_sizeand smooths the model with a filter of sizefilter_size.Subtracts the estimated background from the image data.
Returns the background-corrected image; header and catalog are unchanged.
Input/Output
Input:
pyobs.images.Imagewith 2D pixel data.Output:
pyobs.images.Imagewith background subtracted from its pixel data.
Configuration (YAML)
Basic background removal:
class: pyobs.images.processors.misc.RemoveBackground sigma: 3.0 box_size: [50, 50] filter_size: [3, 3]
Notes
Choose
box_sizelarge enough to capture slowly varying background while avoiding contamination by extended sources.Increasing
sigmareduces the influence of outliers on the background estimate.If your image contains strong gradients or large-scale structures, consider tuning
box_sizeandfilter_sizeto avoid over-subtraction.