-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Profile from openPMD file #151
Conversation
for more information, see https://pre-commit.ci
…to from_openpmd
for more information, see https://pre-commit.ci
As suggested by @RemiLehe |
|
||
if "z" in m.axes.values(): | ||
# Flip to get complex envelope in t assuming z = -c*t | ||
h = np.flip(h, axis=2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably use converters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A typical workflow:
- Run a FBPIC simulation, get z output
- Read in LASY, and do this dummy conversion t=-z/c (needed as lasy requires t representation)
- Write envelope to file, t representation
- Read in from another code, and if needed do the inverse conversion (z = - c*t). Alternatively, this and the step above could be simplified if LASY could output z representation directly, see More features to the z-t converters #155.
Points 2 and 4 are exactly symmetric, which is what we want, and that's easily done with this dummy convertor, so I think it should be like this. But the clean way would be to make this dummy convertor an option of the import_from_z
convertor, that's for another PR (after #155 is addressed).
|
||
if "z" in m.axes.values(): | ||
dt = m.dz / c | ||
t = (m.z - m.z[0]) / c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here you implicitly set t[0]=0, while we usually center beam in time so t_peak=0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also to be discussed in #155.
np.diff(phase), | ||
weights=0.5 * (np.abs(h[:, :, 1:]) + np.abs(h[:, :, :-1])), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here you could probably use np.gradient(phase, axis=-1)
with weights=np.abs(h)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed
if wavelength is None: | ||
s = io.Series(path + "/" + prefix + "_%T.h5", io.Access.read_only) | ||
it = s.iterations[iteration] | ||
omg0 = it.meshes["laserEnvelope"].get_attribute("angularFrequency") | ||
wavelength_loc = 2 * np.pi * c / omg0 | ||
else: | ||
wavelength_loc = wavelength | ||
array = F |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe if wavelength is provided and differs from the one in the field, we should physically re-define the field with the new wavelength, e.g.
array = F
s = io.Series(path + "/" + prefix + "_%T.h5", io.Access.read_only)
it = s.iterations[iteration]
omg0 = it.meshes["laserEnvelope"].get_attribute("angularFrequency")
if wavelength is None:
wavelength_loc = 2 * np.pi * c / omg0
else:
wavelength_loc = wavelength
array *= np.exp(1j * (2 * np.pi * c / wavelength - omg0) * t)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we could do sth like this, I would keep this for another PR, as there are quite a few options that could make sense. I put it int #156.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not sure it's an separate option -- imagine, a user takes an envelope defined with some central frequency, but wants to obtain an object with a different one. In that case the envelope phase should be adjusted as suggested. Otherwise wavelength_loc = wavelength
is only passed to super().__init__()
which registers it but never uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
likewise, discussed offline, this option is useful and independent from this PR.
Thanks for your comments! I should have addressed them. I suggest that, for some of them, we address them in a separate PR, so I opened an issue (#156) accordingly. In particular, there should be CI, but that would be vastly simplified by either openPMD supporting t representation or by working a bit on the converter (also related to #155). |
Discussed offline: I'll remove the |
for more information, see https://pre-commit.ci
…to from_openpmd
This PR creates a new profile to read a laser pulse from an openPMD file. It derives from
fromArrayProfile
. Works both when the profile read is a laser envelope or the electric field of a laser pulse. in the latter case, the envelope is obtained with a Hilbert transform. Both were tested and give the same result as shown in #141.Example
To do (probably in a separate PR):
tools
or (better IMO) openPMD-viewer.