XGC-Analysis package

Module xgc_analysis.data_access.products.accessor_mixin

class xgc_analysis.data_access.products.accessor_mixin.ArrayAccessorMixin[source]

Bases: object

Mixin class to provide access to data arrays in various formats. This class should be used with classes that have a data attribute structured as a dictionary of dictionaries, where the outer key is the variable name and the inner key is the step index.

Design note

This mixin provides generic access helpers that only assume the common self.data[var_name][step_index] storage layout. Reader classes should add thin semantic wrappers (for example get_mesh_data or get_distribution) on top of these methods.

get_array(var_name)[source]

Stack one variable over all loaded step or file indices.

Parameters:

var_name (str) – Native product variable name.

Returns:

Values ordered by sorted step/file index. Scalars have a leading step dimension; mesh/plane arrays retain their spatial axes after that dimension. Units are unchanged from the native product.

Return type:

np.ndarray

Raises:

KeyError – If the variable was not loaded.

get_as(var_name, step_index, expected_type)[source]

Return a stored item and validate its type.

Parameters:
  • var_name (str) – Native product variable name.

  • step_index (int) – Reader-local step or file index.

  • expected_type (type | tuple[type, ...]) – Allowed Python class/type(s).

Returns:

Stored item after type validation.

Return type:

object

Raises:
  • KeyError – If the variable or selected index was not loaded.

  • TypeError – If the stored item does not have an allowed type.

get_item(var_name, step_index)[source]

Return one loaded value without type conversion.

Parameters:
  • var_name (str) – Native product variable name.

  • step_index (int) – Reader-local step or file index.

Returns:

Value stored by the product reader, retaining its native units.

Return type:

object

Raises:

KeyError – If the variable or selected index was not loaded.

has_var(var_name)[source]

Check whether a variable was loaded.

Parameters:

var_name (str) – Native product variable name.

Returns:

Whether self.data contains the variable.

Return type:

bool

list_step_indices(var_name=None)[source]

Return sorted step/file-index keys.

Parameters:

var_name (str or None) – If provided, return keys only for that variable. If None, return the sorted union of keys across all variables.

Returns:

Loaded step or file indices in sorted order.

Return type:

list[int]

list_vars()[source]

Return sorted variable names stored in self.data.

Returns:

Loaded variable names in sorted order.

Return type:

list[str]

Module xgc_analysis.data_access.adios.adios_stream

Shared ADIOS stream helpers.

xgc_analysis.data_access.adios.adios_stream.iter_stream_steps(stream, step_timeout_secs=None)[source]

Iterate ADIOS stream steps with optional timeout-as-EOF handling.

Parameters:
  • stream – ADIOS stream object exposing either normal iteration or steps(timeout=...).

  • step_timeout_secs (int, float, or None, optional) – Timeout passed to stream.steps. When the timeout expires, ADIOS raises a runtime error; this helper treats the expected “no new step” message as end-of-stream for offline files.

Yields:

object – ADIOS step objects from the stream.

xgc_analysis.data_access.adios.adios_stream.open_adios_stream(filename, open_timeout_secs=None, *, force_file_stream=True)[source]

Open an ADIOS stream with optional OpenTimeoutSecs configuration.

Parameters:
  • filename (str) – ADIOS-readable source path.

  • open_timeout_secs (int, float, or None, optional) – Open timeout for FileStream mode. If omitted, the default ADIOS opening path is used.

  • force_file_stream (bool, optional) – If True and open_timeout_secs is provided, open with a declared IO using FileStream. Campaign .aca sources should normally leave this False or use adios2.FileReader instead.

Yields:

adios2.Stream – Open stream context.

Module xgc_analysis.data_access.adios.adios_file_reader

Reusable ADIOS FileReader helpers for finite BP and ACA reads.

class xgc_analysis.data_access.adios.adios_file_reader.AdiosFileSourceReader(file_reader=None, *, qualify_with_source_id: bool = False, owns_reader: bool = False, reopen_on_unopened_file: bool = False, on_reopen=None)[source]

Bases: object

Callable source-reader backend for finite catalog reads.

The same callable shape is used for directory-backed local BP products and campaign-backed ACA products. Directory catalogs construct this class without an open reader, so each physical BP source is opened once per batched read request. Campaign catalogs pass a persistent FileReader handle and enable source-id qualification, avoiding repeated ACA opens.

close() → None[source]

Close the persistent FileReader handle when this reader owns it.

Returns:

The owned reader handle is released when present.

Return type:

None

static qualified_variable_name(source_id: str | None, variable: str) → str[source]

Return source_id/variable unless the name is already qualified.

Parameters:
  • source_id (str or None) – Catalog source id.

  • variable (str) – Reader-facing variable name.

Returns:

Source-qualified variable name when a source id is provided.

Return type:

str

xgc_analysis.data_access.adios.adios_file_reader.available_step_count(reader) → int[source]

Return the maximum AvailableStepsCount advertised by an open FileReader.

Parameters:

reader (adios2.FileReader) – Open FileReader handle.

Returns:

Largest advertised step count across variables.

Return type:

int

xgc_analysis.data_access.adios.adios_file_reader.available_steps_count_for_variable(info) → int[source]

Return AvailableStepsCount from one ADIOS variable metadata record.

Parameters:

info (dict) – Raw metadata for one ADIOS variable.

Returns:

Advertised step count, or zero for missing/invalid metadata.

Return type:

int

xgc_analysis.data_access.adios.adios_file_reader.available_variable_names(reader) → list[str][source]

Return sorted variable names advertised by an open FileReader.

Parameters:

reader (adios2.FileReader) – Open FileReader handle.

Returns:

Advertised variable names in sorted order.

Return type:

list[str]

xgc_analysis.data_access.adios.adios_file_reader.read_adios_file_steps(source_path: Path, variables: Sequence[str], adios_steps: Sequence[int], *, source_id: str | None = None, file_reader=None, qualify_with_source_id: bool = False) → Mapping[int, Mapping[str, object]][source]

Read selected variables and ADIOS steps through adios2.FileReader.

Parameters:
  • source_path (pathlib.Path) – ADIOS-readable BP source. This path is opened when file_reader is omitted.

  • variables (sequence[str]) – Reader-facing variable names to read at each selected step.

  • adios_steps (sequence[int]) – Physical ADIOS step ids to read.

  • source_id (str or None, optional) – Source id used to qualify campaign variables, for example xgc.f3d.00010.bp/e_den.

  • file_reader (adios2.FileReader or None, optional) – Existing open FileReader handle. Supplying this avoids reopening expensive campaign files for every read batch.

  • qualify_with_source_id (bool, optional) – If True, qualify unqualified variable names as source_id/variable.

Returns:

Values keyed by ADIOS step and original reader-facing variable name.

Return type:

dict[int, dict[str, object]]

Module xgc_analysis.data_access.products.bp_reader_mixin

Shared helpers for BP-based diagnostic readers.

class xgc_analysis.data_access.products.bp_reader_mixin.BPReaderMixin[source]

Bases: object

Mixin for readers that load ADIOS BP files into self.data.

This mixin handles: - optional explicit variable selection, - optional all-step vs last-step file reads, - first-step variable validation for explicit requests, - step-index bookkeeping and - zero-filling of later-step missing requested variables.

get_step_info(step_index)[source]

Return file/ADIOS-step metadata for one internal step index.

Parameters:

step_index (int) – Internal sequential index used as second key in self.data.

Returns:

Dictionary with keys: - file_index: integer file index from filename - bp_step: integer ADIOS step id inside that file

Return type:

dict[str, int]

Raises:

KeyError – If step_index is not present in self.step_index_info.

Module xgc_analysis.data_access.catalog.directory_catalog

Directory-backed catalog for XGC ADIOS output discovery.

This module scans one dataset root, groups XGC *.bp outputs into logical products, collects ADIOS metadata when requested, and builds read plans that map user-facing logical steps to concrete ADIOS source/step pairs. It does not read payload arrays; readers execute the returned ReadPlan objects.

class xgc_analysis.data_access.catalog.directory_catalog.SimulationCatalog(root_dir: Path, products: Iterable[DataProduct], *, refresh_func: Callable[[], Iterable[DataProduct]] | None = None, state_key_func: Callable[[], Tuple[Tuple[str, str, int, int], ...]] | None = None, state_key: Tuple[Tuple[str, str, int, int], ...] | None = None, source_reader=None, manifest: dict | None = None, manifest_reader: Callable[[], dict] | None = None, text_reader=None, discovery_timing: CatalogDiscoveryTiming | None = None)[source]

Bases: object

Catalog of ADIOS-readable XGC products in one dataset root.

The catalog is intentionally independent of Simulation so GUI code and automation scripts can inspect available products without constructing mesh or field objects. A Simulation may hold a catalog instance when heavier analysis context is needed.

available_steps(product_key: str, variable: str | None = None) → List[StepInfo][source]

Return deduplicated logical steps for one product and optional variable.

Parameters:
  • product_key (str) – Catalog product key.

  • variable (str or None, optional) – If provided, only sources that advertise the variable contribute steps. If omitted, all sources for the product contribute.

Returns:

Logical steps in ascending order. When several sources advertise the same logical step, the selected fragment follows the newer_source_wins policy and other candidates are retained as duplicates.

Return type:

list[StepInfo]

close() → None[source]

Release backend resources held by this catalog.

Directory-backed catalogs normally do not hold open files. Campaign catalogs may keep an ACA FileReader open so repeated read-plan execution does not reopen an expensive archive. If the installed source_reader exposes close(), this method delegates to it.

Returns:

The owned reader handle is released when present.

Return type:

None

describe(name: str, *, max_steps: int = 10, max_vars: int = 50) → str[source]

Return focused human-readable details for a product or variable.

Parameters:
  • name (str) – Product key, variable name, or explicit "product:variable" selector. Variable-only selectors search all products and show all matches.

  • max_steps (int, optional) – Maximum number of gstep, tindex, and time samples to show.

  • max_vars (int, optional) – Maximum number of variables to show when describing a product.

Returns:

Multi-line description suitable for interactive use.

Return type:

str

Raises:

KeyError – If name does not match a product or variable.

get_product(product_key: str) → DataProduct[source]

Return one product entry by key.

Parameters:

product_key (str) – Catalog key such as xgc.3d.bp or xgc.oneddiag.bp.

Raises:

KeyError – If the product is not present in the catalog.

Returns:

Product record for the requested catalog key.

Return type:

DataProduct

has_text(artifact_path: str) → bool[source]

Return whether a text artifact is known to the catalog.

Parameters:

artifact_path (str) – Manifest-relative artifact path, for example "input".

Returns:

Whether the text artifact is advertised.

Return type:

bool

list_products() → List[DataProduct][source]

Return all discovered products ordered by product key.

Returns:

Stable, alphabetically ordered product list for UI display or scripted inspection.

Return type:

list[DataProduct]

list_texts() → List[TextArtifact][source]

Return text artifacts discovered for this catalog.

Returns:

Manifest text records ordered by relative path. Directory-backed catalogs include standard XGC input/config files, recursively found files referenced by input, and detected XGC stdout logs. Campaign-backed catalogs may return an empty list until the campaign packaging schema is fully standardized.

Return type:

list[TextArtifact]

list_variables(product_key: str) → List[VariableInfo][source]

Return variables available for one product.

Parameters:

product_key (str) – Catalog key for the product to inspect.

Returns:

Variable metadata ordered by native variable name.

Return type:

list[VariableInfo]

overview(*, max_products: int | None = None, max_vars: int = 0, max_steps: int = 5) → str[source]

Return a compact human-readable overview of catalog contents.

Parameters:
  • max_products (int or None, optional) – Maximum number of products to show. None means show all product rows.

  • max_vars (int, optional) – Maximum number of variable rows to show below each product. The default 0 keeps the overview at product level.

  • max_steps (int, optional) – Maximum number of coordinate samples to show when formatting step coverage.

Returns:

Multi-line text intended for print(catalog) and interactive inspection. Use to_summary() for machine-readable output.

Return type:

str

plan_read(product_key: str, variable: str, steps: Iterable[int], missing: str | MissingStepPolicy = MissingStepPolicy.RAISE) → ReadPlan[source]

Resolve a variable read over logical steps into ADIOS source fragments.

Parameters:
  • product_key (str) – Catalog product key.

  • variable (str) – Native XGC/ADIOS variable name to read.

  • steps (iterable[int]) – Requested logical step values, typically XGC gstep values or filename-derived indices when no explicit step variable exists.

  • missing ({"raise", "skip", "zero"} or MissingStepPolicy, optional) – Policy for requested logical steps that are not available.

Returns:

Source fragments grouped by ADIOS-readable source.

Return type:

ReadPlan

Raises:
  • KeyError – If a requested step is unavailable and missing is "raise".

  • ValueError – If missing is not a supported missing-step policy.

product_names() → List[str][source]

Return product keys as a short string list for interactive browsing.

Returns:

Product keys ordered alphabetically. This is the name-only companion to list_products(), which returns full DataProduct records for programmatic use.

Return type:

list[str]

read_arrays(product_key: str, variables: Iterable[str] | str | None = None, steps: Iterable[int] | int | None = None, *, missing: str | MissingStepPolicy = MissingStepPolicy.RAISE, source_reader=None) → CatalogArrayRead[source]

Read catalog variables into plain NumPy arrays.

Parameters:
  • product_key (str) – Catalog product key such as "xgc.2d.bp".

  • variables (iterable[str], str, or None, optional) – Variables to read. If omitted, all variables advertised by the product are read.

  • steps (iterable[int], int, or None, optional) – Logical XGC steps to read. If omitted, each variable is read over the logical steps available for that variable.

  • missing ({"raise", "skip", "zero"} or MissingStepPolicy, optional) – Missing-step policy for explicit steps. "zero" records missing steps but does not synthesize zero arrays.

  • source_reader (callable or None, optional) – Optional read-plan source backend. If omitted, self.source_reader is used when present, otherwise the regular FileReader-backed local BP backend is used.

Returns:

Variable-first array mapping plus read provenance.

Return type:

CatalogArrayRead

read_text(artifact_path: str) → str[source]

Read one catalog text artifact.

Parameters:

artifact_path (str) – Manifest-relative artifact path.

Returns:

Text content decoded by the backend.

Return type:

str

Raises:
  • KeyError – If the artifact is not present in the catalog manifest.

  • RuntimeError – If the backend did not install a text reader.

refresh() → SimulationCatalog[source]

Rebuild this catalog from its backend and update it in place.

Directory-backed catalogs created by open_catalog() rescan the dataset root, regroup products, reread ADIOS metadata when configured to do so, and replace self.products with the refreshed product map. Existing ReadPlan objects are not mutated; callers should request new read plans after refreshing.

Returns:

self, for convenient chaining.

Return type:

SimulationCatalog

Raises:

RuntimeError – If the catalog was constructed without a refresh backend.

refresh_if_changed() → bool[source]

Refresh this catalog only if the backend state key has changed.

This is intended for polling running simulations from scripts or the GUI. The directory backend keeps the state-key computation cheap by stat-ing BP paths and their contents rather than opening ADIOS files. When a change is detected, this method calls refresh().

Returns:

True if the catalog was refreshed, False if the current state key matches self.state_key.

Return type:

bool

Raises:

RuntimeError – If the catalog was constructed without a state-key backend.

text_names() → List[str][source]

Return catalog text artifact paths as a short string list.

Returns:

Manifest-relative text artifact paths ordered alphabetically.

Return type:

list[str]

to_summary(*, include_variables: bool = True, include_sources: bool = False, include_texts: bool = True, include_provenance: bool = False, max_products: int | None = None, max_variables: int | None = None, max_steps: int = 20, max_sources: int = 20) → dict[source]

Return a stable JSON-like summary of catalog contents.

Parameters:
  • include_variables (bool, optional) – Include per-variable dtype, shape, units, description, and coordinate coverage.

  • include_sources (bool, optional) – Include source ids and source-level step counts. Full paths and modification times are omitted unless include_provenance is True.

  • include_texts (bool, optional) – Include catalog text artifacts.

  • include_provenance (bool, optional) – Include backend/source provenance such as campaign path, source paths, modification times, file indices, and ADIOS-step counts.

  • max_products (int or None, optional) – Limit number of products in the returned summary. None means include all products.

  • max_variables (int or None, optional) – Limit number of variables per product. None means include all variables.

  • max_steps (int, optional) – Maximum number of coordinate samples to include for gstep, tindex, and time.

  • max_sources (int, optional) – Maximum number of source records to include per product.

Returns:

Plain JSON-like data with schema name "xgc-catalog-summary-v1". The method intentionally returns built-in containers rather than catalog dataclasses so loosely coupled tools can inspect catalog contents without importing the internal object model.

Return type:

dict

variable_names(product_key: str) → List[str][source]

Return variable names for one product as a short string list.

Parameters:

product_key (str) – Catalog product key such as "xgc.2d.bp".

Returns:

Native variable names ordered alphabetically.

Return type:

list[str]

xgc_analysis.data_access.catalog.directory_catalog.classify_product(product_key: str) → Tuple[ProductType, str][source]

Classify an XGC product key by established filename conventions.

Parameters:

product_key (str) – Logical product key after sequence grouping, for example xgc.3d.bp rather than xgc.3d.00010.bp.

Returns:

Product type and coarse product family. Unknown products return (ProductType.UNKNOWN, "") so callers can still inspect them.

Return type:

tuple[ProductType, str]

xgc_analysis.data_access.catalog.directory_catalog.directory_state_key(root_dir: str | Path, *, exclude_products: Iterable[str] | None = None, manifest_builder: Callable[[Path], dict] | None = None) → Tuple[Tuple[str, str, int, int], ...][source]

Return a cheap filesystem signature for directory-backed catalog contents.

The signature covers top-level *.bp files/directories, all entries beneath BP directories, and manifest-discovered text/input artifacts. It intentionally uses only relative path, path type, modification time, and size, so it can be used for polling without opening ADIOS metadata. A changed key means callers should call SimulationCatalog.refresh(); an unchanged key means the catalog can usually be reused.

Parameters:
  • root_dir (str or pathlib.Path) – Dataset root scanned by the directory backend.

  • exclude_products (iterable[str] or None, optional) – Product keys to omit from the state signature.

  • manifest_builder (callable or None, optional) – Manifest builder used to identify non-BP artifacts to track. If omitted, the full run manifest is used. Lightweight catalogs pass their lightweight manifest builder so refresh checks do not trigger full manifest scans.

Returns:

Stable, sorted records (relative_path, kind, mtime_ns, size). The tuple is empty when the root does not exist or is not a directory.

Return type:

tuple

xgc_analysis.data_access.catalog.directory_catalog.discover_directory_products(root_dir: Path, *, collect_metadata: bool = True, metadata_reader: Callable[[Path], tuple] | None = None, exclude_products: Iterable[str] | None = None, timing: CatalogDiscoveryTiming | None = None) → List[DataProduct][source]

Discover BP products directly contained in root_dir.

Files are grouped using XGC naming conventions. A sequence such as xgc.3d.00010.bp and xgc.3d.00012.bp becomes one product keyed as xgc.3d.bp with two sources. Non-sequence files such as xgc.oneddiag.bp become single-source products.

Parameters:
  • root_dir (pathlib.Path) – Directory to scan. The scan is non-recursive.

  • collect_metadata (bool, optional) – Whether to open ADIOS sources and collect variables/steps.

  • metadata_reader (callable or None, optional) – Optional metadata reader override, mainly for tests.

  • exclude_products (iterable[str] or None, optional) – Product keys to omit from discovery.

  • timing (CatalogDiscoveryTiming or None, optional) – Mutable summary to fill with discovery and physical metadata-read durations. The returned product list is unchanged.

Returns:

Discovered products sorted by product key.

Return type:

list[DataProduct]

xgc_analysis.data_access.catalog.directory_catalog.open_catalog(root_dir: str | Path, *, collect_metadata: bool = True, metadata_reader: Callable[[Path], tuple] | None = None, exclude_products: Iterable[str] | None = None, build_manifest: bool = True) → SimulationCatalog[source]

Discover XGC products in a directory and return a catalog.

Parameters:
  • root_dir (str or pathlib.Path) – Directory containing XGC output files.

  • collect_metadata (bool, optional) – If True, open each ADIOS source to collect variable and step metadata. If False, only filenames, product grouping, and basic source metadata are collected.

  • metadata_reader (callable or None, optional) – Test or backend hook with signature reader(path) -> (variables, step_values, time_values, adios_step_count).

  • exclude_products (iterable[str] or None, optional) – Product keys to omit from discovery, for example live workflow outputs that should not be opened by catalog metadata scans.

  • build_manifest (bool, optional) – If True, build the full run manifest and state key. If False, attach only standard top-level text artifacts and defer the state-key scan so live workflows do not recursively scan large run directories at startup.

Returns:

Directory-backed catalog for root_dir. Missing or non-directory roots produce an empty catalog. discovery_timing reports the latest product scan and physical metadata-read durations.

Return type:

SimulationCatalog

Module xgc_analysis.data_access.catalog.campaign_catalog

HPC-Campaign-backed catalog discovery for XGC ADIOS outputs.

xgc_analysis.data_access.catalog.campaign_catalog.campaign_state_key(campaign_path: Path)[source]

Return a cheap state key for one campaign file.

Parameters:

campaign_path (pathlib.Path) – Campaign file path.

Returns:

Archive path, timestamp, and size signature; empty if unavailable.

Return type:

tuple

xgc_analysis.data_access.catalog.campaign_catalog.discover_campaign_products(campaign_path: Path, *, collect_metadata: bool = True, file_reader=None, timing: CatalogDiscoveryTiming | None = None, metadata_start_s: float | None = None) → List[DataProduct][source]

Discover XGC products advertised by a campaign .aca file.

Parameters:
  • campaign_path (pathlib.Path) – Campaign file to inspect.

  • collect_metadata (bool, optional) – If False, return no products. Campaign discovery currently depends on the campaign’s ADIOS metadata because there is no filesystem listing to scan.

  • file_reader (adios2.FileReader or None, optional) – Existing open campaign reader. Supplying this avoids reopening the ACA file during catalog construction and refresh.

  • timing (CatalogDiscoveryTiming or None, optional) – Mutable summary receiving one physical archive metadata-read duration and the total discovery duration.

  • metadata_start_s (float or None, optional) – perf_counter timestamp taken before opening file_reader when the caller opened it for this discovery. Omit for an already-open reader, including refreshes. Without a supplied reader, this function times its own archive open.

Returns:

Products assembled from archive variable metadata, or an empty list when collect_metadata is False.

Return type:

list[DataProduct]

xgc_analysis.data_access.catalog.campaign_catalog.open_campaign_catalog(campaign_path: str | Path, *, collect_metadata: bool = True, persistent_reads: bool = True) → SimulationCatalog[source]

Open an HPC-Campaign-backed XGC catalog.

Parameters:
  • campaign_path (str or pathlib.Path) – Path to an ADIOS-readable campaign .aca file.

  • collect_metadata (bool, optional) – Whether to inspect campaign variable metadata. The initial campaign backend requires metadata collection to build useful product records.

  • persistent_reads (bool, optional) – If True, reuse the catalog’s open campaign FileReader for data reads. This is the default because opening campaign archives can be expensive, especially for remote datasets. Set False only as a troubleshooting fallback; read-plan batching still prevents one open per variable in that mode.

Returns:

Catalog populated from campaign-qualified ADIOS variable names, with archive-opening and metadata-read durations in discovery_timing.

Return type:

xgc_analysis.data_access.catalog.SimulationCatalog

xgc_analysis.data_access.catalog.campaign_catalog.read_campaign_text(campaign_path: str | Path, artifact_path: str, *, file_reader=None) → str[source]

Read one embedded text artifact from an HPC-Campaign archive.

Parameters:
  • campaign_path (str or pathlib.Path) – Campaign .aca file.

  • artifact_path (str) – Dataset name of the embedded text artifact, for example "input" or "input_dir/profile.dat".

  • file_reader (adios2.FileReader or None, optional) – Existing campaign reader used if the artifact needs an ADIOS variable read.

Returns:

UTF-8 decoded text content.

Return type:

str

Raises:
  • KeyError – If the campaign archive does not contain the named text dataset.

  • RuntimeError – If the archive cannot be queried as an HPC-Campaign SQLite database.

Module xgc_analysis.data_access.catalog.campaign_source_reader

Campaign source-reader backend built on the shared FileReader reader.

class xgc_analysis.data_access.catalog.campaign_source_reader.CampaignSourceReader(file_reader=None, *, owns_reader: bool = False, on_reopen=None)[source]

Bases: AdiosFileSourceReader

Read selected variables and steps from an HPC-Campaign .aca file.

Campaign files expose product variables as qualified ADIOS names such as xgc.f2d.00010.bp/e_den. Product readers use unqualified names such as e_den. The read-plan executor passes source_id from the selected source fragment, and this reader combines it with each requested variable to form the campaign-qualified ADIOS name.

The class intentionally stays thin: catalogs decide what to read and this reader decides only how to execute one physical batch against an ACA source handle.

Module xgc_analysis.data_access.catalog.read_plan_executor

Execution helpers for catalog ReadPlan objects.

class xgc_analysis.data_access.catalog.read_plan_executor.BatchedReadPlanExecution(plans: ~typing.List[~xgc_analysis.data_access.catalog.types.ReadPlan], records: ~typing.List[~xgc_analysis.data_access.catalog.read_plan_executor.ReadPlanRecord] = <factory>, missing_steps_by_variable: ~typing.Dict[str, ~typing.List[int]] = <factory>)[source]

Bases: object

Values produced by executing several ReadPlan objects together.

The batch executor groups fragments by physical source and opens each source once for the union of requested variables and ADIOS steps. Records are then emitted in read-plan order so reader-local step indexing remains stable.

missing_steps_by_variable: Dict[str, List[int]]
plans: List[ReadPlan]
records: List[ReadPlanRecord]
class xgc_analysis.data_access.catalog.read_plan_executor.ReadPlanExecution(plan: ~xgc_analysis.data_access.catalog.types.ReadPlan, records: ~typing.List[~xgc_analysis.data_access.catalog.read_plan_executor.ReadPlanRecord] = <factory>, missing_steps: ~typing.List[int] = <factory>)[source]

Bases: object

Values produced by executing one ReadPlan.

plan

Original read plan.

Type:

ReadPlan

records

Values read from all plan fragments. Fragment order is preserved.

Type:

list[ReadPlanRecord]

missing_steps

Logical steps that the catalog could not resolve. The executor does not synthesize zero values; callers decide how to handle these based on the plan’s missing-step policy and variable-specific shape information.

Type:

list[int]

missing_steps: List[int]
plan: ReadPlan
records: List[ReadPlanRecord]
records_by_logical_step() → Dict[int, ReadPlanRecord][source]

Return read records keyed by logical step.

Later records overwrite earlier records for duplicate logical steps. Normal plans are already deduplicated by SimulationCatalog before execution, so overwriting only matters for hand-built test plans.

Returns:

Records keyed by logical step.

Return type:

dict[int, ReadPlanRecord]

records_in_requested_order() → List[ReadPlanRecord][source]

Return records ordered like plan.requested_steps.

Missing steps are omitted. If requested_steps contains duplicate logical steps, the same record appears more than once in the returned list.

Returns:

Records ordered by the requested steps.

Return type:

list[ReadPlanRecord]

values_by_logical_step() → Dict[int, object][source]

Return read values keyed by logical step.

Returns:

Read values keyed by logical step.

Return type:

dict[int, object]

class xgc_analysis.data_access.catalog.read_plan_executor.ReadPlanRecord(logical_step: int, source_id: str, source_path: Path, adios_step: int, variable: str, value: object, file_index: int | None = None)[source]

Bases: object

One value read from a catalog plan fragment.

A record keeps the logical XGC step next to the physical ADIOS source coordinates. Reader classes can store values under their own sequential step indices while retaining enough metadata to map those indices back to catalog/source coordinates.

file_index

Filename-derived source index when available. Internal-step sources may leave this unset; readers should use logical_step and source_id for unambiguous provenance.

Type:

int or None

adios_step: int
file_index: int | None = None
logical_step: int
source_id: str
source_path: Path
value: object
variable: str
xgc_analysis.data_access.catalog.read_plan_executor.execute_read_plan(plan: ReadPlan, source_reader: Callable[[...], Mapping[int, Mapping[str, object]]] | None = None) → ReadPlanExecution[source]

Execute a catalog ReadPlan and return logical-step records.

Parameters:
  • plan (ReadPlan) – Single-variable plan returned by SimulationCatalog.plan_read.

  • source_reader (callable or None, optional) – Backend hook with signature reader(source_path, variables, adios_steps). If omitted, regular local BP files are read with the FileReader-backed read_regular_bp_steps().

Returns:

Read records and the unresolved logical steps copied from plan.

Return type:

ReadPlanExecution

Raises:
  • KeyError – If a plan fragment points to an ADIOS step or variable that cannot be read from the selected source.

  • ValueError – If a fragment has mismatched logical-step and ADIOS-step lists.

xgc_analysis.data_access.catalog.read_plan_executor.execute_read_plans(plans: Iterable[ReadPlan], source_reader: Callable[[...], Mapping[int, Mapping[str, object]]] | None = None) → BatchedReadPlanExecution[source]

Execute several single-variable ReadPlan objects as one batched read.

Parameters:
  • plans (iterable[ReadPlan]) – Plans to execute together. Plans are expected to use the same product but may request different variables.

  • source_reader (callable or None, optional) – Backend hook with signature reader(source_path, variables, adios_steps). If omitted, regular local BP files are read with the FileReader-backed read_regular_bp_steps().

Returns:

Read records and missing-step lists keyed by variable name.

Return type:

BatchedReadPlanExecution

Raises:
  • KeyError – If a planned ADIOS step or variable cannot be read from its source.

  • ValueError – If any fragment has mismatched logical-step and ADIOS-step lists.

xgc_analysis.data_access.catalog.read_plan_executor.read_regular_bp_steps(source_path: Path, variables: Sequence[str], adios_steps: Sequence[int], *, source_id: str | None = None) → Mapping[int, Mapping[str, object]][source]

Read selected ADIOS steps from one regular local BP source.

Parameters:
  • source_path (pathlib.Path) – ADIOS-readable BP file or directory.

  • variables (sequence[str]) – Variable names to read from each selected ADIOS step.

  • adios_steps (sequence[int]) – Physical ADIOS step ids required by a read-plan fragment.

  • source_id (str or None, optional) – Accepted for source-reader API compatibility. Regular BP paths do not need it.

Returns:

{adios_step: {variable_name: value}} for the requested step span.

Return type:

mapping

Notes

This is the default finite-read backend for directory-backed catalogs. It opens the source with adios2.FileReader, reads the exact requested steps with step_selection, and closes the source when the batch is done. Campaign-backed catalogs use the same source-reader interface with a persistent FileReader handle.

Module xgc_analysis.data_access.catalog.static_product_reader

Helpers for reading static catalog products.

xgc_analysis.data_access.catalog.static_product_reader.build_static_buffer(catalog, requests: Mapping[str, Sequence[str]], *, source_reader: Callable[[...], Mapping[int, Mapping[str, object]]] | None = None, missing: str | MissingStepPolicy = MissingStepPolicy.RAISE, logical_step: int = 0, optional_products: Iterable[str] | None = None, return_timing: bool = False) → Dict[str, Dict[str, object]] | tuple[Dict[str, Dict[str, object]], dict[str, object]][source]

Read several static products into a reusable in-memory buffer.

Parameters:
  • catalog (xgc_analysis.data_access.catalog.SimulationCatalog) – Catalog containing the requested products.

  • requests (mapping[str, sequence[str]]) – Product-to-variable mapping describing the union of static values to prefetch.

  • source_reader (callable or None, optional) – Optional static-product backend with the standard SourceReader signature.

  • missing ({"raise", "skip", "zero"} or MissingStepPolicy, optional) – Missing-variable policy used when a requested product is present but a requested variable is absent. "zero" is treated like "skip" because static readers cannot infer a product-specific fill value.

  • logical_step (int, optional) – Logical step used for static products. Directory-backed static products normally expose logical step 0.

  • optional_products (iterable[str] or None, optional) – Product keys that may be absent from the catalog without failing the buffer build.

  • return_timing (bool, optional) – If True, return (buffer, timing) where timing contains a small breakdown of plan building, campaign/local reads, and in-memory buffer materialization time.

Returns:

Nested mapping keyed by product key and variable name.

Return type:

dict[str, dict[str, object]]

xgc_analysis.data_access.catalog.static_product_reader.has_static_product(catalog, product_key: str, variables: Iterable[str] | None = None) → bool[source]

Return whether catalog advertises a static product and optional variables.

Parameters:
  • catalog (xgc_analysis.data_access.catalog.SimulationCatalog) – Catalog to inspect.

  • product_key (str) – Product key to check.

  • variables (iterable[str] or None, optional) – Variables that must be advertised by the product. If omitted, only the product itself is checked.

Returns:

Whether the product and every requested variable are advertised.

Return type:

bool

xgc_analysis.data_access.catalog.static_product_reader.read_static_variables(catalog, product_key: str, variables: Sequence[str], *, source_reader: Callable[[...], Mapping[int, Mapping[str, object]]] | None = None, missing: str | MissingStepPolicy = MissingStepPolicy.RAISE, logical_step: int = 0, static_buffer: Mapping[str, Mapping[str, object]] | None = None) → Mapping[str, object][source]

Read variables from one static catalog product.

Parameters:
  • catalog (xgc_analysis.data_access.catalog.SimulationCatalog) – Catalog containing product_key.

  • product_key (str) – Static product key such as "xgc.mesh.bp" or "xgc.f0.mesh.bp".

  • variables (sequence[str]) – ADIOS variable names to read.

  • source_reader (callable or None, optional) – Optional read backend with the standard SourceReader signature. None uses catalog.source_reader when present, otherwise the FileReader-backed regular BP backend.

  • missing ({"raise", "skip", "zero"} or MissingStepPolicy, optional) – Missing-variable or missing-step policy. "zero" is treated like "skip" here because static readers do not have enough context to synthesize product-specific zero values.

  • logical_step (int, optional) – Logical step used for static products. Directory-backed static products normally expose logical step 0.

  • static_buffer (mapping[str, mapping[str, object]] or None, optional) – Optional reusable buffer previously built with build_static_buffer(). Variables already present in the buffer are returned directly, while missing variables fall back to the catalog read path.

Returns:

Values keyed by variable name. Missing values are omitted when missing is "skip" or "zero".

Return type:

dict[str, object]

Raises:

KeyError – If the product or a required variable/step is unavailable.

xgc_analysis.data_access.catalog.static_product_reader.static_product_source_path(catalog, product_key: str) → Path[source]

Return the selected path for a static catalog product.

Parameters:
  • catalog (xgc_analysis.data_access.catalog.SimulationCatalog) – Catalog containing product_key.

  • product_key (str) – Static product key to resolve.

Returns:

Path for the newest source advertised by the product.

Return type:

pathlib.Path

Notes

This is a compatibility helper for code paths that still require a local BP path, such as lazy sparse-matrix wrappers. New readers should prefer read_static_variables() so the same code can later use a campaign-backed SourceReader.

Module xgc_analysis.data_access.catalog.types

Data structures for XGC dataset discovery and read planning.

class xgc_analysis.data_access.catalog.types.CatalogArrayRead(arrays: Dict[str, Dict[int, object]], records: List[object], missing_steps_by_variable: Dict[str, List[int]])[source]

Bases: object

Plain-array result returned by catalog raw-array reads.

arrays

Variable-first mapping keyed by logical step. Values are plain arrays or scalar array values, not product-specific wrapper objects.

Type:

dict[str, dict[int, object]]

records

Raw read-plan records with source id, source path, ADIOS step, and logical step provenance.

Type:

list

missing_steps_by_variable

Missing logical steps reported by read planning for each variable.

Type:

dict[str, list[int]]

arrays: Dict[str, Dict[int, object]]
missing_steps_by_variable: Dict[str, List[int]]
records: List[object]
class xgc_analysis.data_access.catalog.types.CatalogDiscoveryTiming(total_s: float = 0.0, metadata_reads: ~typing.List[~xgc_analysis.data_access.catalog.types.MetadataReadTiming] = <factory>)[source]

Bases: object

Backend-neutral timing summary for the most recent catalog discovery.

total_s covers discovery and metadata collection. It excludes later payload reads, manifest construction, and Simulation initialization. metadata_reads contains one record per attempted physical metadata read, including attempts that produced no usable metadata.

metadata_reads: List[MetadataReadTiming]
property metadata_total_s: float

Return the sum of physical metadata-read durations in seconds.

Returns:

Combined elapsed metadata-read time in seconds.

Return type:

float

total_s: float = 0.0
class xgc_analysis.data_access.catalog.types.DataProduct(key: str, label: str, product_type: ~xgc_analysis.data_access.catalog.types.ProductType, layout: ~xgc_analysis.data_access.catalog.types.ProductLayout, sources: ~typing.List[~xgc_analysis.data_access.catalog.types.SourceInfo] = <factory>, variables: ~typing.Dict[str, ~xgc_analysis.data_access.catalog.types.VariableInfo] = <factory>, product_family: str = '')[source]

Bases: object

Catalog entry for one logical XGC product.

A product groups one or more physical sources behind the name a reader or GUI should use, for example xgc.3d.bp for the sequence xgc.3d.XXXXX.bp.

key

Catalog key used in queries and read planning.

Type:

str

label

Human-readable label, initially equal to key.

Type:

str

product_type

Reader-level product category.

Type:

ProductType

layout

Physical source/step layout.

Type:

ProductLayout

sources

Sources contributing to this product.

Type:

list[SourceInfo]

variables

Merged variable metadata, with newer sources taking precedence.

Type:

dict[str, VariableInfo]

product_family

Coarse grouping such as mesh, field, or diagnostic.

Type:

str

key: str
label: str
layout: ProductLayout
product_family: str = ''
product_type: ProductType
sources: List[SourceInfo]
variables: Dict[str, VariableInfo]
class xgc_analysis.data_access.catalog.types.MetadataReadTiming(source_id: str, path: Path, elapsed_s: float, succeeded: bool)[source]

Bases: object

Elapsed time and outcome of one physical metadata read.

source_id identifies the BP source or campaign archive, and path records its location. elapsed_s includes source opening when discovery opens it, and includes failed attempts. Both are useful when diagnosing live output discovery.

elapsed_s: float
path: Path
source_id: str
succeeded: bool
class xgc_analysis.data_access.catalog.types.MissingStepPolicy(value)[source]

Bases: str, Enum

Policy used when a requested logical step is unavailable.

RAISE reports missing steps as errors during read planning. SKIP omits unavailable logical steps from the returned fragments. ZERO records the missing steps so callers can insert zero-filled values using variable-specific shape and dtype information.

RAISE = 'raise'
SKIP = 'skip'
ZERO = 'zero'
class xgc_analysis.data_access.catalog.types.ProductLayout(value)[source]

Bases: str, Enum

Physical layout used by one product.

A layout describes how logical steps map onto ADIOS-readable sources. It is informational metadata for read planning; readers should use ReadPlan fragments rather than branching directly on this enum.

FILE_SEQUENCE = 'file_sequence'
INTERNAL_STEPS = 'internal_steps'
MIXED = 'mixed'
STATIC = 'static'
class xgc_analysis.data_access.catalog.types.ProductType(value)[source]

Bases: str, Enum

Known XGC data product categories.

Product types describe the reader-level role of a discovered product, not an external schema conversion. Most entries correspond to an existing XGC-Analysis reader or to a static support bundle used by those readers.

ANALYSIS = 'analysis'
DIFFUSION_COEFFICIENTS = 'diffusion_coefficients'
DIFFUSION_PROFILES = 'diffusion_profiles'
DISTRIBUTION_FUNCTION = 'distribution_function'
EQUILIBRIUM = 'equilibrium'
FIELD_2D = 'field_2d'
FIELD_3D = 'field_3d'
FMOMENT_2D = 'fmoment_2d'
FMOMENT_3D = 'fmoment_3d'
FSOURCE_DIAG = 'fsource_diag'
HEAT_DIAG = 'heat_diag'
MAGNETIC_FIELD = 'magnetic_field'
MESH_GEOMETRY = 'mesh_geometry'
NEUTRAL_DIAG = 'neutral_diag'
ONE_D_DIAG = 'one_d_diag'
SHEATH_DIAG = 'sheath_diag'
UNKNOWN = 'unknown'
class xgc_analysis.data_access.catalog.types.ReadFragment(source_id: str, source_path: Path, variable: str, logical_steps: List[int], adios_steps: List[int], file_index: int | None = None)[source]

Bases: object

Read request against one ADIOS-readable source.

logical_steps and adios_steps are parallel lists. The caller opens source_path once and reads variable at the listed ADIOS step ids, then maps those values back to the corresponding logical step ids.

file_index

Filename-derived source index when available. This is carried through execution so converted readers can preserve legacy step_index_info metadata while also recording logical XGC steps.

Type:

int or None

adios_steps: List[int]
file_index: int | None = None
logical_steps: List[int]
source_id: str
source_path: Path
variable: str
class xgc_analysis.data_access.catalog.types.ReadPlan(product_key: str, variable: str, requested_steps: ~typing.List[int], fragments: ~typing.List[~xgc_analysis.data_access.catalog.types.ReadFragment] = <factory>, missing_steps: ~typing.List[int] = <factory>, missing_policy: ~xgc_analysis.data_access.catalog.types.MissingStepPolicy = MissingStepPolicy.RAISE)[source]

Bases: object

Resolved source fragments needed to satisfy a logical-step request.

A ReadPlan is the interface between catalog discovery and concrete data readers. It hides whether requested logical steps are stored in one append-only BP file, several one-step files, a mixed layout, or eventually an ADIOS-readable campaign source.

fragments: List[ReadFragment]
missing_policy: MissingStepPolicy = 'raise'
missing_steps: List[int]
product_key: str
requested_steps: List[int]
variable: str
class xgc_analysis.data_access.catalog.types.SourceInfo(source_id: str, path: ~pathlib.Path, file_index: int | None = None, mtime: float = 0.0, variables: ~typing.Dict[str, ~xgc_analysis.data_access.catalog.types.VariableInfo] = <factory>, step_values: ~typing.List[int] = <factory>, time_values: ~typing.List[float] = <factory>, tindex_values: ~typing.List[int] = <factory>, adios_step_count: int = 0)[source]

Bases: object

One physical ADIOS-readable source for a product.

A source is usually one *.bp directory/file, but campaign backends may also use an ADIOS-readable campaign selector. Source metadata is kept separate from product metadata so multiple sources can contribute to one logical product.

source_id

Stable catalog-local identifier, currently the filename for directory sources.

Type:

str

path

Filesystem path to the ADIOS-readable source.

Type:

pathlib.Path

file_index

Index parsed from names such as xgc.3d.00010.bp.

Type:

int or None

mtime

Source modification time used by the newer-source deduplication policy.

Type:

float

variables

Variables advertised by this source.

Type:

dict[str, VariableInfo]

step_values

Logical step values read from gstep, step, or timestep variables.

Type:

list[int]

time_values

Optional time coordinate values read from a time variable.

Type:

list[float]

tindex_values

Optional contiguous output-slice indices read from a tindex variable.

Type:

list[int]

adios_step_count

Number of ADIOS steps observed or inferred for this source.

Type:

int

adios_step_count: int = 0
file_index: int | None = None
mtime: float = 0.0
path: Path
source_id: str
step_values: List[int]
time_values: List[float]
tindex_values: List[int]
variables: Dict[str, VariableInfo]
class xgc_analysis.data_access.catalog.types.StepFragment(source_id: str, source_path: Path, logical_step: int, adios_step: int, file_index: int | None = None, time: float | None = None, selected: bool = True)[source]

Bases: object

A candidate source fragment for one logical step.

Multiple fragments can represent the same logical step when outputs are duplicated or regenerated. SimulationCatalog.available_steps marks the selected fragment according to its deduplication policy.

adios_step: int
file_index: int | None = None
logical_step: int
selected: bool = True
source_id: str
source_path: Path
time: float | None = None
class xgc_analysis.data_access.catalog.types.StepInfo(logical_step: int, selected_fragment: ~xgc_analysis.data_access.catalog.types.StepFragment, duplicate_fragments: ~typing.List[~xgc_analysis.data_access.catalog.types.StepFragment] = <factory>, dedup_policy: str = 'newer_source_wins')[source]

Bases: object

Selected and duplicate fragments for one logical step.

logical_step

XGC/user-facing step value.

Type:

int

selected_fragment

Fragment chosen by the catalog deduplication policy.

Type:

StepFragment

duplicate_fragments

Other fragments that advertise the same logical step.

Type:

list[StepFragment]

dedup_policy

Name of the policy used to select the fragment.

Type:

str

dedup_policy: str = 'newer_source_wins'
duplicate_fragments: List[StepFragment]
logical_step: int
selected_fragment: StepFragment
class xgc_analysis.data_access.catalog.types.VariableInfo(name: str, dtype: str = '', shape: str = '', shape_dims: ~typing.List[int] = <factory>, is_scalar: bool = False, step_count: int = 0, metadata: ~xgc_analysis.data_access.catalog.types.VariableMetadata = <factory>)[source]

Bases: object

ADIOS-native and optional XGC semantic metadata for one variable.

name

Native ADIOS/XGC variable name.

Type:

str

dtype

ADIOS type string when available.

Type:

str

shape

Raw ADIOS shape string, including stepped forms such as 10*{150}.

Type:

str

shape_dims

Parsed payload dimensions excluding the leading ADIOS step count.

Type:

list[int]

is_scalar

True when metadata indicates a scalar payload.

Type:

bool

step_count

Number of ADIOS steps inferred from the variable shape, if present.

Type:

int

metadata

Optional semantic metadata from ADIOS attributes.

Type:

VariableMetadata

dtype: str = ''
is_scalar: bool = False
metadata: VariableMetadata
name: str
shape: str = ''
shape_dims: List[int]
step_count: int = 0
class xgc_analysis.data_access.catalog.types.VariableMetadata(description: str = '', units: str = '', axes: ~typing.List[str] = <factory>, mesh_context: str = '', coordinate_context: str = '', species_context: str = '', time_context: str = '', centering: str = '', normalization: str = '')[source]

Bases: object

Optional semantic metadata attached to a variable.

These fields mirror the metadata conventions used by the XGC output I/O wrapper. Older outputs may leave most fields empty; callers should treat the metadata as advisory and sparse.

description

Human-readable meaning of the variable.

Type:

str

units

Physical units, or a controlled string such as dimensionless.

Type:

str

axes

Optional semantic axis labels such as mesh_node or time_sample.

Type:

list[str]

mesh_context, coordinate_context, species_context, time_context

Optional context strings describing how to interpret the variable.

Type:

str

centering

Optional placement/centering hint.

Type:

str

normalization

Optional normalization convention when units are not sufficient.

Type:

str

axes: List[str]
centering: str = ''
coordinate_context: str = ''
description: str = ''
mesh_context: str = ''
normalization: str = ''
species_context: str = ''
time_context: str = ''
units: str = ''

Module xgc_analysis.constants

Physical constants and CGS-to-SI conversion factors for plasma physics.

Values based on the 2019 NRL Plasma Formulary.

All constants are in SI units unless otherwise noted.

Module xgc_analysis.mesh.csr_matrix

class xgc_analysis.mesh.csr_matrix.SparseMatrixCSR(reader_function)[source]

Bases: object

A class for storing a sparse matrix in CSR format (using SciPy’s csr_matrix).

The constructor takes a reader function as input. This reader function should return the matrix data as:

(ncols, nrows, nelement, width, col_indices, values)

where:
  • ncols (int): Number of columns.

  • nrows (int): Number of rows.

  • nelement (np.ndarray): A 1D array (length nrows) with the number of nonzeros in each row.

  • width (int): The maximal number of nonzeros in any row.

  • col_indices (np.ndarray): A 2D array (nrows x width) with 0-based column indices.

  • values (np.ndarray): A 2D array (nrows x width) with the nonzero values.

The constructor reformats this data and stores the matrix in SciPy’s CSR format.

get_csr_matrix()[source]
Returns:

csr_matrix: The sparse matrix in CSR format.

multiply_left(vector)[source]

Multiplies the CSR matrix from the left by a 1D NumPy array (i.e. computes vector * A).

Args:

vector (np.ndarray): 1D array with length equal to the number of rows of the matrix.

Returns:

np.ndarray: 1D array of length equal to the number of columns of the matrix.

Raises:

ValueError: if the length of vector does not match the number of rows.

multiply_transpose_left(vector)[source]

Multiplies the transpose of the CSR matrix from the left by a 1D NumPy array (i.e. computes vector * A^T).

Args:

vector (np.ndarray): 1D array with length equal to the number of columns of the matrix.

Returns:

np.ndarray: 1D array of length equal to the number of rows of the matrix.

Raises:

ValueError: if the length of vector does not match the number of columns.

xgc_analysis.mesh.csr_matrix.sparse_matrix_reader(filename, var_names)[source]

Read the sparse‑matrix variables stored in an ADIOS2 BP directory.

Parameters:
  • filename (str) – Path to the *.bp directory.

  • var_names (list[str]) –

    The six variable names in this exact order:

    • ncols_name – number of columns

    • nrows_name – number of rows

    • width_name – max. non‑zeros per row

    • nelement_name – 1‑D array of non‑zeros per row

    • col_indices_name – 2‑D array of 1‑based column indices

    • values_name – 2‑D array of non‑zero values

Returns:

(ncols, nrows, nelement, width, col_indices, values), where col_indices has been converted to 0‑based indices.

Return type:

tuple

Module xgc_analysis.data_access.products.distribution_function_data

class xgc_analysis.data_access.products.distribution_function_data.DistributionFunctionData(mesh=None, work_dir='.', file_indices=None, *, simulation=None, velocity_grid=None, f0_mesh_filename='xgc.f0.mesh.bp', ignored_vars=None, variables=None, catalog=None, steps=None, read_all_steps=False, source_reader=None, missing='raise')[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Reader for XGC xgc.f0.XXXXX.bp distribution-function files.

Data layout matches other XGC-Analysis readers:

self.data[var_name][file_step_index] = object

where object is usually:
  • DistributionFunctionField for species *_f arrays

  • PlaneData / MeshData for configuration-space arrays

  • scalar / np.ndarray for metadata

DEFAULT_IGNORED_VARS = {'eden_f0', 'iden_f0_approx', 'imu1m1', 'inode1m1', 'iphi', 'mudata', 'ndata', 'nmup1', 'nnode', 'nphi', 'vpdata'}
distribution_variables()[source]

Return sorted variable names that store distribution-function data.

Returns:

Names of loaded distribution variables in sorted order.

Return type:

list[str]

get_distribution(var_name, step_index=0)[source]

Return var_name at step_index as DistributionFunctionField.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

DistributionFunctionField

get_mesh_data(var_name, step_index=0)[source]

Return var_name at step_index as MeshData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

MeshData

get_plane_data(var_name, step_index=0)[source]

Return var_name at step_index as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name, step_index=0)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

class xgc_analysis.data_access.products.distribution_function_data.DistributionFunctionField(mesh, velocity_grid, data_array, *, name=None)[source]

Bases: object

Wrapper for one XGC distribution-function variable on a mesh and velocity grid.

Python-facing storage order:
  • canonical: (phi, node, vpar, vperp)

Axisymmetric files that omit the toroidal dimension are normalized to phi=1 on read, so self.data is always 4D.

compute_f0_moments(inputs, *, calculator=None)[source]

Compute electrostatic f0 moments using distribution_moments.F0MomentCalculator.

Parameters:
  • inputs (F0MomentInputs) – Geometry/field inputs for the requested moments.

  • calculator (F0MomentCalculator or None, optional) – Reuse an existing calculator instance. If omitted, a new one is created from this field’s velocity_grid.

Returns:

Moment result produced by the selected calculator.

Return type:

object

get_data()[source]

Return the underlying NumPy array in XGC storage order.

Returns:

Stored distribution array in XGC axis order.

Return type:

np.ndarray

property is_axisymmetric_storage

Return True when the array is stored with a single toroidal plane.

Returns:

Whether the stored array has one toroidal plane.

Return type:

bool

node_slice(inode, *, iphi=0)[source]

Return a view with shape (vpar, vperp) for one configuration-space node.

Parameters:
  • inode (int) – Configuration-space mesh node index.

  • iphi (int) – Toroidal plane index (default 0 where optional).

Returns:

View into the stored distribution array with the documented shape.

Return type:

np.ndarray

property nphi

Return the stored toroidal dimension length.

Returns:

Number of stored toroidal planes.

Return type:

int

plane_slice(iphi=0)[source]

Return a view with shape (node, vpar, vperp).

Parameters:

iphi (int) – Toroidal plane index (default 0 where optional).

Returns:

View into the stored distribution array with the documented shape.

Return type:

np.ndarray

velocity_integral(*, data_includes_vperp=True, include_gyroangle=True)[source]

Integrate the stored distribution over velocity-space axes.

Parameters:
  • data_includes_vperp (bool, optional) – Whether the stored values already include the perpendicular-speed Jacobian factor. Passed to VelocityGrid.integrate_over_velocity.

  • include_gyroangle (bool, optional) – Whether to include the gyroangle factor in the integration.

Returns:

Configuration-space result: (n_node,) for one stored plane or (nphi, n_node) otherwise, in the input data’s units times the selected velocity-space measure.

Return type:

np.ndarray

velocity_integral_data(*, data_includes_vperp=True, include_gyroangle=True)[source]

Wrap the velocity integral in a plane or mesh value container.

Parameters:
  • data_includes_vperp (bool, optional) – Integration conventions passed unchanged to velocity_integral().

  • include_gyroangle (bool, optional) – Integration conventions passed unchanged to velocity_integral().

Returns:

One-plane results use PlaneData; multi-plane results use MeshData with the same values and units as the integral.

Return type:

PlaneData or MeshData

Module xgc_analysis.analysis.moments.distribution

class xgc_analysis.analysis.moments.distribution.F0BasicMoments(density: ndarray, mean_parallel_flow: ndarray, parallel_temperature: ndarray, perpendicular_temperature: ndarray)[source]

Bases: object

Density, parallel flow, and temperatures integrated from the full f0.

density: ndarray
mean_parallel_flow: ndarray
parallel_temperature: ndarray
perpendicular_temperature: ndarray
class xgc_analysis.analysis.moments.distribution.F0MomentCalculator(velocity_grid)[source]

Bases: object

Electrostatic f0 moment calculator (first-pass Python port of f0_sum.F90).

Notes

  • Assumes distribution data are stored in canonical order (phi, node, vpar, vperp).

  • Adiabatic/non-adiabatic split follows the XGC diagnostics strategy: compute local density/temperature from f, apply mesh-level flux_avg_to_from_surf to obtain background fields, build adiabatic Maxwellian + Boltzmann response, then split moments.

  • For non-axisymmetric simulations, an additional branch decomposition is available: n0 (toroidally averaged) and turb (deviation from n0). This is controlled by F0MomentInputs.split_n0_turb.

compute(distribution_field, inputs: F0MomentInputs) → F0MomentResult[source]

Compute a first set of electrostatic f0 moments (f0_sum-style split).

Implemented moments (semantic names)

  • density

  • mean parallel flow

  • parallel energy flux (new; linear moment)

  • radial particle flux split into drift, exb, optional delta_b

  • radial energy flux split into drift, exb, optional delta_b

returns:

result.n0 always populated. result.turb populated only when inputs.split_n0_turb is true and the input distribution has more than one toroidal plane.

rtype:

F0MomentResult

Notes

  • Basic moments (density, flow, temperatures) are integrated from the full distribution at each plane and returned in result.basic.

  • Fluxes retain the adiabatic/non-adiabatic and optional n0/turb decompositions.

class xgc_analysis.analysis.moments.distribution.F0MomentComponent(parallel_energy_flux: SplitMoment, radial_particle_flux: FluxSplit, radial_energy_flux: FluxSplit)[source]

Bases: object

Flux set for one component branch (n0 or turb).

Notes

Each flux retains its adiabatic/non-adiabatic split. Basic moments are stored once in F0MomentResult from the full distribution.

parallel_energy_flux: SplitMoment
radial_energy_flux: FluxSplit
radial_particle_flux: FluxSplit
class xgc_analysis.analysis.moments.distribution.F0MomentInputs(mass_kg: float, charge_C: float, temp_node_ev: np.ndarray, den_node_m3: np.ndarray, bfield: np.ndarray, epsi: np.ndarray, etheta: np.ndarray, gradpsi: np.ndarray, nb_curl_nb: np.ndarray, v_gradb: np.ndarray, v_curv: np.ndarray, dpot: np.ndarray | None = None, flux_surface_avg_project: callable | None = None, f_3d_re: np.ndarray | None = None, f_3d_im: np.ndarray | None = None, dbre: np.ndarray | None = None, dbim: np.ndarray | None = None, species_index: int | None = None, split_n0_turb: bool = False, sim_is_axisymmetric: bool | None = None)[source]

Bases: object

Geometry / field inputs required by electrostatic f0 moments (f0_sum-style).

Arrays are expected in axisymmetric-compatible shapes:
  • node arrays: (n_node,) or (1, n_node)

  • vector arrays: (n_node, n_comp) or (1, n_node, n_comp)

Parameters:
  • mass_kg (float) – Species mass and charge.

  • charge_C (float) – Species mass and charge.

  • temp_node_ev (ndarray) – Reference local temperature used for velocity normalization (temp_node in the legacy/C++ diagnostics path, typically f0_fg_T_ev for the species).

  • den_node_m3 (ndarray) – Reference local density (f0_den for the species).

  • bfield (ndarray) – Magnetic field components in cylindrical ordering (R, Z, phi).

  • epsi (ndarray) – Electric-field components used by the electrostatic ExB velocity terms.

  • etheta (ndarray) – Electric-field components used by the electrostatic ExB velocity terms.

  • gradpsi (ndarray) – Gradient of poloidal flux with shape (..., 2) (R,Z components).

  • nb_curl_nb (ndarray) – Scalar b x curl(b) factor used in the denominator D.

  • v_gradb (ndarray) – Drift vectors with the legacy XGC ordering; component 0 is the radial-like (flux) component, component 1 is Z, component 2 is toroidal.

  • v_curv (ndarray) – Drift vectors with the legacy XGC ordering; component 0 is the radial-like (flux) component, component 1 is Z, component 2 is toroidal.

  • dpot (ndarray | None) – Electrostatic potential perturbation (V) for the Boltzmann term.

  • flux_surface_avg_project (callable | None) – Optional callback mapping a node-array to its flux-surface-averaged projection back on the nodes (Fortran mat_transpose_mult + interpolation path analogue). Signature: arr_node -> arr_node.

  • f_3d_re (ndarray | None) – Optional real/imaginary non-axisymmetric distribution components for delta-B radial flux moments. Same shape as the primary distribution.

  • f_3d_im (ndarray | None) – Optional real/imaginary non-axisymmetric distribution components for delta-B radial flux moments. Same shape as the primary distribution.

  • dbre (ndarray | None) – Optional real/imaginary magnetic perturbation vectors (R,Z,phi comps).

  • dbim (ndarray | None) – Optional real/imaginary magnetic perturbation vectors (R,Z,phi comps).

  • species_index (int | None) – Species index used for species-dependent velocity-volume normalization (f0_grid_vol_vonly) when available.

  • split_n0_turb (bool, default False) – Enable decomposition into toroidally averaged (n0) and non-axisymmetric (turb) branches.

  • sim_is_axisymmetric (bool | None) – Simulation-level symmetry flag (distinct from mesh symmetry). Used to choose default branch behavior in from_simulation().

Notes

Moment definitions follow the standard velocity integrals used in XGC analysis: n = ∫ f d^3v, u_parallel = (1/n) ∫ v_parallel f d^3v, T_parallel = (m/en) ∫ (v_parallel-u_parallel)^2 f d^3v, T_perp = (m/2en) ∫ v_perp^2 f d^3v.

bfield: np.ndarray
charge_C: float
dbim: np.ndarray | None = None
dbre: np.ndarray | None = None
den_node_m3: np.ndarray
dpot: np.ndarray | None = None
epsi: np.ndarray
etheta: np.ndarray
f_3d_im: np.ndarray | None = None
f_3d_re: np.ndarray | None = None
flux_surface_avg_project: callable | None = None
classmethod from_simulation(*, simulation, species_index: int, epsi, etheta, dpot=None, flux_surface_avg_geometry=None, f_3d_re=None, f_3d_im=None, dbre=None, dbim=None, bfield=None, gradpsi=None, nb_curl_nb=None, v_gradb=None, v_curv=None, temp_node_ev=None, den_node_m3=None, split_n0_turb=None, sim_is_axisymmetric=None)[source]

Convenience constructor using Simulation and VelocityGrid metadata.

This helper auto-populates most inputs needed by the f0-moment calculator: species mass/charge from simulation.species[species_index], local reference profiles from simulation.velocity_grid, and the equilibrium magnetic field from simulation.magnetic_field.

epsi and etheta are still required explicit inputs because they are time-dependent field quantities.

Parameters:
  • simulation (Simulation) – XGC-Analysis simulation object with species, velocity_grid, mesh, and magnetic_field attributes.

  • species_index (int) – Index into simulation.species and species-indexed arrays in simulation.velocity_grid.

  • flux_surface_avg_geometry (Mesh | None, optional) – Mesh object providing flux_avg_to_from_surf. If omitted, simulation.mesh is used.

  • split_n0_turb (bool | None, optional) – If None, defaults to not simulation.sim_is_axisymmetric.

  • sim_is_axisymmetric (bool | None, optional) – Explicit simulation-level symmetry override. This is intentionally separate from mesh.is_axisymmetric because tokamak turbulence runs can have an axisymmetric mesh but non-axisymmetric dynamics.

  • *overrides* – Any of bfield, gradpsi, nb_curl_nb, v_gradb, v_curv, temp_node_ev, or den_node_m3 may be supplied to override values taken from simulation.

classmethod from_species(*, species, species_index=None, temp_node_ev, den_node_m3, bfield, epsi, etheta, gradpsi, nb_curl_nb, v_gradb, v_curv, dpot=None, flux_surface_avg_project=None, f_3d_re=None, f_3d_im=None, dbre=None, dbim=None, split_n0_turb=False, sim_is_axisymmetric=None)[source]

Assemble moment inputs from species properties and diagnostic arrays.

species supplies mass in kilograms and charge in coulombs; species_index identifies the velocity-grid volume normalization. Node arrays, vector fields, optional perturbations, and the projection callback follow the shapes and units documented on F0MomentInputs. split_n0_turb and sim_is_axisymmetric select the toroidal decomposition. Return a new F0MomentInputs without reading files.

gradpsi: np.ndarray
static make_flux_surface_avg_projector(geometry)[source]

Build a flux_surface_avg_project callback from a Mesh.

The returned callable performs the same conceptual operation as the legacy mat_transpose_mult + interpolation path in f0_sum.F90: flux-surface average followed by projection back to nodal values.

For non-axisymmetric meshes, the mesh-level implementation performs per-plane FSA, toroidal averaging, and nodal back-projection. This is the required path for 3D XGC diagnostics and keeps axisymmetric/3D behavior unified.

Supported input shapes to the callback

  • (n_node,) -> (n_node,)

  • (1, n_node) -> (1, n_node)

  • (nphi, n_node) -> (nphi, n_node)

mass_kg: float
nb_curl_nb: np.ndarray
sim_is_axisymmetric: bool | None = None
species_index: int | None = None
split_n0_turb: bool = False
temp_node_ev: np.ndarray
v_curv: np.ndarray
v_gradb: np.ndarray
class xgc_analysis.analysis.moments.distribution.F0MomentResult(basic: F0BasicMoments, n0: F0MomentComponent, turb: F0MomentComponent | None = None)[source]

Bases: object

Common output structure for axisymmetric and non-axisymmetric runs.

basic contains the full-distribution moments on every plane. n0 is always present. turb is present only for non-axisymmetric simulations when split_n0_turb is enabled, and the branches contain fluxes only.

basic: F0BasicMoments
n0: F0MomentComponent
turb: F0MomentComponent | None = None
class xgc_analysis.analysis.moments.distribution.FluxSplit(drift: SplitMoment, exb: SplitMoment, delta_b: SplitMoment | None = None)[source]

Bases: object

Flux moment split by physical mechanism.

delta_b: SplitMoment | None = None
drift: SplitMoment
exb: SplitMoment
class xgc_analysis.analysis.moments.distribution.SplitMoment(adiabatic: ndarray | None = None, nonadiabatic: ndarray | None = None)[source]

Bases: object

Linear moment split into adiabatic / non-adiabatic pieces.

adiabatic: ndarray | None = None
nonadiabatic: ndarray | None = None
property total

Return the sum of available adiabatic and nonadiabatic arrays, or None.

xgc_analysis.analysis.moments.distribution.compare_f0_moments_to_fmoment(result: F0MomentResult, fmoment_data, *, species_prefix: str, step_index: int = 0, atol: float = 0.0, rtol: float = 0.001, rel_floor_frac: float = 0.001)[source]

Compare selected computed moments against FMomentData reference arrays.

Parameters:
  • result (F0MomentResult) – Output from F0MomentCalculator.compute().

  • fmoment_data (FMomentData) – Reader containing XGC-written moment diagnostics.

  • species_prefix ({"e", "i", "i2", ...}) – Species prefix used by the distribution variable. This helper currently supports the primary XGC fmoment prefixes e and i.

  • step_index (int, default 0) – Index into the FMomentData nested-dict storage.

  • atol (float) – Absolute/relative tolerances for np.allclose checks.

  • rtol (float) – Absolute/relative tolerances for np.allclose checks.

  • rel_floor_frac (float, default 1e-3) – Relative-denominator floor as a fraction of a robust reference scale (95th percentile of abs(ref)). This prevents near-zero reference values from producing uninformative, arbitrarily large relative errors.

Returns:

Per-moment comparison summary containing ok, max_abs, and max_rel.

Return type:

dict[str, dict]

Notes

This helper is intentionally simple and targets quick validation. It checks the moments most likely to be present in xgc.fmoment diagnostics. The comparison uses full-distribution basic moments and the n0 flux branch.

Module xgc_analysis.data_access.products.diffusion_data

Read-only readers for XGC diffusion workflow BP products.

These readers intentionally do not inherit from BPReaderMixin for now. Diffusion products have product-specific indexing rules: coefficient files use species-suffixed variables that may eventually need a project-wide species handling policy, and profile files contain multiple XGC sample steps inside one ADIOS step. The ADIOS reads still go through SimulationCatalog so directory and campaign backends share the same finite-read path.

class xgc_analysis.data_access.products.diffusion_data.DiffusionCoefficientData(data_dir: str = './', filename: str = 'xgc.diffusion_coeff.bp', read_all_steps: bool = True, catalog=None, source_reader=None)[source]

Bases: ArrayAccessorMixin

Read xgc.diffusion_coeff.bp as an analysis data product.

This class is intentionally read-only and independent of the existing workflow-oriented DiffusionCoefficients class, which opens an append stream for live coefficient updates. Each ADIOS step is stored as one reader-local step_index. Species-suffixed coefficient variables are stacked into arrays with shape (n_species, npsi) and exposed under the base coefficient names:

  • ptl_diffusivity

  • momentum_diffusivity

  • heat_conductivity

  • ptl_pinch_velocity

Metadata variables such as psi, n_species, and gstep are stored in the same self.data[var_name][step_index] layout.

COEFFICIENT_NAMES = ('ptl_diffusivity', 'momentum_diffusivity', 'heat_conductivity', 'ptl_pinch_velocity')
SPECIES_SUFFIXES = ('_elec', '_ion', '_imp1', '_imp2', '_imp3', '_imp4', '_imp5')
get_coefficient(name: str, step_index: int = 0) → ndarray[source]

Return one aggregated coefficient array with shape (n_species, npsi).

Parameters:
  • name (str) – Native coefficient or scalar variable name.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_scalar(name: str, step_index: int = 0)[source]

Return one scalar metadata value such as n_species or gstep.

Parameters:
  • name (str) – Native coefficient or scalar variable name.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

get_step_info(step_index: int) → Dict[str, object][source]

Return ADIOS-step metadata for one reader-local step index.

Parameters:

step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Copy of the selected step metadata.

Return type:

dict[str, object]

class xgc_analysis.data_access.products.diffusion_data.DiffusionProfileData(data_dir: str = './', filename: str = 'xgc.diffusion_profiles.bp', read_all_steps: bool = True, catalog=None, source_reader=None)[source]

Bases: ArrayAccessorMixin

Read xgc.diffusion_profiles.bp as buffered profile snapshots.

Each ADIOS step contains multiple XGC simulation samples. The profile variables density, flow, and temp therefore have shape (n_species, n_samples, n_surf) for each ADIOS step. This reader keeps that native layout in self.data[var_name][step_index] and provides helpers to address an inner sample by sample_index or by the XGC sample step stored in the steps variable.

PROFILE_VARIABLES = ('density', 'flow', 'temp')
SAMPLE_STEP_NAMES = ('steps', 'sample_steps', 'gsteps')
available_samples() → List[Dict[str, object]][source]

Return all buffered sample coordinates in ADIOS-step order.

Returns:

Each entry contains step_index, sample_index, gstep and time. gstep or time may be None when absent from the file.

Return type:

list[dict]

get_profile(var_name: str, step_index: int = 0, *, sample_index: int | None = None, gstep: int | None = None) → ndarray[source]

Return a diffusion profile variable or one buffered sample.

Parameters:
  • var_name (str) – Profile variable name, usually density, flow, or temp.

  • step_index (int, optional) – Reader-local ADIOS step index used when gstep is not provided.

  • sample_index (int or None, optional) – Buffered sample index inside the ADIOS step. If omitted, the full native array with shape (n_species, n_samples, n_surf) is returned.

  • gstep (int or None, optional) – XGC sample step to select from the buffered steps array. When provided, it overrides step_index and sample_index.

Returns:

Full native profile array or one sample with shape (n_species, n_surf).

Return type:

np.ndarray

get_step_info(step_index: int) → Dict[str, object][source]

Return ADIOS-step and buffered-sample metadata for one step index.

Parameters:

step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Copy of the selected step metadata.

Return type:

dict[str, object]

Module xgc_analysis.analysis.divertor.eich

Divertor heatdiag profile mapping and Eich-width fitting helpers.

This module converts XGC wall heat diagnostic data from xgc.heatdiag2.bp into upstream/midplane flux-density profiles suitable for Eich heat-load-width fits. The main entry point is compute_divertor_eich_profiles(), which can be called by scripts, notebooks, or thin GUI plugins.

The workflow implemented here is:

  1. Create or reuse a Simulation and its Plane mesh.

  2. Read heatdiag particle and energy totals through HeatDiag.

  3. Average one selected ADIOS frame, or a requested time window, to rates.

  4. Split lower divertor wall points into inner and outer target branches using the private-region poloidal-flux minimum.

  5. Map target-wall psi_N values to inner/outer midplane radius maps built from exact Plane flux-surface crossings with Z=0. The plotted Delta_sep coordinate is therefore a midplane radial distance, not distance along the target.

  6. Estimate a uniform Delta_sep grid spacing from the heatdiag psi_N resolution mapped through the flux-surface midplane map, and remap particle and energy loads with a locally conservative interval-overlap method.

  7. Optionally smooth the remapped loads with total-load renormalization, convert loads to toroidal-surface flux densities, and fit the total particle and energy channels with the Eich functional form.

The helper is deliberately conservative about units and transformations: heatdiag inputs are particle counts and energy in joules accumulated over diagnostic intervals, rates are produced by dividing by interval duration, and energy flux densities are displayed in MW m^-2 only in the plotting layer.

class xgc_analysis.analysis.divertor.eich.AnalysisHooks(check_cancel: Callable[[], None] | None = None, phase_callback: Callable[[str, dict[str, Any] | None], None] | None = None, log_callback: Callable[[str], None] | None = None)[source]

Bases: object

Optional callbacks for orchestration-level progress and cancellation.

The divertor helper remains usable from ordinary Python workflows without these hooks. Callers that want progress reporting or cooperative cancellation can provide one or more callbacks.

check_cancel, phase_callback, log_callback

Optional callable hooks for cancellation, progress phase, and log messages.

check_cancel: Callable[[], None] | None = None
log_callback: Callable[[str], None] | None = None
phase_callback: Callable[[str, dict[str, Any] | None], None] | None = None
class xgc_analysis.analysis.divertor.eich.DivertorEichProfile(label: str, x_mm: ndarray, particle_i: ndarray, particle_e: ndarray, energy_i: ndarray, energy_e: ndarray, fit_particle: tuple[ndarray, ndarray] | None, fit_energy: tuple[ndarray, ndarray] | None)[source]

Bases: object

Mapped profile and optional Eich fits for one divertor target.

The profile stores a human-readable target label, a mapped Delta_sep grid x_mm in millimeters, ion/electron particle and energy flux-density arrays, and optional Eich fit results. Fit tuples contain the fitted parameter vector (q0, q_bg, lambda_q, S, s0) in SI units and a two-column (x_mm, fitted_y) array for plotting.

energy_e: ndarray
energy_i: ndarray
fit_energy: tuple[ndarray, ndarray] | None
fit_particle: tuple[ndarray, ndarray] | None
label: str
particle_e: ndarray
particle_i: ndarray
x_mm: ndarray
class xgc_analysis.analysis.divertor.eich.DivertorLambdaQPoint(label: str, step: int, time_s: float, lambda_q_mm: float, s_mm: float)[source]

Bases: object

One converged total-energy Eich width for a divertor target and time.

label, step, time_s, lambda_q_mm, s_mm

Target name, logical step, physics time in seconds, and fitted widths in millimeters.

label: str
lambda_q_mm: float
s_mm: float
step: int
time_s: float
class xgc_analysis.analysis.divertor.eich.DivertorLoadMap(target_label: str, channel: str, component: str, view: str, x_mm: ndarray, y_values: ndarray, values: ndarray)[source]

Bases: object

Mapped divertor particle or energy flux-density map.

target_label, channel, component, view

Selected target, diagnostic channel, species component, and map orientation.

x_mm, y_values, values

Strike-point distance in millimeters, second map coordinate, and mapped rates.

channel: str
component: str
target_label: str
values: ndarray
view: str
x_mm: ndarray
y_values: ndarray
class xgc_analysis.analysis.divertor.eich.DivertorTargetTotalsPoint(label: str, step: int, time_s: float, particle_i_rate_per_s: float, particle_e_rate_per_s: float, power_i_w: float, power_e_w: float)[source]

Bases: object

One integrated particle and power total for a divertor target and time.

label, step, time_s

Target name, logical step, and physics time in seconds.

particle_i_rate_per_s, particle_e_rate_per_s, power_i_w, power_e_w

Integrated species particle rates and powers in SI units.

label: str
particle_e_rate_per_s: float
particle_i_rate_per_s: float
property particle_rate_per_s: float

Return the total ion-plus-electron particle rate.

power_e_w: float
power_i_w: float
property power_w: float

Return the total ion-plus-electron power.

step: int
time_s: float
class xgc_analysis.analysis.divertor.eich.DivertorWidthScalings(eich_mm: float, chang_mm: float, bpol_midplane_t: float, minor_radius_m: float, ion_temperature_ev: float, ion_name: str)[source]

Bases: object

Static Eich #14 and Chang Eq. (6) widths from Simulation inputs.

eich_mm, chang_mm

Eich and Chang upstream width estimates in millimeters.

bpol_midplane_t, minor_radius_m, ion_temperature_ev, ion_name

Equilibrium and main-ion inputs used in the scaling.

bpol_midplane_t: float
chang_mm: float
eich_mm: float
ion_name: str
ion_temperature_ev: float
minor_radius_m: float
xgc_analysis.analysis.divertor.eich.compute_divertor_eich_profiles(data_dir: str | Path, *, simulation: Any | None = None, include_sheath: bool = False, time_window: tuple[float, float] | None = None, selected_frame_index: int | None = None, psi_window: tuple[float, float] = (0.97, 1.12), fit_window_mm: tuple[float, float] = (-2.0, 20.0), smoothing_sigma_mm: float = 0.0, show_outer: bool = True, show_inner: bool = True, hooks: AnalysisHooks | None = None) → list[DivertorEichProfile][source]

Compute toroidally averaged divertor particle/energy flux-density profiles.

Parameters:
  • data_dir (str | Path) – XGC output directory containing xgc.heatdiag2.bp and the mesh files.

  • simulation (Simulation | None) – Optional pre-built Simulation. If omitted, a Simulation is created from data_dir.

  • include_sheath (bool) – Include [i,e]_potential in the energy channel if available.

  • time_window (tuple[float, float] | None) – Optional heatdiag interval averaging window in seconds. If set, this takes precedence over selected_frame_index.

  • selected_frame_index (int | None) – Optional GUI-selected heatdiag frame. When time_window is omitted, the selected sample is converted to the diagnostic interval ending at that frame.

  • psi_window (tuple[float, float]) – Normalized-poloidal-flux range used to select divertor wall points.

  • fit_window_mm (tuple[float, float]) – Delta_sep window used for the Eich fit.

  • smoothing_sigma_mm (float) – Gaussian smoothing sigma, in millimeters, applied to the displayed particle/energy component profiles before fitting.

  • show_outer (bool) – Select which target profiles to compute.

  • show_inner (bool) – Select which target profiles to compute.

  • hooks (AnalysisHooks | None) – Optional orchestration callbacks for cooperative cancellation and high-level phase or log reporting. Ordinary scripts can ignore this.

Returns:

One profile for each requested target.

Return type:

list[DivertorEichProfile]

xgc_analysis.analysis.divertor.eich.compute_divertor_lambda_q_timeseries(data_dir: str | Path, *, simulation: Any | None = None, include_sheath: bool = False, step_range: tuple[float, float] | None = None, time_window: tuple[float, float] | None = None, selected_frame_index: int | None = None, psi_window: tuple[float, float] = (0.97, 1.12), fit_window_mm: tuple[float, float] = (-2.0, 20.0), smoothing_sigma_mm: float = 0.0, show_outer: bool = True, show_inner: bool = True, hooks: AnalysisHooks | None = None) → list[DivertorLambdaQPoint][source]

Compute total-energy Eich lambda_q values over heatdiag intervals.

