labeled_data_cache
anomaly_match.data_io.labeled_data_cache
¶
Zarr-backed cache for labeled source data (container sources only).
Extracts labeled images once in the setup screen and carries them forward across retrain cycles to avoid re-streaming from remote sources.
For Zarr sources the cache holds the store's raw array values — normalisation is applied at training time, so normalisation changes never need a rebuild.
For Cutana sources the cache holds per-band, unnormalised, float32
cutouts at :data:LABELED_CACHE_RESOLUTION (or larger if the user has
ever requested a higher image_size). The full fitsbolt pipeline —
normalisation method, output dtype, resize, and channel combination — is
applied at read time (see
:func:anomaly_match.data_io.container_loaders.decode_cutana_raw_images).
That decoupling means changing normalisation_method,
output_dtype, channel_combination or n_output_channels does
not trigger a rebuild. The only triggers are:
- Raw-extraction parameters (FITS extension list, padding factor, flux conversion, interpolation order) — these feed into Cutana's reprojection and so affect the stored pixel values.
- A requested
image_sizelarger than the cached resolution — we can always resize down, never up. - A change in the source's resolved band count — the cache stores one
channel per band, so adding/removing a band (e.g. a new NIR-J entry in
the catalogues'
fits_file_paths) makes the cached cutouts disagree with the fresh stream even when the config is untouched.
LABELED_CACHE_RESOLUTION = 384
module-attribute
¶
Default Cutana cutout resolution used for labeled-cache builds.
The cache stores unnormalised float32 data at this resolution (or larger
if the user has ever requested a higher image_size), and the read
path resizes down to cfg.normalisation.image_size on the fly. 384 px
gives ~1.7 MB / cutout for 4 bands — affordable for thousands of
labeled sources, and leaves headroom for detail-view zoom without forcing
a rebuild.
LabeledDataCache(cache_dir)
¶
Zarr-backed cache for raw labeled training images.
Only used for container sources (Zarr, Cutana). Image folders load from disk directly and don't need caching.
For Zarr the cache stores raw arrays — normalisation changes never
trigger a rebuild. For Cutana the cache stores per-band normalised
output; channel_combination is applied at read time, so only the
parameters in :data:EXTRACTION_AFFECTING_NORM_FIELDS trigger a rebuild
(see :func:_compute_extraction_hash). Resolution is tracked separately,
via the stored image_shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_dir
|
Path
|
Directory to store the cache files. |
required |
Source code in anomaly_match/data_io/labeled_data_cache.py
cache_dir
property
¶
Path to the cache directory.
source_type
property
¶
Return the source type stored in the cache info, or empty string.
is_populated
property
¶
Check if the cache has been built and contains data.
Returns:
| Type | Description |
|---|---|
bool
|
True if the cache zarr and metadata files exist. |
build_from_zarr(found_locations, label_df, cfg)
¶
Extract raw labeled images from Zarr stores and write to cache.
Reads directly from known (store_path, local_index) positions
without building a full source index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
found_locations
|
dict[str, tuple[str, int]]
|
Map of |
required |
label_df
|
DataFrame
|
Label DataFrame with |
required |
cfg
|
DotMap
|
Configuration (used for extraction hash). |
required |
Source code in anomaly_match/data_io/labeled_data_cache.py
build_from_cutana(found_locations, label_df, cfg)
¶
Extract raw labeled cutouts from Cutana catalogues and write to cache.
Groups source IDs by catalogue file and streams cutouts via
Cutana with normalisation disabled (CONVERSION_ONLY + float32
output) at :data:LABELED_CACHE_RESOLUTION. That way the
stored values survive any change to normalisation_method,
output_dtype or channel_combination — those are applied
at read time by
:func:~anomaly_match.data_io.container_loaders.decode_cutana_raw_images.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
found_locations
|
dict[str, tuple[str, int]]
|
Map of |
required |
label_df
|
DataFrame
|
Label DataFrame with |
required |
cfg
|
DotMap
|
Configuration. Only raw-extraction fields (fits_extension, padding, flux conversion, interpolation_order) affect the cached pixels; normalisation / channel-combination fields are ignored at build time. |
required |
Source code in anomaly_match/data_io/labeled_data_cache.py
append_from_zarr(new_locations, new_label_df, full_label_df)
¶
Append newly labeled Zarr images to an existing cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_locations
|
dict[str, tuple[str, int]]
|
New |
required |
new_label_df
|
DataFrame
|
Label DataFrame for the new entries. |
required |
full_label_df
|
DataFrame
|
The complete label DataFrame (whole CSV) used to
refresh |
required |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the cache has not been built yet. |
Source code in anomaly_match/data_io/labeled_data_cache.py
append_from_cutana(new_locations, new_label_df, cfg, full_label_df)
¶
Append newly labeled Cutana cutouts to an existing cache.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_locations
|
dict[str, tuple[str, int]]
|
New |
required |
new_label_df
|
DataFrame
|
Label DataFrame for the new entries. |
required |
cfg
|
DotMap
|
Configuration for Cutana orchestrator. |
required |
full_label_df
|
DataFrame
|
The complete label DataFrame (whole CSV) used to
refresh |
required |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the cache has not been built yet. |
Source code in anomaly_match/data_io/labeled_data_cache.py
get_raw_images()
¶
Read all cached raw images.
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
List of |
Source code in anomaly_match/data_io/labeled_data_cache.py
get_raw_images_by_id(ids)
¶
Read a specific subset of cached raw images by id.
Callers are expected to have already checked that the cache is
populated and that every requested id is in it — use
:meth:is_populated and :meth:get_label_df for that. The
method raises on both invariants so a mis-wired call site fails
loudly instead of returning a silently shorter list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ids
|
list[str]
|
Item ids to read. Must be non-empty and every id must exist in the cache. Order is preserved in the output. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[str, ndarray]]
|
List of |
list[tuple[str, ndarray]]
|
in the input order. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If ids is empty. |
RuntimeError
|
If the cache has not been built yet. |
KeyError
|
If any requested id is not in the cache. |
Source code in anomaly_match/data_io/labeled_data_cache.py
get_label_df()
¶
Read the cached label metadata.
Returns:
| Type | Description |
|---|---|
DataFrame
|
DataFrame with |
DataFrame
|
location columns like |
Source code in anomaly_match/data_io/labeled_data_cache.py
get_cache_info()
¶
Read cache metadata (source type, extraction hash, etc.).
Returns:
| Type | Description |
|---|---|
dict
|
Dict with cache metadata, or empty dict if not populated. |
Source code in anomaly_match/data_io/labeled_data_cache.py
needs_rebuild(cfg, label_df=None, found_ids=None)
¶
Check if extraction-affecting parameters changed since cache was built.
For Zarr: never rebuilds on config changes (raw array data is fixed), but still rebuilds on label CSV changes when label_df is supplied.
For Cutana: rebuild when any raw-extraction parameter changed
(FITS extension list, padding, flux conversion, interpolation
order — see :func:_compute_extraction_hash), when the requested
image_size exceeds the stored resolution (resize down is fine;
we can't invent detail that wasn't cached), or when the
source's resolved band count no longer matches the cached channel
count (a band was added to or removed from the catalogues'
fits_file_paths). Normalisation method, output dtype, channel
combination and n_output_channels are all applied at read time
and so never force a rebuild.
When label_df is supplied, also compare its hash against
cache_info.json['label_csv_hash'] and rebuild on mismatch —
this lets a persistent cache (next to the label CSV) detect when
the CSV has been edited between sessions.
When found_ids is supplied, compare it against the cached id
set and rebuild on mismatch. This catches the case where the
CSV is unchanged but the data source grew (e.g. the user dropped
another Cutana catalogue into data_dir) — previously the
cache went stale silently until the CSV hash or extraction
params happened to change.
Every rebuild decision is logged with its reason so spurious rebuilds are diagnosable from the session log alone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cfg
|
DotMap
|
Current configuration. |
required |
label_df
|
DataFrame | None
|
Label DataFrame with |
None
|
found_ids
|
set[str] | None
|
IDs the current validation pass matched against the source. When supplied, mismatch against the cached ids triggers a rebuild. |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
True if the cache should be rebuilt. |
Source code in anomaly_match/data_io/labeled_data_cache.py
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 | |
clear()
¶
Delete all cache files.
Source code in anomaly_match/data_io/labeled_data_cache.py
build(found_locations, label_df, source_type, cfg)
¶
Build the cache from validated locations, dispatching by source type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
found_locations
|
dict[str, tuple]
|
Map from ID to source-specific location tuple. |
required |
label_df
|
DataFrame
|
Label DataFrame with |
required |
source_type
|
str
|
A :class: |
required |
cfg
|
DotMap
|
Configuration for extraction. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If source_type is not a container type. |
Source code in anomaly_match/data_io/labeled_data_cache.py
update(new_labels, cfg)
¶
Update the cache with newly labeled items (rebuild or append).
Decides whether to rebuild from scratch (if extraction parameters changed) or incrementally append new entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_labels
|
dict[str, str]
|
Dict mapping |
required |
cfg
|
DotMap
|
Current configuration. |
required |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If the cache is not populated. |
Source code in anomaly_match/data_io/labeled_data_cache.py
is_labeled_cache_populated(cache_path)
¶
Check if a labeled-cache directory contains all required artefacts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cache_path
|
str | Path
|
Path to the labeled cache directory. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|