XGC-Analysis package
xgc_analysis.AnalyticDiffusionProfiles module
- class xgc_analysis.AnalyticDiffusionProfiles.AnalyticDiffusionProfiles(psi, time, S, Vol, grad_avg, psi_norm)[source]
Bases:
objectCreates diffusion profile data using analytic functions.
- Attributes:
density : A 3D array (shape (n_species, n_samples, n_surf)) of the diffusion density. flow : A 3D array (shape (n_species, n_samples, n_surf) of the parallel mean flow. temp : A 3D array (shape (n_species, n_samples, n_surf)) of temperature (in eV). n_samples : An integer (n_samples) representing the number of time samples. n_species : An integer (default 2) representing the number of particle species. n_surf : An integer (n_surf) representing the number of ψ-surfaces. psi : A 1D array (shape (n_surf,)) containing the poloidal magnetic flux values. steps : A 1D array (shape (n_samples,)) of time step indices. time : A 1D array (shape (n_samples,)) of simulation times (in seconds).
xgc_analysis.DiffusionCoefficients module
- class xgc_analysis.DiffusionCoefficients.DiffusionCoefficients(adios: Adios, *, timeout=10.0, nspecies=2, npsi=100)[source]
Bases:
objectStores the profiles of diffusion model coefficients defined as functions of the poloidal magnetic flux ψ.
- The four diffusion coefficients are:
ptl_diffusivity (m^2/s)
momentum_diffusivity (m^2/s)
heat_conductivity (m^2/s)
ptl_pinch_velocity (m/s)
The data layout of each coefficient is (nspecies, npsi) where the second dimension (the ψ-grid) is contiguous in memory. Also the ψ–grid is stored as a 1D NumPy array of length npsi.
- Parameters:
nspecies: Number of particle species (default: 2). npsi: Number of points in the ψ–grid.
- write_to_file(filename='xgc.diffusion_coeff.bp', gstep=-1)[source]
Writes the diffusion coefficient profiles and the ψ–grid to an Adios BP file as a new step.
For each diffusion coefficient, the data for each species is split into an individual variable using a species suffix. The species suffixes (for species indices 0 through 6) are:
0: _elec 1: _ion 2: _imp1 3: _imp2 4: _imp3 5: _imp4 6: _imp5
- In addition, the file will store:
n_species: a scalar integer (int64).
psi: a 1D array (of length npsi).
The method opens the specified file (filename) using the Adios2 FileWriter in append mode, writes all the individual diffusion profiles, and then ends the step.
xgc_analysis.DiffusionProfiles module
- class xgc_analysis.DiffusionProfiles.DiffusionProfiles(adios: adios2.Adios, *, bp_dir: os.PathLike | str = './xgc.diffusion_profiles.bp', wait_interval: float = 1.0, timeout: float | None = None)[source]
Bases:
objectLive reader for
xgc.diffusion_profiles.bp.Reads diffusion profile data from an Adios BP file (directory)
xgc.diffusion_profiles.bp. The constructor waits for a file called “xgc.diffusion_profiles.py” to be created. Once it is found, it opens it as a persistentadios2.Stream, drains all existing steps while retaining only the final one. The Stream is left open until it is closed with the member method close(). A blocking request for a new step can be posted with the member method read_next_step.The file
xgc.diffusion_profiles.bphas the following structure:double density n_steps*{n_species, n_samples, n_surf} double flow n_steps*{n_species, n_samples, n_surf} double temp n_steps*{n_species, n_samples, n_surf} int32_t n_samples n_steps*scalar int32_t n_species n_steps*scalar int32_t n_surf n_steps*scalar double psi n_steps*{n_surf} int32_t steps n_steps*{n_samples} double time n_steps*{n_samples}
That is, there are (for example) n_steps steps recorded in the BP file. The constructor of this class reads only the last step (i.e. the most recent one).
- The property latest_step_data returns a dictionary with the following keys:
density : A 3D array (shape (n_species, n_samples, n_surf)) of the diffusion density. flow : A 3D array (shape (n_species, n_samples, n_surf) of the parallel mean flow. temp : A 3D array (shape (n_species, n_samples, n_surf)) of temperature (in eV). n_samples : An integer (n_samples) representing the number of time samples. n_species : An integer (default 2) representing the number of particle species. n_surf : An integer (n_surf) representing the number of ψ-surfaces. psi : A 1D array (shape (n_surf,)) containing the poloidal magnetic flux values. steps : A 1D array (shape (n_samples,)) of time step indices. time : A 1D array (shape (n_samples,)) of simulation times (in seconds).
- Parameters:
bp_dir (str | os.PathLike) – Path to the BP directory written by XGC. The constructor blocks until the directory exists (subject to timeout).
wait_interval (float, optional) – Polling interval in seconds while waiting for the directory. Defaults to 1.0 s.
timeout (float | None, optional) – Abort after this many seconds if the directory still does not exist.
None(default) means wait indefinitely.
Notes
The object keeps exactly one snapshot in memory. Callers needing to store a history must copy out the data returned by
latest_step_data.- property latest_step_data: Dict[str, ndarray]
Return a shallow copy of the dictionary holding the current step.
- Raises:
RuntimeError – If no step has been read yet (e.g., the writer hasn’t flushed a step to disk).
- property n_samples: int | None
Number of (time) samples per species in snapshot, else
None.
- property n_species: int | None
Number of species in the current snapshot (or
None).
- property n_surf: int | None
Radial surface count (psi grid size) in snapshot, else
None.
- read_next_step(*, my_timeout: float = 10.0, poll_delay: float = 0.5) bool[source]
Advance the stream by one time step.
Examples
>>> prof = DiffusionProfiles("xgc.diffusion_profiles.bp") >>> prof.read_next_step(block=False) False # no new data yet >>> # ... later >>> prof.read_next_step() True # newest snapshot now loaded
- Parameters:
my_timeout – Maximum wait time for a new step; if no new step is found within my_timeout seconds, return False.
poll_delay – Sleep duration (seconds) between availability checks when block is True.
- Returns:
True if a new step was successfully read, False otherwise.
- Return type:
bool
xgc_analysis.accessor_mixin module
- class xgc_analysis.accessor_mixin.ArrayAccessorMixin[source]
Bases:
objectMixin 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 exampleget_mesh_dataorget_distribution) on top of these methods.- get_array(var_name)[source]
Returns the raw NumPy array for all steps of a given variable.
- Args:
- var_name (str):
Name of the variable to extract (e.g., “eden”, “time”, etc.).
- steps: (list, optional):
List of specific steps to include in the output. If None, all available steps will be used.
- Returns:n
- np.ndarray: The raw NumPy array for the specified variable across all steps.
For scalar variables (e.g., time), the shape will be (n_steps,).
For mesh-based variables, the shape will be (n_steps, n_planes, n_vertices).
For plane-based variables, the shape will be (n_steps, n_nodes). (Or something similar.)
- get_as(var_name, step_index, expected_type)[source]
Return a stored item and validate its type.
- Parameters:
expected_type (type | tuple[type, ...]) – Allowed Python class/type(s).
xgc_analysis.adios_stream module
Shared ADIOS stream helpers.
- xgc_analysis.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.adios_stream.open_adios_stream(filename, open_timeout_secs=None, *, force_file_stream=True)[source]
Open an ADIOS stream with optional
OpenTimeoutSecsconfiguration.- Parameters:
filename (str) – ADIOS-readable source path.
open_timeout_secs (int, float, or None, optional) – Open timeout for
FileStreammode. If omitted, the default ADIOS opening path is used.force_file_stream (bool, optional) – If True and
open_timeout_secsis provided, open with a declared IO usingFileStream. Campaign.acasources should normally leave this False or useadios2.FileReaderinstead.
- Yields:
adios2.Stream – Open stream context.
xgc_analysis.adios_file_reader module
Reusable ADIOS FileReader helpers for finite BP and ACA reads.
- class xgc_analysis.adios_file_reader.AdiosFileSourceReader(file_reader=None, *, qualify_with_source_id: bool = False, owns_reader: bool = False)[source]
Bases:
objectCallable 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.
- xgc_analysis.adios_file_reader.available_step_count(reader) int[source]
Return the maximum
AvailableStepsCountadvertised by an open FileReader.- Parameters:
reader (adios2.FileReader) – Open FileReader handle.
- xgc_analysis.adios_file_reader.available_steps_count_for_variable(info) int[source]
Return
AvailableStepsCountfrom one ADIOS variable metadata record.- Parameters:
info (dict) – Raw metadata for one ADIOS variable.
- xgc_analysis.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.
- xgc_analysis.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_readeris 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]]
xgc_analysis.bp_reader_mixin module
Shared helpers for BP-based diagnostic readers.
- class xgc_analysis.bp_reader_mixin.BPReaderMixin[source]
Bases:
objectMixin 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_indexis not present inself.step_index_info.
xgc_analysis.catalog.directory_catalog module
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.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)[source]
Bases:
objectCatalog of ADIOS-readable XGC products in one dataset root.
The catalog is intentionally independent of
Simulationso GUI code and automation scripts can inspect available products without constructing mesh or field objects. ASimulationmay 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_winspolicy 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
FileReaderopen so repeated read-plan execution does not reopen an expensive archive. If the installedsource_readerexposesclose(), this method delegates to it.
- get_product(product_key: str) DataProduct[source]
Return one product entry by key.
- Parameters:
product_key (str) – Catalog key such as
xgc.3d.bporxgc.oneddiag.bp.- Raises:
KeyError – If the product is not present in the catalog.
- 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_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]
- 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
gstepvalues 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
missingis"raise".ValueError – If
missingis not a supported missing-step policy.
- 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_readeris used when present, otherwise the regular FileReader-backed local BP backend is used.
- Returns:
Variable-first array mapping plus read provenance.
- Return type:
CatalogArrayRead
- 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 replaceself.productswith the refreshed product map. ExistingReadPlanobjects are not mutated; callers should request new read plans after refreshing.- Returns:
self, for convenient chaining.- Return type:
- 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.
- xgc_analysis.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.bprather thanxgc.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.catalog.directory_catalog.directory_state_key(root_dir: str | Path) Tuple[Tuple[str, str, int, int], ...][source]
Return a cheap filesystem signature for directory-backed catalog contents.
The signature covers top-level
*.bpfiles/directories and all entries beneath BP directories. It intentionally uses only relative path, path type, modification time, and size, so it can be used for frequent GUI polling without opening ADIOS metadata. A changed key means callers should callSimulationCatalog.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.
- 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.catalog.directory_catalog.discover_directory_products(root_dir: Path, *, collect_metadata: bool = True, metadata_reader: Callable[[Path], Tuple[Dict[str, VariableInfo], List[int], List[float], int]] | 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.bpandxgc.3d.00012.bpbecomes one product keyed asxgc.3d.bpwith two sources. Non-sequence files such asxgc.oneddiag.bpbecome 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.
- Returns:
Discovered products sorted by product key.
- Return type:
list[DataProduct]
- xgc_analysis.catalog.directory_catalog.open_catalog(root_dir: str | Path, *, collect_metadata: bool = True, metadata_reader: Callable[[Path], Tuple[Dict[str, VariableInfo], List[int], List[float], int]] | None = None) 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).
- Returns:
Directory-backed catalog for
root_dir. Missing or non-directory roots produce an empty catalog.- Return type:
xgc_analysis.catalog.campaign_catalog module
HPC-Campaign-backed catalog discovery for XGC ADIOS outputs.
- xgc_analysis.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.
- xgc_analysis.catalog.campaign_catalog.discover_campaign_products(campaign_path: Path, *, collect_metadata: bool = True, file_reader=None) List[DataProduct][source]
Discover XGC products advertised by a campaign
.acafile.- 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.
- xgc_analysis.catalog.campaign_catalog.open_campaign_catalog(campaign_path: str | Path, *, collect_metadata: bool = True) SimulationCatalog[source]
Open an HPC-Campaign-backed XGC catalog.
- Parameters:
campaign_path (str or pathlib.Path) – Path to an ADIOS-readable campaign
.acafile.collect_metadata (bool, optional) – Whether to inspect campaign variable metadata. The initial campaign backend requires metadata collection to build useful product records.
- Returns:
Catalog populated from campaign-qualified ADIOS variable names.
- Return type:
xgc_analysis.catalog.SimulationCatalog
xgc_analysis.catalog.campaign_source_reader module
Campaign source-reader backend built on the shared FileReader reader.
- class xgc_analysis.catalog.campaign_source_reader.CampaignSourceReader(file_reader=None, *, owns_reader: bool = False)[source]
Bases:
AdiosFileSourceReaderRead selected variables and steps from an HPC-Campaign
.acafile.Campaign files expose product variables as qualified ADIOS names such as
xgc.f2d.00010.bp/e_den. Product readers use unqualified names such ase_den. The read-plan executor passessource_idfrom the selected source fragment, and this reader combines it with each requested variable to form the campaign-qualified ADIOS name.
xgc_analysis.catalog.read_plan_executor module
Execution helpers for catalog ReadPlan objects.
- class xgc_analysis.catalog.read_plan_executor.BatchedReadPlanExecution(plans: ~typing.List[~xgc_analysis.catalog.types.ReadPlan], records: ~typing.List[~xgc_analysis.catalog.read_plan_executor.ReadPlanRecord] = <factory>, missing_steps_by_variable: ~typing.Dict[str, ~typing.List[int]] = <factory>)[source]
Bases:
objectValues produced by executing several
ReadPlanobjects 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.catalog.read_plan_executor.ReadPlanExecution(plan: ~xgc_analysis.catalog.types.ReadPlan, records: ~typing.List[~xgc_analysis.catalog.read_plan_executor.ReadPlanRecord] = <factory>, missing_steps: ~typing.List[int] = <factory>)[source]
Bases:
objectValues 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
SimulationCatalogbefore execution, so overwriting only matters for hand-built test plans.
- records_in_requested_order() List[ReadPlanRecord][source]
Return records ordered like
plan.requested_steps.Missing steps are omitted. If
requested_stepscontains duplicate logical steps, the same record appears more than once in the returned list.
- values_by_logical_step() Dict[int, object][source]
Return read values keyed by logical step.
- class xgc_analysis.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:
objectOne 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_stepandsource_idfor 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.catalog.read_plan_executor.execute_read_plan(plan: ReadPlan, source_reader: Callable[[...], Mapping[int, Mapping[str, object]]] | None = None) ReadPlanExecution[source]
Execute a catalog
ReadPlanand 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-backedread_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.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
ReadPlanobjects 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-backedread_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.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 withstep_selection, and closes the source when the batch is done. Campaign-backed catalogs use the same source-reader interface with a persistent FileReader handle.
xgc_analysis.catalog.static_product_reader module
Helpers for reading static catalog products.
- xgc_analysis.catalog.static_product_reader.has_static_product(catalog, product_key: str, variables: Iterable[str] | None = None) bool[source]
Return whether
catalogadvertises a static product and optional variables.- Parameters:
catalog (xgc_analysis.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.
- xgc_analysis.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) Mapping[str, object][source]
Read variables from one static catalog product.
- Parameters:
catalog (xgc_analysis.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
SourceReadersignature.Noneusescatalog.source_readerwhen 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.
- Returns:
Values keyed by variable name. Missing values are omitted when
missingis"skip"or"zero".- Return type:
dict[str, object]
- Raises:
KeyError – If the product or a required variable/step is unavailable.
- xgc_analysis.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.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-backedSourceReader.
xgc_analysis.catalog.types module
Data structures for XGC dataset discovery and read planning.
- class xgc_analysis.catalog.types.CatalogArrayRead(arrays: Dict[str, Dict[int, object]], records: List[object], missing_steps_by_variable: Dict[str, List[int]])[source]
Bases:
objectPlain-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.catalog.types.DataProduct(key: str, label: str, product_type: ~xgc_analysis.catalog.types.ProductType, layout: ~xgc_analysis.catalog.types.ProductLayout, sources: ~typing.List[~xgc_analysis.catalog.types.SourceInfo] = <factory>, variables: ~typing.Dict[str, ~xgc_analysis.catalog.types.VariableInfo] = <factory>, product_family: str = '')[source]
Bases:
objectCatalog 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.bpfor the sequencexgc.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, ordiagnostic.- Type:
str
- key: str
- label: str
- layout: ProductLayout
- product_family: str = ''
- product_type: ProductType
- sources: List[SourceInfo]
- variables: Dict[str, VariableInfo]
- class xgc_analysis.catalog.types.MissingStepPolicy(value)[source]
Bases:
str,EnumPolicy used when a requested logical step is unavailable.
RAISEreports missing steps as errors during read planning.SKIPomits unavailable logical steps from the returned fragments.ZEROrecords 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.catalog.types.ProductLayout(value)[source]
Bases:
str,EnumPhysical 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
ReadPlanfragments rather than branching directly on this enum.- FILE_SEQUENCE = 'file_sequence'
- INTERNAL_STEPS = 'internal_steps'
- MIXED = 'mixed'
- STATIC = 'static'
- class xgc_analysis.catalog.types.ProductType(value)[source]
Bases:
str,EnumKnown 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.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:
objectRead request against one ADIOS-readable source.
logical_stepsandadios_stepsare parallel lists. The caller openssource_pathonce and readsvariableat 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_infometadata 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.catalog.types.ReadPlan(product_key: str, variable: str, requested_steps: ~typing.List[int], fragments: ~typing.List[~xgc_analysis.catalog.types.ReadFragment] = <factory>, missing_steps: ~typing.List[int] = <factory>, missing_policy: ~xgc_analysis.catalog.types.MissingStepPolicy = MissingStepPolicy.RAISE)[source]
Bases:
objectResolved source fragments needed to satisfy a logical-step request.
A
ReadPlanis 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.catalog.types.SourceInfo(source_id: str, path: ~pathlib.Path, file_index: int | None = None, mtime: float = 0.0, variables: ~typing.Dict[str, ~xgc_analysis.catalog.types.VariableInfo] = <factory>, step_values: ~typing.List[int] = <factory>, time_values: ~typing.List[float] = <factory>, adios_step_count: int = 0)[source]
Bases:
objectOne physical ADIOS-readable source for a product.
A source is usually one
*.bpdirectory/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, ortimestepvariables.- Type:
list[int]
- time_values
Optional time coordinate values read from a
timevariable.- Type:
list[float]
- 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]
- variables: Dict[str, VariableInfo]
- class xgc_analysis.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:
objectA candidate source fragment for one logical step.
Multiple fragments can represent the same logical step when outputs are duplicated or regenerated.
SimulationCatalog.available_stepsmarks 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.catalog.types.StepInfo(logical_step: int, selected_fragment: ~xgc_analysis.catalog.types.StepFragment, duplicate_fragments: ~typing.List[~xgc_analysis.catalog.types.StepFragment] = <factory>, dedup_policy: str = 'newer_source_wins')[source]
Bases:
objectSelected 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.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.catalog.types.VariableMetadata = <factory>)[source]
Bases:
objectADIOS-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.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:
objectOptional 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_nodeortime_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 = ''
xgc_analysis.constants module
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.
xgc_analysis.csr_matrix module
- class xgc_analysis.csr_matrix.SparseMatrixCSR(reader_function)[source]
Bases:
objectA 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.
- 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.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
*.bpdirectory.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), wherecol_indiceshas been converted to 0‑based indices.- Return type:
tuple
xgc_analysis.distribution_function_data module
- class xgc_analysis.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,ArrayAccessorMixinReader for XGC
xgc.f0.XXXXX.bpdistribution-function files.Data layout matches other XGC-Analysis readers:
self.data[var_name][file_step_index] = object- where
objectis usually: DistributionFunctionFieldfor species*_farraysPlaneData/MeshDatafor configuration-space arraysscalar / 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.
- get_distribution(var_name, step_index=0)[source]
Return
var_nameatstep_indexasDistributionFunctionField.
- where
- class xgc_analysis.distribution_function_data.DistributionFunctionField(mesh, velocity_grid, data_array, *, name=None)[source]
Bases:
objectWrapper 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=1on read, soself.datais 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.
- property is_axisymmetric_storage
Return True when the array is stored with a single toroidal plane.
- node_slice(inode, *, iphi=0)[source]
Return a view with shape
(vpar, vperp)for one configuration-space node.
- property nphi
Return the stored toroidal dimension length.
- velocity_integral(*, data_includes_vperp=True, include_gyroangle=True)[source]
Integrate over velocity space and return config-space data.
- Returns:
Axisymmetric: shape
(n_node,)3D: shape(nphi, n_node)- Return type:
np.ndarray
- velocity_integral_data(*, data_includes_vperp=True, include_gyroangle=True)[source]
Velocity-integrated result packaged as PlaneData or MeshData.
This is intentionally a thin wrapper around
velocity_integral().
xgc_analysis.distribution_moments module
- class xgc_analysis.distribution_moments.F0MomentCalculator(velocity_grid)[source]
Bases:
objectElectrostatic 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-levelflux_avg_to_from_surfto obtain background fields, build adiabatic Maxwellian + Boltzmann response, then split moments.For non-axisymmetric simulations, an additional branch decomposition is available:
n0(toroidally averaged) andturb(deviation fromn0). This is controlled byF0MomentInputs.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, optionaldelta_bradial energy flux split into
drift,exb, optionaldelta_b
- returns:
result.n0always populated.result.turbpopulated only wheninputs.split_n0_turbis true and the input distribution has more than one toroidal plane.- rtype:
F0MomentResult
Notes
Basic moments (density, flow, temperatures) are reported as branch totals (
n0and optionalturb), not adiabatic/non-adiabatic sub-splits.Flux-like moments retain adiabatic/non-adiabatic decomposition.
- class xgc_analysis.distribution_moments.F0MomentComponent(density: ndarray, mean_parallel_flow: ndarray, parallel_temperature: ndarray, perpendicular_temperature: ndarray, parallel_energy_flux: SplitMoment, radial_particle_flux: FluxSplit, radial_energy_flux: FluxSplit)[source]
Bases:
objectMoment set for one component branch (
n0orturb).Notes
Basic moments (density, flow, temperatures) are stored as plain arrays for this branch and are not split into adiabatic/non-adiabatic parts. Flux-like moments keep the adiabatic/non-adiabatic split.
- density: ndarray
- mean_parallel_flow: ndarray
- parallel_energy_flux: SplitMoment
- parallel_temperature: ndarray
- perpendicular_temperature: ndarray
- class xgc_analysis.distribution_moments.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:
objectGeometry / 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_nodein the legacy/C++ diagnostics path, typicallyf0_fg_T_evfor the species).den_node_m3 (ndarray) – Reference local density (
f0_denfor 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 denominatorD.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
SimulationandVelocityGridmetadata.This helper auto-populates most inputs needed by the f0-moment calculator: species mass/charge from
simulation.species[species_index], local reference profiles fromsimulation.velocity_grid, and the equilibrium magnetic field fromsimulation.magnetic_field.epsiandethetaare still required explicit inputs because they are time-dependent field quantities.- Parameters:
simulation (Simulation) – XGC-Analysis simulation object with
species,velocity_grid,mesh, andmagnetic_fieldattributes.species_index (int) – Index into
simulation.speciesand species-indexed arrays insimulation.velocity_grid.flux_surface_avg_geometry (Mesh | None, optional) – Mesh object providing
flux_avg_to_from_surf. If omitted,simulation.meshis used.split_n0_turb (bool | None, optional) – If
None, defaults tonot simulation.sim_is_axisymmetric.sim_is_axisymmetric (bool | None, optional) – Explicit simulation-level symmetry override. This is intentionally separate from
mesh.is_axisymmetricbecause 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, orden_node_m3may be supplied to override values taken fromsimulation.
- 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]
- gradpsi: np.ndarray
- static make_flux_surface_avg_projector(geometry)[source]
Build a
flux_surface_avg_projectcallback from aMesh.The returned callable performs the same conceptual operation as the legacy
mat_transpose_mult + interpolationpath inf0_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.distribution_moments.F0MomentResult(n0: F0MomentComponent, turb: F0MomentComponent | None = None)[source]
Bases:
objectCommon output structure for axisymmetric and non-axisymmetric runs.
n0is always present.turbis present only for non-axisymmetric simulations whensplit_n0_turbis enabled.- turb: F0MomentComponent | None = None
- class xgc_analysis.distribution_moments.FluxSplit(drift: SplitMoment, exb: SplitMoment, delta_b: SplitMoment | None = None)[source]
Bases:
objectFlux moment split by physical mechanism.
- delta_b: SplitMoment | None = None
- drift: SplitMoment
- exb: SplitMoment
- class xgc_analysis.distribution_moments.SplitMoment(adiabatic: ndarray | None = None, nonadiabatic: ndarray | None = None)[source]
Bases:
objectLinear moment split into adiabatic / non-adiabatic pieces.
- adiabatic: ndarray | None = None
- nonadiabatic: ndarray | None = None
- property total
- xgc_analysis.distribution_moments.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
FMomentDatareference 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
eandi.step_index (int, default 0) – Index into the
FMomentDatanested-dict storage.atol (float) – Absolute/relative tolerances for
np.allclosechecks.rtol (float) – Absolute/relative tolerances for
np.allclosechecks.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, andmax_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.fmomentdiagnostics. The comparison currently targets then0branch ofF0MomentResult.
xgc_analysis.diffusion_data module
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. Keeping the BP handling explicit here avoids baking those rules
into the generic BP-reader mixin before the broader reader/catalog interface is
settled.
- class xgc_analysis.diffusion_data.DiffusionCoefficientData(data_dir: str = './', filename: str = 'xgc.diffusion_coeff.bp', read_all_steps: bool = True)[source]
Bases:
ArrayAccessorMixinRead
xgc.diffusion_coeff.bpas an analysis data product.This class is intentionally read-only and independent of the existing workflow-oriented
DiffusionCoefficientsclass, which opens an append stream for live coefficient updates. Each ADIOS step is stored as one reader-localstep_index. Species-suffixed coefficient variables are stacked into arrays with shape(n_species, npsi)and exposed under the base coefficient names:ptl_diffusivitymomentum_diffusivityheat_conductivityptl_pinch_velocity
Metadata variables such as
psi,n_species, andgstepare stored in the sameself.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).
- class xgc_analysis.diffusion_data.DiffusionProfileData(data_dir: str = './', filename: str = 'xgc.diffusion_profiles.bp', read_all_steps: bool = True)[source]
Bases:
ArrayAccessorMixinRead
xgc.diffusion_profiles.bpas buffered profile snapshots.Each ADIOS step contains multiple XGC simulation samples. The profile variables
density,flow, andtemptherefore have shape(n_species, n_samples, n_surf)for each ADIOS step. This reader keeps that native layout inself.data[var_name][step_index]and provides helpers to address an inner sample bysample_indexor by the XGC sample step stored in thestepsvariable.- 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,gstepandtime.gsteportimemay beNonewhen 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, ortemp.step_index (int, optional) – Reader-local ADIOS step index used when
gstepis 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
stepsarray. When provided, it overridesstep_indexandsample_index.
- Returns:
Full native profile array or one sample with shape
(n_species, n_surf).- Return type:
np.ndarray
xgc_analysis.divertor_eich module
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:
Create or reuse a
Simulationand itsPlanemesh.Read heatdiag particle and energy totals through
HeatDiag.Average one selected ADIOS frame, or a requested time window, to rates.
Split lower divertor wall points into inner and outer target branches using the private-region poloidal-flux minimum.
Map target-wall
psi_Nvalues to inner/outer midplane radius maps built from exactPlaneflux-surface crossings withZ=0. The plottedDelta_sepcoordinate is therefore a midplane radial distance, not distance along the target.Estimate a uniform
Delta_sepgrid spacing from the heatdiagpsi_Nresolution mapped through the flux-surface midplane map, and remap particle and energy loads with a locally conservative interval-overlap method.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.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:
objectMapped profile and optional Eich fits for one divertor target.
The profile stores a human-readable target
label, a mappedDelta_sepgridx_mmin 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
- xgc_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) list[DivertorEichProfile][source]
Compute toroidally averaged divertor particle/energy flux-density profiles.
- Parameters:
data_dir (str | Path) – XGC output directory containing
xgc.heatdiag2.bpand 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]_potentialin 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_windowis 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_sepwindow 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.
- Returns:
One profile for each requested target.
- Return type:
list[DivertorEichProfile]
- xgc_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_mis the already mapped upstream/midplane radius coordinate.Parameters are in SI units:
x_m,lambda_q,Sands0are meters, whileq0andq_bghave the same units as the profile being fitted.
- xgc_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)witheich_model()and return parameters plus curve.The fit uses positive finite points, optionally restricted to
fit_window_mm. The fittedlambda_qandSparameters are in meters in the returned parameter vector; plotting text converts them to millimeters.
- xgc_analysis.divertor_eich.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.
xlimis in millimeters.ylimapplies to whichever axes are displayed.ylim (tuple[float, float] | None) – Optional display limits.
xlimis in millimeters.ylimapplies 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.field_data module
- class xgc_analysis.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,ArrayAccessorMixinReader for XGC
xgc.2d.XXXXX.bpandxgc.3d.XXXXX.bpfield files.Data are stored in
self.datawith the structure:self.data[var_name][step_index] = PlaneData | MeshData | scalar | np.ndarray
step_indexis a sequential internal index over loaded(file_index, bp_step)pairs. Useget_step_info(step_index)to recover the source file index and ADIOS step id.FieldDatainheritsArrayAccessorMixin, which providesget_array(var_name)for converting stored values to plain NumPy arrays for plotting and analysis.- export_vtu(mesh)[source]
Export loaded field data to
.vtufiles for visualization.- Parameters:
mesh (Mesh) – Mesh object providing geometry/connectivity for the exported grid.
- Returns:
Writes one
.vtufile per loaded internal step to<work_dir>/vtus.- Return type:
None
xgc_analysis.fieldline_mapping module
- xgc_analysis.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
Meshdefined 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)int32Triangle hosting each intersection.
bary_weights(n_vert, n_steps, 3)float64Barycentric weights inside that triangle.
plane_index(n_steps,)int32Index of the target plane within mesh.planes.
delta_phifloatToroidal separation between neighbouring planes (positive).
directionstrCopy of the direction argument.
- Return type:
dict
xgc_analysis.fieldline_mapping2 module
- xgc_analysis.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 meta‑data.
- Parameters:
tor_turns (float, optional) – How many toroidal turns (2π each) to follow. Fractional values are allowed; the actual number of steps is rounded to the nearest multiple of stored planes so the trace always lands on a plane.
direction ({'forward', 'backward'}) – Sign of dφ. forward ⇒ increasing φ, backward ⇒ decreasing.
xgc_analysis.fmoment_data module
- class xgc_analysis.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,ArrayAccessorMixinReader for XGC
f2d/f3dmoment diagnostics.Data are stored in
self.datawith the common XGC-Analysis layout:self.data[var_name][step_index] = PlaneData | MeshData | scalar
step_indexis a sequential internal index over loaded(file_index, bp_step)pairs. Useget_step_info(step_index)to recover the source file index and ADIOS step id.FMomentDatainheritsArrayAccessorMixin, soget_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_moment(var_name, step_index=0)[source]
Return the raw stored moment item for
var_nameandstep_index.
xgc_analysis.fsource_data module
- class xgc_analysis.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,ArrayAccessorMixinReader for
xgc.fsourcediag.XXXXX.bpsource diagnostic files.Data are stored in
self.datausing the common XGC-Analysis pattern:self.data[var_name][step_index] = PlaneData | scalar
step_indexis a sequential internal index over loaded(file_index, bp_step)pairs. Useget_step_info(step_index)to recover the source file index and ADIOS step id.Mesh-based variables are wrapped as
PlaneDataonmesh.get_plane(0). Scalar variables (for exampletime) 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
MeshDatabranch can be added followingFieldData/FMomentData.
xgc_analysis.heatdiag module
Reader for XGC wall heat/particle impact diagnostics (xgc.heatdiag2.bp).
- class xgc_analysis.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,ArrayAccessorMixinRead wall heat diagnostic data from
xgc.heatdiag2.bp.Time-dependent data are stored in
self.datawith the structure:self.data[variable_name][step_idx] = 2D numpy array
where
step_idxis 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_dataas:self.wall_data[variable_name] = 2D numpy array
The class can be constructed stand-alone using
data_diror using aSimulationinstance (it will usesimulation.data_directoryby default). A catalog must be supplied directly or throughsimulation; 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', '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'}
- 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', 'time', 'tindex'}
- get_heat_array(var_name: str, step_index: int)[source]
Return time-dependent heatdiag variable
var_nameasnp.ndarray.
- get_scalar(var_name: str, step_index: int)[source]
Return
var_nameatstep_indexas a scalar numeric value.
- 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 byget_array(...)(stacked overavailable_steps).
- 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
WallCurvefrom 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, usesimulation.mesh.get_plane(0).axis_rwhen available.
xgc_analysis.loop_voltage_data module
Reader for XGC loop-voltage source output (xgc.loop_vol.bp).
- class xgc_analysis.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,ArrayAccessorMixinRead axisymmetric loop-voltage source fields from
xgc.loop_vol.bp.xgc.loop_vol.bpis 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 asPlaneDatausingmesh.get_plane(0). Scalar time-coordinate variables such astime,gstep,tindex, and legacystepare stored directly.Data are stored with the common XGC-Analysis layout:
self.data[var_name][step_index] = PlaneData | scalar | np.ndarray
where
step_indexis a sequential reader-local index over the selected ADIOS steps. Useget_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.
xgc_analysis.magnetic_field module
- class xgc_analysis.magnetic_field.MagneticField(plane_instance, data_dir='.', catalog=None, source_reader=None)[source]
Bases:
object- 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
xgc_analysis.mesh module
- class xgc_analysis.mesh.Mesh(is_axisymmetric, data_dir='.', catalog=None, source_reader=None)[source]
Bases:
objectA 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.
- 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 whenself.is_axisymmetricis 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). The output format is list of MeshData objects of the same type, one for the left, one for the right plane.
- flux_avg_from_surf(flux_avg: ndarray) ndarray[source]
Map flux‑surface averaged data back to vertices on every plane (producing a representative PlaneData).
- flux_avg_to_from_surf(meshdata: ndarray) ndarray[source]
Compute flux-surface average on each plane and project back to the vertices φ.
- flux_avg_to_surf(meshdata: ndarray) ndarray[source]
Flux‑surface average (⟨f⟩_ψ) of a 3‑D field, averaged over φ.
- Returns:
Shape (nsurf,) for scalar, or (nsurf, n_components) for vector data.
- Return type:
ndarray
- flux_avg_to_surf_norm(meshdata: ndarray) ndarray[source]
Flux‑surface average of vector‑norm, averaged over the toroidal direction.
- get_plane(index=0)[source]
Returns the plane at the specified index. If the mesh is axisymmetric, index is ignored.
- 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
WallCurvefrom a selected plane’s wall polygon.
- 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.
- toroidal_average(meshdata: ndarray) ndarray[source]
Simple arithmetic mean over the toroidal direction (returns vertex‑shaped ndarray).
- 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.
xgc_analysis.mesh_data module
- class xgc_analysis.mesh_data.MeshData(mesh, data_array=None, field_type='scalar', n_components=1, dtype=<class 'numpy.float64'>, mesh_is_axisym=False)[source]
Bases:
objectStores field data for a mesh as a list of PlaneData instances (one per plane).
- The constructor accepts:
vertex_counts: a list of integers indicating the number of vertices on each plane.
field_type: ‘scalar’ or ‘vector’.
n_components: for vector fields (2 or 3); for scalar fields this should be 1.
dtype: the NumPy data type for the stored data.
- mesh_is_axisym (bool): True if the mesh is axisymmetric (i.e. all planes have the same number of vertices
and the same (R,Z) coordinates), False otherwise.
The data for each plane is stored as a separate PlaneData instance.
- apply_fieldline_mapping(*, ref_plane: int = 0)[source]
Pull the data of every plane onto the vertices of ref_plane along magnetic-field lines.
- 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).
- 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()[source]
Project the flux-surface average data back to vertices and package into PlaneData.
- flux_avg_to_from_surf()[source]
Compute the flux-surface average of self.get_data() and project back to the plane in self.flux_avg_plane.
- flux_avg_to_surf_norm()[source]
Flux‑surface average of vector‑norm, averaged over the toroidal direction.
xgc_analysis.neutral_data module
Reader for xgc.neutrals.XXXXX.bp neutral diagnostic files.
- class xgc_analysis.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,ArrayAccessorMixinRead neutral Monte-Carlo diagnostic data from
xgc.neutrals.XXXXX.bpfiles.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 asMeshData.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_neutral_field(var_name, step_index=0)[source]
Return the raw stored neutral field item for
var_name.
- get_scalar(var_name, step_index=0)[source]
Return
var_nameatstep_indexas a scalar numeric value.
- required_vars = ['den_neut', 'rel_std', 'temp_neut']
xgc_analysis.oneddiag module
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 inself.static_dataand exposed via compatibility aliasesself.psi,self.psi00, andself.psi_mks.Derived quantities are stored separately in
self.derived_data/self.derived_static_dataand accessed throughod.derived.
The module also provides lightweight species views (od.e, od.i, …)
for backward-compatible attribute access in notebooks.
- class xgc_analysis.oneddiag.OneDDiag(path: str = './', filename: str = 'xgc.oneddiag.bp', simulation=None, catalog=None, steps=None, missing: str = 'raise', source_reader=None)[source]
Bases:
BPReaderMixin,ArrayAccessorMixinReader 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.speciesis used to attachSpeciesobjects 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.catalogis 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 examplepsi).- 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, …) toSpeciesobjects when available.- Type:
dict[str, Species | None]
- mass_by_prefix
Species masses in atomic mass units, from
Speciesmetadata 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.
- get_profile(var_name, step_index=0)[source]
Return a time-dependent oneddiag variable as an ndarray for one step.
- get_scalar(var_name, step_index=0)[source]
Return a scalar time-dependent oneddiag variable for one step.
- get_species_by_prefix(prefix)[source]
Return the associated
Speciesobject (if available) forprefix.
- get_species_view(prefix)[source]
Return the lightweight species view object for a standardized prefix.
- 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.tmaskto index a monotonic subset of the stored time history. Overlapping diagnostic segments are resolved by keeping the last occurrence for each repeated step value.
- has_derived_var(var_name)[source]
Return
Trueif a derived variable exists in dynamic or static storage.
- 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.
- 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.
- 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
varfor labels. If omitted, labels areInitial/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.
- 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>.Lnand<prefix>.Lt- referencedensityandLn-grad_psi_sqrandshear_rNotes
The reference species for
density/shear_ris electrons if present, otherwise the main ion prefixiwhen available.
- protmass = 1.6726e-27
xgc_analysis.periodic_table module
- xgc_analysis.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.
xgc_analysis.plane module
- class xgc_analysis.plane.Plane(filename='xgc.mesh.bp', data_dir='.', setup_ff2real_mapping=False, catalog=None, source_reader=None)[source]
Bases:
objectA 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 : …
- 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
Compute default mapped areas from
calculate_flux_surface_area()[surf_map].Split separatrix area into above-X and below-X contributions by integrating segment lengths in the
(R, Z)surface polyline.Build
area_core_blockusing only separatrix-above-X area at the separatrix index, andarea_sol_blockusing total separatrix area.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.At the separatrix full-surface index, split candidate vertices by region tag:
region == 1forvolume_core_blockandregion == 2forvolume_sol_block.
- 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.ndarrayPsi values on mapped surfaces, shape
(n_map,)(units: psi).area_defaultnp.ndarrayDefault mapped flux-surface areas, shape
(n_map,)(units: m^2).area_core_blocknp.ndarrayCore-side area block; separatrix uses above-X contribution only (units: m^2).
area_sol_blocknp.ndarraySOL-side area block; separatrix uses full area (units: m^2).
volume_defaultnp.ndarrayDefault mapped shell volumes reconstructed from
node_vol(units: m^3).volume_core_blocknp.ndarrayCore-side shell-volume block with separatrix region-1 selection (units: m^3).
volume_sol_blocknp.ndarraySOL-side shell-volume block with separatrix region-2 selection (units: m^3).
i_sep_mapintSeparatrix index in mapped-surface arrays.
i_sep_fullintSeparatrix index in full-surface arrays.
sep_area_abovefloatSeparatrix area above X-point (units: m^2).
sep_area_belowfloatSeparatrix 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 withnp.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) ndarray[source]
Map a flux-surface averaged quantity <f>(psi) back to vertices.
- flux_avg_to_from_surf(vertex_data: ndarray) ndarray[source]
Smooth vertex_data by averaging on ψ and mapping back to vertices.
- flux_avg_to_surf(vertex_data: ndarray) ndarray[source]
Return the flux-surface average ⟨f⟩ for a vertex‑defined scalar or vector field f.
- flux_avg_to_surf_norm(field: ndarray) 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_surfis 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.
- 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]):Single‑vertex surface
If the surface contains exactly one vertex and that vertex’s coordinates
(R, Z)are withintolof the magnetic‑axis position(axis_r, axis_z), accept the surface.
Multi‑vertex surface
Restrict to vertices with
R >= axis_r.Among them, find • the vertex whose
Zis largest below the axis • the vertex whoseZis 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
RandZ. Default is1e‑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_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:
- 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
WallCurvefrom 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.
- 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)[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
Nonethe routine uses the corresponding data extreme.upper (float or None, optional) – Explicit lower/upper bounds for the colour-map. If either is
Nonethe 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.
- 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_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.plane.TriangulationData(RI, ZI, triObj)[source]
Bases:
objectA 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.
xgc_analysis.plane_data module
- class xgc_analysis.plane_data.PlaneData(plane, data_array=None, n_components=1, dtype=<class 'numpy.float64'>)[source]
Bases:
objectStores 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.
- flux_avg_to_from_surf()[source]
Compute the flux-surface average of self.data and project back to the plane in self.flux_avg_plane.
xgc_analysis.plotting module
- xgc_analysis.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)[source]
General filled-contour plot for any 2-D NumPy array Z defined on the rectangular mesh (X, Y).
All keyword arguments after the literal
*are the same as in the wrapper routines; only x_label and y_label are required so the caller can supply axis text appropriate to its own context.
xgc_analysis.read_bp_file module
Standalone ADIOS FileReader-based BP reader.
- xgc_analysis.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 oldReadBPFile(..., 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
IndexErrorand unavailable variables raiseKeyError. If bothstepsandstep_rangeare 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
filenamedoes 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
stepsandstep_rangeare supplied.
- xgc_analysis.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]]
xgc_analysis.sheath_data module
Sheath diagnostics reader integrated with Simulation mesh data.
- class xgc_analysis.sheath_data.SheathData(steps, simulation, sheath_file='xgc.sheathdiag.bp', data_dir='./', catalog=None, missing='raise', source_reader=None)[source]
Bases:
BPReaderMixin,ArrayAccessorMixinClass 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:
- 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_nameatstep_indexas a scalar numeric value.
- get_sheath_array(var_name: str, step_index: int)[source]
Return time-dependent sheath diagnostic
var_nameasnp.ndarray.
- get_wall_array(var_name: str) ndarray[source]
Return a static wall-related array from
self.wall_data.
- property wall_phi: array
Return toroidal angle(s) corresponding to wall planes.
- 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.
xgc_analysis.simulation module
xgc_analysis.sol_wall_loss_rates module
Compute SOL wall-loss source rates on the 1D flux-surface grid.
- class xgc_analysis.sol_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:
objectWall-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.sol_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_1dand 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:
- xgc_analysis.sol_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_mappsi grid.Core surfaces (psi/psi_x < 1) are set to zero.
- Returns:
Keys
particle_e,particle_i,energy_e,energy_i. Ifuse_time_average=True, each value has shape(npsi,). Otherwise each value has shape(n_time_intervals, npsi).- Return type:
dict[str, np.ndarray]
xgc_analysis.sol_wall_mapping module
Map SOL flux-surface pairs to wall arclength intervals.
- class xgc_analysis.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:
objectWall-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.sol_wall_mapping.SOLWallVolumeMap(plane, wall_curve: WallCurve)[source]
Bases:
objectIdentify 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).
xgc_analysis.species module
- class xgc_analysis.species.Species(sim, index)[source]
Bases:
objectClass representing a plasma species with basic physical properties.
- 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.time_step_utils module
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.utils.file_waiter module
- 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:
objectBlock 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.
- 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
xgc_analysis.velocity_grid module
- class xgc_analysis.velocity_grid.VelocityGrid(work_dir='.', filename='xgc.f0.mesh.bp', catalog=None, source_reader=None)[source]
Bases:
objectVelocity-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_perpfrom 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_perpandv_parallelaxes invalues.axis_vp (int) – Indices of the
v_perpandv_parallelaxes invalues.node_axis (int | None) – Index of the configuration-space node axis in
values. Required whenapply_grid_vol_vonly=True.data_includes_vperp (bool) –
Truefor XGC distribution data (*_f), which already includes thev_perpJacobian factor.include_gyroangle (bool) – Multiply by
2*piif the gyrophase angle has been integrated out.apply_grid_vol_vonly (bool) – If
True, multiply by species/node-dependentf0_grid_vol_vonlybefore integrating over velocity.species_index (int | None) – Species index into
f0_grid_vol_vonly. Required whenapply_grid_vol_vonly=Trueand 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 optional2*pigyrophase factor.
- 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 anddsmuare applied because the stored values already carry the cylindrical Jacobian factorv_perp.
- property shape
(n_mu, n_vp).
- Type:
Velocity-grid point shape in XGC storage order
xgc_analysis.wall_curve module
Wall-polygon arclength utilities.
- class xgc_analysis.wall_curve.WallCurve(points_rz: ndarray, *, verify_clockwise: bool = True, auto_reverse: bool = False)[source]
Bases:
objectClosed 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
ValueErrorif violated.auto_reverse (bool) – If
Trueand orientation is counter-clockwise, reverse order instead of raising.
- circular_distance(s1: float, s2: float) float[source]
Shortest arclength distance between two arclength values.
- 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.
- Returns:
Interval on [0,L) where
wraps=Truemeans it crosses L->0.- Return type:
(s_start, s_end, wraps)
- property total_length: float
Total closed-curve length.