Parameters:
  • data_dir (str | Path) – XGC output directory containing xgc.heatdiag2.bp and mesh files.

  • simulation (Simulation | None) – Optional pre-built Simulation. If omitted, a Simulation is created from data_dir.

  • include_sheath (bool) – Include [i,e]_potential in the energy channel if available.

  • step_range (tuple[float, float] | None) – Optional inclusive logical-step range. This takes precedence over time_window when both are provided.

  • time_window (tuple[float, float] | None) – Optional physical-time window in seconds. Intervals overlapping the window are fitted when step_range is omitted.

  • selected_frame_index (int | None) – GUI-style selected heatdiag frame used when no range is provided. If no range and no selected frame are provided, all valid heatdiag intervals are fitted.

  • psi_window (tuple[float, float]) – Normalized-poloidal-flux range used to select divertor wall points.

  • fit_window_mm (tuple[float, float]) – Delta_sep window used for the Eich fit.

  • smoothing_sigma_mm (float) – Gaussian smoothing sigma, in millimeters, applied before fitting.

  • show_outer (bool) – Select which target branches to fit.

  • show_inner (bool) – Select which target branches to fit.

  • hooks (AnalysisHooks | None) – Optional orchestration callbacks for cancellation, progress, and logs.

Returns:

One point for each target/time whose total-energy Eich fit converged.

Return type:

list[DivertorLambdaQPoint]

xgc_analysis.analysis.divertor.eich.compute_divertor_load_map(data_dir: str | Path, *, simulation: Any | None = None, include_sheath: bool = False, view: str = 'time', channel: str = 'energy', target: str = 'outer', component: str = 'total', step_range: tuple[float, float] | None = None, time_window: tuple[float, float] | None = None, selected_frame_index: int | None = None, psi_window: tuple[float, float] = (0.97, 1.12), hooks: AnalysisHooks | None = None) → DivertorLoadMap[source]

Compute a mapped divertor particle or energy flux-density map.

Parameters:
  • data_dir (str | Path) – XGC output directory containing xgc.heatdiag2.bp and mesh files.

  • simulation (Simulation | None) – Optional pre-built Simulation. If omitted, a Simulation is created from data_dir.

  • include_sheath (bool) – Include [i,e]_potential in the energy channel if available.

  • view ({"time", "toroidal"}) – Choose whether the second map coordinate is heatdiag time or toroidal angle. The time view uses all selected intervals. The toroidal view duration-averages selected intervals and requires toroidal resolution.

  • channel ({"particle", "energy"}) – Select particle flux density or energy flux density.

  • target ({"outer", "inner"}) – Select the divertor branch, using the same split as the Eich profile helper.

  • component ({"ion", "electron", "total"}) – Select species component.

  • step_range (tuple[float, float] | None) – Optional inclusive logical-step range. This takes precedence over time_window when both are provided.

  • time_window (tuple[float, float] | None) – Optional physical-time window in seconds. Intervals overlapping the window are selected when step_range is omitted.

  • selected_frame_index (int | None) – GUI-style selected heatdiag frame used when no range is provided. For the time view, no range and no frame means all valid intervals. For the toroidal view, no range and no frame means the latest valid interval.

  • psi_window (tuple[float, float]) – Normalized-poloidal-flux range used to select divertor wall points.

  • hooks (AnalysisHooks | None) – Optional orchestration callbacks for cancellation, progress, and logs.

Returns:

Mapped load values on (y, Delta_sep) coordinates. Energy values are stored in SI units, W m^-2. Plotting converts them to MW m^-2.

Return type:

DivertorLoadMap

xgc_analysis.analysis.divertor.eich.compute_divertor_target_totals_timeseries(data_dir: str | Path, *, simulation: Any | None = None, include_sheath: bool = False, step_range: tuple[float, float] | None = None, time_window: tuple[float, float] | None = None, selected_frame_index: int | None = None, psi_window: tuple[float, float] = (0.97, 1.12), show_outer: bool = True, show_inner: bool = True, show_total: bool = True, show_wall: bool = True, hooks: AnalysisHooks | None = None) → list[DivertorTargetTotalsPoint][source]

Compute integrated divertor and wall particle/power totals over time.

Parameters:
  • data_dir (str | Path) – XGC output directory containing xgc.heatdiag2.bp and mesh files.

  • simulation (Simulation | None) – Optional pre-built Simulation. If omitted, a Simulation is created from data_dir.

  • include_sheath (bool) – Include [i,e]_potential in the energy channel if available.

  • step_range (tuple[float, float] | None) – Optional inclusive logical-step range. This takes precedence over time_window when both are provided.

  • time_window (tuple[float, float] | None) – Optional physical-time window in seconds. Intervals overlapping the window are integrated when step_range is omitted.

  • selected_frame_index (int | None) – GUI-style selected heatdiag frame used when no range is provided. If no range and no selected frame are provided, all valid heatdiag intervals are integrated.

  • psi_window (tuple[float, float]) – Normalized-poloidal-flux range used to select inner/outer divertor wall points, matching compute_divertor_eich_profiles().

  • show_outer (bool) – Select which traces to return. The Total trace sums the inner and outer divertor masks. The wall control trace sums all heatdiag wall segments after the reader has removed the garbage bin.

  • show_inner (bool) – Select which traces to return. The Total trace sums the inner and outer divertor masks. The wall control trace sums all heatdiag wall segments after the reader has removed the garbage bin.

  • show_total (bool) – Select which traces to return. The Total trace sums the inner and outer divertor masks. The wall control trace sums all heatdiag wall segments after the reader has removed the garbage bin.

  • show_wall (bool) – Select which traces to return. The Total trace sums the inner and outer divertor masks. The wall control trace sums all heatdiag wall segments after the reader has removed the garbage bin.

  • hooks (AnalysisHooks | None) – Optional orchestration callbacks for cancellation, progress, and logs.

Returns:

One point for each requested trace and heatdiag interval.

Return type:

list[DivertorTargetTotalsPoint]

xgc_analysis.analysis.divertor.eich.eich_model(x_m: ndarray, q0: float, q_bg: float, lambda_q: float, s: float, s0: float) → ndarray[source]

Eich profile model from Eich et al. NF 53, 093031, Eq. 1 without f_x.

The omitted target flux-expansion factor is appropriate when x_m is the already mapped upstream/midplane radius coordinate.

Parameters are in SI units: x_m, lambda_q, S and s0 are meters, while q0 and q_bg have the same units as the profile being fitted.

Parameters:
  • x_m – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

  • q0 – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

  • q_bg – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

  • lambda_q – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

  • s – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

  • s0 – Upstream coordinate, width, spreading, and offset in meters; amplitude and background use the same units as the fitted profile.

Returns:

modeled heat-load profile at x_m.

Return type:

ndarray

xgc_analysis.analysis.divertor.eich.estimate_divertor_width_scalings(simulation: Simulation) → DivertorWidthScalings[source]

Evaluate Eich (2013) #14 and Chang et al. (2021) Eq. (6).

Both scalings predict upstream outer-midplane width in millimeters. Chang uses the initial main-ion temperature at psi_N=0.99, so its estimate is constant over a heatdiag time series. The ion poloidal gyroradius uses sqrt(2*m_i*T_i)/(|q_i|*B_pol) with T_i converted from eV to joules.

Parameters:

simulation – Initialized Simulation with equilibrium, mesh, and species.

Returns:

DivertorWidthScalings

Return type:

static predictions and input parameters.

xgc_analysis.analysis.divertor.eich.fit_eich_profile(x_m: ndarray, y: ndarray, fit_window_mm, smoothing_sigma_mm: float = 0.0) → tuple[ndarray, ndarray] | None[source]

Fit y(x_m) with eich_model() and return parameters plus curve.

The fit uses positive finite points, optionally restricted to fit_window_mm. The fitted lambda_q and S parameters are in meters in the returned parameter vector; plotting text converts them to millimeters.

Parameters:
  • x_m – Profile coordinates in meters, measured values, optional fit interval in millimeters, and Gaussian smoothing width in millimeters.

  • y – Profile coordinates in meters, measured values, optional fit interval in millimeters, and Gaussian smoothing width in millimeters.

  • fit_window_mm – Profile coordinates in meters, measured values, optional fit interval in millimeters, and Gaussian smoothing width in millimeters.

  • smoothing_sigma_mm – Profile coordinates in meters, measured values, optional fit interval in millimeters, and Gaussian smoothing width in millimeters.

Returns:

fitted parameters and a sampled fit curve.

Return type:

tuple

Module xgc_analysis.data_access.products.field_data

class xgc_analysis.data_access.products.field_data.FieldData(mesh, work_dir='./', file_indices=None, is_axisymmetric=False, split_n0_turb=False, variables=None, read_all_steps=False, catalog=None, steps=None, missing='raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Reader for XGC xgc.2d.XXXXX.bp and xgc.3d.XXXXX.bp field files.

Data are stored in self.data with the structure:

self.data[var_name][step_index] = PlaneData | MeshData | scalar | np.ndarray

step_index is a sequential internal index over loaded (file_index, bp_step) pairs. Use get_step_info(step_index) to recover the source file index and ADIOS step id.

FieldData inherits ArrayAccessorMixin, which provides get_array(var_name) for converting stored values to plain NumPy arrays for plotting and analysis.

export_vtu(mesh)[source]

Export loaded field data to .vtu files for visualization.

Parameters:

mesh (Mesh) – Mesh object providing geometry/connectivity for the exported grid.

Returns:

Writes one .vtu file per loaded internal step to <work_dir>/vtus.

Return type:

None

get_field(var_name, step_index=0)[source]

Return the raw stored field item for a variable/time selection.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_mesh_data(var_name, step_index=0)[source]

Return var_name at step_index as MeshData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

MeshData

get_plane_data(var_name, step_index=0)[source]

Return var_name at step_index as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name, step_index=0)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

Module xgc_analysis.mesh.fieldline_mapping

xgc_analysis.mesh.fieldline_mapping.compute_fieldline_mapping(mesh, magnetic_field, *, rk4_substeps=2, n_int=250, direction='forward')[source]

Build a magnetic‑field‑line mapping between adjacent planes.

Parameters:
  • mesh (Mesh) – Instance of the Mesh defined in mesh.py.

  • magnetic_field (MagneticField) – Instance of MagneticField (see magnetic_field.py).

  • rk4_substeps (int, optional) – Number of RK4 sub‑steps per plane‑to‑plane advance (default 2).

  • n_int (int, optional) – Interpolation‑grid resolution used when creating a matplotlib.tri.TriFinder (default 250).

  • direction ({"forward", "backward"}, optional) – Direction of tracing; forward increases φ, backward decreases φ.

Returns:

triangle_index(n_vert, n_steps) int32

Triangle hosting each intersection.

bary_weights(n_vert, n_steps, 3) float64

Barycentric weights inside that triangle.

plane_index(n_steps,) int32

Index of the target plane within mesh.planes.

delta_phifloat

Toroidal separation between neighbouring planes (positive).

directionstr

Copy of the direction argument.

Return type:

dict

Module xgc_analysis.mesh.fieldline_mapping2

xgc_analysis.mesh.fieldline_mapping2.compute_fieldline_mapping(mesh, magnetic_field, *, tor_turns: float = 1.0, rk4_substeps: int = 2, n_int: int = 250, direction: str = 'forward')[source]

Trace mesh vertices along B and return interpolation metadata.

Parameters:
  • mesh (Mesh) – Mesh whose first plane supplies the starting vertices.

  • magnetic_field (MagneticField) – Background field used by the RK4 tracer.

  • tor_turns (float, optional) – How many toroidal turns (2π each) to follow. Fractional values are allowed; the number of plane steps is rounded to the nearest integer and is at least one.

  • rk4_substeps (int, optional) – RK4 steps between adjacent toroidal planes.

  • n_int (int, optional) – Resolution used when constructing a missing triangulation.

  • direction ({'forward', 'backward'}, optional) – Sign of dφ. forward ⇒ increasing φ, backward ⇒ decreasing.

Returns:

Per-step triangle_index, bary_weights, plane_index, delta_phi, and direction. On axisymmetric geometry this implementation records data plane_index 0 at every step; that behavior is under review and differs from the Mesh-wired routine.

Return type:

dict

Module xgc_analysis.data_access.products.fmoment_data

class xgc_analysis.data_access.products.fmoment_data.FMomentData(mesh, work_dir='.', file_indices=None, is_axisymmetric=False, split_n0_turb=False, variables=None, read_all_steps=False, catalog=None, steps=None, missing='raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Reader for XGC f2d / f3d moment diagnostics.

Data are stored in self.data with the common XGC-Analysis layout:

self.data[var_name][step_index] = PlaneData | MeshData | scalar

step_index is a sequential internal index over loaded (file_index, bp_step) pairs. Use get_step_info(step_index) to recover the source file index and ADIOS step id.

FMomentData inherits ArrayAccessorMixin, so get_array(var) is available for converting stored values to plain NumPy arrays.

export_vtu(mesh)[source]

Export loaded FMoment data to VTK-compatible structures.

Parameters:

mesh (Mesh) – Mesh object providing connectivity and coordinates.

Returns:

Creates output directory metadata and prepares VTK structures.

Return type:

None

get_mesh_data(var_name, step_index=0)[source]

Return var_name at step_index as MeshData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

MeshData

get_moment(var_name, step_index=0)[source]

Return the raw stored moment item for var_name and step_index.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_plane_data(var_name, step_index=0)[source]

Return var_name at step_index as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name, step_index=0)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

read_from_campaign(mesh)[source]

Legacy placeholder for campaign reads; currently performs no read.

Parameters:

mesh (Mesh) – Unused mesh argument retained for compatibility.

Returns:

This method currently has no implementation.

Return type:

None

Module xgc_analysis.data_access.products.fsource_data

class xgc_analysis.data_access.products.fsource_data.FsourceData(mesh, work_dir='./', file_indices=None, variables=None, read_all_steps=False, catalog=None, steps=None, missing='raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Reader for xgc.fsourcediag.XXXXX.bp source diagnostic files.

Data are stored in self.data using the common XGC-Analysis pattern:

self.data[var_name][step_index] = PlaneData | scalar

step_index is a sequential internal index over loaded (file_index, bp_step) pairs. Use get_step_info(step_index) to recover the source file index and ADIOS step id.

Mesh-based variables are wrapped as PlaneData on mesh.get_plane(0). Scalar variables (for example time) are stored as raw NumPy/Python values.

Notes

This diagnostic is currently treated as poloidal-plane data (axisymmetric storage on a single plane). For a 3D version, a MeshData branch can be added following FieldData / FMomentData.

get_plane_data(var_name, step_index=0)[source]

Return var_name at step_index as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name, step_index=0)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

get_source(var_name, step_index=0)[source]

Return the raw stored source-diagnostic item for var_name.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

Module xgc_analysis.data_access.products.heatdiag

Reader for XGC wall heat/particle impact diagnostics (xgc.heatdiag2.bp).

class xgc_analysis.data_access.products.heatdiag.HeatDiag(simulation=None, data_dir: str = './', filename: str = 'xgc.heatdiag2.bp', step_range: Tuple[int, int] | None = None, variables: Iterable[str] | None = None, catalog=None, steps: Iterable[int] | None = None, missing: str = 'raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Read wall heat diagnostic data from xgc.heatdiag2.bp.

Time-dependent data are stored in self.data with the structure:

self.data[variable_name][step_idx] = 2D numpy array

where step_idx is the ADIOS step index in the BP file. Variables with an extra “garbage bin” (first segment entry) are split into:

  • <var>: wall-segment data excluding the garbage bin

  • <var>_garbage: garbage-bin values with shape (nphi, 1)

Static wall geometry/metadata are stored in self.wall_data as:

self.wall_data[variable_name] = 2D numpy array

The class can be constructed stand-alone using data_dir or using a Simulation instance (it will use simulation.data_directory by default). A catalog must be supplied directly or through simulation; direct local filename reads are disabled.

DEFAULT_VARS = ('ds', 'e_number', 'e_para_energy', 'e_perp_energy', 'e_potential', 'gstep', 'i_number', 'i_para_energy', 'i_perp_energy', 'i_potential', 'nphi', 'nseg', 'nseg1', 'psi', 'r', 'step', 'strike_angle', 'time', 'tindex', 'z')
GARBAGE_BIN_VARS = {'e_number', 'e_para_energy', 'e_perp_energy', 'e_potential', 'i_number', 'i_para_energy', 'i_perp_energy', 'i_potential'}
MINIMAL_INTERVAL_VARS = ('time', 'ds', 'psi', 'r', 'z', 'strike_angle', 'e_number', 'i_number', 'e_para_energy', 'e_perp_energy', 'i_para_energy', 'i_perp_energy')
STATIC_VARS = {'ds', 'nphi', 'nseg', 'nseg1', 'psi', 'r', 'strike_angle', 'z'}
TIME_VARS = {'e_number', 'e_para_energy', 'e_perp_energy', 'e_potential', 'gstep', 'i_number', 'i_para_energy', 'i_perp_energy', 'i_potential', 'step', 'time', 'tindex'}
get_heat_array(var_name: str, step_index: int)[source]

Return time-dependent heatdiag variable var_name as np.ndarray.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_scalar(var_name: str, step_index: int)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

get_time_mask() → ndarray[source]

Return indices that sort and de-duplicate the diagnostic history.

This mirrors OneDDiag.get_time_mask() and is useful when heatdiag output contains overlapping time ranges. The returned indices apply to arrays returned by get_array(...) (stacked over available_steps).

Returns:

Integer indices retaining the last occurrence of repeated diagnostic steps in increasing time order.

Return type:

np.ndarray

get_wall_array(var_name: str) → ndarray[source]

Return a static wall variable from self.wall_data.

Parameters:

var_name (str) – Native variable name in the loaded product.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_wall_curve(*, phi_index: int = 0, verify_clockwise: bool = True, auto_reverse: bool = False, set_inboard_origin: bool = False, r_axis: float | None = None)[source]

Build a WallCurve from the HeatDiag wall polygon.

Parameters:
  • phi_index (int) – Toroidal index for selecting one wall polygon from heatdiag arrays.

  • verify_clockwise (bool) – Validate clockwise ordering of wall points.

  • auto_reverse (bool) – Reverse point order automatically if not clockwise.

  • set_inboard_origin (bool) – If True, set arclength origin at Z=0 with R<R_axis.

  • r_axis (float | None) – Magnetic-axis R used when set_inboard_origin=True. If omitted, use simulation.mesh.get_plane(0).axis_r when available.

Returns:

Wall polygon in the requested orientation and origin convention.

Return type:

WallCurve

Module xgc_analysis.data_access.products.loop_voltage_data

Reader for XGC loop-voltage source output (xgc.loop_vol.bp).

class xgc_analysis.data_access.products.loop_voltage_data.LoopVoltageData(mesh, data_dir: str = './', filename: str = 'xgc.loop_vol.bp', variables: Iterable[str] | str | None = None, read_all_steps: bool = True, catalog=None, steps: Iterable[int] | None = None, missing: str = 'raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Read axisymmetric loop-voltage source fields from xgc.loop_vol.bp.

xgc.loop_vol.bp is a single BP product with ADIOS steps. Its main payload variables are node-centered 2D fields on the poloidal mesh, so this reader wraps one-dimensional node arrays as PlaneData using mesh.get_plane(0). Scalar time-coordinate variables such as time, gstep, tindex, and legacy step are stored directly.

Data are stored with the common XGC-Analysis layout:

self.data[var_name][step_index] = PlaneData | scalar | np.ndarray

where step_index is a sequential reader-local index over the selected ADIOS steps. Use get_step_info() to map it back to the source ADIOS step id.

TIME_COORDINATES = {'gstep', 'step', 'time', 'timestep', 'tindex'}
get_field(var_name: str, step_index: int = 0)[source]

Return one stored loop-voltage item without type conversion.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_plane_data(var_name: str, step_index: int = 0) → PlaneData[source]

Return a loop-voltage field as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name: str, step_index: int = 0)[source]

Return a scalar loop-voltage metadata value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

Module xgc_analysis.magnetic_equilibrium.magnetic_field

class xgc_analysis.magnetic_equilibrium.magnetic_field.MagneticField(plane_instance, data_dir='.', catalog=None, source_reader=None, static_buffer=None)[source]

Bases: object

Background magnetic equilibrium on a poloidal plane.

Equilibrium values and the (R, Z) flux grid come from xgc.equil.bp; nodal magnetic-field and flux values come from xgc.bfield.bp. The supplied Plane provides mesh coordinates and triangulation for nodal interpolation. R and Z are cylindrical coordinates in metres, and toroidal angles used by field-line tracing are in radians.

compute_background_field(R, Z)[source]

Return the magnetic-field components (B_R, B_Z, B_t) at the given cylindrical coordinates.

Parameters:
  • R (float or ndarray) – Cylindrical coordinates. Scalars and arbitrary-shaped NumPy arrays are both accepted; broadcasting is supported as long as R and Z have compatible shapes.

  • Z (float or ndarray) – Cylindrical coordinates. Scalars and arbitrary-shaped NumPy arrays are both accepted; broadcasting is supported as long as R and Z have compatible shapes.

Returns:

B_R, B_Z, B_t – Radial, vertical (poloidal) and toroidal components. Their type/shape matches the broadcasted shape of R and Z.

Return type:

float or ndarray

Module xgc_analysis.mesh.mesh

class xgc_analysis.mesh.mesh.Mesh(is_axisymmetric, data_dir='.', catalog=None, source_reader=None, static_buffer=None)[source]

Bases: object

A general mesh class that consists of an array of “plane” objects.

The mesh data for all planes comes from the same BP file (“xgc.mesh.bp”). The file also contains the variables “delta_phi” and “wedge_angle”. The number of wedges is computed as:

wedge_n = 2*pi / wedge_angle,

and the number of planes is computed as:

nphi = wedge_angle / delta_phi.

If the input flag is_axisymmetric is True, then the mesh is axisymmetric and only one plane is set up. Otherwise, nphi planes are created (all identical in this version).

apply_fieldline_mapping(meshdata, *, ref_plane: int = 0)[source]

Pull the data of every plane onto the vertices of ref_plane along magnetic-field lines.

meshdata has toroidal plane as axis zero; ref_plane selects the reference mesh plane. A field-line mapping must already exist.

Returns:

If the stored field is scalar:

shape (n_steps, n_vert)

If the stored field is vector:

shape (n_steps, n_vert, n_components)

Axis-0 walks along the field line (φ = φ₀ + (s+1)Δφ); Axis-1 enumerates the vertices of the reference plane.

Return type:

np.ndarray

evaluate_grad_par(field_2d: ndarray, bt_sign: int) → ndarray[source]

Compute b·∇(field) on an axisymmetric mesh.

Parameters:
  • field_2d (np.ndarray, shape (nphi, n_n)) – Scalar field values on the full mesh (first index = poloidal plane, second = node).

  • bt_sign (int, sign of the toroidal magnetic field ( +1 or -1 ).)

Returns:

Same shape as field_2d with the parallel derivative.

Return type:

np.ndarray

Notes

Uses the centred, 2-nd-order accurate stencil

b·∇f ≈ sgn * [ -l_r/(l_l l_tot) f_{i-1}
  • (l_r-l_l)/(l_l l_r) f_i

  • l_l/(l_r l_tot) f_{i+1} ]

where the forward / reverse projection matrices ff_1dp_fwd and ff_1dp_rev as well as the parallel arc-lengths dl_par_1dp_fwd and dl_par_1dp_rev are taken from planes[0] (valid only when self.is_axisymmetric is True).

evaluate_scalar_gradients(field_2d: ndarray) → ndarray[source]

Apply per-plane gradient operators to a scalar field on the full 3-D mesh.

Parameters:

field_2d (np.ndarray, shape (nphi, n_n)) – field_2d[i_phi, i_node] holds the scalar value at node i_node on poloidal plane i_phi.

Returns:

grads – grads[i_phi] is the (n_n, 2) array returned by the corresponding plane’s evaluate_scalar_gradients.

Return type:

np.ndarray, shape (nphi, n_n, 2)

ff_map_real2ff(meshdata: ndarray) → ndarray[source]

Maps mesh data from the regular representation of data on planes (points with the same index on different planes are connected toroidally) to field-following representation (vertices with the same index are connected along the magnetic field). meshdata has shape (nphi, node[, component]). Return a NumPy array whose leading dimension selects left and right mapped data. The mesh must have multiple toroidal planes and loaded interpolation matrices; otherwise the function raises ValueError or RuntimeError.

flux_avg_from_surf(flux_avg: ndarray, *, fsa: str = 'volume') → ndarray[source]

Project surface values onto vertices and average over stored planes.

flux_avg contains surface samples; fsa selects the weighting scheme. Return a representative vertex array, not a PlaneData.

flux_avg_to_from_surf(meshdata: ndarray, *, fsa: str = 'volume') → ndarray[source]

Average meshdata over flux surfaces and project to vertices.

fsa selects the plane-level weighting scheme. Return the toroidally averaged projection on reference plane zero.

flux_avg_to_surf(meshdata: ndarray, *, fsa: str = 'volume') → ndarray[source]

Flux‑surface average (⟨f⟩_ψ) of a 3‑D field, averaged over φ.

meshdata has toroidal plane as axis zero; fsa selects the plane-level weighting scheme. Axisymmetric data may omit that axis.

Returns:

Shape (nsurf,) for scalar, or (nsurf, n_components) for vector data.

Return type:

ndarray

flux_avg_to_surf_norm(meshdata: ndarray, *, fsa: str = 'volume') → ndarray[source]

Average the vector norm of meshdata over surfaces and planes.

fsa selects the plane-level weighting scheme. Return one value per flux surface.

get_plane(index=0)[source]

Return the plane at index; ignore the index for axisymmetric meshes.

Raise IndexError when a non-axisymmetric index is out of range.

get_vertex_counts()[source]

Returns a list of the number of vertices on each of the mesh’s planes.

For an axisymmetric mesh (is_axisymmetric=True), the same number of vertices (from the single plane stored) is repeated for each plane (nphi times).

For a non-axisymmetric mesh, the function returns the number of vertices for each plane.

get_wall_curve(*, plane_index: int = 0, verify_clockwise: bool = True, auto_reverse: bool = False, set_inboard_origin: bool = True)[source]

Build a WallCurve from a selected plane’s wall polygon.

plane_index selects the plane. The three boolean options control orientation checks, reversal, and arclength origin as documented by Plane.get_wall_curve(). Return the new wall curve.

setup_fieldline_mapping(magnetic_field, *, direction='forward', rk4_substeps: int = 2, n_int: int = 250)[source]

Trace all mesh vertices along B and build one CSR propagator matrix for every stored toroidal step. The objects are cached as

self.fl_mapping – raw dict from compute_fieldline_mapping self.fl_csr_matrices – list[CSR] (length = n_steps)

Call this after construction if the mapping was not required earlier.

magnetic_field supplies the background field. direction sets tracing orientation, rk4_substeps sets integration subdivisions, and n_int sets toroidal steps. Updates fl_mapping and fl_csr_matrices in place. Only axisymmetric meshes are supported.

toroidal_average(meshdata: ndarray) → ndarray[source]

Return the arithmetic mean of meshdata along toroidal axis zero.

The output retains its vertex and optional component axes.

property wall_phi

Return toroidal angle for each plane in radians.

property wall_rz

Return wall node coordinates per plane as a list of arrays.

Module xgc_analysis.mesh.mesh_data

class xgc_analysis.mesh.mesh_data.MeshData(mesh, data_array=None, field_type='scalar', n_components=1, dtype=<class 'numpy.float64'>, mesh_is_axisym=False)[source]

Bases: object

Stores field data for a mesh as a list of PlaneData instances (one per plane).

The data for each toroidal plane is stored in a separate PlaneData. Axisymmetric geometry can be shared while the toroidal data slices differ. get_data() stacks those slices with plane index on axis 0.

apply_fieldline_mapping(*, ref_plane: int = 0)[source]

Pull the data of every plane onto the vertices of ref_plane along magnetic-field lines.

ref_plane selects the reference plane passed to the mesh mapping.

Returns:

If the stored field is scalar:

shape (n_steps, n_vert)

If the stored field is vector:

shape (n_steps, n_vert, n_components)

Axis-0 walks along the field line (φ = φ₀ + (s+1)Δφ); Axis-1 enumerates the vertices of the reference plane.

Return type:

np.ndarray

evaluate_full_gradients(bt_sign: int) → MeshData[source]

Return a 3-component gradient vector field as a new MeshData:

grads[…, 0] = ∂f/∂ψ grads[…, 1] = ∂f/∂θ grads[…, 2] = b·∇f

Parameters:

bt_sign (int) – Sign of the toroidal magnetic field Bᵗ (±1).

Return type:

MeshData # field_type = ‘vector’

evaluate_grad_par(bt_sign: int) → MeshData[source]

Parallel derivative b·∇(f) returned as a new scalar MeshData.

Parameters:

bt_sign (int) – Sign of the toroidal magnetic field (±1).

Return type:

MeshData # field_type = ‘scalar’

evaluate_scalar_gradients() → MeshData[source]

Return (R,Z)/(psi,theta)-gradients as a new MeshData object (vector field).

Return type:

MeshData # field_type = ‘vector’

extract_component(component_index)[source]

For vector fields only.

Returns a new MeshData instance where each plane contains only the specified component of the original vector field (i.e. a scalar field).

component_index is zero-based. Raise ValueError for scalar input; the returned object owns per-plane component arrays.

ff_map_real2ff()[source]

Maps mesh data from the regular representation of data on planes (points with the same index on different planes are connected toroidally) to field-following representation (vertices with the same index are connected along the magnetic field). The output format is list of MeshData objects of the same type, one for the left, one for the right plane.

Returns:

MeshData (vector-type): Field on a mesh mapped to field-aligned representation.

flux_avg_from_surf(*, fsa: str = 'volume')[source]

Project stored surface values to vertices in flux_avg_plane.

fsa selects the plane weighting scheme. The method returns no value and replaces the cached PlaneData.

flux_avg_to_from_surf(*, fsa: str = 'volume')[source]

Average this field and cache its vertex projection.

fsa selects the plane weighting scheme. The projected PlaneData is stored in flux_avg_plane; return None.

flux_avg_to_surf(*, fsa: str = 'volume')[source]

Store the surface average in flux_avg_psi.

fsa selects the plane weighting scheme. This mutates the object and returns no array.

flux_avg_to_surf_norm(*, fsa: str = 'volume')[source]

Cache the toroidally averaged vector norm by flux surface.

fsa selects the plane weighting scheme. Requires vector data; stores flux_avg_norm_psi and returns None.

get_data()[source]

Stack values from all toroidal planes into one NumPy array.

Returns:

Toroidal plane is axis 0. The remaining axes preserve each PlaneData array’s shape: typically (n_vertices,) for loaded scalars or (n_vertices, n_components) for vectors.

Return type:

ndarray

get_plane(plane_index)[source]

Return the PlaneData at zero-based plane_index.

Raise IndexError when the index is outside stored planes.

toroidal_average()[source]

Cache the plane-wise arithmetic mean in toroidal_avg_data.

Returns:

The average is stored as a PlaneData on this MeshData.

Return type:

None

Module xgc_analysis.data_access.products.neutral_data

Reader for xgc.neutrals.XXXXX.bp neutral diagnostic files.

class xgc_analysis.data_access.products.neutral_data.NeutralData(mesh, work_dir='./', file_indices=None, is_axisymmetric=None, variables=None, read_all_steps=False, catalog=None, steps=None, missing='raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Read neutral Monte-Carlo diagnostic data from xgc.neutrals.XXXXX.bp files.

The data layout follows the pattern used by FieldData/FsourceData:

self.data[var_name][file_step_index] = PlaneData | MeshData | scalar

For axisymmetric data, mesh fields are stored as PlaneData. For non-axisymmetric data, mesh fields are stored as MeshData.

Axisymmetry is inferred from the shape of the variables in the neutrals file (not from the mesh geometry):

  • axisymmetric neutrals: (n_n,) or (1, n_n)

  • non-axisymmetric neutrals: (nphi, n_n)

The inferred mode is tracked in self.is_axisymmetric. If multiple files are loaded, all neutrals fields are required to use the same axisymmetry mode.

get_mesh_data(var_name, step_index=0)[source]

Return var_name at step_index as MeshData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

MeshData

get_neutral_field(var_name, step_index=0)[source]

Return the raw stored neutral field item for var_name.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_plane_data(var_name, step_index=0)[source]

Return var_name at step_index as PlaneData.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

PlaneData

get_scalar(var_name, step_index=0)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

required_vars = ['den_neut', 'rel_std', 'temp_neut']

Module xgc_analysis.data_access.products.oneddiag

Reader and utilities for XGC 1D diagnostics (xgc.oneddiag.bp).

This module refactors the 1D diagnostic reader to follow the common XGC-Analysis data layout used by other readers:

self.data[var_name][step_index] = scalar | np.ndarray

Key conventions

  • Species-resolved variables are normalized to standardized dotted keys such as "e.gc_density_df_1d" and "i2.parallel_flow_df_1d".

  • Static arrays that are effectively constant in time (for example psi) are stored in self.static_data and exposed via compatibility aliases self.psi, self.psi00, and self.psi_mks.

  • Derived quantities are stored separately in self.derived_data / self.derived_static_data and accessed through od.derived.

The module also provides lightweight species views (od.e, od.i, …) for backward-compatible attribute access in notebooks.

class xgc_analysis.data_access.products.oneddiag.OneDDiag(path: str = './', filename: str = 'xgc.oneddiag.bp', simulation=None, catalog=None, steps=None, missing: str = 'raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Reader for XGC 1D diagnostics with standard nested-dict storage layout.

Parameters:
  • path (str, default "./") – Directory containing the oneddiag BP file.

  • filename (str, default "xgc.oneddiag.bp") – Diagnostic filename.

  • simulation (Simulation or None, optional) – If provided, simulation.species is used to attach Species objects and species masses to standardized prefixes detected from the file.

  • catalog (SimulationCatalog or None, optional) – Optional catalog used to resolve logical steps into BP sources. If omitted, simulation.catalog is used when present. Direct local filename reads are disabled when no catalog is available.

  • steps (iterable[int] or None, optional) – Logical XGC steps to read from catalog. If omitted, all available oneddiag steps are read.

  • missing ({"raise", "skip", "zero"}, optional) – Missing-step policy for catalog read planning.

  • source_reader (callable or None, optional) – Optional read-plan backend hook.

data

Time-dependent raw variables in the common reader layout.

Type:

dict[str, dict[int, object]]

static_data

Time-independent arrays promoted out of data (for example psi).

Type:

dict[str, np.ndarray]

derived_data

Time-dependent derived quantities (e.g. "e.T", "shear_r").

Type:

dict[str, dict[int, object]]

species_by_prefix

Mapping from standardized prefixes (e, i, i2, …) to Species objects when available.

Type:

dict[str, Species | None]

mass_by_prefix

Species masses in atomic mass units, from Species metadata or internal fallback defaults.

Type:

dict[str, float | None]

SPECIES_PREFIXES = ['e', 'i', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9']
d_dpsi(var, psi)[source]

Compute d(var)/d(psi) on a non-uniform 1D grid.

Parameters:
  • var (np.ndarray) – Array of shape (n_step, n_psi).

  • psi (np.ndarray) – 1D non-uniform coordinate array of length n_psi.

Returns:

Numerical derivative with the same shape as var.

Return type:

np.ndarray

echarge = 1.6022e-19
get_derived_array(var_name)[source]

Return a derived variable stacked over steps, or a derived static array.

Parameters:

var_name (str) – Native variable name in the loaded product.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_derived_item(var_name, step_index)[source]

Return one derived item for a specific step_index.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_profile(var_name, step_index=0)[source]

Return a time-dependent oneddiag variable as an ndarray for one step.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_scalar(var_name, step_index=0)[source]

Return a scalar time-dependent oneddiag variable for one step.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

get_species_by_prefix(prefix)[source]

Return the associated Species object (if available) for prefix.

Parameters:

prefix (str) – Standardized species prefix in this diagnostic.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_species_view(prefix)[source]

Return the lightweight species view object for a standardized prefix.

Parameters:

prefix (str) – Standardized species prefix in this diagnostic.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

object

get_static_array(var_name)[source]

Return a static array from self.static_data (for example psi).

Parameters:

var_name (str) – Native variable name in the loaded product.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_time_mask()[source]

Build a mask selecting the last occurrence of each diagnostic step.

This is a legacy helper kept for compatibility with older notebook workflows that expect self.tmask to index a monotonic subset of the stored time history. Overlapping diagnostic segments are resolved by keeping the last occurrence for each repeated step value.

Returns:

Indices retaining the last occurrence of repeated diagnostic steps.

Return type:

np.ndarray

has_derived_var(var_name)[source]

Return True if a derived variable exists in dynamic or static storage.

Parameters:

var_name (str) – Native variable name in the loaded product.

Returns:

Whether the derived variable is available.

Return type:

bool

list_species()[source]

Return active species prefixes detected in the file.

Returns:

Detected active species prefixes.

Return type:

list[str]

load_data()[source]

Disabled legacy direct-file reader.

One-dimensional diagnostic data must be read through catalog read plans so the same code path works for directory and campaign backends.

Raises:

RuntimeError – Always; use a catalog to construct this reader instead.

load_data_from_catalog()[source]

Read the oneddiag product through catalog read plans.

All variables advertised by the catalog product are read unless they are ignored by this reader. The resulting raw step-major data are then normalized by the same path used for direct BP reads.

Returns:

The reader stores values in its data containers.

Return type:

None

mu0 = 1.2566370614359173e-06
plot1d_if(var, time=None, varstr=None, psi=None, xlim=None, initial=True)[source]

Plot first/last profiles from a time-series array (legacy helper).

Parameters:
  • var (np.ndarray) – Array of shape (n_step, n_psi).

  • time (np.ndarray or None, optional) – Time array aligned with var for labels. If omitted, labels are Initial / Final.

  • varstr (str or None, optional) – Label/title string.

  • psi (np.ndarray or None, optional) – X-axis coordinate. Defaults to self.psi.

  • xlim (tuple[float, float] or None, optional) – Restrict plotting to a psi interval.

  • initial (bool, default True) – Whether to also plot the first time slice.

Returns:

The method creates a Matplotlib figure as a side effect.

Return type:

None

post_process()[source]

Compute commonly used derived quantities and store them in od.derived.

Derived quantities currently include: - species temperatures <prefix>.T - species gradient scale lengths <prefix>.Ln and <prefix>.Lt - reference density and Ln - grad_psi_sqr and shear_r

Notes

The reference species for density / shear_r is electrons if present, otherwise the main ion prefix i when available.

Returns:

Derived values are stored on this reader.

Return type:

None

protmass = 1.6726e-27
report_profiles(sp_names=None, init_idx=0, end_idx=-1, edge_lim=[0.85, 1.05], show_edge=True)[source]

Generate a small set of legacy profile plots for quick inspection.

This method is retained for backward compatibility and is a candidate for migration into plotting.py in a future cleanup.

Parameters:
  • sp_names (list[str] or None, optional) – Labels for active species; defaults to the stored species names.

  • init_idx (int, optional) – Time-slice bounds for the reported profiles.

  • end_idx (int, optional) – Time-slice bounds for the reported profiles.

  • edge_lim (list[float], optional) – Normalized-flux interval for optional edge plots.

  • show_edge (bool, optional) – Whether to include edge-only views.

Returns:

Figures are created through Matplotlib as side effects.

Return type:

None

Module xgc_analysis.species.periodic_table

xgc_analysis.species.periodic_table.get_element_name_by_mass(mass_au, tolerance=0.5)[source]

Returns the name of the element with atomic mass closest to the given mass_au.

Parameters:
  • mass_aufloat

    Mass in atomic mass units.

  • tolerancefloat

    Maximum allowed deviation to consider a match.

Returns:
  • str: Element symbol or ‘Unknown’ if no match is found.

Module xgc_analysis.mesh.plane

class xgc_analysis.mesh.plane.Plane(filename='xgc.mesh.bp', data_dir='.', setup_ff2real_mapping=False, catalog=None, source_reader=None, static_buffer=None)[source]

Bases: object

A class to represent a planar unstructured triangle mesh (in cylindrical coordinates at constant toroidal angle) read from an Adios BP (BP version 5) file using the Adios2 Python FileReader API (v2.10.2+).

The BP file (e.g., ‘xgc.mesh.bp’) is assumed to contain the following variables:

Scalars:
  • n_n : Number of mesh vertices.

  • n_t : Number of triangles.

  • nsurf : Number of psi contour surfaces.

  • surf_maxlen : Maximum number of vertices on any psi surface.

Arrays:
  • rz : (n_n, 2) coordinates (R, Z) of vertices.

  • nd_connect_list : (n_t, 3) triangle connectivity (1-based indices).

  • tr_area : (n_t,) triangle areas.

  • node_vol : (n_n,) Voronoi volume (measure 1).

  • node_vol_nearest: (n_n,) Voronoi volume (nearest neighbor measure).

  • psi : (n_n,) poloidal magnetic flux.

  • theta : (n_n,) straight field-line poloidal angle.

  • region : (n_n,) region index of the vertices (1) core, (2) SOL, (3) privat flux, (100) wall

  • surf_len : (nsurf,) number of vertices on each psi surface.

  • surf_idx : (nsurf, surf_maxlen) 1-based vertex indices on each psi surface.

  • rmin : (nsurf,) minor radius of each surface.

  • rmaj : (nsurf,) major radius of each surface.

  • epsilon : (nsurf,) inverse aspect ratio.

  • m_max_surf : (nsurf,) Fourier space resolution limit.

  • psi_surf : (nsurf,) psi value on each surface.

  • qsafety : (nsurf,) safety factor.

  • trapped : (nsurf,) trapped particle fraction.

Plotting functionality:
  • triObjMatplotlib triangulation object for unstructured meshes.

    This is needed for plotting fields defined on the planar mesh

Matrices:
  • cnv_to_surf : …

  • cnv_from_surf : …

  • grad_r_psi : …

  • grad_z_theta : …

Diagnostic functions:
  • plot_vertices_with_wall : …

  • plot surfaces : …

  • plot_triangles : …

build_line_fsa_matrix(bfield=None)[source]

Build a sparse trapezoidal dl/B_pol averaging operator on every surface.

Triangle-edge connectivity orders each contour without relying on surf_idx order. On the separatrix, leaf pruning retains only the closed X-point loop. The singular X-point receives zero nodal inverse-B weight, giving a finite, mesh-resolution-dependent cutoff.

calculate_flux_surface_area()[source]

Calculates the surface area of each flux surface assuming that the 2D ψ-surfaces are rotated around the Z-axis by 2π.

For each ψ-surface, the routine:
  • Loops over its vertices.

  • For each segment between adjacent vertices, computes the midpoint (R_m, Z_m) and the distance l_seg.

  • If the surface is closed (i.e. self.surf_region[i] == 1), the last vertex connects to the first; if open (region==2 or 3), the last vertex is skipped.

  • The area of each segment is 2π * R_m * l_seg.

Returns:

A list of surface areas (one per ψ-surface).

Assumes that the Plane class has the following attributes:
  • self.nsurf: total number of ψ-surfaces.

  • self.surf_len: 1D array of length nsurf (number of vertices per surface).

  • self.surf_idx: 2D array (nsurf × surf_maxlen) of 0-based vertex indices.

  • self.rz: 2D array (n_n × 2) with (R,Z) coordinates.

  • self.surf_region: 1D array (length nsurf) with region codes (1 for closed, 2 or 3 for open).

compute_core_sol_geometry_blocks(sep_tol: float = 1e-05) → dict[str, ndarray | float | int][source]

Build mapped geometry blocks for default, core-side, and SOL-side discretizations.

This helper computes flux-surface area and shell-volume arrays on the mapped surface index set (surf_map) that are suitable for transport discretizations requiring different separatrix treatment on core and SOL sides.

Construction summary

  1. Compute default mapped areas from calculate_flux_surface_area()[surf_map].

  2. Split separatrix area into above-X and below-X contributions by integrating segment lengths in the (R, Z) surface polyline.

  3. Build area_core_block using only separatrix-above-X area at the separatrix index, and area_sol_block using total separatrix area.

  4. Reconstruct shell volumes from vertex volumes in two passes. The first pass loops over all full-grid surfaces and directly accumulates vertex volumes while marking used vertices. The second pass distributes remaining unused vertices to mapped surfaces by linear interpolation in psi.

  5. At the separatrix full-surface index, split candidate vertices by region tag: region == 1 for volume_core_block and region == 2 for volume_sol_block.

  6. Distribute off-surface vertex volumes in the two gaps adjacent to the separatrix using cnv_from_surf interpolation weights, excluding private-region vertices.

param sep_tol:

Reserved separatrix tolerance (dimensionless). Kept for API compatibility; not currently used in this implementation.

type sep_tol:

float

returns:

Geometry dictionary with the following entries:

psi_mapnp.ndarray

Psi values on mapped surfaces, shape (n_map,) (units: psi).

area_defaultnp.ndarray

Default mapped flux-surface areas, shape (n_map,) (units: m^2).

area_core_blocknp.ndarray

Core-side area block; separatrix uses above-X contribution only (units: m^2).

area_sol_blocknp.ndarray

SOL-side area block; separatrix uses full area (units: m^2).

volume_defaultnp.ndarray

Default mapped shell volumes reconstructed from node_vol (units: m^3).

volume_core_blocknp.ndarray

Core-side shell-volume block with separatrix region-1 selection (units: m^3).

volume_sol_blocknp.ndarray

SOL-side shell-volume block with separatrix region-2 selection (units: m^3).

i_sep_mapint

Separatrix index in mapped-surface arrays.

i_sep_fullint

Separatrix index in full-surface arrays.

sep_area_abovefloat

Separatrix area above X-point (units: m^2).

sep_area_belowfloat

Separatrix area below X-point (units: m^2).

rtype:

dict[str, np.ndarray | float | int]

Notes

volume_* arrays are shell volumes per mapped surface index, not cumulative enclosed volume. Cumulative volume can be formed with np.cumsum(volume_default) (or corresponding core/SOL block).

evaluate_scalar_gradients(field_1d: ndarray) → ndarray[source]

Evaluate the radial and poloidal gradients of a scalar field. (Note that it depends on the value of self.basis whether the derivatives are (R,Z) or (psi,theta) directonal derivatives!)

Parameters:

field_1d (np.ndarray, shape (n_n,)) – Nodal values of the scalar field on this plane.

Returns:

grads – Column 0 → ∂f/∂ψ (gradient_r_psi ⋅ f) Column 1 → ∂f/∂θ (gradient_z_theta ⋅ f)

Return type:

np.ndarray, shape (n_n, 2)

flux_avg_from_surf(flux_avg: ndarray, *, fsa: str = 'volume') → ndarray[source]

Map surface samples flux_avg back to plane vertices.

flux_avg has shape (nsurf[, component]) and fsa must be volume or line. Return shape (n_n[, component]). Raise RuntimeError when the projection matrix is unavailable.

flux_avg_to_from_surf(vertex_data: ndarray, *, fsa: str = 'volume') → ndarray[source]

Average vertex_data on flux surfaces and project to vertices.

fsa selects volume or line weights. Return a nodal array with the input component layout; missing conversion matrices raise RuntimeError.

flux_avg_to_surf(vertex_data: ndarray, *, exclude_separatrix_legs: bool = False, fsa: str = 'volume') → ndarray[source]

Return surface averages for scalar or component-wise vertex data.

vertex_data has shape (n_n[, component]). fsa chooses volume or line weights. exclude_separatrix_legs replaces the volume-weighted separatrix row with its closed-loop portion. Return surface samples with the component axis retained when supplied.

flux_avg_to_surf_norm(field: ndarray, *, fsa: str = 'volume') → ndarray[source]

Flux-surface average of the Euclidean norm of a vertex-centred field on this poloidal plane.

Parameters:

field (np.ndarray) –

  • If shape == (n_n,) → treated as a scalar field.

  • If shape == (n_n, n_comp) → treated as a vector field; the norm is computed along the last axis.

Returns:

1-D array of length n_psi (the number of flux-surfaces on the plane) containing the volume-weighted flux-surface averages.

Return type:

np.ndarray

Raises:
  • RuntimeError – If the conversion matrix cnv_to_surf is unavailable because its backing .bp file was missing when the Plane was constructed.

  • ValueError – If the input array does not have the required first dimension n_n.

gen_ff2real_mapping()[source]

Construct the field-aligned to real-plane sparse interpolation map.

Uses the forward mapping and field-aligned node volumes to normalize each target row. Rows without forward support use the reverse map. Updates this plane’s mapping arrays in place and prints progress.

get_psi_surface_index_map(tol=0.0001)[source]

Identify the ψ‑surfaces that are valid for subsequent analysis.

Strategy

For every surface i (whose length is surf_len[i]):

  1. Single‑vertex surface

    • If the surface contains exactly one vertex and that vertex’s coordinates (R, Z) are within tol of the magnetic‑axis position (axis_r, axis_z), accept the surface.

  2. Multi‑vertex surface

    • Restrict to vertices with R >= axis_r.

    • Among them, find • the vertex whose Z is largest below the axis • the vertex whose Z is smallest above the axis.

    • Accept the surface only if both vertices exist.

param tol:

Tolerance that defines “close to the magnetic axis”, measured in the same units as R and Z. Default is 1e‑4.

type tol:

float, optional

returns:

Zero‑based indices of the ψ‑surfaces that satisfy the above criteria.

rtype:

list[int]

get_surface_indices()[source]
Returns:

np.ndarray: 2D array (shape: (nsurf, surf_maxlen)) containing 1-based vertex indices on each surface.

get_surface_lengths()[source]
Returns:

np.ndarray: 1D array of length nsurf indicating the number of vertices on each surface.

get_surface_properties()[source]
Returns:
dict: A dictionary of surface properties with keys:
  • ‘rmin’ : Minor radius (np.ndarray of shape (nsurf,))

  • ‘rmaj’ : Major radius (np.ndarray of shape (nsurf,))

  • ‘epsilon’ : Inverse aspect ratio (np.ndarray of shape (nsurf,))

  • ‘m_max_surf’ : Fourier space resolution limit (np.ndarray of shape (nsurf,))

  • ‘psi_surf’ : Psi value on each surface (np.ndarray of shape (nsurf,))

  • ‘qsafety’ : Safety factor (np.ndarray of shape (nsurf,))

  • ‘trapped’ : Trapped particle fraction (np.ndarray of shape (nsurf,))

get_surface_vertex_indices(surface_index)[source]

Returns the vertex indices for a given psi surface.

Args:

surface_index (int): The index of the surface (0-based).

Returns:

np.ndarray: An array of vertex indices (0-based) corresponding to the given surface.

get_triangle_areas()[source]
Returns:

np.ndarray: Array of triangle areas with shape (n_t,).

get_triangle_connectivity()[source]
Returns:

np.ndarray: Array of triangle connectivity indices (1-based) with shape (n_t, 3).

get_triangulation_data(n_int: int = 200, R_bounds: tuple[float, float] | None = None, Z_bounds: tuple[float, float] | None = None)[source]

Build a regular (R,Z) interpolation grid and a Matplotlib Triangulation that matches the unstructured mesh.

Parameters:
  • n_int (int, default 200) – Number of grid points in each dimension (R and Z).

  • R_bounds ((min, max) tuple or None, optional) – Explicit coordinate limits for the interpolation grid. If None (default) the routine uses the min/max of the vertex coordinates.

  • Z_bounds ((min, max) tuple or None, optional) – Explicit coordinate limits for the interpolation grid. If None (default) the routine uses the min/max of the vertex coordinates.

Returns:

Object containing (RI, ZI, triObj).

Return type:

TriangulationData

get_vertex_coordinates()[source]
Returns:

np.ndarray: Array of vertex coordinates with shape (n_n, 2) representing (R,Z) pairs.

get_voronoi_volumes()[source]
Returns:
tuple: Two np.ndarray objects representing the vertex Voronoi volumes

(node_vol and node_vol_nearest), each with shape (n_n,).

get_wall_curve(*, verify_clockwise: bool = True, auto_reverse: bool = False, set_inboard_origin: bool = True)[source]

Build a WallCurve from this plane’s wall polygon.

Parameters:
  • verify_clockwise (bool) – Validate clockwise ordering of wall nodes.

  • auto_reverse (bool) – Reverse node order automatically if not clockwise.

  • set_inboard_origin (bool) – If True, set arclength origin at Z=0 with R<R_axis.

property line_fsa_matrix

Return the cached surface-by-node CSR line-average operator.

plot_contour(values_in: ndarray, *, n_int: int = 200, plot_norm: bool = False, i_comp: int = 0, var_name: str = '', title: str = '', levels: int | None = 60, lower: float | None = None, upper: float | None = None, R_bounds: tuple[float, float] | None = None, Z_bounds: tuple[float, float] | None = None, filename: str | None = None, ax=None, render_as_image: bool = False, cmap: str = 'seismic')[source]

Plot the field stored in this PlaneData instance as a filled-contour map in the (R,Z) plane.

Parameters:
  • values_in (np.ndarray) – 1-D array of length self.n_n (= number of vertices). If you pass a 2-D array, its Euclidean norm is taken or a single component (convenient for vector data), controlled by plot_norm and i_comp.

  • n_int (int, default 200) – Grid resolution in both R and Z used for interpolation.

  • plot_norm (bool, default False) – In case of vector data, whether to plot the norm | v | of the vector.

  • i_comp (int, default 0) – In case of vector data, which component to plot.

  • var_name (str, optional) – Label for the colour-bar (e.g. "nₑ (m⁻³)"). Defaults to "".

  • title (str, optional) – Header for the plot window. Defaults to "".

  • levels (int or sequence, optional) – If an int, the number of evenly-spaced contour levels (Matplotlib default is fine). If an explicit 1-D sequence, those values are used as contour levels. Defaults to 60.

  • lower (float or None, optional) – Explicit lower/upper bounds for the colour-map. If either is None the routine uses the corresponding data extreme.

  • upper (float or None, optional) – Explicit lower/upper bounds for the colour-map. If either is None the routine uses the corresponding data extreme.

  • R_bounds ((min, max) tuple or None, optional) – Explicit limits for the interpolation grid. Passed straight through to plane.get_triangulation_data. None ⇒ auto-limits.

  • Z_bounds ((min, max) tuple or None, optional) – Explicit limits for the interpolation grid. Passed straight through to plane.get_triangulation_data. None ⇒ auto-limits.

  • ax (matplotlib.axes.Axes or None, optional) – Draw into an existing axes for composite plots.

  • render_as_image (bool, default False) – Draw the mapped grid as an image so SVG exports embed a bitmap.

plot_fieldline_contour(data: ndarray, surf_idx: int, *, var_name: str = '', title: str = '', levels: int | ndarray | None = 60, lower: float | None = None, upper: float | None = None, filename: str | None = None)[source]

Filled-contour plot of data along the magnetic field on the requested ψ-surface.

Parameters:
  • data (ndarray) – Result of MeshData.apply_fieldline_mapping, shape (n_steps, n_vertices). Axis-0 = distance along B, axis-1 = vertex index on this plane.

  • surf_idx (int) – Which ψ-surface to plot (index into self.surf_* arrays).

  • var_name (str) – Labels for colour-bar and figure title.

  • title (str) – Labels for colour-bar and figure title.

  • levels (int or 1-D array or None) – Passed to contourf, like in plot_contour.

  • lower (float or None) – Manual colour limits (None → data min/max).

  • upper (float or None) – Manual colour limits (None → data min/max).

plot_surfaces()[source]

Plot all psi surfaces.

plot_triangles()[source]

Plots all the triangles of the mesh. For each triangle, the 3 vertex indices from nd_connect_list are used to get the corresponding (R, Z) coordinates from rz. The first vertex is appended to close the triangle, and the outline is plotted.

plot_vertices_with_wall()[source]

Plots the mesh vertices as dots and overlays the wall as a closed line in the background. The wall is defined by the grid_wall_nodes variable.

property wall_rz

Return (R, Z) coordinates of wall nodes for this plane.

class xgc_analysis.mesh.plane.TriangulationData(RI, ZI, triObj)[source]

Bases: object

A simple container class to hold interpolation grid data and a Matplotlib Triangulation object.

Attributes:

RI (np.ndarray): 2D array of R coordinates of the interpolation grid. ZI (np.ndarray): 2D array of Z coordinates of the interpolation grid. triObj (Triangulation): A Matplotlib Triangulation object for the mesh.

Module xgc_analysis.mesh.plane_data

class xgc_analysis.mesh.plane_data.PlaneData(plane, data_array=None, n_components=1, dtype=<class 'numpy.float64'>)[source]

Bases: object

Stores field data for a single plane.

For a scalar field, data is a 1D NumPy array of shape (n,). For a vector field, data is a 2D NumPy array of shape (n, n_components), where for each vertex the vector components are stored contiguously in memory.

Attributes:
  • n: number of vertices in this plane.

  • field_type: ‘scalar’ or ‘vector’.

  • n_components: number of components (1 for scalar, 2 or 3 for vector fields).

  • dtype: data type for the array.

  • data: the NumPy array storing the field data.

evaluate_scalar_gradients() → PlaneData[source]

Compute ∇_{R,Z}f and return the result as a new PlaneData instance (two-component vector on the same plane).

Return type:

PlaneData # field_type = ‘vector’

extract_component(component_index)[source]

For vector fields only.

Returns a new PlaneData instance (a scalar field) containing the specified component from the vector.

component_index is zero-based and must be within the vector’s component count. Scalar input raises ValueError.

flux_avg_from_surf(*, fsa: str = 'volume')[source]

Project stored surface values into flux_avg_plane.

fsa selects surface weighting. Return None.

flux_avg_to_from_surf(*, fsa: str = 'volume')[source]

Average data over surfaces and cache its vertex projection.

fsa selects surface weighting. Return None.

flux_avg_to_surf(*, fsa: str = 'volume')[source]

Store the surface average of this field in flux_avg_psi.

fsa selects surface weighting. The method mutates this object and returns None.

flux_avg_to_surf_norm(*, fsa: str = 'volume')[source]

Cache the flux-surface average of this vector field’s norm.

fsa selects surface weighting. Scalar data raise ValueError; the method stores flux_avg_norm_psi and returns None.

get_data()[source]

Return the underlying NumPy array without making a copy.

plot_contour(plane: Plane | None = None, **kwargs)[source]

Convenience wrapper that forwards to Plane.plot_contour using this instance’s data.

plane optionally overrides this object’s plane. kwargs are forwarded to Plane.plot_contour. Return its figure/axes result.

Module xgc_analysis.mesh.plotting

xgc_analysis.mesh.plotting.plot_grid_contour(Z: ndarray, X: ndarray | None = None, Y: ndarray | None = None, *, x_label: str, y_label: str, var_name: str = '', title: str = '', filename: str | None = None, levels: int | ndarray | None = 60, lower: float | None = None, upper: float | None = None, ax=None, render_as_image: bool = False, cmap: str = 'seismic')[source]

Draw a filled contour or image for a two-dimensional mesh array.

Z holds the plotted values; X and Y are plotting coordinates. The caller owns the returned figure. A file is written only when filename is provided. ax embeds the plot in a caller-owned figure; render_as_image uses pixel rendering instead of contours. Color and axis limits, labels, levels, and colormap are passed explicitly.

Returns:

Figure and axes containing the plotted values and color bar.

Return type:

tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]

Module xgc_analysis.data_access.adios.read_bp_file

Standalone ADIOS FileReader-based BP reader.

xgc_analysis.data_access.adios.read_bp_file.ReadBPFile(filename, variables: Sequence[str] | str | None = None, step_range: tuple[int, int] | None = None, *, steps: Iterable[int] | int | None = None, open_timeout_secs=None, step_timeout_secs=None)[source]

Read selected variables and ADIOS steps from a BP file with FileReader.

Parameters:
  • filename (str or pathlib.Path) – ADIOS-readable BP file or BP directory.

  • variables (sequence[str], str, or None, optional) – Variable names to read. If omitted, all variables advertised by the file are read.

  • step_range (tuple[int, int] or None, optional) – Legacy half-open ADIOS step range (start, end). This path clips the requested range to the currently available steps, preserving the old ReadBPFile(..., step_range=(0, huge)) “read all available” behavior.

  • steps (iterable[int], int, or None, optional) – Explicit ADIOS step ids to read. This path is strict: unavailable steps raise IndexError and unavailable variables raise KeyError. If both steps and step_range are omitted, the last available ADIOS step is read.

  • open_timeout_secs – Accepted for compatibility with the previous Stream-based implementation. FileReader is a finite snapshot API and does not use open/step wait timeouts.

  • step_timeout_secs – Accepted for compatibility with the previous Stream-based implementation. FileReader is a finite snapshot API and does not use open/step wait timeouts.

Returns:

Step-major mapping {adios_step: {variable_name: value}}.

Return type:

dict[int, dict[str, object]]

Raises:
  • FileNotFoundError – If filename does not exist.

  • KeyError – If an explicitly requested variable is not available.

  • IndexError – If an explicitly requested ADIOS step is outside the available range.

  • ValueError – If both steps and step_range are supplied.

xgc_analysis.data_access.adios.read_bp_file.read_bp_file(filename, variables: Sequence[str] | str | None = None, steps: Iterable[int] | int | None = None)[source]

Strict standalone BP reader using explicit ADIOS step ids.

Parameters:
  • filename (str or pathlib.Path) – ADIOS-readable BP file or BP directory.

  • variables (sequence[str], str, or None, optional) – Variable names to read. If omitted, all available variables are read.

  • steps (iterable[int], int, or None, optional) – ADIOS step ids to read. If omitted, the last available step is read.

Returns:

Step-major mapping {adios_step: {variable_name: value}}.

Return type:

dict[int, dict[str, object]]

Module xgc_analysis.data_access.products.sheath_data

Sheath diagnostics reader integrated with Simulation mesh data.

class xgc_analysis.data_access.products.sheath_data.SheathData(steps, simulation, sheath_file='xgc.sheathdiag.bp', data_dir='./', catalog=None, missing='raise', source_reader=None)[source]

Bases: BPReaderMixin, ArrayAccessorMixin

Class to handle / construct sheath data utilizing xgc.mesh.bp and xgc.sheathdiag.bp files.

Mesh data are accessed via the Simulation instance (mesh/plane).

xgc.sheathdiag.bp - nwall : Integer representing the number of wall nodes. - sheath_pot : Sheath Potential - sheath_ilost : Sheath Ion Loss - sheath_lost : Sheath Electron Loss - sheath_nphi : Sheath Electron Density

simulation

Simulation instance providing mesh and magnetic field data.

Type:

Simulation

data

Nested dictionary storing time-dependent sheath diagnostics in the common XGC-Analysis layout: self.data[var_name][step_idx] = ndarray.

Type:

dict[str, dict[int, np.ndarray]]

wall_data

Static wall-related geometry/derived arrays: wall_rz, wall_phi, wall_psi.

Type:

dict[str, np.ndarray]

Returns

SheathData: An instance of the SheathData class.

TIME_VARS = ['sheath_pot', 'sheath_ilost', 'sheath_lost', 'sheath_nphi']
get_scalar(var_name: str, step_index: int)[source]

Return var_name at step_index as a scalar numeric value.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

int | float | np.number

get_sheath_array(var_name: str, step_index: int)[source]

Return time-dependent sheath diagnostic var_name as np.ndarray.

Parameters:
  • var_name (str) – Native variable name in the loaded product.

  • step_index (int) – Reader-local ADIOS step or file index (default 0 where optional).

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

get_wall_array(var_name: str) → ndarray[source]

Return a static wall-related array from self.wall_data.

Parameters:

var_name (str) – Native variable name in the loaded product.

Returns:

Loaded value in the product’s native units and indexing.

Return type:

np.ndarray

property wall_phi: array

Return toroidal angle(s) corresponding to wall planes.

Returns:

Toroidal wall-plane angle values in radians.

Return type:

np.ndarray

property wall_psi: array

Returns poloidal magnetic flux (psi) at wall nodes for plane 0.

property wall_rz

Return wall node (R, Z) coordinates for each mesh plane.

Returns:

Wall R/Z coordinates in meters.

Return type:

np.ndarray

Module xgc_analysis.simulation.simulation

class xgc_analysis.simulation.simulation.Simulation(directories=None, is_stellarator=False, sim_is_axisymmetric=False, catalog=None, initialize=True, static_buffer=None)[source]

Bases: object

Run context that composes catalog, mesh, field, species, and velocity grid.

Construction reads the XGC input text and static products through the selected catalog. initialize=False defers the heavy core construction. The caller owns the catalog’s lifetime and should close it after use.

OPTIONAL_STATIC_BUFFER_PRODUCTS = {'xgc.cnv_from_surf.bp', 'xgc.cnv_to_surf.bp', 'xgc.current_drive.bp', 'xgc.f0.mesh.bp', 'xgc.ff_1dp_fwd.bp', 'xgc.ff_1dp_rev.bp', 'xgc.ff_hdp_fwd.bp', 'xgc.ff_hdp_rev.bp', 'xgc.grad_rz.bp'}
REQUIRED_CATALOG_PRODUCTS = ('xgc.mesh.bp', 'xgc.equil.bp', 'xgc.bfield.bp')
REQUIRED_CATALOG_TEXTS = ('input',)
STATIC_BUFFER_REQUESTS = {'xgc.bfield.bp': ('bfield', 'n_n', 'psi'), 'xgc.cnv_from_surf.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value'), 'xgc.cnv_to_surf.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value'), 'xgc.current_drive.bp': ('jpar_bg', 'jpar_bg_fs_avg'), 'xgc.equil.bp': ('bp_sign', 'bt_sign', 'eq_I', 'eq_axis_b', 'eq_axis_r', 'eq_axis_z', 'eq_max_r', 'eq_max_z', 'eq_min_r', 'eq_min_z', 'eq_mpsi', 'eq_mr', 'eq_mz', 'eq_psi_grid', 'eq_psi_rz', 'eq_x_psi', 'eq_x_r', 'eq_x_z'), 'xgc.f0.mesh.bp': ('f0_nmu', 'f0_nvp', 'f0_smu_max', 'f0_vp_max', 'f0_dsmu', 'f0_dvp', 'f0_fg_T_ev', 'f0_T_ev', 'f0_den', 'f0_flow', 'gradpsi', 'nb_curl_nb', 'v_curv', 'v_gradb', 'f0_grid_vol_vonly'), 'xgc.ff_1dp_fwd.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value', 'dl_par'), 'xgc.ff_1dp_rev.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value', 'dl_par'), 'xgc.ff_hdp_fwd.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value', 'dl_par'), 'xgc.ff_hdp_rev.bp': ('ncols', 'nrows', 'width', 'nelement', 'eindex', 'value', 'dl_par'), 'xgc.grad_rz.bp': ('basis', 'n_r', 'm_r', 'w_r', 'nelement_r', 'eindex_r', 'value_r', 'n_z', 'm_z', 'w_z', 'nelement_z', 'eindex_z', 'value_z'), 'xgc.mesh.bp': ('delta_phi', 'wedge_angle', 'n_n', 'n_t', 'nsurf', 'surf_maxlen', 'grid_nwall', 'rz', 'nd_connect_list', 'grid_wall_nodes', 'tr_area', 'node_vol', 'node_vol_nearest', 'theta', 'region', 'surf_len', 'surf_idx', 'rmin', 'rmaj', 'epsilon', 'm_max_surf', 'psi_surf', 'qsafety', 'trapped'), 'xgc.volumes.bp': ('diag_1d_vol',)}
convert_fortran_value(val)[source]

