Skip to content

Conversation

mafshari64
Copy link
Contributor

Comment on lines 86 to 91
if self.data_preparation_strategy is not None and self.data_preparation_strategy not in [
"doubleBuffer",
"adios",
"mappedMemory",
"hdf5",
]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to use Literals and enforce them via the type system in the constructor

source: Optional[Source] = None,
range: Optional[str] = None,
file: Optional[str] = None,
ext: Optional[str] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the ext parameter should defined as a literal not a str

Comment on lines 102 to 115
def __init__(
self,
period: TimeStepSpec,
source: Optional[Source] = None,
range: Optional[str] = None,
file: Optional[str] = None,
ext: Optional[str] = None,
infix: Optional[str] = None,
json: Optional[Union[str, Dict]] = None,
json_restart: Optional[Union[str, Dict]] = None,
data_preparation_strategy: Optional[str] = None,
toml: Optional[str] = None,
particle_io_chunk_size: Optional[int] = None,
file_access: Optional[str] = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default value slisted in the documentation do not match the actual constructor defaults

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

follwoing here we have

--openPMD.source | Select data sources and filters to dump. Default is species_all,fields_all,
for this reason self.source = source if source is not None else Source(["species_all", "fields_all"]). is it still wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's not what I meant, for example
the default for ext is bp following the documentation, but the constructor default argument is None it should be bp instead.
Please match the default arguments in the documentation to the defaults specified by the constructor.

And more general, most of the settings are currently PIConGPU specific. That is fine for now but we have to figure out a way to abstract that in the future

Comment on lines 18 to 19
"""
Specifies the parameters for the openPMD plugin in PIConGPU simulations.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the PICMI implementation should not reference PIConGPU

Comment on lines 32 to 34
source: Source, optional
Data sources and filters to dump (e.g., Source([ChargeDensity(filter="filterX"), "species_all"])).
Default: Source(["species_all", "fields_all"]).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a fan of allowing "str" specification of sources, that jsut adds another way to get the same results and I would prefer just one good way to specify stuff.

Comment on lines 27 to 40
class Source:
"""
Consolidates data sources for the openPMD plugin in PIConGPU.
This class aggregates individual data sources (e.g., ChargeDensity) or predefined
keywords (species_all, fields_all) to define the --openPMD.source parameter:
https://picongpu.readthedocs.io/en/latest/usage/plugins/openPMD.html
Parameters
----------
sources: List[Union[str, <DataSourceClasses>]]
List of data sources, either as strings (e.g., "species_all", "fields_all") or
as data source objects (e.g., ChargeDensity, Density).
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mafshari64 could you please comment on why you consider the aggregator functionality class necessary? I currently don' see why it is needed, it looks like the entire functionality could be moved to the openPMD plugin.
Instead I would use this class as an interface for all source implementations

Comment on lines 12 to 13
@typeguard.typechecked
class BoundElectronDensity:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class should inherit from a common interface of all Sources for the openPMD plugin

Comment on lines 58 to 63
The dataset name with optional filter (e.g., "bound_electron_density" or
"bound_electron_density:filterX").
"""
if self.filter:
return f"bound_electron_density:{self.filter}"
return "bound_electron_density"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the conversion to strings should not happen on the PICMI side, that string is already PIConGPU specific

Comment on lines 51 to 62
def get_source_string(self) -> str:
"""
Return the source string for use in --openPMD.source.
Returns
-------
str
The dataset name with optional filter (e.g., "charge_density" or "charge_density:filterX").
"""
if self.filter:
return f"charge_density:{self.filter}"
return "charge_density"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same problem here, the source string should happen at the earliest in PyPIConGPU, as the generated string is PIConGPU specific.
also the generated string is wrong, it should be source_all

Comment on lines 33 to 69
str,
ChargeDensity,
BoundElectronDensity,
Counter,
Density,
Energy,
EnergyDensity,
EnergyDensityCutoff,
LarmorPower,
MacroCounter,
MidCurrentDensityComponent,
Momentum,
MomentumDensity,
WeightedVelocity,
]
]
)

def __init__(
self,
sources: typing.List[
typing.Union[
str,
ChargeDensity,
BoundElectronDensity,
Counter,
Density,
Energy,
EnergyDensity,
EnergyDensityCutoff,
LarmorPower,
MacroCounter,
MidCurrentDensityComponent,
Momentum,
MomentumDensity,
WeightedVelocity,
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a fan of the many repeats of the all the different source,please switch to using interfaces and testing with isinstance for the interface

@BrianMarre
Copy link
Member

fundamentally and in summary, the current PR lacks an common interface for all the current sources of the openPMD plugin and this interface is required.

@chillenzer chillenzer added CI:no-compile CI is skipping compile/runtime tests but runs PICMI tests PICMI pypicongpu and picmi related labels Apr 28, 2025
@chillenzer chillenzer added this to the 0.9.0 / next stable milestone Apr 28, 2025
@chillenzer chillenzer self-requested a review April 28, 2025 14:41
Copy link
Member

@BrianMarre BrianMarre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

general the current version is still missing the configuration of species contributing to the derived field sources.

Comment on lines 33 to 31
def __init__(self, filter: typing.Optional[str] = None):
self.filter = filter
self.check()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default filter should be all, as this is the PIConGPU standard. And since we will stick to str for now, I would like to avoid using Optional here as it only complicates the implementation.

In addition, this class is missing the option to configure the species contributing to this source, please add a list of species that should contribute to this source.

Comment on lines 33 to 31
def __init__(self, filter: typing.Optional[str] = None):
self.filter = filter
self.check()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same problem as charge density source, the user must be able to specify the species that will contribute to the derived field source

Copy link
Member

@BrianMarre BrianMarre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks generally good, but documentation strings should use doxygen annotations

Comment on lines 18 to 44
"""
Specifies parameters for openPMD diagnostic output in particle-in-cell simulations.
This diagnostic outputs simulation data (fields and particles) to disk using the openPMD
standard, with configurable periods, data sources, and backend settings.
Attention: **period is mandatory.**
Parameters
----------
period: TimeStepSpec
Specifies the time steps for data output.
Unit: simulation time steps. Required.
source: List[SourceBase], optional
List of data source objects to dump (e.g., [ChargeDensity(filter="all")]).
Default: None (no sources specified).
range: str, optional
Contiguous range of cells per dimension to dump (e.g., ":,:,:").
Format: comma-separated ranges like "begin:end,begin:end,begin:end".
Default: ":,::,:" (all cells).
file: str, optional
Relative or absolute file prefix for openPMD output files.
If relative, files are stored under the simulation output directory.
Default: None (backend-dependent default).
ext: Literal["bp", "h5", "sst"], optional
File extension controlling the openPMD backend.
Options: "bp" (ADIOS2), "h5" (HDF5), "sst" (ADIOS2/SST for streaming).
Default: "bp" (ADIOS2 backend).
infix: str, optional
Filename infix for iteration layout (e.g., "_%06T").
Use "NULL" for group-based layout. Required as "NULL" if ext="sst".
Default: "NULL" (group-based layout).
json: Union[str, Dict], optional
Backend-specific parameters for writing, as a JSON string, dictionary, or filename
(filename must be prepended with "@").
Default: {} (empty dictionary).
json_restart: Union[str, Dict], optional
Backend-specific parameters for restarting, as a JSON string, dictionary, or filename
(filename must be prepended with "@").
Default: {} (empty dictionary).
data_preparation_strategy: Literal["doubleBuffer", "adios", "mappedMemory", "hdf5"], optional
Strategy for particle data preparation.
Options: "doubleBuffer" or "adios" (ADIOS2-based), "mappedMemory" or "hdf5" (HDF5-based).
Default: None (backend-dependent).
toml: str, optional
Path to a TOML file for openPMD configuration.
Default: None.
particle_io_chunk_size: int, optional
Size of particle data chunks for writing (in MiB).
Reduces host memory footprint for certain backends.
Default: None (backend-dependent).
file_access: Literal["create", "append"], optional
File access mode for writing.
Options: "create" (new files), "append" (for checkpoint-restart workflows).
Default: "create" (new files).
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""
Specifies parameters for openPMD diagnostic output in particle-in-cell simulations.
This diagnostic outputs simulation data (fields and particles) to disk using the openPMD
standard, with configurable periods, data sources, and backend settings.
Attention: **period is mandatory.**
Parameters
----------
period: TimeStepSpec
Specifies the time steps for data output.
Unit: simulation time steps. Required.
source: List[SourceBase], optional
List of data source objects to dump (e.g., [ChargeDensity(filter="all")]).
Default: None (no sources specified).
range: str, optional
Contiguous range of cells per dimension to dump (e.g., ":,:,:").
Format: comma-separated ranges like "begin:end,begin:end,begin:end".
Default: ":,::,:" (all cells).
file: str, optional
Relative or absolute file prefix for openPMD output files.
If relative, files are stored under the simulation output directory.
Default: None (backend-dependent default).
ext: Literal["bp", "h5", "sst"], optional
File extension controlling the openPMD backend.
Options: "bp" (ADIOS2), "h5" (HDF5), "sst" (ADIOS2/SST for streaming).
Default: "bp" (ADIOS2 backend).
infix: str, optional
Filename infix for iteration layout (e.g., "_%06T").
Use "NULL" for group-based layout. Required as "NULL" if ext="sst".
Default: "NULL" (group-based layout).
json: Union[str, Dict], optional
Backend-specific parameters for writing, as a JSON string, dictionary, or filename
(filename must be prepended with "@").
Default: {} (empty dictionary).
json_restart: Union[str, Dict], optional
Backend-specific parameters for restarting, as a JSON string, dictionary, or filename
(filename must be prepended with "@").
Default: {} (empty dictionary).
data_preparation_strategy: Literal["doubleBuffer", "adios", "mappedMemory", "hdf5"], optional
Strategy for particle data preparation.
Options: "doubleBuffer" or "adios" (ADIOS2-based), "mappedMemory" or "hdf5" (HDF5-based).
Default: None (backend-dependent).
toml: str, optional
Path to a TOML file for openPMD configuration.
Default: None.
particle_io_chunk_size: int, optional
Size of particle data chunks for writing (in MiB).
Reduces host memory footprint for certain backends.
Default: None (backend-dependent).
file_access: Literal["create", "append"], optional
File access mode for writing.
Options: "create" (new files), "append" (for checkpoint-restart workflows).
Default: "create" (new files).
"""
"""
openPMD diagnostic output
This diagnostic writes simulation data (base fields , derived fields and/or particles) to disk using the openPMD
standard, with configurable periods, data sources and backend settings.
@param period specification of the the time steps for data output, outputs will always be written at the end of a PIC time step.
@param source list of data source objects to include in the dump (e.g., [ChargeDensity(filter="all")]),
Setting this to None will cause an empty dump
@param range contiguous range of cells to dump the base- and derived field for
specification as comma-separated "begin:end" range for each dimension, i.e. "begin:end,begin:end,begin:end"
Notes: Values will be clipped to the simulation box. Begin and/or end may be omitted to indicate the limit of the simulation box in the dimension. The Default value ":,::,:" indicates that fields should be dumped for all cells.
@param file relative or absolute file path prefix for openPMD output files. Relative path are interpreted as relative to the simulation output directory, the default value None indicates the backend's default.
@param ext file extension controlling the openPMD backend, options are "bp" (default backend ADIOS2), "bp4" (bp4 backend ADIOS2), "bp5" (bp5 backend ADIOS2), "h5" (HDF5), "sst" (ADIOS2/SST for streaming).
@param infix filename infix for the iteration layout (e.g., "_%06T"), use "NULL" for the group-based layout, ext="sst" requires infix="NULL".
@param json openPMD backend configuration as a JSON string, dictionary, or filename (filename must be prepended with "@").
@param json_restart: backend-specific parameters for restarting, as a JSON string, dictionary, or filename (filenames must be prepended with "@").
@param data_preparation_strategy: strategy for particle data preparation, options: "doubleBuffer" or "adios" (ADIOS2-based), "mappedMemory" or "hdf5" (HDF5-based), the default value None indicates the backend default
@param toml path to a TOML file for openPMD configuration. Replaces the JSON or keyword configuration.
@param particle_io_chunk_size size of particle data chunks used in writing (in MiB), reduces host memory footprint for certain backends, default "None" indicates the backend default.
@param file_access file access mode for writing, options: "create" (new files), "append" (for checkpoint-restart workflows).
"""

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use the doxygen annotations for the documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for review,
a short question: in other picmi/diagnositcs files I used standard Python docstring format eg lib/python/picongpu/picmi/diagnostics/macro_particle_count.py and not oxygen annotations. just for this file
lib/python/picongpu/picmi/diagnostics/openpmd.py for documentation or do for all?

@chillenzer chillenzer mentioned this pull request May 5, 2025
3 tasks
Copy link
Member

@PrometheusPi PrometheusPi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a first review - no test yet

Contiguous range of cells per dimension to dump (e.g., ":,:,:").
Format: comma-separated ranges like "begin:end,begin:end,begin:end".
Default: None (all cells).
Default: ":,::,:" (all cells).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a typo, right?

Suggested change
Default: ":,::,:" (all cells).
Default: ":,:,:" (all cells).

File extension controlling the openPMD backend.
Options: "bp" (ADIOS2), "h5" (HDF5), "sst" (ADIOS2/SST for streaming).
Default: None (backend-dependent).
Default: "bp" (ADIOS2 backend).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not ensured, as we might compile with hdf5 only

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really want to hard code your selection below here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just mentioned bp as the default as it is in documentation not hardcoded. users can specify what they want.

@@ -0,0 +1,59 @@
"""
This file is part of PIConGPU.
Copyright 2021-2024 PIConGPU contributors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021-2024 PIConGPU contributors
Copyright 2021-2025 PIConGPU contributors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it start in 2021? Was it copied from somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I forgot to change it. I will do

Represents a default data source for openPMD output in particle-in-cell simulations.
This class specifies a backend-specific default source for dumping simulation data
using the openPMD standard. For example, in some backends, it may dump all particle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why only in some backends. As I understand it, backends are e.g. ADIOS or HDF5, but that doesn't determine what you write out.

----------
filter: str, optional
Name of a filter to select data contributing to the source.
Default: None (backend-dependent).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the filter backend dependent. Our filters are defined in PIConGPU.

"""
This file is part of PIConGPU.
Copyright 2021-2025 PIConGPU contributors
Copyright 2021-2024 PIConGPU contributors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2021-2024 PIConGPU contributors
Copyright 2021-2025 PIConGPU contributors

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it start in 2021? Was it copied from some file?

"""
This file is part of PIConGPU.
Copyright 2021-2025 PIConGPU contributors
Copyright 2021-2024 PIConGPU contributors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

@@ -0,0 +1,34 @@
"""
This file is part of PIConGPU.
Copyright 2021-2024 PIConGPU contributors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@chillenzer chillenzer changed the title openpmd.py pluging for PICMI openpmd.py plugin for PICMI May 20, 2025
@PrometheusPi
Copy link
Member

@mafshari64 There seems to be conflicts with the current PR. See info.

Copy link
Contributor

@chillenzer chillenzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offline discussion: We need further testing before approval.

Comment on lines 1 to 7
"""
This file is part of PIConGPU.
Copyright 2024 PIConGPU contributors
Authors: Julian Lenz, Masoud Afshari
License: GPLv3+
"""

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why's this removed?

from .timestepspec import TimeStepSpec
from .checkpoint import Checkpoint
from .openpmd import OpenPMD
from .openpmd_sources.source_base import SourceBase
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this should be here. We don't want to expose this to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so delete it?

Comment on lines 29 to 31
@param range contiguous range of cells to dump the base- and derived field for
specification as comma-separated "begin:end" range for each dimension, i.e. "begin:end,begin:end,begin:end"
Notes: Values will be clipped to the simulation box. Begin and/or end may be omitted to indicate the limit of the simulation box in the dimension. The Default value ":,::,:" indicates that fields should be dumped for all cells.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should become a class similar to TimeStepSpec. But be aware that there are subtle differences in semantics that would need to be represented in that new class.

Comment on lines 47 to 48
if self.period is None:
raise ValueError("period is mandatory")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean should I delete it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I retained for defensive programming probably in future other external users might subclass or modify behavior in unexpected ways. but if you want I can remove it.

@mafshari64
Copy link
Contributor Author

Hi Julian,

@chillenzer, I have finally solved the issues and finalized this branch. In a separate PR I will add all CI tests for picim and pypicongpu. agree?

@PrometheusPi
Copy link
Member

@mafshari64 Please rebase your PR to the current dev. The branch has conflicts.

@PrometheusPi
Copy link
Member

@mafshari64 I do not see a fix of this PR yet, do you have problems resolving the conflict? This feature would be great to have in dev.

@chillenzer
Copy link
Contributor

Superseded by #5461 which includes these commits.

@chillenzer chillenzer closed this Sep 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI:no-compile CI is skipping compile/runtime tests but runs PICMI tests PICMI pypicongpu and picmi related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants