API Reference
- class astromol.database.Database(data_dir: str | Path | None = None)
Central container for all astromol data. Loads JSON files, resolves cross-references, and exposes simple lookups.
- get_ref(bibcode)
Look up a Ref by BibTeX citation key.
- get_telescope(nick)
Look up a Telescope by nick.
- get_source(nick)
Look up a Source by nick.
- get_molecule(label)
Look up a Molecule by unique label.
- get_molecules_by_formula(formula)
Look up all molecules with a given chemical formula.
- get_molecules_by_name(name)
Look up all molecules with a given name.
Census-scoped views over an astromol.database.Database.
The view layer centralizes record selection for manuscript tables, figures, slides, and statistics. Output code should consume these views instead of reimplementing census/history filtering locally.
- class astromol.census.CensusView(db: object, scope: str = 'census', census: str | None = None)
A filtered view of astromol records for a census boundary or live data.
Use
for_census()for frozen/historical census outputs andcurrent()for the live database. In census mode, accepted records are selected byhistory.accepted.census <= census. In current mode, accepted records are selected regardless of census label. Context queries exclude isotopologues by default; passinclude_isotopologues=Truefor isotope-expanded views.- classmethod for_census(db, census: str | int) CensusView
Create a view frozen at a census boundary.
- classmethod current(db) CensusView
Create a live view of all currently accepted records.
- property is_current: bool
Whether this view represents live database contents.
- property census_year: int | None
The integer census boundary, or
Nonefor current views.
- accepted_record(record) bool
Return whether a molecule or detection is accepted in this view.
- introduced_record(record) bool
Return whether a record had entered tracking by this view.
- detection_in_scope(detection: Detection, *, include_tentative: bool = False, include_disputed: bool = False) bool
Return whether a detection belongs in this view.
Secure detections require accepted history. Tentative and disputed detections are included only when requested, and then by introduced history rather than accepted history.
- detections(detection_type: str | None = None, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return detections in this view, optionally restricted by type.
Isotopologue detections are excluded by default. Set
include_isotopologues=Truewhen the expanded isotopologue inventory is wanted.
- context_detections(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return detections for one context such as
"ISM/CSM".
- context_molecules(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Molecule]
Return unique molecules detected in one context.
Isotopologues are excluded by default and can be included with
include_isotopologues=True.
- accepted_molecules(*, include_isotopologues: bool = False) list[Molecule]
Return molecule records accepted in this view by molecule history.
Isotopologues are excluded by default and can be included with
include_isotopologues=True.
- exoplanet_detections(**kwargs) list[Detection]
Return exoplanet-atmosphere detections in this view.
- source_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick', group_diffuse_cloud: bool = False, diffuse_cloud_label: str = 'DiffuseCloud') Counter
Count source contributions for detections in this view.
keymay be"nick","name", or"latex_name". Setgroup_diffuse_cloud=Trueto consolidate all diffuse-cloud/LOS sources under one label for historical manuscript table reproduction.
- facility_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick') Counter
Count telescope/facility contributions for detections in this view.
- molecule_labels(molecules: Iterable[Molecule]) set[str]
Return molecule labels from a molecule iterable.
- filtered(*, molecule_filter: Callable[[Molecule], bool] | None = None, detection_filter: Callable[[Detection], bool] | None = None) FilteredCensusView
Return a custom view that filters records from this view.
Use this when a standard census/current view is the correct historical boundary, but an analysis should be restricted to a special subset such as carbon-bearing molecules, detections from one source type, or detections observed with one wavelength family.
- class astromol.census.FilteredCensusView(base: CensusView, molecule_filter: Callable[[Molecule], bool] | None = None, detection_filter: Callable[[Detection], bool] | None = None)
View wrapper that applies custom filters to an existing census view.
- property db
The underlying database.
- property scope: str
The wrapped view scope.
- property census: str | None
The wrapped census boundary, or
Nonefor current views.
- property is_current: bool
Whether this view represents live database contents.
- property census_year: int | None
The integer census boundary, or
Nonefor current views.
- accepted_record(record) bool
Return whether a record is accepted in the wrapped view.
- introduced_record(record) bool
Return whether a record had entered tracking by the wrapped view.
- detection_in_scope(detection: Detection, *, include_tentative: bool = False, include_disputed: bool = False) bool
Return whether a detection belongs in the wrapped view.
- detections(detection_type: str | None = None, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return filtered detections from the wrapped view.
- context_detections(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return filtered detections for one context.
- context_molecules(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Molecule]
Return unique filtered molecules detected in one context.
- accepted_molecules(*, include_isotopologues: bool = False) list[Molecule]
Return filtered molecule records accepted in the wrapped view.
- source_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick', group_diffuse_cloud: bool = False, diffuse_cloud_label: str = 'DiffuseCloud') Counter
Count filtered source contributions for detections in this view.
- facility_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick') Counter
Count filtered telescope/facility contributions.
- class astromol.models.Ref(bibcode: str, author: str, journal: str, year: int, month: int = None, day: int = None, volume: str = None, page: str = None, title: str = None, doi: str = None, note: str = None)
A single bibliographic reference.
- property sortdate
Build a date for sorting/ordering purposes. Uses the 1st for any unknown month or day. Two papers from 1937 with no month both get Jan 1 1937, but a paper from March 1937 sorts after January 1937.
- class astromol.models.HistoryEvent(kind: str, summary: str, date: str = None, census: str = None, fields: list[str] = <factory>, legacy_version: str = None)
A semantic database-history event exposed through a record.
- class astromol.models.RecordHistory(introduced: dict = None, accepted: dict = None, last_modified: str = None, events: list[HistoryEvent] = <factory>)
Semantic update history for a database record.
- property introduced_census
Census release where this record entered astromol tracking.
- property introduced_context
Context for record introduction, such as confirmed or tentative.
- property accepted_census
Census release where this record first became accepted/confirmed.
- property accepted_context
Context for first accepted/confirmed census membership.
- class astromol.models.Telescope(name: str, nick: str, shortname: str, type: str, wavelength: list, diameter: float = None, latitude: float = None, longitude: float = None, built: int = None, decommissioned: int = None, note: str = None, latex_name: str = None, history: RecordHistory = None)
An observing facility or instrument.
- property active
True if the telescope has not been decommissioned.
- class astromol.models.Source(name: str, nick: str, type: str, ra: str = None, dec: str = None, simbad_url: str = None, latex_name: str = None, note: str = None, history: RecordHistory = None)
An astronomical object where molecules have been detected.
- class astromol.models.RotationalConstants(A: float = None, B: float = None, C: float = None, refs: list = <factory>, note: str = None)
Rotational constants of a molecule in MHz.
- property ref
Legacy alias for the first reference, if present.
- class astromol.models.DipoleMoment(a: float = None, b: float = None, c: float = None, refs: list = <factory>, note: str = None)
Dipole moment components of a molecule in Debye.
- property ref
Legacy alias for the first reference, if present.
- property total
Total dipole moment magnitude in Debye.
- class astromol.models.Molecule(name: str, formula: str, table_formula: str = None, label: str = None, note: str = None, iupac_name: str = None, selfies: str = None, synonyms: list[str] = <factory>, smiles: str = None, canonical_smiles: str = None, inchi: str = None, inchikey: str = None, radical_override: bool = None, fullerene: bool = False, pah: bool = False, n_rings: int = 0, cyclic: bool = False, tags: dict[str, list[str]]=<factory>, rotcon: RotationalConstants = None, dipole: DipoleMoment = None, refs: dict = None, isotopologue_of: str = None, latex_section_override: str = None, latex_body: str = None, history: RecordHistory = None)
A chemical species detected (or potentially detectable) in the ISM/CSM.
The optional
smilesandselfiesfields are retained as identifiers or future display metadata only; they are stored but not interpreted here.- property introduced_census
Census release where this molecule entered astromol tracking.
- property introduced_context
Context for molecule introduction, such as confirmed or tentative.
- property accepted_census
Census release where this molecule first became accepted/confirmed.
- property accepted_context
Context for first accepted/confirmed census membership.
- property atom_counts
Elemental composition with isotopic substitutions collapsed.
Examples
HCOOH -> {‘H’: 2, ‘C’: 1, ‘O’: 2} CH -> {‘C’: 1, ‘H’: 1}
Use isotope_counts if isotope labels need to be retained.
- property atoms
Legacy alias for atom_counts.
- property isotope_counts
Elemental composition retaining isotope labels where present.
- property mass
Exact/monoisotopic molecular mass in amu.
- property average_mass
Average molecular mass from terrestrial isotopic abundances.
- property nominal_mass
Nominal integer mass of the formula.
- property natoms
Total number of nuclei in the formula.
- property charge
Formal charge of the molecule.
- property cation
True if positively charged.
- property anion
True if negatively charged.
- property neutral
True if not charged.
- property nelectrons
Total number of electrons after correcting for formal charge.
This is the sum of neutral atomic numbers minus the molecular charge. A cation has fewer electrons; an anion has more.
- property odd_electron
True if the molecule has an odd number of electrons.
- property radical
Whether the molecule should be treated as a radical.
If radical_override is set, the curated value is returned. Otherwise, radical character is inferred from the odd-electron rule.
- property du
Degree of unsaturation using the original astromol convention.
This is only computed for molecules containing H/D, C, N, O, Cl, F, and S. It is a formula-based heuristic, not a structure assignment. Returns None outside the domain where the simple expression is useful.
- property maxdu
Maximum degree of unsaturation for the same heavy-atom inventory.
This preserves the original astromol convention and is only computed for the same limited element set as du.
- property is_linear
True if the molecule is linear. Determined by having only a B rotational constant (no A or C). Returns None if no rotational constants are available.
- property kappa
Ray’s asymmetry parameter. Ranges from -1 (prolate) to +1 (oblate). Linear rotors are treated as the perfectly prolate limit, kappa = -1. Nonlinear rotors require all three rotational constants.
- class astromol.models.Detection(id: str, molecule: str, sources: list, telescopes: list, wavelengths: list, year: int, type: str, note: str = None, status: str = 'secure', status_note: str = None, first: bool = False, month: int = None, day: int = None, refs: dict = None, confirms: list = <factory>, confirmed_by: list = <factory>, disputes: list = <factory>, disputed_by: list = <factory>, supersedes: list = <factory>, superseded_by: list = <factory>, latex_text: str = None, history: RecordHistory = None)
A specific detection event of a molecule in an astronomical source.
- property introduced_census
Census release where this detection entered astromol tracking.
- property introduced_context
Context for detection introduction, such as confirmed or tentative.
- property accepted_census
Census release where this detection first became accepted/confirmed.
- property accepted_context
Context for first accepted/confirmed census membership.
- property sortdate
Build a date for sorting/ordering purposes. Uses the 1st for any unknown month or day.
Validation helpers for astromol production data.
- class astromol.validation.ValidationIssue(severity: str, code: str, record: str, message: str)
One validation issue found in the production data.
- class astromol.validation.ValidationReport(issues: list[ValidationIssue] = <factory>)
Collection of validation issues.
- astromol.validation.validate_database(db: Database | None = None) ValidationReport
Validate production records and return a report.
Database()already validates parsing, required dataclass values, duplicate primary keys, reference resolution, and relationship targets. This layer adds semantic consistency checks that are useful before releases and data-update commits.
- astromol.validation.format_issue(issue: ValidationIssue) str
Return one issue formatted for command-line output.
- astromol.validation.format_report(report: ValidationReport) str
Return a human-readable validation report.
LaTeX output helpers for census manuscripts.
- class astromol.latex.TableColumn(header: str, anchor: str, molecules: list[Molecule])
One logical molecule-table column.
- class astromol.latex.DetectionRateFit(label: str, onset_year: int, slope: float, r_value: float, r_squared: float)
Linear detection-rate fit for one molecule-size category.
- astromol.latex.endinput(value: object) str
Return a LaTeX input fragment terminated with
\endinput.
- astromol.latex.write_fragments(fragments: dict[str, str], output_dir: str | Path = '.') None
Write filename-to-content LaTeX fragments to
output_dir.
- astromol.latex.molecule_link(molecule: Molecule) str
Return a hyperlinked mhchem formula for a molecule.
- astromol.latex.detection_molecule_link(detection: Detection) str
Return a linked molecule formula with a tentative marker if needed.
- astromol.latex.linked_header(anchor: str, text: str) str
Return a hyperlinked table-column header.
- astromol.latex.first_detection_sort_keys(detections: Iterable[Detection]) dict[str, tuple]
Return first-detection sort keys by molecule label.
- astromol.latex.molecules_by_first_detection(molecules: Iterable[Molecule], detections: Iterable[Detection]) list[Molecule]
Sort molecules by first detection represented in
detections.
- astromol.latex.split_legacy_pair_column(values: list[Molecule]) tuple[list[Molecule], list[Molecule]]
Split legacy paired table columns using the historical midpoint rule.
- astromol.latex.split_balanced_columns(values: list[Molecule], max_rows: int) list[list[Molecule]]
Split values into balanced chunks with no chunk over
max_rows.
- astromol.latex.table_rows(columns: list[list[Molecule]]) list[str]
Render molecule columns as LaTeX table rows.
- astromol.latex.table_column_rows(columns: list[TableColumn]) list[str]
Render logical table columns as LaTeX rows.
- astromol.latex.table_column_header(columns: list[TableColumn]) str
Render logical table-column headers with grouped split columns.
- astromol.latex.atom_reference_table_header(atom_counts: Iterable[int]) list[str]
Return grouped atom-count and species/reference table headers.
- astromol.latex.tabular_spec(ncols: int) str
Return a flexible full-width tabular specification.
- astromol.latex.species_reference_tabular_spec(npairs: int) str
Return a full-width tabular spec for species/reference column pairs.
- astromol.latex.single_reference_tabular_spec(width: str = '\\columnwidth') str
Return a tabular spec for one species/reference column pair.
- astromol.latex.latex_table_fragment(*, caption: str, tabular_spec: str, header: str, rows: list[str], label: str) str
Render a complete LaTeX table fragment.
- astromol.latex.molecule_count(view: CensusView) int
Number of accepted ISM/CSM molecules in the view.
- astromol.latex.element_count(view: CensusView) int
Number of unique elements in accepted ISM/CSM molecules.
- astromol.latex.context_molecule_count(view: CensusView, detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = True) int
Count unique molecules in one detection context.
- astromol.latex.ppd_molecule_count(view: CensusView) int
Number of non-isotopologue molecules detected in PPDs.
- astromol.latex.ppd_isotopologue_count(view: CensusView) int
Number of isotopologue entries detected in PPDs.
- astromol.latex.exgal_molecule_count(view: CensusView) int
Number of accepted extragalactic molecules.
- astromol.latex.exgal_percent(view: CensusView) int
Accepted extragalactic molecules as a percentage of ISM/CSM molecules.
- astromol.latex.exoplanet_molecule_count(view: CensusView) int
Number of accepted exoplanet-atmosphere molecules.
- astromol.latex.ice_molecule_count(view: CensusView) int
Number of accepted interstellar-ice molecules.
- astromol.latex.molecule_detections_by_label(detections: Iterable[Detection]) dict[str, list[Detection]]
Group detections by molecule label.
- astromol.latex.radio_percent(view: CensusView) int
Percentage of ISM/CSM molecules detected at radio wavelengths.
- astromol.latex.facility_count(view: CensusView) int
Number of facilities contributing to accepted ISM/CSM detections.
- astromol.latex.hydrocarbon_molecules(view: CensusView) list[Molecule]
ISM/CSM molecules with C and H and a computable degree of unsaturation.
- astromol.latex.saturated_hydrocarbons(view: CensusView) list[Molecule]
Hydrocarbon molecules with zero degree of unsaturation.
- astromol.latex.unsaturated_hydrocarbons(view: CensusView) list[Molecule]
Hydrocarbon molecules with nonzero degree of unsaturation.
- astromol.latex.saturated_hydrocarbon_count(view: CensusView) int
Number of saturated hydrocarbon molecules.
- astromol.latex.saturated_hydrocarbon_percent(view: CensusView) int
Saturated hydrocarbons as a percentage of hydrocarbon molecules.
- astromol.latex.unsaturated_hydrocarbon_percent(view: CensusView) int
Unsaturated hydrocarbons as a percentage of hydrocarbon molecules.
- astromol.latex.saturated_hydrocarbon_list(view: CensusView) str
LaTeX list of saturated hydrocarbon formulas.
- astromol.latex.molecule_source_types(view: CensusView) dict[str, set[str]]
Map ISM/CSM molecule labels to source types represented in detections.
- astromol.latex.radical_percent_by_source_type(view: CensusView, source_type: str) int
Percentage of molecules detected in a source type that are radicals.
- astromol.latex.first_detection_years(view: CensusView) list[int]
First accepted ISM/CSM detection year for each molecule.
- astromol.latex.detection_rate_since(view: CensusView, start_year: int) float
Linear cumulative-detection rate since
start_year.
- astromol.latex.scalar_fragments(view: CensusView) dict[str, str]
Return standard scalar LaTeX input fragments for a census view.
- astromol.latex.write_scalar_fragments(view: CensusView, output_dir: str | Path = '.') dict[str, str]
Write standard scalar LaTeX fragments and return generated content.
- astromol.latex.rate_fit_end_year(view: CensusView, detections: Iterable[Detection]) int
Return the final year to use for rate-table fits.
- astromol.latex.category_detection_years(detections: Iterable[Detection], category: int | str) list[int]
Return first-detection years for one atom-count rate category.
- astromol.latex.cumulative_counts_by_year(detection_years: Iterable[int], *, onset_year: int, end_year: int) tuple[ndarray, ndarray]
Return years and cumulative detection counts since the onset year.
- astromol.latex.linear_rate_fit(detection_years: Iterable[int], *, onset_year: int, end_year: int) tuple[float, float, float] | None
Return slope, Pearson R, and R^2 for cumulative detections since onset.
- astromol.latex.rate_by_atoms_fits(view: CensusView) list[DetectionRateFit]
Return detection-rate fits by atom-count category for ISM/CSM molecules.
- astromol.latex.rate_by_atoms_table_fragment(view: CensusView) str
Return the detection-rate-by-atoms table as a LaTeX fragment.
- astromol.latex.rate_by_atoms_table_fragments(view: CensusView, filename: str = 'rates_by_atoms_table.tex') dict[str, str]
Return the detection-rate-by-atoms table fragment.
- astromol.latex.write_rate_by_atoms_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'rates_by_atoms_table.tex') dict[str, str]
Write the detection-rate-by-atoms table and return content.
- astromol.latex.sorted_count_entries(counts: dict[str, int]) list[tuple[str, int]]
Return count entries sorted descending by count, then by label.
- astromol.latex.paired_count_table_rows(entries: list[tuple[str, int]]) list[str]
Render count entries into two side-by-side table-column pairs.
- astromol.latex.paired_count_table_fragment(*, caption: str, label: str, item_header: str, count_header: str, entries: list[tuple[str, int]]) str
Return a two-column-pair LaTeX count table fragment.
- astromol.latex.facility_table_entries(view: CensusView) list[tuple[str, int]]
Return observing-facility contribution counts for the facility table.
- astromol.latex.facility_table_fragment(view: CensusView) str
Return the observing-facility count table as a LaTeX fragment.
- astromol.latex.facility_table_fragments(view: CensusView, filename: str = 'facilities_table.tex') dict[str, str]
Return the observing-facility count table fragment.
- astromol.latex.write_facility_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'facilities_table.tex') dict[str, str]
Write the observing-facility count table and return content.
- astromol.latex.source_table_entries(view: CensusView) list[tuple[str, int]]
Return source contribution counts for the source table.
- astromol.latex.source_table_fragment(view: CensusView) str
Return the source contribution count table as a LaTeX fragment.
- astromol.latex.source_table_fragments(view: CensusView, filename: str = 'source_table.tex') dict[str, str]
Return the source contribution count table fragment.
- astromol.latex.write_source_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'source_table.tex') dict[str, str]
Write the source contribution count table and return content.
- astromol.latex.ism_table_molecules(view: CensusView) list[Molecule]
Return non-isotopologue ISM/CSM molecules for the main molecule table.
- astromol.latex.ism_table_detections(view: CensusView) list[Detection]
Return non-isotopologue ISM/CSM detections for table ordering.
- astromol.latex.ism_table_columns(view: CensusView) tuple[list[list[Molecule]], list[list[Molecule]]]
Return legacy ISM/CSM table columns for a census view.
- astromol.latex.balanced_ism_table_columns(view: CensusView, *, max_rows: int = 23, max_columns: int = 7) list[list[TableColumn]]
Return balanced ISM/CSM table columns packed into table groups.
- astromol.latex.legacy_ism_table_fragments(view: CensusView, basename: str = 'ism_table') dict[str, str]
Return the two legacy 2021-style ISM/CSM molecule table fragments.
- astromol.latex.balanced_ism_table_fragments(view: CensusView, basename: str = 'ism_table', *, max_rows: int = 23, max_columns: int = 7) dict[str, str]
Return balanced, future-oriented ISM/CSM molecule table fragments.
- astromol.latex.ism_table_fragments(view: CensusView, basename: str = 'ism_table', *, layout: str = 'balanced', max_rows: int = 23, max_columns: int = 7) dict[str, str]
Return ISM/CSM molecule table fragments.
layout="legacy"reproduces the two historical audit tables.layout="balanced"produces future-oriented tables constrained bymax_rowsandmax_columns.
- astromol.latex.write_ism_tables(view: CensusView, output_dir: str | Path = '.', basename: str = 'ism_table', *, layout: str = 'balanced', max_rows: int = 23, max_columns: int = 7) dict[str, str]
Write standard ISM/CSM molecule tables and return generated content.
- astromol.latex.first_context_detection_by_molecule(detections: Iterable[Detection]) dict[str, Detection]
Return the first secure detection per molecule, falling back to tentative.
- astromol.latex.exgal_table_detections(view: CensusView) list[Detection]
Return non-isotopologue exgal detections for the molecule table.
Secure detections are included by accepted census membership. Tentative detections are included by introduced census membership and rendered with a dagger marker.
- astromol.latex.chunked_atom_groups(atom_counts: list[int], *, first_group_size: int, group_size: int) list[tuple[int, ...]]
Split atom-count labels into first-page and continuation groups.
- astromol.latex.exgal_table_atom_groups(view: CensusView) list[tuple[int, ...]]
Return non-empty atom-count groups for the exgal molecule table.
- astromol.latex.exgal_table_columns(view: CensusView, atom_groups: Iterable[Iterable[int]] | None = None) list[list[list[Detection]]]
Return exgal table columns split by configured atom-count groups.
- astromol.latex.observation_ref_bibcodes(detection: Detection) list[str]
Return observation-reference BibTeX keys for a detection.
- astromol.latex.reference_numbers(bibcodes: Iterable[str], references: dict[str, int]) str
Assign and render stable numeric reference labels for BibTeX keys.
- astromol.latex.detection_reference_table_rows(columns: list[list[Detection]], references: dict[str, int]) list[str]
Render rows for molecule/reference table columns.
- astromol.latex.single_detection_reference_table_rows(detections: Iterable[Detection], references: dict[str, int]) list[str]
Render rows for a one-column species/reference table.
- astromol.latex.numbered_reference_notes(references: dict[str, int]) str
Render numbered citation notes from BibTeX key to index mapping.
- astromol.latex.exgal_table_fragment(view: CensusView) str
Return the external-galaxy molecule table as a LaTeX fragment.
- astromol.latex.exgal_table_fragments(view: CensusView, filename: str = 'exgal_table.tex') dict[str, str]
Return the external-galaxy molecule table fragment.
- astromol.latex.write_exgal_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'exgal_table.tex') dict[str, str]
Write the external-galaxy molecule table and return generated content.
- astromol.latex.ppd_table_detections(view: CensusView) list[Detection]
Return PPD detections for the molecule table, including isotopologues.
The PPD table intentionally includes isotope records. Ordering is parent-first: each parent molecule is followed by any detected PPD isotopologues that point to it.
- astromol.latex.ppd_table_atom_groups(view: CensusView) list[tuple[int, ...]]
Return non-empty atom-count groups for the PPD molecule table.
- astromol.latex.ppd_table_columns(view: CensusView, atom_groups: Iterable[Iterable[int]] | None = None) list[list[list[Detection]]]
Return PPD table columns split by configured atom-count groups.
- astromol.latex.ppd_table_fragment(view: CensusView) str
Return the protoplanetary-disk molecule table as a LaTeX fragment.
- astromol.latex.ppd_table_fragments(view: CensusView, filename: str = 'ppd_table.tex') dict[str, str]
Return the protoplanetary-disk molecule table fragment.
- astromol.latex.write_ppd_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'ppd_table.tex') dict[str, str]
Write the protoplanetary-disk molecule table and return content.
- astromol.latex.parent_first_context_detections(db, detections: Iterable[Detection], *, include_isotopologues: bool) list[Detection]
Order context detections in database order, parent before isotopologues.
- astromol.latex.exoplanet_table_detections(view: CensusView, *, include_isotopologues: bool = False) list[Detection]
Return exoplanet detections for the molecule table.
- astromol.latex.exoplanet_table_fragment(view: CensusView, *, include_isotopologues: bool = False) str
Return the exoplanet-atmosphere molecule table as a LaTeX fragment.
- astromol.latex.exoplanet_table_fragments(view: CensusView, filename: str = 'exo_table.tex', *, include_isotopologues: bool = False) dict[str, str]
Return the exoplanet-atmosphere molecule table fragment.
- astromol.latex.write_exoplanet_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'exo_table.tex', *, include_isotopologues: bool = False) dict[str, str]
Write the exoplanet-atmosphere table and return content.
- astromol.latex.ice_table_detections(view: CensusView, *, include_tentative: bool = True, include_isotopologues: bool = False) list[Detection]
Return ice detections for the molecule table.
- astromol.latex.ice_table_fragment(view: CensusView, *, include_tentative: bool = True, include_isotopologues: bool = False) str
Return the interstellar-ice molecule table as a LaTeX fragment.
- astromol.latex.ice_table_fragments(view: CensusView, filename: str = 'ice_table.tex', *, include_tentative: bool = True, include_isotopologues: bool = False) dict[str, str]
Return the interstellar-ice molecule table fragment.
- astromol.latex.write_ice_table(view: CensusView, output_dir: str | Path = '.', filename: str = 'ice_table.tex', *, include_tentative: bool = True, include_isotopologues: bool = False) dict[str, str]
Write the interstellar-ice table and return content.
Public figure API.
The implementation is split into private/focused modules, but public callers
should continue importing figure helpers from astromol.figures.
- class astromol.figures.defaultdict
defaultdict(default_factory=None, /, […]) –> dict with default factory
The default factory is called without arguments to produce a new value when a key is not present, in __getitem__ only. A defaultdict compares equal to a dict with the same items. All remaining arguments are treated the same as if they were passed to the dict constructor, including keyword arguments.
- copy() a shallow copy of D.
- default_factory
Factory for default value called by __missing__().
- astromol.figures.dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)
Add dunder methods based on the fields defined in the class.
Examines PEP 526 __annotations__ to determine fields.
If init is true, an __init__() method is added to the class. If repr is true, a __repr__() method is added. If order is true, rich comparison dunder methods are added. If unsafe_hash is true, a __hash__() method is added. If frozen is true, fields may not be assigned to after instance creation. If match_args is true, the __match_args__ tuple is added. If kw_only is true, then by default all fields are keyword-only. If slots is true, a new class with a __slots__ attribute is returned.
- class astromol.figures.date
date(year, month, day) –> date object
- ctime()
Return ctime() style string.
- classmethod fromisocalendar()
int, int, int -> Construct a date from the ISO year, week number and weekday.
This is the inverse of the date.isocalendar() function
- classmethod fromisoformat()
str -> Construct a date from a string in ISO 8601 format.
- classmethod fromordinal()
int -> date corresponding to a proleptic Gregorian ordinal.
- classmethod fromtimestamp(timestamp, /)
Create a date from a POSIX timestamp.
The timestamp is a number, e.g. created via time.time(), that is interpreted as local time.
- isocalendar()
Return a named tuple containing ISO year, week number, and weekday.
- isoformat()
Return string in ISO 8601 format, YYYY-MM-DD.
- isoweekday()
Return the day of the week represented by the date. Monday == 1 … Sunday == 7
- replace()
Return date with new specified fields.
- strftime()
format -> strftime() style string.
- timetuple()
Return time tuple, compatible with time.localtime().
- classmethod today()
Current date or datetime: same as self.__class__.fromtimestamp(time.time()).
- toordinal()
Return proleptic Gregorian ordinal. January 1 of year 1 is day 1.
- weekday()
Return the day of the week represented by the date. Monday == 0 … Sunday == 6
- class astromol.figures.Path(*args, **kwargs)
PurePath subclass that can make system calls.
Path represents a filesystem path but unlike PurePath, also offers methods to do system calls on path objects. Depending on your system, instantiating a Path will return either a PosixPath or a WindowsPath object. You can also instantiate a PosixPath or WindowsPath directly, but cannot instantiate a WindowsPath on a POSIX system or vice versa.
- stat(*, follow_symlinks=True)
Return the result of the stat() system call on this path, like os.stat() does.
- lstat()
Like stat(), except if the path points to a symlink, the symlink’s status information is returned, rather than its target’s.
- exists(*, follow_symlinks=True)
Whether this path exists.
This method normally follows symlinks; to check whether a symlink exists, add the argument follow_symlinks=False.
- is_dir()
Whether this path is a directory.
- is_file()
Whether this path is a regular file (also True for symlinks pointing to regular files).
- is_mount()
Check if this path is a mount point
- is_symlink()
Whether this path is a symbolic link.
- is_junction()
Whether this path is a junction.
- is_block_device()
Whether this path is a block device.
- is_char_device()
Whether this path is a character device.
- is_fifo()
Whether this path is a FIFO.
- is_socket()
Whether this path is a socket.
- samefile(other_path)
Return whether other_path is the same or not as this file (as returned by os.path.samefile()).
- open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
Open the file pointed to by this path and return a file object, as the built-in open() function does.
- read_bytes()
Open the file in bytes mode, read it, and close the file.
- read_text(encoding=None, errors=None)
Open the file in text mode, read it, and close the file.
- write_bytes(data)
Open the file in bytes mode, write to it, and close the file.
- write_text(data, encoding=None, errors=None, newline=None)
Open the file in text mode, write to it, and close the file.
- iterdir()
Yield path objects of the directory contents.
The children are yielded in arbitrary order, and the special entries ‘.’ and ‘..’ are not included.
- glob(pattern, *, case_sensitive=None)
Iterate over this subtree and yield all existing files (of any kind, including directories) matching the given relative pattern.
- rglob(pattern, *, case_sensitive=None)
Recursively yield all existing files (of any kind, including directories) matching the given relative pattern, anywhere in this subtree.
- walk(top_down=True, on_error=None, follow_symlinks=False)
Walk the directory tree from this directory, similar to os.walk().
- classmethod cwd()
Return a new path pointing to the current working directory.
- classmethod home()
Return a new path pointing to the user’s home directory (as returned by os.path.expanduser(‘~’)).
- absolute()
Return an absolute version of this path by prepending the current working directory. No normalization or symlink resolution is performed.
Use resolve() to get the canonical path to a file.
- resolve(strict=False)
Make the path absolute, resolving all symlinks on the way and also normalizing it.
- owner()
Return the login name of the file owner.
- group()
Return the group name of the file gid.
- readlink()
Return the path to which the symbolic link points.
- touch(mode=438, exist_ok=True)
Create this file with the given access mode, if it doesn’t exist.
- mkdir(mode=511, parents=False, exist_ok=False)
Create a new directory at this given path.
- chmod(mode, *, follow_symlinks=True)
Change the permissions of the path, like os.chmod().
- lchmod(mode)
Like chmod(), except if the path points to a symlink, the symlink’s permissions are changed, rather than its target’s.
- unlink(missing_ok=False)
Remove this file or link. If the path is a directory, use rmdir() instead.
- rmdir()
Remove this directory. The directory must be empty.
- rename(target)
Rename this path to the target path.
The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.
Returns the new Path instance pointing to the target path.
- replace(target)
Rename this path to the target path, overwriting if that path exists.
The target path may be absolute or relative. Relative paths are interpreted relative to the current working directory, not the directory of the Path object.
Returns the new Path instance pointing to the target path.
- symlink_to(target, target_is_directory=False)
Make this path a symlink pointing to the target path. Note the order of arguments (link, target) is the reverse of os.symlink.
- hardlink_to(target)
Make this path a hard link pointing to the same file as target.
Note the order of arguments (self, target) is the reverse of os.link’s.
- expanduser()
Return a new path with expanded ~ and ~user constructs (as returned by os.path.expanduser)
- class astromol.figures.CensusView(db: object, scope: str = 'census', census: str | None = None)
A filtered view of astromol records for a census boundary or live data.
Use
for_census()for frozen/historical census outputs andcurrent()for the live database. In census mode, accepted records are selected byhistory.accepted.census <= census. In current mode, accepted records are selected regardless of census label. Context queries exclude isotopologues by default; passinclude_isotopologues=Truefor isotope-expanded views.- classmethod for_census(db, census: str | int) CensusView
Create a view frozen at a census boundary.
- classmethod current(db) CensusView
Create a live view of all currently accepted records.
- property is_current: bool
Whether this view represents live database contents.
- property census_year: int | None
The integer census boundary, or
Nonefor current views.
- accepted_record(record) bool
Return whether a molecule or detection is accepted in this view.
- introduced_record(record) bool
Return whether a record had entered tracking by this view.
- detection_in_scope(detection: Detection, *, include_tentative: bool = False, include_disputed: bool = False) bool
Return whether a detection belongs in this view.
Secure detections require accepted history. Tentative and disputed detections are included only when requested, and then by introduced history rather than accepted history.
- detections(detection_type: str | None = None, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return detections in this view, optionally restricted by type.
Isotopologue detections are excluded by default. Set
include_isotopologues=Truewhen the expanded isotopologue inventory is wanted.
- context_detections(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Detection]
Return detections for one context such as
"ISM/CSM".
- context_molecules(detection_type: str, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[Molecule]
Return unique molecules detected in one context.
Isotopologues are excluded by default and can be included with
include_isotopologues=True.
- accepted_molecules(*, include_isotopologues: bool = False) list[Molecule]
Return molecule records accepted in this view by molecule history.
Isotopologues are excluded by default and can be included with
include_isotopologues=True.
- exoplanet_detections(**kwargs) list[Detection]
Return exoplanet-atmosphere detections in this view.
- source_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick', group_diffuse_cloud: bool = False, diffuse_cloud_label: str = 'DiffuseCloud') Counter
Count source contributions for detections in this view.
keymay be"nick","name", or"latex_name". Setgroup_diffuse_cloud=Trueto consolidate all diffuse-cloud/LOS sources under one label for historical manuscript table reproduction.
- facility_counts(detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, key: str = 'nick') Counter
Count telescope/facility contributions for detections in this view.
- molecule_labels(molecules: Iterable[Molecule]) set[str]
Return molecule labels from a molecule iterable.
- filtered(*, molecule_filter: Callable[[Molecule], bool] | None = None, detection_filter: Callable[[Detection], bool] | None = None) FilteredCensusView
Return a custom view that filters records from this view.
Use this when a standard census/current view is the correct historical boundary, but an analysis should be restricted to a special subset such as carbon-bearing molecules, detections from one source type, or detections observed with one wavelength family.
- class astromol.figures.Detection(id: str, molecule: str, sources: list, telescopes: list, wavelengths: list, year: int, type: str, note: str = None, status: str = 'secure', status_note: str = None, first: bool = False, month: int = None, day: int = None, refs: dict = None, confirms: list = <factory>, confirmed_by: list = <factory>, disputes: list = <factory>, disputed_by: list = <factory>, supersedes: list = <factory>, superseded_by: list = <factory>, latex_text: str = None, history: RecordHistory = None)
A specific detection event of a molecule in an astronomical source.
- property introduced_census
Census release where this detection entered astromol tracking.
- property introduced_context
Context for detection introduction, such as confirmed or tentative.
- property accepted_census
Census release where this detection first became accepted/confirmed.
- property accepted_context
Context for first accepted/confirmed census membership.
- property sortdate
Build a date for sorting/ordering purposes. Uses the 1st for any unknown month or day.
- class astromol.figures.DetectionTrend(label: str, start_year: int, stop_year: int | None, slope: float)
Linear trend fitted to a section of a cumulative detection curve.
- class astromol.figures.CumulativeDetectionData(years: ndarray, counts: ndarray, first_detection_years: dict[str, int], trends: tuple[DetectionTrend, ...], show_facility_markers: bool = False)
Data needed to plot cumulative detections over time.
- property total: int
Final cumulative detection count.
- property start_year: int
First year in the cumulative series.
- property end_year: int
Last year in the cumulative series.
- class astromol.figures.CumulativeByAtomsSeries(category: int | str, label: str, color: str, years: ndarray, counts: ndarray, first_detection_years: dict[str, int])
One cumulative-detection series for an atom-count category.
- property final_count: int
Final count for this series.
- class astromol.figures.CumulativeByAtomsData(years: ndarray, series: tuple[CumulativeByAtomsSeries, ...])
Data needed to plot cumulative detections grouped by atom count.
- property start_year: int
First year in the cumulative series.
- property end_year: int
Last year in the cumulative series.
- property max_count: int
Largest cumulative count across all plotted series.
- property total: int
Total number of molecules counted across all series.
- class astromol.figures.RollingRateHeatmapData(years: ndarray, labels: tuple[str, ...], matrix: ndarray, window: int, vmax: float)
Data needed to plot rolling detection rates by atom-count category.
- property start_year: int
First year in the rolling-rate series.
- property end_year: int
Last year in the rolling-rate series.
- class astromol.figures.PeriodicHeatmapCell(symbol: str, atomic_number: int, atomic_mass: float, name: str, group: int, y_position: float, count: int)
One displayed cell in the periodic-table heatmap.
- property x_position: float
Left x-coordinate for this periodic-table cell.
- class astromol.figures.PeriodicHeatmapData(cells: tuple[PeriodicHeatmapCell, ...], element_counts: dict[str, int], molecule_count: int)
Data needed to plot the elemental-composition periodic heatmap.
- property detected_element_count: int
Number of elements present in one or more molecules.
- property max_count: int
Largest molecule count for any element.
- class astromol.figures.DUHistogramData(values: tuple[float, ...], molecule_labels: tuple[str, ...], formula_labels: tuple[str, ...], molecule_count: int)
Data needed to plot degree-of-unsaturation histograms.
- property saturated_count: int
Number of included molecules with DU = 0.
- property unsaturated_count: int
Number of included molecules with DU > 0.
- property unsaturated_percent: int
Integer unsaturated percentage, matching legacy truncation.
- property max_du: float
Largest degree of unsaturation in the sample.
- histogram_counts(bins: tuple[float, ...] = (np.float64(-0.25), np.float64(0.25), np.float64(0.75), np.float64(1.25), np.float64(1.75), np.float64(2.25), np.float64(2.75), np.float64(3.25), np.float64(3.75), np.float64(4.25), np.float64(4.75), np.float64(5.25), np.float64(5.75), np.float64(6.25), np.float64(6.75), np.float64(7.25), np.float64(7.75), np.float64(8.25), np.float64(8.75), np.float64(9.25), np.float64(9.75), np.float64(10.25), np.float64(10.75), np.float64(11.25), np.float64(11.75), np.float64(12.25))) ndarray
Return counts in the legacy half-DU-width bins.
- property counts_by_value: dict[float, int]
Return exact DU-value counts.
- value_counts(*, include_negative_du: bool = True) dict[float, int]
Return exact DU-value counts, optionally excluding domain artifacts.
- class astromol.figures.KappaHistogramData(values: tuple[float, ...], molecule_labels: tuple[str, ...], molecule_count: int)
Data needed to plot Ray asymmetry-parameter histograms.
- property min_kappa: float
Smallest Ray asymmetry parameter in the sample.
- property max_kappa: float
Largest Ray asymmetry parameter in the sample.
- histogram_counts(bins: int = 100) ndarray
Return histogram counts using the legacy integer-bin convention.
- class astromol.figures.MoleculeTypeCategory(key: str, label: str, plural_label: str, color: str, percent_color: str, count: int, fraction: float)
One molecule-type category used by the type ring chart.
- property percent: float
Category percentage of the molecule sample.
- class astromol.figures.MoleculeTypeData(categories: tuple[MoleculeTypeCategory, ...], molecule_count: int)
Data needed to plot the molecule-type ring chart.
- property counts: dict[str, int]
Category counts keyed by short category name.
- property fractions: dict[str, float]
Category fractions keyed by short category name.
- class astromol.figures.SourceTypeCategory(key: str, label: str, color: str, count: int, fraction: float, label_y: float, percent_y: float)
One generalized first-detection source category.
- property percent: float
Category percentage of the molecule sample.
- class astromol.figures.SourceTypeData(categories: tuple[SourceTypeCategory, ...], molecule_count: int)
Data needed to plot the generalized source-type ring chart.
- property counts: dict[str, int]
Generalized source-type counts keyed by category name.
- property fractions: dict[str, float]
Generalized source-type fractions keyed by category name.
- class astromol.figures.IndividualSourceData(categories: tuple[SourceTypeCategory, ...], molecule_count: int)
Data needed to plot the individual first-detection source ring chart.
- property counts: dict[str, int]
Individual-source contribution counts keyed by category name.
- property fractions: dict[str, float]
Individual-source contribution fractions keyed by category name.
- class astromol.figures.MoleculeTypesForSource(key: str, label: str, source_count: int, counts_by_type: dict[str, int])
Molecule-type counts credited to one generalized first-detection source.
- property total_type_count: int
Total molecule-type credits in this source category.
- class astromol.figures.MoleculeTypeBySourceData(categories: tuple[MoleculeTypesForSource, ...], molecule_count: int, overall_type_counts: dict[str, int])
Data needed to plot molecule-type mixes by source category.
- property counts: dict[str, dict[str, int]]
Nested counts keyed first by source category and then molecule type.
- property source_counts: dict[str, int]
Source-category molecule counts keyed by source category.
- class astromol.figures.DUBySourceTypeCategory(key: str, label: str, color: str, values: tuple[float, ...])
DU values credited to one generalized first-detection source category.
- property count: int
Number of DU values in this source category.
- class astromol.figures.DUBySourceTypeData(categories: tuple[DUBySourceTypeCategory, ...], molecule_count: int)
Data needed to plot DU distributions by generalized source category.
- property counts: dict[str, int]
DU-value counts keyed by generalized source category.
- property values_by_source: dict[str, tuple[float, ...]]
DU values keyed by generalized source category.
- class astromol.figures.RelativeDUBySourceTypeCategory(key: str, label: str, color: str, values: tuple[float, ...])
Relative-DU values credited to one generalized source category.
- property count: int
Number of relative-DU values in this source category.
- class astromol.figures.RelativeDUBySourceTypeData(categories: tuple[RelativeDUBySourceTypeCategory, ...], molecule_count: int)
Data needed to plot relative-DU distributions by source category.
- property counts: dict[str, int]
Relative-DU value counts keyed by source category.
- property values_by_source: dict[str, tuple[float, ...]]
Relative-DU values keyed by source category.
- class astromol.figures.MassBySourceTypeCategory(key: str, label: str, color: str, masses: tuple[float, ...])
Molecular masses credited to one generalized source category.
- property count: int
Number of molecular masses in this source category.
- class astromol.figures.MassBySourceTypeData(categories: tuple[MassBySourceTypeCategory, ...], molecule_count: int, mass_range: tuple[float, float])
Data needed to plot molecular-mass distributions by source category.
- property counts: dict[str, int]
Molecular-mass counts keyed by generalized source category.
- property masses_by_source: dict[str, tuple[float, ...]]
Molecular masses keyed by generalized source category.
- class astromol.figures.WavelengthBySourceTypeCategory(key: str, label: str, counts_by_wavelength: dict[str, int])
First-detection wavelength counts for one source category.
- property count: int
Total wavelength credits in this source category.
- count_for_display_wavelength(wavelength: str) int
Return counts for a displayed wavelength, combining UV/Vis if needed.
- class astromol.figures.WavelengthBySourceTypeData(categories: tuple[WavelengthBySourceTypeCategory, ...], molecule_count: int)
Data needed to plot wavelength mixes by source category.
- property counts: dict[str, dict[str, int]]
Nested counts keyed first by source category, then wavelength.
- class astromol.figures.MassByWavelengthSeries(key: str, label: str, color: str, masses: tuple[float, ...], annotation_xy: tuple[float, float], truncate_at_data_max: bool = False, zorder: int | None = None)
Molecular masses contributing to one wavelength KDE trace.
- property count: int
Number of molecule masses in the wavelength sample.
- class astromol.figures.MassByWavelengthData(series: tuple[MassByWavelengthSeries, ...], molecule_count: int)
Data needed to plot molecular mass distributions by wavelength.
- property counts: dict[str, int]
Sample counts keyed by wavelength label.
- class astromol.figures.MoleculesByWavelengthAtomsSeries(key: str, label: str, plot: str, atom_counts: tuple[int, ...])
Atom counts contributing to one wavelength-panel distribution.
- property count: int
Number of molecules in this wavelength sample.
- class astromol.figures.MoleculesByWavelengthAtomsData(series: tuple[MoleculesByWavelengthAtomsSeries, ...], molecule_count: int)
Data needed to plot atom-count distributions by detection wavelength.
- property counts: dict[str, int]
Sample counts keyed by wavelength label.
- property max_atoms: int
Largest atom count in any wavelength sample.
- matrix(bins: tuple[int | str, ...] = (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, '13+')) ndarray
Return wavelength-by-atom-count matrix for discrete heatmaps.
- class astromol.figures.DetectionRateByAtomsPoint(category: int | str, label: str, x_position: float, count: int, first_year: int | None, rate: float)
One average detection-rate point for an atom-count category.
- class astromol.figures.DetectionRateByAtomsData(end_year: int, points: tuple[DetectionRateByAtomsPoint, ...])
Data needed to plot average detection rate by atom-count category.
- property visible_points: tuple[DetectionRateByAtomsPoint, ...]
Return points visible in the legacy 2-12 atom x-axis range.
One facility’s share of first detections during its operating window.
Facility contribution fraction during its operating window.
Integer percentage label, matching legacy truncation.
Data needed to plot facility shares.
- class astromol.figures.ScopeDetectionSeries(nick: str, label: str, start_year: int, fit_stop_year: int, color: str, years: ndarray, counts: ndarray, detection_count: int, rate: float)
Cumulative first-detection contribution series for one facility.
- property final_count: int
Final cumulative contribution count.
- class astromol.figures.ScopesByYearData(years: ndarray, series: tuple[ScopeDetectionSeries, ...], end_year: int)
Data needed to plot cumulative facility contributions over time.
- property max_count: int
Largest final cumulative contribution count.
- astromol.figures.first_detections_by_molecule(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) dict[str, Detection]
Return the first detection record for each molecule in a view.
- astromol.figures.first_detection_years_by_molecule(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) dict[str, int]
Return the first detection year for each molecule in a view.
- astromol.figures.cumulative_by_atoms_series_specs(view: CensusView) tuple[dict[str, object], ...]
Return the default atom-count palette for a census/current view.
Legacy 2018/2021 reproduction views keep the original census palette. Current and future-facing views use the color-blind-friendly palette.
- astromol.figures.cumulative_by_atoms_data(view: CensusView, detection_type: str = 'ISM/CSM', *, start_year: int | None = None, end_year: int | None = None, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, series_specs: tuple[dict[str, object], ...] | None = None) CumulativeByAtomsData
Return cumulative-detection data grouped by atom-count category.
The default grouping follows the legacy figure: 2-12 atoms, a true 13+ category excluding PAHs and fullerenes, and separate PAH/fullerene traces.
- astromol.figures.annual_detection_counts(first_detection_years: dict[str, int], years: ndarray) ndarray
Return annual first-detection counts over fixed plot years.
- astromol.figures.trailing_rolling_detection_rate(first_detection_years: dict[str, int], years: ndarray, *, window: int = 10) ndarray
Return trailing rolling detection rates in detections per year.
A 10-year value at 2026 counts detections from 2017 through 2026 and divides by 10. The fixed denominator keeps rates comparable across years.
- astromol.figures.rolling_rate_by_atoms_heatmap_data(view: CensusView, detection_type: str = 'ISM/CSM', *, start_year: int | None = None, end_year: int | None = None, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, series_specs: tuple[dict[str, object], ...] | None = None, window: int = 10, vmax: float = 2.0) RollingRateHeatmapData
Return rolling detection-rate heatmap data grouped by atom count.
- astromol.figures.periodic_heatmap_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) PeriodicHeatmapData
Return element-composition counts for the periodic-table heatmap.
- astromol.figures.du_histogram_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = False) DUHistogramData
Return degree-of-unsaturation values for the legacy histogram domain.
- astromol.figures.kappa_histogram_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) KappaHistogramData
Return Ray asymmetry-parameter values for molecules with A/B/C constants.
- astromol.figures.molecule_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) MoleculeTypeData
Return molecule-type category counts for a census view.
Categories are counted independently, so one molecule may contribute to more than one category. This preserves the legacy manuscript convention used for neutral radical species, cyclic ions, PAHs, and fullerenes.
- astromol.figures.source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) SourceTypeData
Return generalized first-detection source-type counts for a view.
Each molecule can receive credit for multiple source categories if its first detection lists sources in multiple categories, but it is credited at most once per generalized category.
- astromol.figures.individual_source_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) IndividualSourceData
Return individual first-detection source contribution counts.
This preserves the legacy convention: each listed source on a first detection contributes one count. The four named sources are counted individually; every other source contribution is counted in
Other. The denominator remains the number of first-detected molecules, so percentages may sum to more than 100%.
- astromol.figures.molecule_type_by_source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) MoleculeTypeBySourceData
Return molecule-type counts for generalized first-detection sources.
Source categories are credited once per molecule. Molecule-type categories are counted independently within each source category, preserving the legacy convention that a molecule can contribute to multiple type wedges.
- astromol.figures.du_by_source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = False) DUBySourceTypeData
Return DU values grouped by generalized first-detection source type.
Each molecule is credited at most once per source category, matching the legacy convention used for source-type trend figures. Fullerenes are excluded by default because their extreme DU values dominate this comparison.
- astromol.figures.relative_du_by_source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = False) RelativeDUBySourceTypeData
Return relative-DU values grouped by first-detection source type.
Relative DU is defined as
du / maxduusing the same formula-domain convention as the legacy code. Each molecule is credited at most once per source category.
- astromol.figures.mass_by_source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = False) MassBySourceTypeData
Return molecular masses grouped by generalized first-detection source.
Each molecule is credited at most once per source category, matching the legacy source-type figures. Fullerenes are excluded by default because their masses dominate this comparison.
- astromol.figures.wavelength_by_source_type_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = True) WavelengthBySourceTypeData
Return first-detection wavelength counts by generalized source type.
Each molecule is credited at most once per source category, matching the legacy source/wavelength pie-grid convention. Within a credited source category, every wavelength listed for the first detection is counted.
- astromol.figures.mass_by_wavelength_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = True) MassByWavelengthData
Return molecular masses grouped by first-detection wavelength.
- astromol.figures.molecules_by_wavelength_atoms_data(view: CensusView, detection_type: str = 'ISM/CSM', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, include_fullerenes: bool = False) MoleculesByWavelengthAtomsData
Return molecule atom counts grouped by first-detection wavelength.
- astromol.figures.detection_rate_by_atoms_data(view: CensusView, detection_type: str = 'ISM/CSM', *, end_year: int | None = None, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, categories: tuple[dict[str, object], ...] = ({'category': 2, 'label': '2', 'x': 2}, {'category': 3, 'label': '3', 'x': 3}, {'category': 4, 'label': '4', 'x': 4}, {'category': 5, 'label': '5', 'x': 5}, {'category': 6, 'label': '6', 'x': 6}, {'category': 7, 'label': '7', 'x': 7}, {'category': 8, 'label': '8', 'x': 8}, {'category': 9, 'label': '9', 'x': 9}, {'category': 10, 'label': '10', 'x': 10}, {'category': 11, 'label': '11', 'x': 11}, {'category': 12, 'label': '12', 'x': 12}, {'category': '13+', 'label': '13+', 'x': 13}, {'category': 'PAHs', 'label': 'PAHs', 'x': 15}, {'category': 'Fullerenes', 'label': 'Fullerenes', 'x': 17})) DetectionRateByAtomsData
Return average detections/year by atom-count category.
The rate is the number of first detections in a category divided by the number of years from that category’s first detection through
end_year. This matches the legacydet_per_year_per_atomfigure definition.
Return facility-share data for first molecule detections.
Facilities are ranked by their number of first detections, then displayed by descending share of all first detections that occurred during their operational window. The 2021 published figure used a facility set that is preserved when
use_legacy_2021_selectionis true.
- astromol.figures.scopes_by_year_data(view: CensusView, detection_type: str = 'ISM/CSM', *, start_year: int = 1965, end_year: int | None = None, min_detections: int = 10, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, cutoffs: dict[str, int] | None = None, colors_by_shortname: dict[str, str] | None = None) ScopesByYearData
Return cumulative facility first-detection contributions by year.
- astromol.figures.cumulative_counts_by_year(first_detection_years: dict[str, int], *, start_year: int | None = None, end_year: int | None = None) tuple[ndarray, ndarray]
Return cumulative detection counts for each year in a range.
- astromol.figures.linear_cumulative_rate(years: ndarray, counts: ndarray, *, start_year: int, stop_year: int | None = None) float
Fit a linear cumulative-detection rate over a year range.
stop_yearis included in the fit. This makes plot annotations read as closed date ranges, such as 1968-2005 and 2005-2021.
- astromol.figures.cumulative_detection_trend_ranges(view: CensusView, end_year: int) tuple[tuple[str, int, int | None], ...]
Return census-aware trend ranges for cumulative-detection plots.
- astromol.figures.cumulative_detection_data(view: CensusView, detection_type: str = 'ISM/CSM', *, start_year: int | None = None, end_year: int | None = None, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) CumulativeDetectionData
Return cumulative-detection data for a census view.
By default, the data represent secure, non-isotopologue ISM/CSM molecule detections. For census views, the default end year is the census boundary; for current views, it is the current calendar year.
- astromol.figures.plot_cumulative_detections(data: CumulativeDetectionData, *, ax=None, color: str = 'dodgerblue', linewidth: float = 4, annotate_trends: bool = True, annotate_total: bool = True, annotate_facilities: bool | None = None, text_size: int = 24)
Plot cumulative detections and return
(figure, axes).
- astromol.figures.write_cumulative_detections_plot(data: CumulativeDetectionData, output_path: str | Path, *, file_format: str | None = None) Path
Write the cumulative-detections plot and return the output path.
- astromol.figures.plot_cumulative_by_atoms(data: CumulativeByAtomsData, *, ax=None, linewidth: float = 2.5, text_size: int = 24, legend_text_size: int = 16, legend_x: float = 0.1, legend_y: float = 0.92, legend_step: float = 0.04, y_axis_padding_fraction: float = 0.05)
Plot cumulative ISM/CSM detections grouped by atom-count category.
- astromol.figures.write_cumulative_by_atoms_plot(data: CumulativeByAtomsData, output_path: str | Path, *, file_format: str | None = None) Path
Write the cumulative-by-atoms plot and return the output path.
- astromol.figures.plot_stacked_cumulative_by_atoms(data: CumulativeByAtomsData, *, ax=None, text_size: int = 24, legend_text_size: int = 16, legend_x: float = 0.1, legend_y: float = 0.92, legend_step: float = 0.04, stack_alpha: float = 0.88, y_axis_padding_fraction: float = 0.04)
Plot cumulative ISM/CSM detections as a stacked atom-count history.
- astromol.figures.write_stacked_cumulative_by_atoms_plot(data: CumulativeByAtomsData, output_path: str | Path, *, file_format: str | None = None) Path
Write the stacked cumulative-by-atoms plot and return the output path.
- astromol.figures.plot_periodic_heatmap(data: PeriodicHeatmapData, *, ax=None, figure_size: tuple[float, float] = (20, 9.5))
Plot a periodic-table heatmap of element occurrence in molecules.
- astromol.figures.write_periodic_heatmap(data: PeriodicHeatmapData, output_path: str | Path, *, file_format: str | None = None) Path
Write the periodic-table heatmap and return the output path.
- astromol.figures.plot_du_histogram(data: DUHistogramData, *, ax=None, bins: tuple[float, ...] | None = None, text_size: int = 24, annotation_size: int = 16, facecolor: str = 'dodgerblue', edgecolor: str = 'royalblue', alpha: float = 0.25)
Plot the legacy degree-of-unsaturation histogram.
- astromol.figures.write_du_histogram(data: DUHistogramData, output_path: str | Path, *, file_format: str | None = None) Path
Write the degree-of-unsaturation histogram and return the output path.
- astromol.figures.plot_kappa_histogram(data: KappaHistogramData, *, ax=None, bins: int = 100, figure_size: tuple[float, float] = (8.0, 4.8), text_size: int = 24, facecolor: str = 'dodgerblue', edgecolor: str = 'dodgerblue', alpha: float = 0.25, show_shape_guide: bool = True)
Plot the Ray asymmetry-parameter histogram.
- astromol.figures.write_kappa_histogram(data: KappaHistogramData, output_path: str | Path, *, bins: int = 100, file_format: str | None = None) Path
Write the Ray asymmetry-parameter histogram and return the output path.
- astromol.figures.plot_du_bar_chart(data: DUHistogramData, *, ax=None, text_size: int = 24, annotation_size: int = 16, facecolor: str = 'dodgerblue', edgecolor: str = 'black', alpha: float = 0.65, bar_width: float = 0.32, include_negative_du: bool = False)
Plot exact degree-of-unsaturation counts as a discrete bar chart.
- astromol.figures.write_du_bar_chart(data: DUHistogramData, output_path: str | Path, *, file_format: str | None = None) Path
Write the exact-value degree-of-unsaturation bar chart.
- astromol.figures.plot_type_pie_chart(data: MoleculeTypeData, *, ax=None, figure_size: tuple[float, float] = (10, 8), ring_width: float = 0.1, ring_gap: float = 0.02, label_text_size: int = 13, label_y_offsets: tuple[float, ...] | None = None, percent_text_size: int = 11, remainder_color: str = '#EEEEEE', order: str = 'count')
Plot the molecule-type concentric ring chart.
- astromol.figures.write_type_pie_chart(data: MoleculeTypeData, output_path: str | Path, *, file_format: str | None = None, order: str = 'count') Path
Write the molecule-type ring chart and return the output path.
- astromol.figures.plot_source_pie_chart(data: SourceTypeData, *, ax=None, figure_size: tuple[float, float] = (10, 8), ring_width: float = 0.1, ring_gap: float = 0.02, label_text_size: int = 14, percent_text_size: int = 12, remainder_color: str = '#EEEEEE', diffuse_cloud_label: str = 'Diffuse Cloud', order: str = 'count')
Plot the generalized source-type concentric ring chart.
- astromol.figures.write_source_pie_chart(data: SourceTypeData, output_path: str | Path, *, file_format: str | None = None, diffuse_cloud_label: str = 'Diffuse Cloud', pad_inches: float = -0.65, order: str = 'count') Path
Write the generalized source-type ring chart and return the path.
- astromol.figures.plot_individual_source_pie_chart(data: IndividualSourceData, *, ax=None, figure_size: tuple[float, float] = (10, 8), ring_width: float = 0.1, ring_gap: float = 0.02, label_text_size: int = 14, percent_text_size: int = 12, remainder_color: str = '#EEEEEE', order: str = 'count')
Plot the individual first-detection source concentric ring chart.
- astromol.figures.write_individual_source_pie_chart(data: IndividualSourceData, output_path: str | Path, *, file_format: str | None = None, pad_inches: float = -0.65, order: str = 'count') Path
Write the individual-source ring chart and return the path.
- astromol.figures.plot_molecule_type_by_source_type(data: MoleculeTypeBySourceData, *, figure_size: tuple[float, float] = (15, 12), label_text_size: int = 26, title_text_size: int = 30, legend_text_size: int = 26, wedge_alpha: float = 0.5, source_label_overrides: dict[str, str] | None = None)
Plot molecule-type pie charts within generalized source categories.
- astromol.figures.write_molecule_type_by_source_type(data: MoleculeTypeBySourceData, output_path: str | Path, *, file_format: str | None = None, source_label_overrides: dict[str, str] | None = None) Path
Write the molecule-type-by-source pie grid and return the path.
- astromol.figures.plot_molecule_type_by_source_enrichment_matrix(data: MoleculeTypeBySourceData, *, figure_size: tuple[float, float] = (12, 8), axes_bounds: tuple[float, float, float, float] = (0.205, 0.15, 0.62, 0.775), colorbar_bounds: tuple[float, float, float, float] = (0.86, 0.15, 0.035, 0.775), source_label_overrides: dict[str, str] | None = None, text_size: int = 24, factor_text_size: int = 21, count_text_size: int = 17, depletion_limit: float = 0.25, enrichment_limit: float = 4.0)
Plot the production molecule-type/source enrichment matrix.
Cell values are fractional enrichments relative to the overall secure ISM/CSM molecule-type mix. Color is log-scaled and centered on
1x.
- astromol.figures.write_molecule_type_by_source_enrichment_matrix(data: MoleculeTypeBySourceData, output_path: str | Path, *, file_format: str | None = None, source_label_overrides: dict[str, str] | None = None) Path
Write the production molecule-type/source enrichment matrix.
- astromol.figures.plot_du_by_source_type(data: DUBySourceTypeData, *, ax=None, bandwidth: float = 0.5, figure_size: tuple[float, float] = (10, 8), text_size: int = 24, source_label_overrides: dict[str, str] | None = None, count_label_overrides: dict[str, tuple[float, float]] | None = None, ylabel: str = 'Probability Density Estimate')
Plot DU KDE distributions by generalized first-detection source type.
- astromol.figures.write_du_by_source_type(data: DUBySourceTypeData, output_path: str | Path, *, bandwidth: float = 0.5, source_label_overrides: dict[str, str] | None = None, count_label_overrides: dict[str, tuple[float, float]] | None = None, ylabel: str = 'Probability Density Estimate', file_format: str | None = None) Path
Write the DU-by-source KDE plot and return the output path.
- astromol.figures.plot_relative_du_by_source_type(data: RelativeDUBySourceTypeData, *, axes=None, bandwidth: float = 0.5, figure_size: tuple[float, float] = (10, 8), text_size: int = 18, label_size: int = 24, source_label_overrides: dict[str, str] | None = None)
Plot the legacy relative-DU KDE panel by source type.
- astromol.figures.write_relative_du_by_source_type(data: RelativeDUBySourceTypeData, output_path: str | Path, *, bandwidth: float = 0.5, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the relative-DU-by-source KDE plot and return the output path.
- astromol.figures.plot_mass_by_source_type(data: MassBySourceTypeData, *, ax=None, bandwidth: float = 0.5, figure_size: tuple[float, float] = (10, 8), text_size: int = 24, source_label_overrides: dict[str, str] | None = None)
Plot legacy molecular-mass KDE distributions by source type.
- astromol.figures.write_mass_by_source_type(data: MassBySourceTypeData, output_path: str | Path, *, bandwidth: float = 0.5, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the mass-by-source KDE plot and return the output path.
- astromol.figures.plot_wavelength_by_source_type(data: WavelengthBySourceTypeData, *, axes=None, figure_size: tuple[float, float] = (15, 12), text_size: int = 26, panel_label_size: int = 30, source_label_overrides: dict[str, str] | None = None)
Plot the legacy wavelength-by-source-type pie grid.
- astromol.figures.write_wavelength_by_source_type(data: WavelengthBySourceTypeData, output_path: str | Path, *, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the wavelength-by-source-type pie grid and return the path.
- astromol.figures.plot_wavelength_by_source_type_stacked_bar(data: WavelengthBySourceTypeData, *, ax=None, figure_size: tuple[float, float] = (8.0, 4.8), text_size: float = 18.0, tick_size: float = 16.0, segment_text_size: float = 13.0, show_segment_labels: bool = False, source_label_overrides: dict[str, str] | None = None)
Plot wavelength shares by source type as normalized stacked bars.
- astromol.figures.write_wavelength_by_source_type_stacked_bar(data: WavelengthBySourceTypeData, output_path: str | Path, *, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the production wavelength/source stacked bar chart.
- astromol.figures.plot_mass_by_wavelength(data: MassByWavelengthData, *, ax=None, bandwidth: float = 0.5, figure_size: tuple[float, float] = (10, 8), text_size: int = 24, legend_step: float = 0.05, label_mode: str = 'fixed', label_overrides: dict[str, tuple[float, float]] | None = None)
Plot KDE molecular-mass distributions by detection wavelength.
- astromol.figures.write_mass_by_wavelength_plot(data: MassByWavelengthData, output_path: str | Path, *, bandwidth: float = 0.5, label_mode: str = 'fixed', label_overrides: dict[str, tuple[float, float]] | None = None, file_format: str | None = None) Path
Write the mass-by-wavelength KDE plot and return the output path.
- astromol.figures.plot_mass_by_wavelength_boxplot(data: MassByWavelengthData, *, ax=None, figure_size: tuple[float, float] = (7.2, 4.8), text_size: float = 18.0, tick_size: float = 16.0, point_size: float = 22.0, point_alpha: float = 0.34, x_limit: tuple[float, float] = (0, 240), marker_mass: float = 80.0)
Plot wavelength mass distributions as horizontal boxes plus detections.
- astromol.figures.write_mass_by_wavelength_boxplot(data: MassByWavelengthData, output_path: str | Path, *, file_format: str | None = None) Path
Write the production mass-by-wavelength boxplot and return the path.
- astromol.figures.plot_du_by_source_type_boxplot(data: DUBySourceTypeData, *, ax=None, figure_size: tuple[float, float] = (7.2, 4.8), text_size: float = 18.0, tick_size: float = 16.0, point_size: float = 22.0, point_alpha: float = 0.34, include_negative_du: bool = False, x_limit: tuple[float, float] | None = None, source_label_overrides: dict[str, str] | None = None)
Plot DU distributions by source type as boxes plus exact detections.
- astromol.figures.write_du_by_source_type_boxplot(data: DUBySourceTypeData, output_path: str | Path, *, include_negative_du: bool = False, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the production DU-by-source box/strip plot and return the path.
- astromol.figures.plot_relative_du_by_source_type_boxplot(data: RelativeDUBySourceTypeData, *, ax=None, figure_size: tuple[float, float] = (7.2, 4.8), text_size: float = 18.0, tick_size: float = 16.0, point_size: float = 22.0, point_alpha: float = 0.34, include_negative_du: bool = False, x_limit: tuple[float, float] | None = None, source_label_overrides: dict[str, str] | None = None)
Plot relative-DU source distributions as boxes plus exact values.
- astromol.figures.write_relative_du_by_source_type_boxplot(data: RelativeDUBySourceTypeData, output_path: str | Path, *, include_negative_du: bool = False, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the production relative-DU source box/strip plot.
- astromol.figures.plot_mass_by_source_type_boxplot(data: MassBySourceTypeData, *, ax=None, figure_size: tuple[float, float] = (7.2, 4.8), text_size: float = 18.0, tick_size: float = 16.0, point_size: float = 22.0, point_alpha: float = 0.34, x_limit: tuple[float, float] | None = None, source_label_overrides: dict[str, str] | None = None)
Plot source-type mass distributions as boxes plus exact detections.
- astromol.figures.write_mass_by_source_type_boxplot(data: MassBySourceTypeData, output_path: str | Path, *, source_label_overrides: dict[str, str] | None = None, file_format: str | None = None) Path
Write the production mass-by-source box/strip plot.
- astromol.figures.plot_molecules_by_wavelength_atoms(data: MoleculesByWavelengthAtomsData, *, axes=None, bandwidth: float = 0.5, figure_size: tuple[float, float] = (10, 8), trace_color: str = 'dodgerblue', text_size: int = 18, panel_label_size: int = 24)
Plot atom-count distributions grouped by first-detection wavelength.
- astromol.figures.write_molecules_by_wavelength_atoms_plot(data: MoleculesByWavelengthAtomsData, output_path: str | Path, *, bandwidth: float = 0.5, file_format: str | None = None) Path
Write the atom-count-by-wavelength plot and return the output path.
- astromol.figures.plot_molecules_by_wavelength_atoms_bubble_heatmap(data: MoleculesByWavelengthAtomsData, *, ax=None, colorbar_ax=None, value_mode: str = 'count', figure_size: tuple[float, float] = (7.2, 4.8), text_size: float = 18.0, tick_size: float = 16.0, value_text_size: float = 12.0, colorbar_text_size: float = 12.0, min_bubble_size: float = 85.0, max_bubble_size: float = 1300.0, value_text_y_offset: float = 0.025)
Plot atom-count/wavelength counts as a discrete bubble heatmap.
- astromol.figures.write_molecules_by_wavelength_atoms_bubble_heatmap(data: MoleculesByWavelengthAtomsData, output_path: str | Path, *, file_format: str | None = None, value_mode: str = 'count') Path
Write the production atom-count/wavelength bubble heatmap.
- astromol.figures.plot_rolling_rate_by_atoms_heatmap(data: RollingRateHeatmapData, *, ax=None, colorbar_ax=None, cmap: str = 'cividis', text_size: float = 8.5, tick_size: float = 7.2, colorbar_text_size: float = 7.2)
Plot rolling detection rates by atom-count category as a heatmap.
- astromol.figures.write_rolling_rate_by_atoms_heatmap(data: RollingRateHeatmapData, output_path: str | Path, *, file_format: str | None = None) Path
Write the rolling-rate-by-atoms heatmap and return the output path.
- astromol.figures.plot_detection_rate_by_atoms(data: DetectionRateByAtomsData, *, ax=None, facecolor: str = 'dodgerblue', edgecolor: str = '#0A1589', alpha: float = 0.9, text_size: int = 24, xlim: tuple[float, float] = (1, 12.8), ylim: tuple[float, float] | None = None)
Plot average detections/year by atom-count category.
- astromol.figures.write_detection_rate_by_atoms_plot(data: DetectionRateByAtomsData, output_path: str | Path, *, file_format: str | None = None) Path
Write the detection-rate-by-atoms plot and return the output path.
- astromol.figures.plot_detection_rate_by_atoms_comparison(current_data: DetectionRateByAtomsData, baseline_data: DetectionRateByAtomsData, *, ax=None, current_label: str = 'Current', baseline_label: str = '2021', marker_area_per_detection: float = 70, current_facecolor: str = 'dodgerblue', current_edgecolor: str = '#0A1589', baseline_edgecolor: str = 'black', current_alpha: float = 0.86, text_size: int = 24, legend_text_size: int = 18, xlim: tuple[float, float] = (1, 12.8), ylim: tuple[float, float] = (0, 1.0))
Plot current rate-by-atoms values over a 2021 comparison baseline.
Marker area uses a single absolute scale for both datasets, so area is directly comparable between the baseline and current views.
- astromol.figures.write_detection_rate_by_atoms_comparison_plot(current_data: DetectionRateByAtomsData, baseline_data: DetectionRateByAtomsData, output_path: str | Path, *, file_format: str | None = None, current_label: str = 'Current', baseline_label: str = '2021') Path
Write the production detection-rate-by-atoms comparison plot.
Plot facility shares as a 3x3 pie grid.
Write the facility-shares plot and return the output path.
Plot facility shares as a horizontal bar chart.
This is the production-facing facility-share view. The pie-grid function is retained for legacy reproduction, while this bar view is easier to compare quantitatively and labels each denominator explicitly.
Write the facility-share bar chart and return the output path.
- astromol.figures.plot_scopes_by_year(data: ScopesByYearData, *, ax=None, figure_size: tuple[float, float] = (10, 8), axes_bounds: tuple[float, float, float, float] = (0.14, 0.13, 0.82, 0.82), text_size: int = 24, annotation_text_size: int = 18, line_width: float = 2.0, style: str = 'legacy')
Plot cumulative first-detection contributions for prolific facilities.
- astromol.figures.write_scopes_by_year_plot(data: ScopesByYearData, output_path: str | Path, *, file_format: str | None = None, style: str = 'legacy') Path
Write the scopes-by-year plot and return the output path.
PowerPoint slide generation helpers for census products.
The slide code is intentionally split into selection, layout, and rendering
steps. That makes the visually tuned PowerPoint output auditable before it is
written to a binary .pptx file.
- class astromol.slides.SlideBox(left: float, top: float, width: float, height: float)
A PowerPoint box expressed in slide inches.
- property right: float
Right edge in inches.
- property bottom: float
Bottom edge in inches.
- class astromol.slides.FormulaRun(text: str, baseline: str = 'normal', italic: bool = False)
One formatted PowerPoint text run for a molecule formula.
- class astromol.slides.SlideMoleculeEntry(molecule: Molecule, display_formula: str)
A molecule selected for a slide, with display metadata.
- property label: str
Stable molecule label.
- property natoms: int
Number of atoms in the molecule.
- class astromol.slides.SlideGroupSpec(label: str, natoms: int, ncols: int, label_box: SlideBox, column_boxes: tuple[SlideBox, ...], natoms_greater: bool = False)
Static layout specification for one atom-count group.
- class astromol.slides.SlideColumnPlan(box: SlideBox, molecules: tuple[SlideMoleculeEntry, ...], estimated_capacity: int)
Molecules assigned to one rendered column.
- property overflow: int
Estimated number of rows beyond the column capacity.
- class astromol.slides.SlideGroupPlan(spec: SlideGroupSpec, columns: tuple[SlideColumnPlan, ...])
Rendered plan for one atom-count group.
- property molecules: tuple[SlideMoleculeEntry, ...]
All molecules in this group.
- class astromol.slides.MoleculeSlideLayout(groups: tuple[~astromol.slides.SlideGroupPlan, ...], title: str, total: int, profile: str = 'legacy', slide_width_pt: int = 1920, slide_height_pt: int = 1080, title_box: ~astromol.slides.SlideBox = SlideBox(left=0.35, top=0.22, width=18.33, height=1.18), credit_box: ~astromol.slides.SlideBox = SlideBox(left=22.15, top=0.22, width=4.166666666666667, height=1.25), total_box: ~astromol.slides.SlideBox = SlideBox(left=6.35, top=10.6, width=6.0, height=1.4), footer_box: ~astromol.slides.SlideBox = SlideBox(left=6.35, top=12.2, width=6.0, height=1.0), molecule_font_pt: float = 22, group_label_font_pt: float = 26, total_font_pt: float = 45, footer_font_pt: float = 32, total_line_width_pt: float = 6, package_version: str = 'development', last_updated: str | None = None, detection_type: str = 'ISM/CSM', include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, warnings: tuple[str, ...] = <factory>)
Complete molecule-slide layout plan.
- property molecules: tuple[SlideMoleculeEntry, ...]
All molecule entries in slide order.
- astromol.slides.legacy_molecule_slide_specs() tuple[SlideGroupSpec, ...]
Return the historically tuned molecule-slide layout specification.
- astromol.slides.balanced_molecule_slide_specs(entries: list[SlideMoleculeEntry]) tuple[tuple[SlideGroupSpec, ...], float]
Return adaptive slide group specs and the chosen molecule font size.
The balanced profile keeps all atom-count groups in a single molecule band and adapts by choosing a readable font size, deriving column counts from row capacity, estimating per-group widths from display formulas, and distributing remaining horizontal space as group gaps.
- astromol.slides.compact_molecule_slide_specs(entries: list[SlideMoleculeEntry]) tuple[tuple[SlideGroupSpec, ...], float]
Return compact slide specs for sparse molecule inventories.
- astromol.slides.balanced_total_box(specs: tuple[SlideGroupSpec, ...]) SlideBox
Return a count box centered under the first six molecule columns.
- astromol.slides.compact_total_box(specs: tuple[SlideGroupSpec, ...]) SlideBox
Return a centered count box for a compact slide layout.
- astromol.slides.rendered_group_label_box(group: SlideGroupPlan, profile: str) SlideBox
Return the textbox used for rendering a group label.
- astromol.slides.group_label_alignment(group: SlideGroupPlan, profile: str, PP_ALIGN)
Return label alignment for a group header.
- astromol.slides.balanced_column_width(entries: list[SlideMoleculeEntry], font_pt: float) float
Estimate a readable PowerPoint column width for formula entries.
- astromol.slides.balanced_label_width(label: str) float
Return a minimum group width that leaves room for the atom-count label.
- astromol.slides.compact_label_width(label: str) float
Return a minimum compact-profile group width for one-line labels.
- astromol.slides.selected_molecule_slide_entries(view: CensusView, *, detection_type: str = 'ISM/CSM', include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False) list[SlideMoleculeEntry]
Return molecules selected for a molecule-summary slide.
The default is the main secure, non-isotopologue ISM/CSM inventory. Ordering follows first accepted detection order within the selected view, which is the order used for the manuscript molecule tables.
- astromol.slides.first_detection_sort_keys(detections: list[Detection]) dict[str, tuple]
Return first-detection sort keys by molecule label.
- astromol.slides.build_molecule_slide_layout(view: CensusView, *, detection_type: str = 'ISM/CSM', include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, profile: str = 'legacy', title: str = 'Known Interstellar Molecules', last_updated: str | None = None) MoleculeSlideLayout
Build a molecule-slide layout plan without writing PowerPoint output.
- astromol.slides.estimated_column_capacity(box: SlideBox, *, font_pt: float = 22) int
Return a conservative estimated row capacity for a column box.
- astromol.slides.selected_records_last_modified(entries: list[SlideMoleculeEntry]) str | None
Return the latest molecule-history modification date in selected entries.
- astromol.slides.package_version() str
Return installed package version, or a traceable development label.
- astromol.slides.repository_git_label() str | None
Return the current repository short hash, with dirty marker if needed.
- astromol.slides.slide_version_label(version: str) str
Return display text for the slide package-version line.
- astromol.slides.molecule_slide_report(layout: MoleculeSlideLayout) str
Return a concise Markdown report for a molecule slide layout.
- astromol.slides.write_molecule_slide_report(layout: MoleculeSlideLayout, output_path: str | Path) Path
Write a molecule-slide layout report and return its path.
- astromol.slides.write_molecule_slide(view: CensusView, output_path: str | Path = 'astro_molecules.pptx', *, detection_type: str = 'ISM/CSM', include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = False, profile: str = 'legacy', title: str = 'Known Interstellar Molecules', last_updated: str | None = None) Path
Write a molecule-summary PowerPoint slide and return the output path.
- astromol.slides.build_ppd_detection_slide_layout(view: CensusView, *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = True, profile: str = 'compact', title: str = 'Protoplanetary Disk Molecules', last_updated: str | None = None) MoleculeSlideLayout
Build the PPD molecule/isotopologue slide layout plan.
- astromol.slides.write_ppd_detection_slide(view: CensusView, output_path: str | Path = 'ppd_molecules.pptx', *, include_tentative: bool = False, include_disputed: bool = False, include_isotopologues: bool = True, profile: str = 'compact', title: str = 'Protoplanetary Disk Molecules', last_updated: str | None = None) Path
Write a PPD molecule/isotopologue PowerPoint slide.
- astromol.slides.render_molecule_slide(layout: MoleculeSlideLayout)
Render a molecule-slide layout to a
python-pptxPresentation.
- astromol.slides.format_slide_date(value: str | None) str
Format ISO dates for slide display.
- astromol.slides.powerpoint_formula_runs(formula: str) list[FormulaRun]
Return formatted runs for a molecule formula in PowerPoint text.
This is not a full LaTeX or mhchem parser. It handles the formula forms used by astromol table formulas: atom counts, leading isomer/conformer labels, terminal charges, and isotope forms such as
^{13}or[13C].
- astromol.slides.strip_formula_wrappers(formula: str) str
Remove common formula wrappers not meaningful in PowerPoint text.
- astromol.slides.is_atom_count_token(tokens: list[str], index: int) bool
Return whether a numeric token should be shown as an atom subscript.
- astromol.slides.is_terminal_charge(tokens: list[str], index: int) bool
Return whether a plus/minus token is a terminal molecular charge.
Registry of standard astromol generated outputs.
The registry is intentionally metadata-first: each entry has a stable name, human-readable label, description, and the callable pieces needed to generate the product. This gives docs, notebooks, automated bundles, and future CLI commands one canonical list of standard outputs.
- class astromol.registry.FigureOutputSpec(name: str, label: str, description: str, data_builder: ~collections.abc.Callable[[~astromol.registry.OutputContext], ~typing.Any], writer: ~collections.abc.Callable[[...], ~pathlib.Path], writer_kwargs: ~collections.abc.Callable[[~astromol.registry.OutputContext], ~collections.abc.Mapping[str, ~typing.Any]] = <function _empty_kwargs>, baseline_data_builder: ~collections.abc.Callable[[~astromol.registry.OutputContext], ~typing.Any] | None = None)
One standard figure product.
- writer_kwargs() Mapping[str, Any]
Return no keyword arguments for a registry entry.
- build_data(context: OutputContext) Any
Build the primary data object for this figure.
- write(context: OutputContext, output_path: str | Path) Path
Write this figure to
output_path.
- class astromol.registry.OutputContext(view: CensusView, view_choice: str = 'current', baseline_view: CensusView | None = None, cache: dict[str, ~typing.Any]=<factory>)
Shared context for generating standard outputs from one selected view.
- cached(key: str, builder: Callable[[], Any]) Any
Return a cached intermediate data product.
- class astromol.registry.SlideOutputSpec(name: str, label: str, description: str, filename_template: str, writer: ~collections.abc.Callable[[...], ~pathlib.Path], writer_kwargs: ~collections.abc.Callable[[~astromol.registry.OutputContext], ~collections.abc.Mapping[str, ~typing.Any]] = <function _empty_kwargs>, layout_builder: ~collections.abc.Callable[[...], ~typing.Any] | None = None, report_label: str | None = None, report_description: str | None = None, report_filename_template: str | None = None)
One standard PowerPoint slide plus its optional layout report.
- writer_kwargs() Mapping[str, Any]
Return no keyword arguments for a registry entry.
- filename(context: OutputContext) str
Return this slide’s filename for the selected context.
- report_filename(context: OutputContext) str | None
Return this slide’s layout-report filename when configured.
- write_slide(context: OutputContext, output_dir: str | Path) Path
Write this PowerPoint slide.
- write_report(context: OutputContext, output_dir: str | Path) Path | None
Write this slide’s layout report when configured.
- class astromol.registry.TableOutputSpec(name: str, label: str, description: str, writer: Callable[[CensusView, Path], Any])
One standard LaTeX table-fragment product group.
- write(view: CensusView, output_dir: str | Path) list[Path]
Write this table group and return generated
.texpaths.
- astromol.registry.figure_output_names() tuple[str, ...]
Return stable names for standard figure outputs.
- astromol.registry.slide_output_names() tuple[str, ...]
Return stable names for standard slide outputs.
- astromol.registry.table_output_names() tuple[str, ...]
Return stable names for standard table output groups.
Generate standard astromol output bundles.
This module powers the GitHub Actions workflow that publishes the latest standard figures and PowerPoint slides. It intentionally uses the public table, figure, and slide APIs so automated products exercise the same code paths that users call from notebooks or local scripts.
- class astromol.outputs.GeneratedProduct(label: str, path: Path, description: str)
One generated output file for the static product index.
- class astromol.outputs.FigureProductGroup(name: str, label: str, description: str, png_product: GeneratedProduct | None = None, pdf_product: GeneratedProduct | None = None)
One figure with its available download formats.
- astromol.outputs.view_from_choice(db: Database, choice: str) CensusView
Return a census/current view from a command-line choice.
- astromol.outputs.generate_standard_outputs(output_dir: str | Path = PosixPath('build/astromol_outputs'), *, view_choice: str = 'current', formats: tuple[str, ...] = ('png', 'pdf'), clean: bool = True, include_tables: bool = True, include_slides: bool = True) list[GeneratedProduct]
Generate standard latest astromol products and return their paths.
- astromol.outputs.parse_args(argv: list[str] | None = None) Namespace
Parse command-line arguments for the output generator.
- astromol.outputs.main(argv: list[str] | None = None) int
Command-line entry point for standard output generation.