Convert one namelist token to bool or float, retaining strings otherwise.

Module xgc_analysis.analysis.divertor.wall_loss_rates

Compute SOL wall-loss source rates on the 1D flux-surface grid.

class xgc_analysis.analysis.divertor.wall_loss_rates.SOLWallLossRatesResult(lower_surface: ndarray, upper_surface: ndarray, psi_lower: ndarray, psi_upper: ndarray, psi_center: ndarray, psi_center_norm: ndarray, volume_shell: ndarray, segment_to_bin: ndarray, time_left: ndarray, time_right: ndarray, dt: ndarray, interval_mask_used: ndarray, particle_rate_e: ndarray, particle_rate_i: ndarray, energy_rate_e: ndarray, energy_rate_i: ndarray, particle_rate_e_avg: ndarray, particle_rate_i_avg: ndarray, energy_rate_e_avg: ndarray, energy_rate_i_avg: ndarray)[source]

Bases: object

Wall-loss source rates mapped to adjacent SOL surface-pair volumes.

dt: ndarray
energy_rate_e: ndarray
energy_rate_e_avg: ndarray
energy_rate_i: ndarray
energy_rate_i_avg: ndarray
interval_mask_used: ndarray
lower_surface: ndarray
particle_rate_e: ndarray
particle_rate_e_avg: ndarray
particle_rate_i: ndarray
particle_rate_i_avg: ndarray
psi_center: ndarray
psi_center_norm: ndarray
psi_lower: ndarray
psi_upper: ndarray
segment_to_bin: ndarray
time_left: ndarray
time_right: ndarray
upper_surface: ndarray
volume_shell: ndarray
xgc_analysis.analysis.divertor.wall_loss_rates.compute_sol_wall_loss_rates(plane, heatdiag, *, phi_index: int = 0, psi_norm_min: float = 1.0, psi_norm_max: float | None = None, interval_sample: str = 'right', time_window: tuple[float, float] | None = None) → SOLWallLossRatesResult[source]

Compute SOL wall-loss source rates on adjacent-surface shell volumes.

Parameters:
  • plane (Plane) – Plane object with surf_map, psi_surf, x_psi, vol_1d and wall data.

  • heatdiag (HeatDiag) – HeatDiag reader with wall polygon and time-dependent wall loads.

  • phi_index (int) – Toroidal index for selecting one heatdiag wall curve.

  • psi_norm_min (float) – Lower normalized-psi cutoff for SOL pairing (default: 1.0).

  • psi_norm_max (float | None) – Optional upper normalized-psi cutoff for SOL pairing.

  • interval_sample (str) – Which time sample to use for interval-accumulated wall loads: "right" uses sample k+1 for [k,k+1], "left" uses sample k.

  • time_window (tuple[float, float] | None) – Optional averaging window [t0, t1] in seconds. If provided, only heatdiag intervals overlapping this window contribute to time averages.

Returns:

Per-interval volumetric particle/energy loss rates [m^-3 s^-1, W m^-3] for electrons and ions, and their dt-weighted averages.

Return type:

SOLWallLossRatesResult

xgc_analysis.analysis.divertor.wall_loss_rates.interpolate_wall_loss_rates_to_surf_map(plane, result: SOLWallLossRatesResult, *, use_time_average: bool = True) → dict[str, ndarray][source]

Interpolate SOL wall-loss rates from bin centers to plane.surf_map psi grid.

Core surfaces (psi/psi_x < 1) are set to zero.

Returns:

Keys particle_e, particle_i, energy_e, energy_i. If use_time_average=True, each value has shape (npsi,). Otherwise each value has shape (n_time_intervals, npsi).

Return type:

dict[str, np.ndarray]

Module xgc_analysis.mesh.sol_wall_mapping

Map SOL flux-surface pairs to wall arclength intervals.

class xgc_analysis.mesh.sol_wall_mapping.SOLVolumeWallBounds(lower_surface: int, upper_surface: int, psi_lower: float, psi_upper: float, lower_wall_nodes: tuple[int, int], upper_wall_nodes: tuple[int, int], intervals: tuple[tuple[float, float, bool], tuple[float, float, bool]])[source]

Bases: object

Wall-boundary information for one adjacent SOL surface pair.

intervals: tuple[tuple[float, float, bool], tuple[float, float, bool]]
lower_surface: int
lower_wall_nodes: tuple[int, int]
psi_lower: float
psi_upper: float
upper_surface: int
upper_wall_nodes: tuple[int, int]
class xgc_analysis.mesh.sol_wall_mapping.SOLWallVolumeMap(plane, wall_curve: WallCurve)[source]

Bases: object

Identify wall ranges that bound volumes between adjacent SOL surfaces.

build_from_surf_map(*, psi_norm_min: float = 1.0, psi_norm_max: float | None = None) → list[SOLVolumeWallBounds][source]

Build adjacent-surface wall bounds from plane.surf_map.

Parameters:
  • psi_norm_min (float) – Minimum normalized psi for surfaces to include (default: SOL only, >=1).

  • psi_norm_max (float | None) – Optional maximum normalized psi cutoff (e.g., diff_bd_out).

Module xgc_analysis.species.species

class xgc_analysis.species.species.Species(sim, index)[source]

Bases: object

One XGC species and its input-defined radial functions.

initial_profiles retains the existing file-profile API. prescribed_profiles describes all input-defined radial functions, including analytic choices and particle source rates. Heat/torque deposition weights are stored separately in deposition_shapes. Mass and charge are retained in both XGC input units and SI units.

evaluate_input_profile(name: str, psi_n: ndarray) → ndarray[source]

Evaluate one input-defined raw radial function before XGC damping.

Parameters:
  • name (str) – Key in prescribed_profiles.

  • psi_n (array_like) – Normalized poloidal flux at the query locations.

Returns:

Input-defined values in the profile’s declared units.

Return type:

ndarray

Notes

XGC applies edge/private-flux decay and region-dependent behavior in Eq::Profile::value using the magnetic equilibrium and R/Z point. This method deliberately evaluates only the radial shape. For an electron particle source, XGC derives the applied increment from ion charge balance rather than directly applying this input profile.

evaluate_xgc_profile(name: str, psi_n, *, region: str, xpoint_psi_n=None, upper_xpoint_psi_n=None)[source]

Evaluate an input profile with XGC’s region-dependent decay.

Parameters:
  • name (str) – Key in prescribed_profiles.

  • psi_n (array_like) – Normalized poloidal flux.

  • region ({'core_edge', 'private_lower', 'private_upper'}) – Region already classified from the magnetic equilibrium and R/Z.

  • xpoint_psi_n (float or None, optional) – Lower X-point flux divided by the run’s psi normalization. Required for the lower private-flux region; this need not be 1 for a 3D equilibrium.

  • upper_xpoint_psi_n (float or None, optional) – Required for an upper private-flux region.

Returns:

Profile values with XGC’s configured exponential decay.

Return type:

ndarray

Notes

For a quasineutrality responder, XGC constructs the density from the other species; this method cannot reconstruct it from one species’ input parameters. Runtime region selection and particle-source masks also require the caller’s geometry context.

interpolate_profile(name: str, psi_new: ndarray, *, fill: str | float | None = 'edge') → ndarray[source]

Interpolate one of this species’ initial profiles onto a new ψ grid.

Parameters:
  • name (str) – Profile key in self.initial_profiles (“density”, “temperature”, “flow”, …).

  • psi_new (ndarray) – Target ψ‑grid (1‑D NumPy array).

  • fill ({"edge", None, float}, default "edge") –

    How to handle ψ outside the original range:
    • ”edge” – use nearest edge value (default)

    • None – raise ValueError if extrapolation needed

    • float – fill with that scalar

Returns:

Interpolated profile values at psi_new.

Return type:

ndarray

xgc_analysis.species.species.build_run_prescribed_profiles(sim) → dict[source]

Build active run-wide profiles that are not owned by one species.

Parameters:

sim (xgc_analysis.simulation.Simulation) – Simulation with parsed input and a catalog of input text artifacts.

Returns:

Currently contains radiation effective_charge only when rad_use_zeff_profile is enabled.

Return type:

dict[str, PrescribedProfile]

Module xgc_analysis.species.prescribed_profiles

Input-defined XGC species profiles and heat/torque deposition shapes.

The analytic formulas follow XGC_core/cpp/plasma/profile.hpp. File shapes follow profile_setup.F90: a not-a-knot spline is sampled on 1000 equally spaced flux points and those samples are linearly interpolated at query points. Values here are the prescribed radial functions before XGC’s spatial-region selection, edge/private-flux decay, and source normalization.

class xgc_analysis.species.prescribed_profiles.DepositionShape(region: int, pin: float, pout: float, decay_width: float, shape: int, special_mode: int, r_begin: float, z_begin: float, radius: float)[source]

Bases: object

Unnormalized heat/torque deposition weight for one source region.

The spatial weight is separate from whole-torus power (W), torque (N m), volume normalization, and source timing. Special mode 1 includes a -Z distance factor in metres; it is not a dimensionless weight. Runtime region and wall masks used by XGC are not available from a one-dimensional input shape and are deliberately excluded here.

evaluate_weight(psi_n, *, r=None, z=None)[source]

Evaluate XGC’s input-defined deposition weight.

Parameters:
  • psi_n (array_like) – Normalized poloidal flux at the query points.

  • r (array_like or None, optional) – Cylindrical coordinates in metres, required for special modes 2 and 1 respectively.

  • z (array_like or None, optional) – Cylindrical coordinates in metres, required for special modes 2 and 1 respectively.

Returns:

Spatial weighting factor before source amplitude and volume normalization. Runtime region/wall masks remain the caller’s job.

Return type:

ndarray

class xgc_analysis.species.prescribed_profiles.PrescribedProfile(name: str, shape: int, x: tuple[float, float, float, float, float], v: tuple[float, float, float, float], unit: str, source: str, psi_n: ndarray | None = None, values: ndarray | None = None, unavailable_reason: str | None = None)[source]

Bases: object

One per-species or run-wide XGC Eq::Profile input definition.

x contains normalized poloidal-flux coordinates; v contains values in unit. evaluate_raw returns the shape before XGC applies edge/private-flux decay or other geometry-dependent adjustments.

evaluate_raw(psi_n)[source]

Evaluate the XGC radial formula at normalized poloidal flux.

Parameters:

psi_n (array_like) – Normalized poloidal flux, including possible edge/SOL points.

Returns:

Input-defined profile values in unit; no region decay is applied. File shapes use XGC’s spline-then-linear interpolation.

Return type:

ndarray

Raises:
  • ValueError – If the selected analytic shape has unusable parameters.

  • FileNotFoundError – If the selected file shape has no catalog text artifact.

evaluate_with_region(psi_n, *, region: str, outpsi_n: float = 1.05, outer_factor: float = 0.1, outer_width_n: float = 0.03, xpoint_psi_n: float = 1.0, private_factor: float = 0.05, private_width_n: float = 0.015, upper_xpoint_psi_n: float | None = None)[source]

Apply XGC’s profile decay for an explicitly identified region.

Parameters:
  • psi_n (array_like) – Normalized poloidal flux.

  • region ({'core_edge', 'private_lower', 'private_upper'}) – Region classification supplied by the caller. XGC determines this from R/Z and the magnetic equilibrium; psi alone is insufficient.

  • outpsi_n (float, optional) – sml_outpsi and eq_out_decay_* values in normalized psi.

  • outer_factor (float, optional) – sml_outpsi and eq_out_decay_* values in normalized psi.

  • outer_width_n (float, optional) – sml_outpsi and eq_out_decay_* values in normalized psi.

  • xpoint_psi_n (float, optional) – Lower X-point normalized flux and eq_priv_flux_decay_* values.

  • private_factor (float, optional) – Lower X-point normalized flux and eq_priv_flux_decay_* values.

  • private_width_n (float, optional) – Lower X-point normalized flux and eq_priv_flux_decay_* values.

  • upper_xpoint_psi_n (float or None, optional) – Upper X-point normalized flux; required for private_upper.

