Skip to content

Add t_offset Argument to ParticleGroup.write - #152

Open
electronsandstuff wants to merge 8 commits into
ChristopherMayes:masterfrom
electronsandstuff:pierce/t_offset
Open

Add t_offset Argument to ParticleGroup.write #152
electronsandstuff wants to merge 8 commits into
ChristopherMayes:masterfrom
electronsandstuff:pierce/t_offset

Conversation

@electronsandstuff

Copy link
Copy Markdown
Contributor

This PR adds the new argument t_offset to ParticleGroup.write. This gets written as the OpenPMD timeOffset attribute to avoid numerical roundoff error when writing ParticleGroup objects with reference time included for some codes (ie Bmad which reads them separately and stores internally as a quad precision floating point number.

Full changes:

  • New argument t_offset in ParticleGroup.write supporting scalar and array types. Does not write timeOffset when not specified.
  • Update write_pmd_bunch docstring to numpy
  • Add cell that demonstrates use of t_offset to docs/examples/write_examples.ipynb

Screenshot

image

@ken-lauer ken-lauer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you and @ChristopherMayes say the round-trippability doesn't matter, then I'm fine with this proceeding as-is.

Comment thread beamphysics/writers.py
name : str, optional
Subgroup to create for the bunch. If None, writes directly into `h5`.
t_offset : float or numpy.ndarray, optional
Time offset, scalar or per-particle, written as the 'timeOffset' record.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Per-particle offset seems a strange thing to me (as clearly a non-physicist), but apparently it's a reasonable thing?
The standard does indicate this, after all:

The reference time may depend upon the longitudinal position of a particle and so may be different for different particles.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I allowed offsets because it's in the standard. I also don't have an immediate use, but if it's allowed in the standard, we might as well expose it.

Comment thread beamphysics/particles.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The time offset itself seems to be special enough to deserve its own spot in ParticleGroup. Well, at least from my usual standpoint of "if your data isn't round-trippable (de/serializable) to its original representation it's a problem".

Trying to think this through a bit:

# assume timeOffset is set in particles.h5
P = ParticleGroup("particles.h5")   # defaults to include_offset=True
P.t  # includes timeOffset from the original file
# P.time_offset ❌ not retrievable or otherwise inspectable
P.write("out.h5", t_offset=0.0)  # not round-trippable / lossy: timeOffset goes away

The test suite does:

        ParticleGroup(
            data=load_bunch_data(hf[particle_paths(hf)[0]], include_offset=False)
        )

And then allows it to be handled on the side. This include_offset flag opts out of all offsets wholesale though, so you can't just opt out of time offset handling. A bit awkward, I think.

@electronsandstuff electronsandstuff Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I think it's up to @ChristopherMayes if he wants to start including the offsets. I agree with you on being able to round-trip in principle. This was the smallest atomic edit I could make to avoid the numerical artifacts without doing a big architecture change of ParticleGroup.

If we wanted to think about a bigger change, one path forward could be to promote x, y, z, t... to properties and have the actual fields be raw_x, offset_x with .x returning raw_x + offset_x. This would keep the current behavior while supporting the offset fields (which are in the OpenPMD standard). For the sake of small PRs and keeping work flowing, it might be best to start here and think about the bigger ParticleGroup change in a separate issue?

@ChristopherMayes?

edit: Just read below comment, I will merge and add the offset notes as a suggestion in an issue

@ken-lauer ken-lauer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well, I don't like it but @ChristopherMayes said it's the design intent.

In short, LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants