Reference / API reference / dorothy / dorothy.data / dorothy.data.catalogue_loader
dorothy.data.catalogue_loader¶
Load the DOROTHY super-catalogue HDF5 file.
CatalogueLoader reads spectra of one or several surveys and the
labels of one or several label sources, and builds the model inputs of the
trainer. Catalogues from scripts/build_catalogue_v2.py have one row per
star, aligned across surveys and label sources.
Examples
>>> loader = CatalogueLoader("/path/to/super_catalogue.h5")
>>> loader.info() # Print catalogue summary
>>> data = loader.load(survey="boss") # Loads BOSS with APOGEE labels
>>> data = loader.load(survey="lamost_lrs") # Loads LAMOST LRS with its labels
>>> print(f"Loaded {len(data.gaia_ids)} stars")
Classes
|
Container for loaded catalogue data. |
|
Summary information about a catalogue. |
|
Loader for DOROTHY super-catalogue HDF5 files. |
|
Container for merged multi-survey data with outer join structure. |
|
Memory-efficient multi-survey data with sparse survey storage. |
- class dorothy.data.catalogue_loader.CatalogueData(gaia_ids, ra, dec, flux, ivar, wavelength, snr, labels, label_errors, label_flags, survey_name, label_source, has_spectrum=<factory>, has_labels=<factory>)[source]¶
Bases:
objectContainer for loaded catalogue data.
This is the output from CatalogueLoader.load(), containing spectral data from one or more surveys and labels from a selected source.
- gaia_ids¶
Gaia DR3 source IDs for each star.
- ra¶
Right ascension in degrees.
- dec¶
Declination in degrees.
- flux¶
Spectral flux values, shape (N, wavelength_bins).
- ivar¶
Inverse variance, shape (N, wavelength_bins).
- wavelength¶
Wavelength grid, shape (wavelength_bins,).
- snr¶
Signal-to-noise ratio for each spectrum.
- labels¶
Stellar parameter values, shape (N, n_params).
- label_errors¶
Uncertainties on labels, shape (N, n_params).
- label_flags¶
Per-parameter quality flags, shape (N, n_params).
- survey_name¶
Name of the survey (for single-survey loading).
- label_source¶
Name of the label source used.
- has_spectrum¶
Boolean mask for stars with valid spectra. If empty, any ivar > 0.
- has_labels¶
Boolean mask for stars with valid labels. If empty, any label error > 0.
- property n_stars: int¶
Total number of stars in the dataset.
- property n_with_spectra: int¶
Number of stars with valid spectra.
- property n_with_labels: int¶
Number of stars with valid labels.
- property n_complete: int¶
Number of stars with both spectra and labels.
- filter_complete()[source]¶
Keep the stars with a valid spectrum and valid labels.
- Returns:
A new CatalogueData with the stars where has_spectrum and has_labels are both True.
- Return type:
- class dorothy.data.catalogue_loader.MergedCatalogueData(gaia_ids, ra, dec, surveys, label_source, primary_labels, primary_errors, primary_flags)[source]¶
Bases:
objectContainer for merged multi-survey data with outer join structure.
This dataclass stores data from multiple surveys aligned by Gaia DR3 ID. Each survey’s data is stored in a dictionary keyed by survey name, with missing data indicated by ivar=0 (natural masking).
- gaia_ids¶
Gaia DR3 source IDs for each unique star (union of all surveys).
- ra¶
Right ascension in degrees.
- dec¶
Declination in degrees.
- surveys¶
Dictionary mapping survey names to their data dictionaries. Each entry contains: ‘flux’, ‘ivar’, ‘wavelength’, ‘snr’, ‘labels’, ‘label_errors’, ‘label_flags’, ‘has_data’ (bool mask).
- label_source¶
Label source used (typically ‘apogee’).
- primary_labels¶
Primary labels, shape (N, n_params). Each star takes the labels of the first survey, in loading order, with a positive label error.
- primary_errors¶
Primary label errors, shape (N, n_params).
- primary_flags¶
Primary label flags, shape (N, n_params).
Examples
>>> merged = loader.load_merged(surveys=["boss", "lamost_lrs"]) >>> # Access BOSS spectra for all stars (missing = ivar=0) >>> boss_flux = merged.surveys["boss"]["flux"] # (N, wavelengths) >>> boss_ivar = merged.surveys["boss"]["ivar"] # 0 where missing >>> # Check which stars have BOSS data >>> has_boss = merged.surveys["boss"]["has_data"] # bool array
- property n_stars: int¶
Total number of unique stars.
- property survey_names: list[str]¶
List of survey names in this merged dataset.
- get_coverage_stats()[source]¶
Get the number of stars with data from each survey.
- Returns:
Survey name -> number of stars.
- Return type:
dict[str, int]
- get_overlap_matrix()[source]¶
Get pairwise overlap counts between surveys.
- Returns:
(survey_a, survey_b) -> number of stars with data from both, for each pair in loading order.
- Return type:
dict[tuple[str, str], int]
- filter_by_surveys(required_surveys)[source]¶
Keep only the stars that have data from all specified surveys.
- Parameters:
required_surveys (list[str]) – List of survey names that must have data.
- Returns:
A new MergedCatalogueData; the wavelength grids are shared.
- Raises:
ValueError – If a required survey is not in the merged data.
- Return type:
- class dorothy.data.catalogue_loader.SparseMergedData(flux, sigma, wavelengths, snr, global_to_local, local_to_global, labels, gaia_ids, ra, dec, surveys, n_total, n_params, labels_dict=None, has_labels_dict=None, label_sources=None, parameter_names=None)[source]¶
Bases:
objectMemory-efficient multi-survey data with sparse survey storage.
Unlike MergedCatalogueData which stores dense arrays for each survey (with zeros for missing stars), this class stores only stars that have actual data for each survey. Index mappings allow efficient lookup between global star indices and survey-local indices.
A survey with low coverage stores only its rows with data.
- flux¶
Per-survey sparse spectra. Maps survey name to array of shape (n_with_data[survey], n_wavelengths) containing only stars with data. Normalized if requested, and 0 at invalid pixels (
zero_invalid_pixels()).
- sigma¶
Per-survey 1/sqrt(ivar) arrays with the same structure as flux, 0 at invalid pixels (so the pixel mask is sigma > 0). With the precision encoding they hold log(1 + 1/sigma) instead, which is also positive exactly at the valid pixels.
- wavelengths¶
Per-survey wavelength grids (n_wavelengths,).
- snr¶
Per-survey SNR values for stars with data.
- global_to_local¶
Maps survey name to index array (n_total,) where value = local index into sparse array, or -1 if no data.
- local_to_global¶
Maps survey name to index array (n_with_data,) where value = global star index.
- labels¶
Dense labels array (n_total, 3, n_params) with [values, errors, mask].
- gaia_ids¶
Gaia DR3 source IDs for all stars (n_total,).
- ra¶
Right ascension in degrees (n_total,).
- dec¶
Declination in degrees (n_total,).
- surveys¶
List of survey names.
- n_total¶
Total number of unique stars across all surveys.
- n_params¶
Number of stellar parameters.
- labels_dict¶
Per label source, labels (n_total, 3, n_params), when several sources are loaded.
- has_labels_dict¶
Per label source, whether each star has at least one valid label after the flag filter (mask 1 in
labels_dict).
- has_data(survey)[source]¶
Return the boolean mask of stars with data for a survey.
- Parameters:
survey (str) – Survey name.
- Returns:
Boolean mask of shape (n_total,) indicating which stars have data for
survey.- Return type:
ndarray
- coverage(survey)[source]¶
Return the fraction of stars with data for a survey.
- Parameters:
survey (str) – Survey name.
- Returns:
Fraction of total stars in [0, 1] observed by
survey.- Return type:
float
- n_with_data(survey)[source]¶
Return the number of stars with data for a survey.
- Parameters:
survey (str) – Survey name.
- Returns:
Count of stars observed by
survey.- Return type:
int
- get_coverage_stats()[source]¶
Get the number of stars with data from each survey.
- Returns:
Mapping from survey name to star count.
- Return type:
dict[str, int]
- memory_usage_mb()[source]¶
Report the size in MB (1e6 bytes) of the main arrays.
- Returns:
Dict with
<survey>_fluxand<survey>_sigmaper survey,labels,gaia_idsand their sum,total. Index maps andlabels_dictare not counted.- Return type:
dict[str, float]
- get_labels_for_source(source)[source]¶
Get the labels of a label source.
- Parameters:
source (str) – Label source name (e.g., ‘apogee’, ‘galah’).
- Returns:
Labels array of shape (n_total, 3, n_params). The primary labels if
labels_dictis None or does not hold source.- Return type:
ndarray
- has_labels_for_source(source)[source]¶
Get has_labels mask for a specific source.
- Parameters:
source (str) – Label source name.
- Returns:
Boolean mask of shape (n_total,) – stars with at least one valid label (mask 1) from the source.
- Raises:
ValueError – If has_labels_dict exists but source is not in it.
- Return type:
ndarray
- class dorothy.data.catalogue_loader.CatalogueInfo(n_stars, parameter_names, survey_names, creation_date, version, surveys, labels)[source]¶
Bases:
objectSummary information about a catalogue.
- n_stars¶
Number of stars (rows).
- parameter_names¶
Label parameter names, in column order.
- survey_names¶
Survey names from the catalogue attributes.
- creation_date¶
Creation date from the catalogue attributes.
- version¶
Catalogue version.
- surveys¶
Survey name -> dict with
wavelength_bins,n_with_data(stars with snr > 0) andwavelength_range.
- labels¶
Label source -> dict with
n_with_data(stars with a label error > 0).
- class dorothy.data.catalogue_loader.CatalogueLoader(catalogue_path)[source]¶
Bases:
objectLoader for DOROTHY super-catalogue HDF5 files.
Inspects the catalogue and loads one survey (
load()), several surveys (load_multi(),load_merged(),load_merged_sparse()) or training inputs (load_for_training(),load_merged_for_training()), with APOGEE or GALAH labels.Examples
>>> loader = CatalogueLoader("super_catalogue.h5") >>> loader.info()
>>> # Load DESI spectra with APOGEE labels >>> data = loader.load(survey="desi", label_source="apogee") >>> complete = data.filter_complete() # Only stars with both >>> print(f"Training set: {complete.n_stars} stars")
>>> # Load multiple surveys >>> data = loader.load_multi(["desi", "boss"])
- get_info()[source]¶
Get summary information about the catalogue.
Reads the snr and error arrays of every survey and label group.
- Returns:
CatalogueInfo object with catalogue metadata.
- Return type:
- load(survey=None, label_source=None, require_complete=False)[source]¶
Load data from a single survey in the catalogue.
Spectra and labels are row-aligned. All rows of the survey are returned, including rows without data.
- Parameters:
survey (str | None) – Survey name to load (e.g., “boss”, “lamost_lrs”, “desi”). If None, loads the first survey with data.
label_source (str | None) – Label group to use. If None, the first of
SURVEY_LABEL_MAP[survey], “apogee”, “galah” and “apogee_<survey>” that the catalogue has. A name that is not a group falls back to “<label_source>_<survey>”.require_complete (bool) – If True, only return stars with both spectra and labels.
- Returns:
CatalogueData object with loaded data.
- Raises:
ValueError – If the survey or label source is not in the catalogue, no survey has data, the catalogue has no labels group, the survey has no spectra, or the arrays differ in length.
- Return type:
Examples
>>> loader = CatalogueLoader("super_catalogue.h5") >>> # Load BOSS spectra with corresponding APOGEE labels >>> boss_data = loader.load(survey="boss") >>> # Load LAMOST LRS with its APOGEE labels >>> lamost_data = loader.load(survey="lamost_lrs")
- load_for_training(survey, label_source=None, max_flag_bits=0, normalize_spectra=False, precision_encoding=True)[source]¶
Load data ready for training in unified 3-channel format.
Loads the stars with a spectrum and labels, drops the stars with more set flag bits than
max_flag_bits, and masks each label with a nonzero flag or a non-positive error.- Parameters:
survey (str) – Survey to load from.
label_source (str | None) – Label source to use; see
load().max_flag_bits (int) – Maximum number of set flag bits of a star, summed over its parameters. Stars with more are dropped. A negative value drops none.
normalize_spectra (bool) – Apply per-spectrum median/IQR normalization to flux (and rescale ivar) before building the model inputs. Training and inference must use the same setting.
precision_encoding (bool) – Replace sigma with log(1 + 1/sigma) after normalization (see
data.precision_encoding).
- Returns:
Tuple of (X, y) where –
- X: Spectral data, shape (N, 3, wavelength_bins)
Channel 0: flux values Channel 1: sigma = 1/sqrt(ivar), or log(1 + 1/sigma) with precision_encoding Channel 2: mask (1=valid, 0=invalid wavelength)
- y: Labels, shape (N, 3, n_params)
Channel 0: label values Channel 1: label errors (uncertainties) Channel 2: mask (1=valid, 0=masked parameter)
- Raises:
ValueError – As
load().- Return type:
tuple[ndarray, ndarray]
- load_raw_spectra(survey)[source]¶
Load a survey’s datasets exactly as stored in the HDF5 file.
LAMOST MRS stores padded
spectraof shape (N, 4, max_wave) = [flux_b, ivar_b, flux_r, ivar_r] withwavelength_bandwavelength_r; the other surveys storeflux,ivarandwavelength.- Parameters:
survey (str) – Survey to load from.
- Returns:
Dictionary of the survey group’s datasets, plus
channel_nameswhen the group has that attribute.- Raises:
ValueError – If the survey is not in the catalogue.
- Return type:
dict[str, ndarray]
- list_surveys()[source]¶
List the survey names in the catalogue.
- Returns:
Survey group names present under
surveys/in the HDF5 file.- Return type:
list[str]
- list_label_sources()[source]¶
List the label group names in the catalogue.
- Returns:
Label source group names present under
labels/in the HDF5 file.- Return type:
list[str]
- get_label_source_for_survey(survey)[source]¶
Get the label group that
SURVEY_LABEL_MAPassigns to a survey.- Parameters:
survey (str) – Survey name.
- Returns:
The group name, or None if the survey is not in the map.
- Return type:
str | None
- load_multi(surveys, mode='union', deduplicate=True)[source]¶
Load data from multiple surveys.
Each survey is loaded with
load()and its default label source.- Parameters:
surveys (list[str]) – List of survey names to load.
mode (Literal['union', 'intersection']) – “union” returns all rows of every survey. “intersection” returns the first row with data (snr > 0) of each star that has data in every survey.
deduplicate (bool) – In “union” mode, keep only the first row of each Gaia ID, and every row with an integer ID <= 0. Ignored in “intersection” mode.
- Returns:
Dictionary mapping survey names to CatalogueData objects. In “intersection” mode, all CatalogueData objects are filtered to the same set of stars (ordered consistently by Gaia ID).
- Raises:
ValueError – If
surveysis empty,modeis not “union” or “intersection”, in “intersection” mode if no star is in every survey, or asload().- Return type:
dict[str, CatalogueData]
Examples
>>> loader = CatalogueLoader("super_catalogue.h5") >>> # Load stars observed by both BOSS and LAMOST LRS >>> data = loader.load_multi( ... surveys=["boss", "lamost_lrs"], ... mode="intersection" ... ) >>> print(f"Stars in both: {data['boss'].n_stars}")
- load_merged(surveys, label_source='apogee')[source]¶
Load and merge multiple surveys with outer join structure.
This method uses memory-efficient two-pass loading: 1. First pass: Load only metadata to check for duplicates 2. Second pass: Load spectra selectively using HDF5 indexed access
Stars that don’t appear in a survey have ivar=0 (natural masking). Prints the coverage of each survey.
Note
This method needs one row per star, as catalogues built by
scripts/build_catalogue_v2.pyhave; duplicate rows raise an error.- Parameters:
surveys (list[str]) – List of survey names to load and merge.
label_source (str) – Primary label source to use for combined labels.
- Returns:
MergedCatalogueData with outer join structure. Dense arrays of shape (n_stars, wavelength_bins) per survey.
- Raises:
ValueError – If duplicate observations are found in the catalogue, or it has no Gaia IDs.
- Return type:
Examples
>>> merged = loader.load_merged(["boss", "lamost_lrs", "desi"]) >>> print(f"Total unique stars: {merged.n_stars}") >>> print(f"Coverage: {merged.get_coverage_stats()}")
- load_merged_sparse(surveys, label_source='apogee', max_flag_bits=0, label_sources=None, normalize_spectra=False, precision_encoding=True)[source]¶
Load and merge multiple surveys with memory-efficient sparse storage.
Unlike load_merged() which stores dense arrays (with zeros for missing stars), this method stores only stars that have actual data per survey. Prints progress.
Note
This method needs one row per star, as catalogues built by
scripts/build_catalogue_v2.pyhave; duplicate rows raise an error.- Parameters:
surveys (list[str]) – List of survey names to load and merge.
label_source (str) – Label source of the primary
labelsarray.max_flag_bits (int) – Largest number of set flag bits, summed over the parameters of a star, for its labels to count; the labels of a star with more are masked. A negative value masks none. A label with a nonzero flag or a non-positive error is always masked.
label_sources (list[str] | None) – Optional list of label sources for multi-label training. With more than one,
labels_dict,has_labels_dictandlabel_sourcesare set, with the labels of each source.normalize_spectra (bool) – Apply per-spectrum median/IQR normalization to flux (and rescale ivar) before building the model inputs. Training and inference must use the same setting.
precision_encoding (bool) – Replace sigma with log(1 + 1/sigma) after normalization (see
data.precision_encoding).
- Returns:
SparseMergedData with memory-efficient sparse survey storage. Use with trainer’s sparse batch construction for training.
- Raises:
ValueError – If duplicate observations are found in the catalogue, a label source is not in the catalogue, the primary label group’s
gaia_iddiffers frommetadata/gaia_id, or another label group inlabel_sourceshas nogaia_id.- Return type:
Examples
>>> sparse_data = loader.load_merged_sparse(["boss", "desi", "lamost_lrs"]) >>> print(f"Memory: {sparse_data.memory_usage_mb()['total']:.1f} MB") >>> print(f"Coverage: {sparse_data.get_coverage_stats()}") >>> >>> # Multi-label loading >>> sparse_data = loader.load_merged_sparse( ... ["lamost_lrs", "lamost_mrs"], ... label_sources=["apogee", "galah"] ... ) >>> print(f"Multi-label: {sparse_data.is_multi_label()}")
- get_survey_wavelengths(survey)[source]¶
Get the wavelength grid for a survey (LAMOST MRS: blue then red arm).
- Parameters:
survey (str) – Survey name.
- Returns:
Wavelengths, shape (wavelength_bins,).
- Raises:
ValueError – If the survey is not in the catalogue.
- Return type:
ndarray
- load_spectrum(survey, index, normalize_spectra=False, precision_encoding=True)[source]¶
Load one star’s spectrum as a 3-channel model input.
- Parameters:
survey (str) – Survey name (e.g. “boss”, “lamost_mrs”).
index (int) – Row index in the catalogue (v2 rows are aligned with
metadata/gaia_id).normalize_spectra (bool) – Apply per-spectrum median/IQR normalization, as during training (see
data.normalize_spectra).precision_encoding (bool) – Replace sigma with log(1 + 1/sigma) after normalization (see
data.precision_encoding).
- Returns:
Tuple of (X, wavelength, gaia_id) where X has shape (3, n_wave) with channels [flux, sigma, mask], matching the training inputs (sigma is replaced by its encoding with precision_encoding), wavelength is float32, and gaia_id is -1 without metadata/gaia_id.
- Raises:
ValueError – If the survey is not in the catalogue.
- Return type:
tuple[ndarray, ndarray, int]
- load_labels_for_index(index, label_source='apogee', survey=None)[source]¶
Load one star’s labels by catalogue row index.
- Parameters:
index (int) – Row index in the catalogue.
label_source (str) – Label source (e.g. “apogee”, “galah”).
survey (str | None) – Survey name, only needed to resolve v1 per-survey label groups (e.g. “apogee_boss”).
- Returns:
Tuple of (values, errors, flags), each of shape (n_params,), or None if the label source is not in the catalogue.
- Return type:
tuple[ndarray, ndarray, ndarray] | None
- load_labels(label_source, max_flag_bits=0)[source]¶
Load one label source’s labels for every catalogue star.
The labels are matched to stars by Gaia ID, in the row order of
metadata/gaia_id, so the label group may store its rows in any order. A label is valid (mask 1) when its error is positive and its flag is 0; withmax_flag_bits>= 0, every label of a star with more set flag bits thanmax_flag_bitsis masked.- Parameters:
label_source (str) – Label group name, such as “apogee” or “galah”.
max_flag_bits (int) – Largest number of set flag bits, summed over the parameters of a star, for its labels to count; -1 sets no limit.
- Returns:
Labels of shape (n_stars, 3, n_parameters) = [values, errors, mask], in the catalogue’s units. Stars without a row in the label group have mask 0.
- Raises:
ValueError – If max_flag_bits is not an integer >= -1, the catalogue has no labels, the label source is not in the catalogue, or the catalogue or its label group has no Gaia IDs.
- Return type:
ndarray
- get_parameter_names()[source]¶
Get the label parameter names, in catalogue column order.
- Returns:
The
parameter_namesattribute of the catalogue. Without it, the first names ofSTELLAR_PARAMETERS, one per label column.- Raises:
ValueError – If the attribute is missing and there are more label columns than
STELLAR_PARAMETERS.- Return type:
list[str]
- load_merged_for_training(surveys, label_source='apogee', max_flag_bits=0, label_sources=None, normalize_spectra=False, precision_encoding=True)[source]¶
Load merged multi-survey data ready for training with MultiHeadMLP.
Loads the surveys with
load_merged()(outer join) and returns the 3-channel format of the trainer. With label_sources, returns the labels and a mask for each source, for per-source loss masking.Note
This method needs one row per star, as catalogues built by
scripts/build_catalogue_v2.pyhave; duplicate rows raise an error.- Parameters:
surveys (list[str]) – List of survey names to load and merge.
label_source (str) – Primary label source to use for combined labels. Used when label_sources is None (single-source mode).
max_flag_bits (int) – Largest number of set flag bits, summed over the parameters of a star, for its labels to count; the labels of a star with more are masked. A negative value masks none.
label_sources (list[str] | None) – List of label sources for multi-labelset training. If None, uses single-source mode with label_source parameter. If provided, returns y_dict and has_labels_dict instead of y.
normalize_spectra (bool) – Apply per-spectrum median/IQR normalization to flux (and rescale ivar) before building the model inputs. Training and inference must use the same setting.
precision_encoding (bool) – Replace sigma with log(1 + 1/sigma) after normalization (see
data.precision_encoding).
- Returns:
Tuple of (X_dict, y, has_data_dict, has_labels_dict) where –
- X_dict: Dict mapping survey name to spectral data array
Each array has shape (N, 3, wavelength_bins) with: - Channel 0: flux values - Channel 1: sigma, or its precision encoding - Channel 2: mask (1=valid, 0=invalid wavelength)
- y: Labels. In single-source mode (label_sources=None):
Array of shape (N, 3, n_params) with: - Channel 0: label values - Channel 1: label errors (uncertainties) - Channel 2: mask (1=valid, 0=masked parameter)
- In multi-source mode (label_sources provided):
Dict mapping label source name to array (N, 3, n_params)
- has_data_dict: Dict mapping survey name to boolean mask
indicating which stars have data from that survey.
- has_labels_dict: Dict mapping label source to boolean mask
of the stars with at least one valid label (mask 1) from that source, after the flag filter. Only present in multi-source mode; None in single-source mode.
- Raises:
ValueError – If duplicate observations are found in the catalogue, it has no Gaia IDs, a label source is not in the catalogue, or a label group in
label_sourcesother thanlabel_sourcehas nogaia_id.- Return type:
tuple[dict[str, ndarray], ndarray | dict[str, ndarray], dict[str, ndarray], dict[str, ndarray] | None]
- Example (single-source):
>>> loader = CatalogueLoader("super_catalogue.h5") >>> X_dict, y, has_data, _ = loader.load_merged_for_training( ... surveys=["boss", "lamost_lrs"] ... ) >>> # y.shape = (N, 3, n_params)
- Example (multi-source):
>>> X_dict, y_dict, has_data, has_labels = loader.load_merged_for_training( ... surveys=["boss", "lamost_lrs"], ... label_sources=["apogee", "galah"] ... ) >>> # y_dict["apogee"].shape = (N, 3, n_params) >>> # y_dict["galah"].shape = (N, 3, n_params) >>> # has_labels["apogee"] = boolean array of shape (N,)
- get_survey_wavelength_counts(surveys)[source]¶
Get the number of wavelength bins for each survey.
- Parameters:
surveys (list[str]) – List of survey names.
- Returns:
Dictionary mapping survey name to number of wavelength bins.
- Raises:
ValueError – If a survey is not in the catalogue.
- Return type:
dict[str, int]
Examples
>>> loader = CatalogueLoader("super_catalogue.h5") >>> counts = loader.get_survey_wavelength_counts(["boss", "lamost_lrs"]) >>> # counts = {"boss": 4506, "lamost_lrs": 3473}