Returns:

Profile values with the same edge/private exponential decay as Eq::Profile::value in the caller-designated region.

Return type:

ndarray

xgc_analysis.species.prescribed_profiles.build_deposition_shapes(src_params: Mapping, index: int) → dict[int, DepositionShape][source]

Read one species’ active heat/torque region weights from src_param.

Parameters:
  • src_params (mapping) – Parsed src_param namelist.

  • index (int) – Zero-based species index.

Returns:

One-based active region number to unnormalized shape definition.

Return type:

dict[int, DepositionShape]

xgc_analysis.species.prescribed_profiles.build_prescribed_profile(*, params: Mapping, prefix: str, name: str, unit: str, index: int, defaults_x: tuple[float, float, float] = (0.0, 0.0, 0.0), defaults_v: tuple[float, float, float] = (0.0, 0.0, 0.0), inherited: PrescribedProfile | None = None, read_file: Callable[[str], tuple[ndarray, ndarray]] | None = None, default_file: str = 'example.dat', source_override: str | None = None) → PrescribedProfile[source]

Build a profile definition from XGC’s per-species namelist defaults.

Parameters:
  • params (mapping) – One parsed XGC namelist, usually eq_param or src_param.

  • prefix (str) – Input key stem, for example eq_temp.

  • name (str) – Public quantity name attached to Species.prescribed_profiles.

  • unit (str) – Units of the raw input-defined function.

  • index (int) – Zero-based species index.

  • defaults_x (tuple[float, float, float]) – XGC source-code defaults for the first three coordinate/value inputs.

  • defaults_v (tuple[float, float, float]) – XGC source-code defaults for the first three coordinate/value inputs.

  • inherited (PrescribedProfile or None) – Base temperature/flow definition inherited by fg/mk profiles.

  • read_file (callable or None) – Catalog text resolver returning normalized psi and values.

  • default_file (str) – XGC source-code fallback filename for file shapes.

  • source_override (str or None) – Catalog package/group name when a file shape comes from ADIOS input.

Returns:

Shape definition; a missing file is reported when evaluated.

Return type:

PrescribedProfile

xgc_analysis.species.prescribed_profiles.indexed_value(params: Mapping, key: str, index: int, default)[source]

Read one zero-based per-species namelist entry with its XGC default.

Parameters:
  • params (mapping) – Parsed eq_param or src_param values.

  • key (str) – Per-species input name.

  • index (int) – Zero-based species index.

  • default (object) – Value used only when the input key is absent.

Returns:

Selected value or default. A scalar input belongs to index 0.

Return type:

object

Raises:

ValueError – If a present per-species input has no entry for this species, as in XGC’s NamelistReader::get.

xgc_analysis.species.prescribed_profiles.read_input_package_profile(catalog, product_key: str, group: str) → tuple[ndarray, ndarray][source]

Read one XGC equilibrium profile group from a cataloged ADIOS package.

Parameters:
  • catalog (SimulationCatalog) – Catalog with the input package registered as a static BP product.

  • product_key (str) – Catalog key for sml_input_package_file.

  • group (str) – XGC package group such as /profiles/density/species0.

Returns:

Normalized poloidal flux and profile values from the package.

Return type:

tuple[ndarray, ndarray]

Raises:
  • FileNotFoundError – If the package is absent from the catalog.

  • ValueError – If the package group is incomplete.

xgc_analysis.species.prescribed_profiles.read_profile_text(text: str) → tuple[ndarray, ndarray][source]

Read XGC’s count/psi-value/-1 profile text without reordering points.

Parameters:

text (str) – Catalog text artifact in XGC’s one-dimensional profile format.

Returns:

Normalized poloidal flux and corresponding profile values.

Return type:

tuple[ndarray, ndarray]

Module xgc_analysis.time_step_utils

Utilities for handling diagnostic time-step sequences with overlaps.

xgc_analysis.time_step_utils.build_last_occurrence_step_mask(step_values) → ndarray[source]

Return indices that sort by step value and keep the last duplicate occurrence.

This is useful for diagnostics that may contain overlapping sections in time.

Parameters:

step_values (array-like) – 1D or broadcastable array of step indices / timestamps.

Returns:

Integer indices into the original sequence, ordered by increasing step value, with duplicate step values reduced to their last occurrence.

Return type:

np.ndarray

xgc_analysis.time_step_utils.select_interval_sample_indices(time_values, *, time_window=None, selected_frame_index: int | None = None) → ndarray[source]

Return deduplicated sample indices needed for one interval selection.

Parameters:
  • time_values (array-like) – Monotonic or mostly monotonic per-sample physical times after any duplicate-step reduction. The values correspond to sample endpoints; intervals are formed between adjacent entries.

  • time_window (tuple[float, float] or None, optional) – Optional physical-time window. Intervals overlapping the window are selected. If omitted, selected_frame_index chooses one interval.

  • selected_frame_index (int or None, optional) – GUI-style frame index into the deduplicated sample sequence. Frame 0 is promoted to the first valid interval because interval rates require a previous sample.

Returns:

Integer indices into time_values containing the minimal contiguous sample subset needed for the selected interval range.

Return type:

np.ndarray

Module xgc_analysis.utils.file_waiter

class xgc_analysis.utils.file_waiter.FileWaiter(required_files: Sequence[str | Path], run_dir: str | Path, poll_interval: float = 5.0, grace_period: float = 3.0, timeout: float | None = 600.0)[source]

Bases: object

Block execution until all files in required_files exist inside run_dir.

Parameters:
  • required_files – Relative paths (strings or pathlib.Path) that must appear inside run_dir.

  • run_dir – Directory expected to contain the files.

  • poll_interval – Delay in seconds between successive checks (default 5.0).

  • grace_period – Maximum time in seconds to wait before raising TimeoutError. None (default) means “wait forever”.

Notes

Prints a short status line on every poll. Switch to the missing_files() method if you want to plug this into a custom logging setup.

missing_files() → list[str][source]

Return a list of relative paths that are still absent.

wait() → None[source]

Block until all files are present (plus grace_period) or until timeout elapses.

xgc_analysis.utils.file_waiter.wait_for_files(run_dir: str | Path, required_files: Sequence[str | Path], poll_interval: float = 5.0, grace_period: float = 3.0, timeout: float | None = 600.0) → None[source]

Convenience wrapper around FileWaiter.

Examples

>>> wait_for_files("/scratch/run42",
...               ["xgc.mesh.bp", "input"],
...               poll_interval=1.0,
...               grace_period=0.0)         # proceed immediately once ready

Module xgc_analysis.simulation.velocity_grid

class xgc_analysis.simulation.velocity_grid.VelocityGrid(work_dir='.', filename='xgc.f0.mesh.bp', catalog=None, source_reader=None, static_buffer=None)[source]

Bases: object

Velocity-space grid metadata for XGC distribution functions.

The XGC f0 mesh file stores a cylindrical velocity grid in (v_perp, v_parallel) normalized to a reference thermal speed, with the gyrophase angle removed. XGC distribution data on this grid already includes the factor v_perp from the cylindrical Jacobian.

OPTIONAL_VARIABLES = ('gradpsi', 'nb_curl_nb', 'v_curv', 'v_gradb', 'f0_grid_vol_vonly')
REQUIRED_VARIABLES = ('f0_nmu', 'f0_nvp', 'f0_smu_max', 'f0_vp_max', 'f0_dsmu', 'f0_dvp', 'f0_fg_T_ev', 'f0_T_ev', 'f0_den', 'f0_flow')
integrate_over_velocity(values, *, axis_mu=-3, axis_vp=-1, node_axis=None, data_includes_vperp=True, include_gyroangle=True, apply_grid_vol_vonly=False, species_index=None)[source]

Integrate an array over (v_perp, v_parallel) in normalized coordinates.

Parameters:
  • values (np.ndarray) – Array containing velocity-grid data.

  • axis_mu (int) – Indices of the v_perp and v_parallel axes in values.

  • axis_vp (int) – Indices of the v_perp and v_parallel axes in values.

  • node_axis (int | None) – Index of the configuration-space node axis in values. Required when apply_grid_vol_vonly=True.

  • data_includes_vperp (bool) – True for XGC distribution data (*_f), which already includes the v_perp Jacobian factor.

  • include_gyroangle (bool) – Multiply by 2*pi if the gyrophase angle has been integrated out.

  • apply_grid_vol_vonly (bool) – If True, multiply by species/node-dependent f0_grid_vol_vonly before integrating over velocity.

  • species_index (int | None) – Species index into f0_grid_vol_vonly. Required when apply_grid_vol_vonly=True and multiple species are present.

integration_weights_2d(*, data_includes_vperp=True, include_gyroangle=True)[source]

2D velocity-space integration weights in normalized coordinates.

Returns weights for arrays shaped (..., n_mu, ..., n_vp) after axes are aligned, with optional 2*pi gyrophase factor.

mu_edge_factors()[source]

Return trapezoidal endpoint factors for the perpendicular velocity grid.

mu_integration_weights(*, data_includes_vperp=True)[source]

1D weights for the v_perp axis (normalized units).

If data_includes_vperp=True (XGC default), only trapezoidal weights and dsmu are applied because the stored values already carry the cylindrical Jacobian factor v_perp.

property shape

(n_mu, n_vp).

Type:

Velocity-grid point shape in XGC storage order

vp_edge_factors()[source]

Return trapezoidal endpoint factors for the parallel velocity grid.

vp_integration_weights()[source]

1D trapezoidal weights for the v_parallel axis (normalized units).

Module xgc_analysis.mesh.wall_curve

Wall-polygon arclength utilities.

class xgc_analysis.mesh.wall_curve.WallCurve(points_rz: ndarray, *, verify_clockwise: bool = True, auto_reverse: bool = False)[source]

Bases: object

Closed wall polygon with arclength coordinate.

Parameters:
  • points_rz (np.ndarray) – Wall vertices as shape (n, 2) in clockwise order. The first vertex should not be repeated at the end.

  • verify_clockwise (bool) – Validate clockwise orientation and raise ValueError if violated.

  • auto_reverse (bool) – If True and orientation is counter-clockwise, reverse order instead of raising.

circular_distance(s1: float, s2: float) → float[source]

Return the shortest wall arclength distance between s1 and s2.

Coordinates are in meters and wrap around the closed wall curve.

find_z0_crossings(*, z_tol: float = 1e-10) → list[ZeroCrossing][source]

Find intersections of the closed curve with Z=0.

property n_vertices: int

Number of wall vertices.

property points: ndarray

Wall vertices (R,Z) in the stored order.

property s_vertex: ndarray

Arclength at each vertex (origin-shifted, modulo total length).

set_origin_at_inboard_midplane(r_axis: float, *, z_tol: float = 1e-10) → float[source]

Set s=0 at the intersection with Z=0 and R<R_axis.

Returns:

The selected crossing arclength in the original coordinate.

Return type:

float

shortest_interval(s1: float, s2: float) → tuple[float, float, bool][source]

Return shortest directed interval from s1 to s2.

s1 and s2 are wall arclength coordinates in meters; both are reduced modulo total wall length.

Returns:

Interval on [0,L) where wraps=True means it crosses L->0.

Return type:

(s_start, s_end, wraps)

property total_length: float

Total closed-curve length.

class xgc_analysis.mesh.wall_curve.ZeroCrossing(s: float, r: float, segment_index: int)[source]

Bases: object

A crossing of the line Z=0 by the wall curve.

r: float
s: float
segment_index: int

Module contents

Readers and scientific analysis routines for XGC output.

Submodules are loaded when requested so importing the package itself does not initialize ADIOS2 or other optional runtime components.

Stage 5 analysis modules

The domain guide is Reusable analysis workflows. Additional public modules are listed below.

Reusable midplane geometry for divertor and radial transport analyses.

xgc_analysis.analysis.geometry.finite_pair_count(x: ndarray, y: ndarray) → int[source]

Count positions with finite values in both x and y arrays.

The arrays must broadcast to the same comparison shape; return that finite-pair count as an integer.

xgc_analysis.analysis.geometry.interp_radius_at_psi(psi_mid: ndarray, r_mid: ndarray, psi_value: float, branch: str) → float[source]

Return midplane radius in metres at one normalized-flux value.

psi_mid and r_mid are one branch from midplane_radius_maps(); branch labels errors. Duplicate flux points are averaged. A map with fewer than two finite pairs, or a query outside its bounds, raises ValueError.

xgc_analysis.analysis.geometry.interp_radius_map(psi_mid: ndarray, r_mid: ndarray, psi_query: ndarray, branch: str) → ndarray[source]

Interpolate midplane radii at normalized-flux query points.

psi_mid and r_mid are one branch from midplane_radius_maps(); branch labels error messages. Duplicate flux points are averaged. Query points outside the finite map return NaN. The output is in metres. A map with fewer than two finite pairs raises ValueError.

xgc_analysis.analysis.geometry.midplane_radius_maps(plane) → tuple[ndarray, ndarray, ndarray][source]

Build psi_N -> R_midplane maps for outer and inner midplanes.

For each Plane flux surface, this linearly interpolates exact intersections with Z=0. Surfaces that do not cross the outboard or inboard midplane keep NaN for that branch. The result is sorted by normalized flux and later used to map target-wall psi_N to upstream/midplane radial distance from the separatrix.

Parameters:

plane (Plane) – Poloidal mesh with flux surfaces, (R, Z) coordinates, magnetic axis radius, and X-point flux.

Returns:

Sorted normalized poloidal flux, outer midplane radius, and inner midplane radius. Radii are in metres; missing crossings are NaN.

Return type:

tuple[ndarray, ndarray, ndarray]

Figures for reusable divertor profile, width, total, and load-map results.

xgc_analysis.analysis.divertor.plots.plot_divertor_eich_profiles(profiles: list[DivertorEichProfile], *, show_particle: bool = True, show_energy: bool = True, show_ions: bool = True, show_electrons: bool = True, show_total: bool = True, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None)[source]

Plot divertor particle/energy profiles with optional Eich fit overlays.

Parameters:
  • profiles (list[DivertorEichProfile]) – Profiles returned by compute_divertor_eich_profiles().

  • show_particle (bool) – Select which physical channels are shown. At least one must be enabled.

  • show_energy (bool) – Select which physical channels are shown. At least one must be enabled.

  • show_ions (bool) – Select species/component curves. Eich fits are only overlaid for total profiles.

  • show_electrons (bool) – Select species/component curves. Eich fits are only overlaid for total profiles.

  • show_total (bool) – Select species/component curves. Eich fits are only overlaid for total profiles.

  • xlim (tuple[float, float] | None) – Optional display limits. xlim is in millimeters. ylim applies to whichever axes are displayed.

  • ylim (tuple[float, float] | None) – Optional display limits. xlim is in millimeters. ylim applies to whichever axes are displayed.

Returns:

Figure owned by the caller. GUI code can save it to PNG; scripts can display or further customize it.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.divertor.plots.plot_divertor_lambda_q_timeseries(points: list[DivertorLambdaQPoint], *, scalings: DivertorWidthScalings | None = None, ylim: tuple[float, float] | None = None, show_lines: bool = True, show_symbols: bool = False, show_eich_uncertainty: bool = False, show_chang_uncertainty: bool = False)[source]

Plot total-energy Eich lambda_q values versus heatdiag time.

Parameters:
  • points (list[DivertorLambdaQPoint]) – Points returned by compute_divertor_lambda_q_timeseries().

  • scalings (DivertorWidthScalings | None) – Optional static upstream-midplane scaling estimates from Simulation.

  • ylim (tuple[float, float] | None) – Optional vertical axis limits in millimeters.

  • show_lines (bool) – Select line, symbol-only, or line-plus-symbol display style.

  • show_symbols (bool) – Select line, symbol-only, or line-plus-symbol display style.

  • show_eich_uncertainty (bool) – Shade the published Eich parameter bounds and Chang fit RMS range.

  • show_chang_uncertainty (bool) – Shade the published Eich parameter bounds and Chang fit RMS range.

Returns:

Figure owned by the caller. GUI code can save it to PNG.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.divertor.plots.plot_divertor_load_map(load_map: DivertorLoadMap, *, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, clim: tuple[float, float] | None = None, contour_count: int = 256, cmap: str = 'seismic')[source]

Plot a mapped divertor load map as filled contours without contour lines.

Parameters:
  • load_map (DivertorLoadMap) – Map returned by compute_divertor_load_map().

  • xlim (tuple[float, float] | None) – Optional display ranges. xlim is in millimeters. ylim is in milliseconds for the time view and degrees for the toroidal view.

  • ylim (tuple[float, float] | None) – Optional display ranges. xlim is in millimeters. ylim is in milliseconds for the time view and degrees for the toroidal view.

  • clim (tuple[float, float] | None) – Optional color scale in displayed units. Energy maps are displayed in MW m^-2; particle maps are displayed in ptl m^-2 s^-1.

  • contour_count (int) – Number of filled contour levels. Values below two are promoted to two.

  • cmap (str) – Matplotlib colormap name. The default is "seismic".

Returns:

Figure owned by the caller. GUI code can save it to PNG.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.divertor.plots.plot_divertor_target_totals_timeseries(points: list[DivertorTargetTotalsPoint], *, show_particle: bool = True, show_power: bool = True, show_outer: bool = True, show_inner: bool = True, show_total: bool = True, show_control: bool = True, show_ions: bool = True, show_electrons: bool = True, show_target_total: bool = True, xlim_ms: tuple[float, float] | None = None, particle_ylim: tuple[float, float] | None = None, power_ylim_mw: tuple[float, float] | None = None)[source]

Plot integrated target particle flux and power versus heatdiag time.

Parameters:
  • points (list[DivertorTargetTotalsPoint]) – Points returned by compute_divertor_target_totals_timeseries().

  • show_particle (bool) – Select particle-flux and power panels.

  • show_power (bool) – Select particle-flux and power panels.

  • show_outer (bool) – Select target/control trace groups. Total is the inner-plus-outer divertor sum, while Control is the full-wall control quantity after excluding the heatdiag garbage bin.

  • show_inner (bool) – Select target/control trace groups. Total is the inner-plus-outer divertor sum, while Control is the full-wall control quantity after excluding the heatdiag garbage bin.

  • show_total (bool) – Select target/control trace groups. Total is the inner-plus-outer divertor sum, while Control is the full-wall control quantity after excluding the heatdiag garbage bin.

  • show_control (bool) – Select target/control trace groups. Total is the inner-plus-outer divertor sum, while Control is the full-wall control quantity after excluding the heatdiag garbage bin.

  • show_ions (bool) – Select ion, electron, and ion-plus-electron component lines for the inner and outer target groups.

  • show_electrons (bool) – Select ion, electron, and ion-plus-electron component lines for the inner and outer target groups.

  • show_target_total (bool) – Select ion, electron, and ion-plus-electron component lines for the inner and outer target groups.

  • xlim_ms (tuple[float, float] | None) – Optional horizontal axis range in milliseconds.

  • particle_ylim (tuple[float, float] | None) – Optional particle-flux vertical range in particles per second.

  • power_ylim_mw (tuple[float, float] | None) – Optional power vertical range in megawatts.

Returns:

Figure owned by the caller. GUI code can save it to PNG.

Return type:

matplotlib.figure.Figure

Flux-surface neoclassical transport comparison for an XGC Simulation.

The analytical curves follow the active Hinton–Hazeltine, Chang–Hinton and Sauter terms in IDL_stuff/{neo_flux,bootstrap_formulas}.pro. In particular, the Sauter bootstrap term contains pressure and temperature gradients only; the loop-voltage-driven Ohmic term is calculated separately. The XGC curves use the nonadiabatic magnetic-drift and ExB moment channels, as in the IDL diagnostic. Resolved f3d profiles are toroidally averaged first; its axisymmetric _n0_df transport channels correspond to the f2d _df channels. Turbulent _turb_df transport is excluded from this comparison. The local formulas are evaluated on closed surfaces with psi_N < 1 and should be interpreted cautiously in a steep pedestal.

class xgc_analysis.analysis.transport.neoclassical.NeoResult(profiles: dict[str, ndarray], gstep_range: tuple[int, int], time_range_s: tuple[float, float], sample_count: int, source: str, smoothing_sigma_surfaces: float = 0.0, denominator_smoothing_sigma_surfaces: float = 0.0, current_drive: bool = False, fsa: str = 'volume')[source]

Bases: object

Time-averaged XGC and model profiles on the outer-midplane grid.

profiles

Named radial profiles; units and descriptions are in PROFILE_INFO.

Type:

dict[str, ndarray]

gstep_range, time_range_s

Inclusive diagnostic gsteps and physics-time extent in seconds.

Type:

tuple

sample_count

Number of moment samples in the average.

Type:

int

source

F2D or F3D product used for the measured moments.

Type:

str

smoothing_sigma_surfaces, denominator_smoothing_sigma_surfaces

Gaussian widths in surface-index units.

Type:

float

current_drive

Whether loop-voltage contributions were requested.

Type:

bool

fsa

Surface-averaging convention, volume or line.

Type:

str

xgc_analysis.analysis.transport.neoclassical.compute_neoclassical_transport(simulation, *, gstep_window: tuple[int, int] | None = None, time_window_ms: tuple[float, float] | None = None, selected_frame_index: int | None = None, smoothing_sigma: float = 2.0, denominator_smoothing_sigma: float | None = None, current_drive: bool = False, moment_product: str = 'xgc.f2d.bp', fsa: str = 'volume', check_cancel: Callable[[], None] | None = None) → NeoResult[source]

Compute XGC and analytical neoclassical profiles for a Simulation.

Windows are inclusive. With no window, the last 100 moment samples up to the selected frame are used. moment_product may be xgc.f2d.bp or xgc.f3d.bp; resolved f3d moments are averaged over toroidal planes. Gaussian sigmas are in surface-index units; zero disables smoothing. The denominator_smoothing_sigma controls density and temperature profiles independently before coefficient gradients. The current IDL coefficient set applies to one singly charged ion species and electrons; their masses and charges are taken from Simulation.species. Analytical profiles are NaN at and beyond the separatrix.

Parameters:
  • simulation (Simulation) – Initialized run with mesh, equilibrium, species, and diagnostic catalog.

  • gstep_window (tuple, optional) – Inclusive averaging limits in gsteps and milliseconds.

  • time_window_ms (tuple, optional) – Inclusive averaging limits in gsteps and milliseconds.

  • selected_frame_index (int, optional) – Last eligible moment frame when no window is supplied.

  • smoothing_sigma (float, optional) – Gaussian widths in surface indices; the latter applies separately to density and temperature before coefficient gradients are taken.

  • denominator_smoothing_sigma (float, optional) – Gaussian widths in surface indices; the latter applies separately to density and temperature before coefficient gradients are taken.

  • current_drive (bool, optional) – Include a loop-voltage Ohmic estimate when loop-voltage data exist.

  • moment_product (str, optional) – xgc.f2d.bp or xgc.f3d.bp axisymmetric moment channels.

  • fsa (str, optional) – volume or line flux-surface averaging weights.

  • check_cancel (callable, optional) – Callback invoked during long calculations to permit cancellation.

Returns:

XGC and analytical surface profiles with averaging provenance.

Return type:

NeoResult

Plot and explicitly save neoclassical transport comparisons.

xgc_analysis.analysis.transport.neoclassical_plots.plot_neoclassical_transport(result: NeoResult, quantity: str, *, xlim=None, ylim=None, show_uncertainty: bool = True, uncertainty_sigma: float = 1.0)[source]

Plot XGC and analytical curves with optional temporal-spread bands.

The band is the selected multiple of the standard deviation across time samples, as in the IDL plots. It is not a standard error or a confidence interval for the time-averaged value. The bootstrap band covers variation in XGC current only, not uncertainty in the modeled Ohmic subtraction.

Parameters:
  • result (NeoResult) – Computed transport comparison.

  • quantity (str) – One key from the plotted transport quantities.

  • xlim (pair, optional) – Axis bounds; None leaves Matplotlib autoscaling in effect.

  • ylim (pair, optional) – Axis bounds; None leaves Matplotlib autoscaling in effect.

  • show_uncertainty (bool) – Whether to shade temporal spread of the XGC curve.

  • uncertainty_sigma (float) – Number of temporal standard deviations in the shaded band.

Returns:

Figure ready for display or SVG export.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.transport.neoclassical_plots.save_neoclassical_svg_plots(result: NeoResult, directory: str | Path, *, quantities=None, show_uncertainty: bool = True, uncertainty_sigma: float = 1.0) → list[Path][source]

Write selected comparison plots as standalone SVG files.

Parameters:
  • result – Previously computed analysis result.

  • directory – Directory where SVG files are written.

  • quantities – Optional subset of plot quantity names; all are used by default.

  • show_uncertainty – Shade the temporal spread when plotting.

  • uncertainty_sigma – Width of the shaded band in standard deviations.

Returns:

paths of written SVG plots.

Return type:

list[Path]

Optional file output and standalone neoclassical analysis workflow.

xgc_analysis.analysis.transport.neoclassical_workflow.run_neoclassical_transport(simulation, *, output_bp: str | Path | None = None, plot_directory: str | Path | None = None, plot_quantities=None, show_uncertainty: bool = True, uncertainty_sigma: float = 1.0, **compute_options) → NeoResult[source]

Run the analysis from a script, optionally writing BP and SVG plots.

simulation is an initialized xgc_analysis.simulation.Simulation. All other computation options are forwarded to compute_neoclassical_transport(). The GUI calls the compute and plot functions directly and never requests output files.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • output_bp – Optional path for the documented BP output.

  • plot_directory – Optional directory for SVG plots.

  • plot_quantities – Optional subset of SVG quantity names.

  • show_uncertainty – Shade the temporal spread when plotting.

  • uncertainty_sigma – Width of the shaded band in standard deviations.

  • compute_options – Keyword options forwarded to compute_neoclassical_transport.

Returns:

calculated profiles; requested files are written as side effects.

Return type:

NeoResult

xgc_analysis.analysis.transport.neoclassical_workflow.write_neoclassical_bp(result: NeoResult, path: str | Path) → Path[source]

Write one documented ADIOS BP package with averaging provenance.

Parameters:
  • result – Previously computed analysis result.

  • path – Input HDF5 path or output BP path, according to the routine.

Returns:

written ADIOS BP package.

