source_scanning
anomaly_match.data_io.source_scanning
¶
Source scanning utilities for counting and previewing data sources.
Provides backend functions for detecting source types, counting items, reading
label maps, and loading preview samples. These are pure data I/O operations
that the UI layer delegates to via BackendInterface.
SourceScanResult(source_type=DataSourceType.IMAGE_FOLDER, count=0, image_files=list())
dataclass
¶
Result of scanning a source directory.
Attributes:
| Name | Type | Description |
|---|---|---|
source_type |
DataSourceType
|
Detected source type. |
count |
int
|
Number of sources found. |
image_files |
list[str]
|
File paths (only populated for image_folder sources). |
scan_and_count_sources(folder)
¶
Detect source type and count items in a folder.
Handles image folders, Zarr stores, and Cutana catalogues.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Path to the data directory. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
SourceScanResult
|
class: |
Source code in anomaly_match/data_io/source_scanning.py
is_zarr_store(path)
¶
Return whether path is a Zarr store, by name or on-disk marker.
A Zarr v3 store is not required to have a .zarr name, so a top-level
zarr.json is also accepted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Directory path to check. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if path looks like a Zarr store. |
Source code in anomaly_match/data_io/source_scanning.py
find_prediction_zarr_stores(folder)
¶
Find Zarr store paths for prediction within folder.
Treats folder itself as a single store when its name/contents mark it
as one; otherwise looks one level down for *.zarr stores or
<batch>/images.zarr chunks (the layout chunked prediction output uses).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Directory to scan, or a direct path to a single store. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[str, str]]
|
List of (display_name, store_path) pairs. |
Source code in anomaly_match/data_io/source_scanning.py
detect_source_channel_count(folder, source_type, image_files=None)
¶
Return how many channels each image in a Zarr store or image folder has.
The setup screen sizes the channel-combination matrix's input columns from this, so a matrix left over from a previous source (e.g. four Cutana bands) can't be applied to a three-channel store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Source directory, or a direct path to a single Zarr store. |
required |
source_type
|
DataSourceType
|
:attr: |
required |
image_files
|
list[str] | None
|
Image filenames for image-folder sources (the first is sampled). |
None
|
Returns:
| Type | Description |
|---|---|
int | None
|
The per-image channel count, or |
int | None
|
(e.g. FITS files, whose channels depend on |
Source code in anomaly_match/data_io/source_scanning.py
detect_prediction_source_type(search_dir)
¶
Detect the dominant prediction source type for search_dir.
Checks whether search_dir itself is a single Zarr store first. Otherwise
scans immediate directory entries by precedence: any Zarr store wins,
then any file passing _is_cutana_catalogue wins over image files; a
folder with only non-catalogue CSV/parquet files falls back to CUTANA.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
search_dir
|
str
|
Directory to scan, or a direct path to a single store. |
required |
Returns:
| Type | Description |
|---|---|
DataSourceType
|
The detected |
DataSourceType
|
search_dir doesn't exist or nothing recognizable is found. |
Source code in anomaly_match/data_io/source_scanning.py
detect_and_count_prediction_sources(folder)
¶
Detect the prediction source type in folder and count its items.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Directory to scan, or a direct path to a single Zarr store. |
required |
Returns:
| Type | Description |
|---|---|
tuple[DataSourceType, int]
|
Tuple of (detected type, total item count). |
Source code in anomaly_match/data_io/source_scanning.py
read_label_map(label_path)
¶
Read a label CSV and return an {id: label} mapping.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label_path
|
str
|
Path to an existing label CSV file. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Mapping from sample id to label string. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If |
ValueError
|
If the CSV is missing the required |
Source code in anomaly_match/data_io/source_scanning.py
load_preview_samples(cfg, folder, source_type, *, image_files=None, source_ids=None, max_items=9, offset=0, stale_check=None)
¶
Load sample images for preview display.
Returns raw numpy arrays (HWC uint8) so the UI can convert to display format independently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
DotMap
|
AnomalyMatch configuration with normalisation settings. |
required |
folder
|
str
|
Path to the data directory. |
required |
source_type
|
DataSourceType | str
|
Detected source type. |
required |
image_files
|
list[str] | None
|
Files to load for image_folder sources. |
None
|
source_ids
|
list[str] | None
|
Source IDs to load for Cutana or Zarr sources. |
None
|
max_items
|
int
|
Maximum number of preview samples to return. |
9
|
offset
|
int
|
Skip this many items from the start before loading
|
0
|
stale_check
|
Optional zero-arg callable returning |
None
|
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
List of |
Source code in anomaly_match/data_io/source_scanning.py
load_cutana_preview(cfg, folder, source_ids, max_items, *, stale_check=None)
¶
Load Cutana preview cutouts and the raw arrays worth holding in memory.
Reads the labeled cache's raw (normalisation-independent) float32 cutouts once and decodes them in-process; for ids the cache can't serve it falls back to Cutana extraction (which bakes the current normalisation in, so those cutouts are not re-decodable). Returning the raw arrays alongside the decoded images lets the setup screen hold them and re-decode on a normalisation change without touching the cache again (issue #501) — in a single read, rather than one read to hold and another to display.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
DotMap
|
AnomalyMatch configuration. |
required |
folder
|
str
|
Source catalogue directory (fallback search root). |
required |
source_ids
|
list[str]
|
Preview ids, already stratified by label. |
required |
max_items
|
int
|
Cap on preview grid size. |
required |
stale_check
|
Optional zero-arg callable returning |
None
|
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
|
list[tuple[str, ndarray]] | None
|
|
tuple[list[tuple[str, ndarray]], list[tuple[str, ndarray]] | None]
|
|
tuple[list[tuple[str, ndarray]], list[tuple[str, ndarray]] | None]
|
request (safe to hold + re-decode) or |
tuple[list[tuple[str, ndarray]], list[tuple[str, ndarray]] | None]
|
fallback preview has cutouts with normalisation already baked in). |
Source code in anomaly_match/data_io/source_scanning.py
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 | |
load_preview_raw_cutouts(cfg, source_ids, max_items)
¶
Return normalisation-independent raw cutouts from the labeled cache.
The labeled cache stores per-band float32 cutouts at the cache resolution, before normalisation/resize/channel-combine. Returning the raw arrays lets the setup-screen preview re-apply a changed normalisation in-process (issue #501) without re-reading the catalogue or FITS tiles — the read of these arrays is identical regardless of the user's normalisation settings.
Ids the populated cache doesn't hold are omitted; the caller decides whether to fall back to catalogue extraction for them (that path bakes normalisation in, so its cutouts are not raw and can't be re-decoded later).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
DotMap
|
AnomalyMatch configuration; |
required |
source_ids
|
list[str]
|
Candidate ids, already stratified by label. |
required |
max_items
|
int
|
Cap on the number of cutouts to read. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
|
list[tuple[str, ndarray]]
|
order, or |
list[tuple[str, ndarray]]
|
rebuild. |
Source code in anomaly_match/data_io/source_scanning.py
decode_raw_cutouts(cfg, raw_items)
¶
Apply the current normalisation to raw cache cutouts.
Rebuilds cfg.fitsbolt_cfg from cfg.normalisation and runs the full
decode (normalise + resize + channel-combine) on the raw float32 arrays,
returning display-ready HWC uint8. This is the in-process re-decode the
setup-screen preview uses to reflect a normalisation change without touching
the cache again (issue #501).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
DotMap
|
AnomalyMatch configuration with the desired normalisation settings. |
required |
raw_items
|
list[tuple[str, ndarray]]
|
|
required |
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
|