Return type:

Path

Compare turbulence-model, flux-derived neoclassical, and input coefficients.

class xgc_analysis.analysis.transport.combined_coefficients.CombinedTransportResult(psi_n: ndarray, curves: dict[str, dict[str, ndarray]], gstep_range: tuple[int, int], time_range_s: tuple[float, float] | None)[source]

Bases: object

Coefficient families mapped onto one normalized-psi grid.

psi_n

Common normalized-poloidal-flux coordinate.

Type:

ndarray

curves

Selected source group and coefficient family, with values in m²/s.

Type:

dict[str, dict[str, ndarray]]

gstep_range, time_range_s

Averaged diagnostic gsteps and optional physics-time range in seconds.

Type:

tuple

xgc_analysis.analysis.transport.combined_coefficients.compute_combined_transport_coefficients(simulation, *, groups: tuple[str, ...] = ('turbulence', 'neoclassical', 'anomalous'), gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, max_default_samples: int = 30, smoothing_sigma: float = 2.0, denominator_smoothing_sigma: float | None = None, moment_product: str = 'xgc.f2d.bp') → CombinedTransportResult[source]

Collect all requested coefficient groups for a standalone Simulation.

turbulence is the time-averaged diffusion-model BP output. anomalous is the configured input profile held by Species and is not time averaged. neoclassical is inferred from F2D/F3D radial particle and heat fluxes using the existing neoclassical backend. No flux-derived ion momentum diffusivity is currently calculated there.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • groups – Subset of turbulence, neoclassical, and anomalous groups.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • max_default_samples – Number of latest samples used when no window is supplied.

  • smoothing_sigma – Gaussian width in flux-surface indices.

  • denominator_smoothing_sigma – Separate Gaussian width for density and temperature denominators.

  • moment_product – F2D or axisymmetric F3D moment product.

Returns:

selected coefficient groups on a common psi grid.

Return type:

CombinedTransportResult

Compare XGC prescribed transport coefficients with TRANSP profiles.

class xgc_analysis.analysis.transport.coefficient_comparison.TransportCoefficientComparison(quantity: str, psi_n: ndarray, r_over_a: ndarray, xgc: ndarray, transp: ndarray | None, ylabel: str, gstep_range: tuple[int, int], time_range_s: tuple[float, float] | None, transp_path: str | None)[source]

Bases: object

Time-averaged XGC coefficient and optional mapped TRANSP reference.

quantity, ylabel

Selected coefficient key and its labeled physical units.

Type:

str

psi_n, r_over_a, xgc, transp

Radial coordinates and XGC/optional TRANSP values on the XGC grid.

Type:

ndarray or None

gstep_range, time_range_s

Averaged gsteps and optional physics-time range in seconds.

Type:

tuple

transp_path

Reference HDF5 path when used.

Type:

str or None

xgc_analysis.analysis.transport.coefficient_comparison.compare_transport_coefficients(simulation, quantity: str, *, transp_path: str | Path | None = None, gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, max_default_samples: int = 30) → TransportCoefficientComparison[source]

Average XGC coefficient BP steps and map a TRANSP HDF5 curve to psi_N.

TRANSP diffusivities are converted from cm^2/s to m^2/s. The supplied transp_path may be outside the XGC run; it is read only. TRANSP does not provide a matching pinch-velocity variable in the reference HDF5.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • quantity – Coefficient or particle/energy balance selector.

  • transp_path – Optional TRANSP HDF5 reference path.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • max_default_samples – Number of latest samples used when no window is supplied.

Returns:

XGC and optional TRANSP profiles.

Return type:

TransportCoefficientComparison

Compare the XGC and TRANSP gradients of flux-surface averaged potential.

class xgc_analysis.analysis.transport.potential_gradient.PotentialGradientComparison(psi_n: ndarray, r_over_a: ndarray, xgc: ndarray, transp: ndarray | None, gstep_range: tuple[int, int], time_range_s: tuple[float, float] | None, transp_path: str | None, field_product: str)[source]

Bases: object

Profiles of -d<phi>/d(r/a) in volts on the XGC surface grid.

psi_n, r_over_a

Normalized poloidal flux and outboard-midplane minor-radius coordinate.

Type:

ndarray

xgc, transp

XGC gradient and optional TRANSP comparison, both in volts.

Type:

ndarray or None

gstep_range, time_range_s

Averaged gsteps and optional physics-time range in seconds.

Type:

tuple

transp_path, field_product

Reference path and XGC potential product used.

Type:

str or None

xgc_analysis.analysis.transport.potential_gradient.compare_potential_gradient(simulation, *, transp_path: str | Path | None = None, gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, max_default_samples: int = 30) → PotentialGradientComparison[source]

Average XGC pot0 and compare -d<phi>/d(r/a) with TRANSP VRPOT.

The XGC field is averaged over toroidal planes when necessary, then over each flux surface and the selected diagnostic times. The separatrix FSA excludes its legs below the X-point. Both derivatives use the outboard midplane r/a coordinate of the XGC mesh. The result has units of volts, rather than the V/m units of a physical radial field.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • transp_path – Optional TRANSP HDF5 reference path.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • max_default_samples – Number of latest samples used when no window is supplied.

Returns:

XGC and optional TRANSP gradient profiles.

Return type:

PotentialGradientComparison

Flux-surface and volume-integrated rates from XGC f-source diagnostics.

class xgc_analysis.analysis.sources.diagnostics.SourceRateResult(psi_n: ndarray, local: ndarray, cumulative: ndarray, gsteps: ndarray, time_s: ndarray, total: ndarray, units: str, channel: str, source: str, species: str)[source]

Bases: object

One f-source term evaluated over the selected diagnostic window.

local is the source rate in each mapped flux-surface shell; cumulative is the enclosed volume integral, following the IDL core/SOL separatrix treatment. total is the full-domain rate at each selected time. All rates use the unit in units.

psi_n, local, cumulative

Flux-surface coordinate, shell rates, and enclosed rates.

Type:

ndarray

gsteps, time_s, total

Selected gsteps, physics times in seconds, and total-rate trace.

Type:

ndarray

units, channel, source, species

Rate unit and selected diagnostic identifiers.

Type:

str

xgc_analysis.analysis.sources.diagnostics.available_source_terms(simulation) → list[str][source]

Return f-source suffixes with matching density and change channels.

Parameters:

simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

Returns:

source suffixes present in the diagnostic.

Return type:

list[str]

xgc_analysis.analysis.sources.diagnostics.compute_source_rates(simulation, *, channel: str, source: str, species: str, gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, max_default_samples: int = 30, source_steps_per_diagnostic: int | None = None) → SourceRateResult[source]

Evaluate local, cumulative, and total rates from xgc.fsourcediag.

The BP change channel is normalized to its source-specific density. Its product with that density is a change per XGC source step. A source step’s duration is inferred from neighboring diagnostic time and gstep coordinates and sml_f_source_period, including for the first selected sample. The optional source_steps_per_diagnostic overrides the number of source updates between output slices, matching the IDL routine’s fsource_rate argument. Positive momentum sources are converted from parallel linear momentum to toroidal torque by multiplying by R*B_phi/|B| before spatial integration.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • channel – Fueling, heating, or torque channel.

  • source – F-source term suffix to evaluate.

  • species – Ion or electron species selector.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • max_default_samples – Number of latest samples used when no window is supplied.

  • source_steps_per_diagnostic – Optional override of source updates per diagnostic frame.

Returns:

shell, cumulative, and time-trace rates.

Return type:

SourceRateResult

XGC particle and energy balances with optional TRANSP source profiles.

class xgc_analysis.analysis.sources.balance.BalanceComparison(quantity: str, psi_n: ndarray, xgc_transport: ndarray, xgc_sources: ndarray, transp_sources: ndarray | None, units: str, source_terms: tuple[str, ...], gstep_range: tuple[int, int], time_range_s: tuple[float, float], transp_path: str | None)[source]

Bases: object

Transport and physical-source rates enclosed by mapped flux surfaces.

quantity, units

Balance channel and units of all curves.

Type:

str

psi_n, xgc_transport, xgc_sources, transp_sources

Surface coordinate and enclosed XGC/optional TRANSP rates.

Type:

ndarray or None

source_terms

XGC physical-source components included in the sum.

Type:

tuple[str, …]

gstep_range, time_range_s

Averaged gsteps and physics-time range in seconds.

Type:

tuple

transp_path

Reference HDF5 path when used.

Type:

str or None

class xgc_analysis.analysis.sources.balance.ParticleFuelingComparison(psi_n: ndarray, xgc_neutral: ndarray, xgc_beam: ndarray, transp_neutral: ndarray | None, transp_beam: ndarray | None, gstep_range: tuple[int, int], time_range_s: tuple[float, float], transp_path: str | None)[source]

Bases: object

Separate enclosed electron fueling rates from XGC and TRANSP.

psi_n

Surface coordinate shared by all curves.

Type:

ndarray

xgc_neutral, xgc_beam, transp_neutral, transp_beam

Cumulative particle rates in particles/s; TRANSP curves are optional.

Type:

ndarray or None

gstep_range, time_range_s

Averaged gsteps and physics-time range in seconds.

Type:

tuple

transp_path

Reference HDF5 path when used.

Type:

str or None

xgc_analysis.analysis.sources.balance.compare_particle_energy_balance(simulation, quantity: str, *, transp_path: str | Path | None = None, gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, smoothing_sigma: float = 2.0, max_default_samples: int = 30, moment_product: str = 'xgc.f2d.bp', source_steps_per_diagnostic: int | None = None) → BalanceComparison[source]

Compare XGC neo-plus-diffusion transport with physical sources.

Transport follows the IDL balance: negative cumulative diffusion plus measured nonadiabatic radial flux times flux-surface area. The XGC source curve sums available neutral, external heat/torque, collision, and particle-source terms. The optional TRANSP source curve sums wall-neutral, volume-neutral, and beam particle sources, ion beam power, or electron beam and ohmic power.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • quantity – Coefficient or particle/energy balance selector.

  • transp_path – Optional TRANSP HDF5 reference path.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • smoothing_sigma – Gaussian width in flux-surface indices.

  • max_default_samples – Number of latest samples used when no window is supplied.

  • moment_product – F2D or axisymmetric F3D moment product.

  • source_steps_per_diagnostic – Optional override of source updates per diagnostic frame.

Returns:

XGC transport and source curves with optional TRANSP sources.

Return type:

BalanceComparison

xgc_analysis.analysis.sources.balance.compare_particle_fueling_sources(simulation, *, transp_path: str | Path | None = None, gstep_range: tuple[int, int] | None = None, time_range_ms: tuple[float, float] | None = None, max_default_samples: int = 30, source_steps_per_diagnostic: int | None = None) → ParticleFuelingComparison[source]

Compare separate XGC neutral and prescribed beam fueling with TRANSP.

XGC particle_source represents the prescribed beam source for runs configured with a beam source profile. All curves are cumulative rates inside the flux surface, in particles/s.

Parameters:
  • simulation – Initialized XGC Simulation containing the needed geometry and diagnostics.

  • transp_path – Optional TRANSP HDF5 reference path.

  • gstep_range – Optional inclusive gstep bounds.

  • time_range_ms – Optional inclusive physics-time bounds in milliseconds.

  • max_default_samples – Number of latest samples used when no window is supplied.

  • source_steps_per_diagnostic – Optional override of source updates per diagnostic frame.

Returns:

separate XGC and optional TRANSP curves.

Return type:

ParticleFuelingComparison

xgc_analysis.analysis.sources.balance.read_transp_particle_fueling(path: str | Path) → tuple[ndarray, ndarray, ndarray][source]

Integrate TRANSP wall-plus-volume neutrals and beam over DVOL.

Parameters:

path – TRANSP HDF5 input path.

Returns:

psi, cumulative neutral, and beam rates.

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray]

xgc_analysis.analysis.sources.balance.read_transp_sources(path: str | Path, quantity: str) → tuple[ndarray, ndarray][source]

Integrate TRANSP source densities over DVOL shell volumes.

SCEW, SCEV, and SBE use particles/cm^3/s; PBI, PBE, and POH use W/cm^3; DVOL uses cm^3. Energy output is converted to MW.

Parameters:
  • path – TRANSP HDF5 input path.

  • quantity – Coefficient or particle/energy balance selector.

Returns:

psi and cumulative source rates.

Return type:

tuple[np.ndarray, np.ndarray]

Slices of scalar data on XGC poloidal and toroidal triangular meshes.

Surface indices are the zero-based indices of Plane.surf_idx. Angles are the straight field-line angle stored in Plane.theta and the physical toroidal plane angle plane_index * Mesh.delta_phi.

xgc_analysis.analysis.slicing.mesh_slicing.flux_surface_overlay_paths(plane)[source]

Return ordered vertex paths for all R-Z flux-surface overlays.

Valid straight field-line angles set the order. XGC assigns theta=-10 to SOL vertices, so those paths are traced through mesh edges shared by vertices of the same surface. Separate paths are returned separately to avoid lines across disconnected surface pieces.

Parameters:

plane – Mesh Plane whose flux-surface paths are requested.

Returns:

ordered vertex paths, split at disconnected pieces.

Return type:

list[np.ndarray]

xgc_analysis.analysis.slicing.mesh_slicing.flux_surface_profile(plane_data, statistic='average', *, fsa='volume')[source]

Return a radial mean or poloidal residual RMS on all flux surfaces.

The RMS back-projects the surface mean to vertices, then computes sqrt(<(X - <X>)²>) with the same flux-surface weighting. This avoids cancellation between two large moments when the variation is small.

Parameters:
  • plane_data (PlaneData) – Scalar data at every vertex of one poloidal plane.

  • statistic ({"average", "rms"}) – Flux-surface average or poloidal residual RMS.

  • fsa (str) – Plane flux-surface averaging convention.

Returns:

One value per flux surface in the input field’s units.

Return type:

ndarray

xgc_analysis.analysis.slicing.mesh_slicing.line_of_sight(plane_data, psi_plane_data, *, r0, z0, slope=0.0, angle_degrees=None, n_points=500)[source]

Sample field and normalized psi along a line through (r0,z0).

angle_degrees measures the line direction from +R toward +Z and must lie in [-90, 90]. The legacy slope=dZ/dR argument remains available when no angle is supplied. Samples outside the triangulated XGC domain are returned as NaN.

Parameters:
  • plane_data – One scalar value per mesh vertex, with its Plane geometry.

  • psi_plane_data – Node-centered poloidal flux on the same Plane.

  • r0 – R coordinate of the sight-line origin in meters.

  • z0 – Z coordinate of the sight-line origin in meters.

  • slope – Legacy dZ/dR direction when angle_degrees is omitted.

  • angle_degrees – Sight-line angle from +R, within [-90, 90] degrees.

  • n_points – Number of samples along the sight line.

Returns:

R, Z, normalized psi, and sampled field.

Return type:

tuple[np.ndarray, …]

xgc_analysis.analysis.slicing.mesh_slicing.psi_theta_slice(plane_data, *, n_psi=256, n_theta=256, psi_bounds=(0.1, 1.05), theta_domain=(-3.141592653589793, 3.141592653589793), return_boundaries=False)[source]

Map outer-midplane surfaces to a uniform (psi_N, theta*) grid.

Interpolation follows mesh2uni.pro: periodic interpolation along each core surface, then linear interpolation in normalized poloidal flux. The separatrix uses only vertices with defined theta*. Open SOL surfaces use their strike-to-strike theta* with zero shifted to the outer midplane. Surfaces with unset theta* are skipped. theta_domain can span more than one turn to show both strike endpoints; closed surfaces occupy only the single [-π, π] turn. With return_boundaries=True the fourth return value is an array of (psi_N, first endpoint, second endpoint) SOL coordinates.

Parameters:
  • plane_data – One scalar value per mesh vertex, with its Plane geometry.

  • n_psi – Number of points on the uniform normalized-psi grid.

  • n_theta – Number of points on the uniform theta-star grid.

  • psi_bounds – Minimum and maximum normalized psi for interpolation.

  • theta_domain – Angular interval for the output grid, in radians.

  • return_boundaries – Also return open-SOL strike-point angle boundaries.

Returns:

psi grid, theta grid, mapped values, and optional SOL boundaries.

Return type:

tuple

xgc_analysis.analysis.slicing.mesh_slicing.split_line_at_psi_minimum(psi, values, *, ignore_end_points=5)[source]

Split a sampled sight line into its two branches around minimum ψ_N.

Nonfinite samples do not take part in finding the minimum. A configurable number of finite samples at each end are also excluded from that search, to avoid dead boundary points. The returned slices retain their original order and share the turning point.

Parameters:
  • psi – Normalized psi samples along a sight line.

  • values – Field samples aligned with psi.

  • ignore_end_points – Finite points ignored at each end when finding minimum psi.

Returns:

two (psi, value) branches and the turning index.

Return type:

tuple

xgc_analysis.analysis.slicing.mesh_slicing.surface_lines(plane_data, surface_indices)[source]

Return (index, psi_N, theta_star, values) for selected surfaces.

Parameters:
  • plane_data – One scalar value per mesh vertex, with its Plane geometry.

  • surface_indices – Zero-based indices or collection of selected flux surfaces.

Returns:

surface index, psi, theta, and values for each selection.

Return type:

list[tuple]

xgc_analysis.analysis.slicing.mesh_slicing.surface_phi_slice(mesh_data, surface_index, n_theta=256)[source]

Interpolate all toroidal planes at one closed surface to common theta*.

Parameters:
  • mesh_data – Vertex data on all toroidal planes.

  • surface_index – Zero-based selected flux-surface index.

  • n_theta – Number of points on the uniform theta-star grid.

Returns:

theta grid, toroidal angles, sampled values, and surface psi.

Return type:

tuple

Time-resolved one-dimensional slices of scalar XGC mesh diagnostics.

The catalog supplies the variable’s logical steps and physics times. Each frame is reduced to a mapped radial profile, a theta-star surface trace, or one branch of a line of sight before the next batch is read.

class xgc_analysis.analysis.slicing.mesh_time_slicing.MeshSliceTimeMap(coordinate: ndarray, time_s: ndarray, gsteps: ndarray, values: ndarray, coordinate_name: str, statistic: str, detail: str)[source]

Bases: object

One scalar slice sampled across physical time.

coordinate

Increasing horizontal coordinates: normalized psi or theta-star radians.

Type:

ndarray

time_s, gsteps

Physics time in seconds and matching logical gsteps.

Type:

ndarray

values

Slice values with shape (n_time, n_coordinate).

Type:

ndarray

coordinate_name, statistic, detail

Horizontal coordinate, chosen reduction, and slice description.

Type:

str

xgc_analysis.analysis.slicing.mesh_time_slicing.compute_mesh_slice_time_map(simulation, product_key, variable, *, statistic='average', vertex_axis=0, plane_axis=None, plane_index=0, other_indices=None, surface_index=0, line_origin='axis', line_r0=None, line_z0=None, line_angle_deg=0.0, line_branch='toward', line_points=500, line_end_ignore=5, n_coordinate=256, gstep_range=None, time_range_ms=None, frame_stride=1, last_frame_index=None, check_cancel: Callable[[], None] | None = None) → MeshSliceTimeMap[source]

Reduce catalog frames to a contour-ready mesh-slice time map.

Radial averages and RMS profiles use only Plane.surf_map surfaces, which cross the outer midplane. A theta trace uses one selected surface. The line of sight is split at its interior minimum psi and one branch is interpolated to a fixed normalized-psi grid. Missing spatial samples stay NaN; time is never inferred from output-frame spacing.

Parameters:
  • simulation (Simulation) – Initialized XGC Simulation with mesh, magnetic field, and catalog.

  • product_key (str) – Source product and scalar vertex variable.

  • variable (str) – Source product and scalar vertex variable.

  • statistic ({"average", "rms", "surface", "line"}) – Spatial reduction to apply independently at every time step.

  • vertex_axis – Spatial axis indices and selectors for one frame of the variable.

  • plane_axis – Spatial axis indices and selectors for one frame of the variable.

  • plane_index – Spatial axis indices and selectors for one frame of the variable.

  • other_indices – Spatial axis indices and selectors for one frame of the variable.

  • surface_index (int) – Zero-based surface for a theta-star time map.

  • line_origin – Sight-line origin and angle from +R for a line time map.

  • line_r0 – Sight-line origin and angle from +R for a line time map.

  • line_z0 – Sight-line origin and angle from +R for a line time map.

  • line_angle_deg – Sight-line origin and angle from +R for a line time map.

  • line_branch ({"toward", "away"}) – Side of the interior psi minimum to retain.

  • line_points (int) – Sight-line samples, ignored endpoint samples, and contour-grid points.

  • line_end_ignore (int) – Sight-line samples, ignored endpoint samples, and contour-grid points.

  • n_coordinate (int) – Sight-line samples, ignored endpoint samples, and contour-grid points.

  • gstep_range (tuple or None) – Optional inclusive limits on logical gsteps and physics time in ms.

  • time_range_ms (tuple or None) – Optional inclusive limits on logical gsteps and physics time in ms.

  • frame_stride (int) – Take every Nth selected frame after applying window limits.

  • last_frame_index (int or None) – Optional last eligible ordinal frame; None includes all frames.

  • check_cancel (callable or None) – Invoked between catalog batches and frame reductions.

Returns:

Increasing horizontal coordinate, physics times, gsteps, and values.

Return type:

MeshSliceTimeMap

Reusable mapped R-Z diagnostic plots for XGC monitor and Python workflows.

xgc_analysis.analysis.slicing.plotting.plot_mesh_slice(plane_data, *, view, variable, description='', units='', mesh_data=None, surface_indices=(), surface_index=0, n_theta=256, n_psi=256, psi_bounds=(0.1, 1.05), remove_fsa=False, color_bounds=None, theta_bounds=None, phi_bounds=None, surface_value_bounds=None, line_psi_data=None, line_origin=None, line_r0=None, line_z0=None, line_slope=0.0, line_angle_deg=None, line_xaxis='R', line_points=500, line_end_ignore=5, line_xbounds=None, line_ybounds=None)[source]

Plot a surface, theta-phi, psi-theta, or line-of-sight mesh slice.

The interpolation functions in mesh_slicing are also usable in Python workflows without creating a figure.

Parameters:
  • plane_data – One scalar value per mesh vertex, with its Plane geometry.

  • view – Named plot view.

  • variable – Display name or variable key for plot labeling.

  • description – Optional descriptive color-scale label.

  • units – Physical units for plot labeling.

  • mesh_data – Vertex data on all toroidal planes.

  • surface_indices – Zero-based indices or collection of selected flux surfaces.

  • surface_index – Zero-based selected flux-surface index.

  • n_theta – Number of points on the uniform theta-star grid.

  • n_psi – Number of points on the uniform normalized-psi grid.

  • psi_bounds – Minimum and maximum normalized psi for interpolation.

  • remove_fsa – Subtract the flux-surface average before mapping.

  • color_bounds – Optional field color limits.

  • theta_bounds – Optional theta-star axis limits in radians.

  • phi_bounds – Optional toroidal-angle axis limits in radians.

  • surface_value_bounds – Optional surface-trace value limits.

  • line_psi_data – Poloidal-flux PlaneData for line-of-sight sampling.

  • line_origin – Magnetic-axis, X-point, or custom origin selector.

  • line_r0 – Custom R coordinate in meters.

  • line_z0 – Custom Z coordinate in meters.

  • line_slope – Legacy line direction dZ/dR.

  • line_angle_deg – Line direction from +R in degrees.

  • line_xaxis – R, Z, or normalized psi horizontal axis.

  • line_points – Number of sight-line samples.

  • line_end_ignore – Endpoint samples excluded from psi-minimum search.

  • line_xbounds – Optional sight-line horizontal limits.

  • line_ybounds – Optional sight-line value limits.

Returns:

rendered mesh slice.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.slicing.plotting.plot_mesh_time_map(time_map, *, variable, description='', units='', color_bounds=None, coordinate_bounds=None, time_bounds_ms=None)[source]

Plot a mesh slice over physics time with a normalized-psi or theta-star axis.

Parameters:
  • time_map (MeshSliceTimeMap) – Precomputed spatial slices and their physical times.

  • variable (str) – Field label, optional verbose title, and display units.

  • description (str) – Field label, optional verbose title, and display units.

  • units (str) – Field label, optional verbose title, and display units.

  • color_bounds (tuple or None) – Optional color, horizontal, and millisecond axis limits.

  • coordinate_bounds (tuple or None) – Optional color, horizontal, and millisecond axis limits.

  • time_bounds_ms (tuple or None) – Optional color, horizontal, and millisecond axis limits.

Returns:

Contour-ready time map rendered as a pseudocolor figure.

Return type:

matplotlib.figure.Figure

xgc_analysis.analysis.slicing.plotting.plot_rz_diagnostic(plane_data, *, variable: str, description: str = '', units: str = '', split_average: bool = False, view: str | None = None, n_int: int = 300, r_bounds=None, z_bounds=None, color_bounds=None, residual_color_bounds=None, profile_psi_bounds=None, profile_value_bounds=None, show_wall: bool = True, show_mesh: bool = False, show_flux: bool = False)[source]

Plot a full field, mapped radial mean or RMS, or its R-Z residual.

plane_data must hold one scalar per vertex. The surface average and residual use its existing flux-surface conversion methods. Radial views select the outer-midplane surfaces in Plane.surf_map. view also accepts split for existing Python callers; the GUI presents the average and residual as separate choices. R-Z fields are mapped to a bitmap grid by Plane.plot_contour().

Parameters:
  • plane_data – One scalar value per mesh vertex, with its Plane geometry.

  • variable – Display name or variable key for plot labeling.

  • description – Optional descriptive color-scale label.

  • units – Physical units for plot labeling.

  • split_average – Legacy switch for a combined average-and-residual view.

  • view – Named plot view.

  • n_int – Number of R-Z raster grid points per axis.

  • r_bounds – Optional R-axis bounds in meters.

  • z_bounds – Optional Z-axis bounds in meters.

  • color_bounds – Optional field color limits.

  • residual_color_bounds – Optional residual color limits.

  • profile_psi_bounds – Optional normalized-psi axis limits.

  • profile_value_bounds – Optional profile-value axis limits.

  • show_wall – Draw the wall outline.

  • show_mesh – Draw triangular mesh edges.

  • show_flux – Draw ordered flux-surface paths.

Returns:

rendered R-Z field or surface profile.

Return type:

matplotlib.figure.Figure