-
Notifications
You must be signed in to change notification settings - Fork 2
feat: pulse shaping #211
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
base: main
Are you sure you want to change the base?
feat: pulse shaping #211
Conversation
58cc140 to
3cd12af
Compare
jl-wynen
left a comment
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.
Two overarching questions:
- Is there a description of the maths somewhere? There are a lot of nontrivial equations here that don't seem to be explained.
- How much of this is bespoke McStas code? We shouldn't mix that kind of code with code for measured data because that will make it difficult to know which functions to use once we have both.
src/ess/beer/clustering.py
Outdated
| from scippneutron.conversion.tof import dspacing_from_tof | ||
| from scipy.signal import find_peaks, medfilt | ||
|
|
||
| from .conversions import _t0_estimate, _time_of_arrival |
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.
Please don't import protected attributes. If you need them across modules, make them public. Possibly in a protected module if you don't want package users to use them.
src/ess/beer/io.py
Outdated
| if 'lambda' in da.coords: | ||
| da.coords['wavelength_estimate'] = da.coords.pop('lambda') | ||
|
|
||
| if da.coords['wavelength_estimate'].value == '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.
This is bad because it scatters parameters and associations of modes with parameters over the code. Can you combine these parameters in one place? E.g., a mapping from mode to dict / dataclass of parameters? Then these long if-else chains can be collapsed into dict-lookups.
You're right that it could use some more documentation. The tof math for these pulse shaping chopper modes is:
The McStas specific stuff should be contained in the |
True, but where will code for nexus files go? Also the |
src/ess/beer/conversions.py
Outdated
| _eto = event_time_offset | ||
| T = sc.scalar(1 / 14, unit='s').to(unit=_eto.unit) | ||
| tc = tc.to(unit=_eto.unit) | ||
| return sc.where(_eto >= tc % T, _eto, _eto + 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.
Why is there a modulo here? 'time cutoff' sounds like the condition should be _eto >= tc.
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 you're right. tc should be in the interval [0, 1/14s], so the modulo does nothing.
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.
Are there tests for this code? If not, can you add some? (I mean the additions in the PR overall.)
| ): | ||
| '''Does frame unwrapping based on the cutoff time `tc` and `event_time_ffset`. | ||
| Events before `tc` are assumed to come from the previous pulse.''' | ||
| _eto = event_time_offset |
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.
| _eto = event_time_offset | |
| eto = event_time_offset |
It's unusual to use a protected local name like this.
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 agree, but spellcheck complained about eto for some reason, so I renamed it.
src/ess/beer/conversions.py
Outdated
| tc: sc.Variable, | ||
| ): | ||
| '''Does frame unwrapping based on the cutoff time `tc` and `event_time_ffset`. | ||
| Events before `tc` are assumed to come from the previous pulse.''' |
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.
Some general comments on docstring style:
- According to https://peps.python.org/pep-0257/ they should always use double quotes.
- Sphinx will use the entire first paragraph as the summary which is displayed in the overview tables:
These get unwieldy when the summary is long. So as a general rule, it is best to limit the summary to a single line and then use a separate paragraph for the detailed description. See also the [coding convention](https://scipp.github.io/development/coding-conventions.html#docstrings)
| else: | ||
| raise ValueError('Sample position entry not found in file.') | ||
| data, events, params, sample_pos, chopper_pos = _load_h5( | ||
| raise ValueError(f'Unkonwn chopper mode {mode}.') |
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.
Which chopper's position is this? And why do we need to compute it? Isn't it written in the file?
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.
It's the "effective" chopper position. It's either the position of one of the choppers, or the midpoint between two choppers.
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.
But of which chopper? It looks like there is only a single position in the code even though there are many choppers. Is it the t0 chopper?
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.
Good question.. After thinking a bit more about this, here is how I think it works:
The chopper system is designed so that, in pulse shaping mode,
- there is one point along the beamline where every neutron has to pass within a short interval of time. That can be seen as a "virtual source" position or a "virtual chopper" position. This is "the chopper position" in the code.
- a neutron emitted at the start of the pulse, with a particular wavelength, called
lambdain the McStas files, reaches this virtual chopper exactly in the center of the time window when the chopper is open. That's why we can use thelambdaparameter from the files to determine the opening time of the chopper.
I don't know if we are going to have access to this lambda parameter in practice, or if we are going to have to find the opening time of the virtual chopper by some other means.
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 pretty sure we won't have lambda in the file. But isn't it a constant for a given chopper setting?
What about other modes? The code doesn't seem to only run for pulse shaping.
there is one point along the beamline where every neutron has to pass within a short interval of time. That can be seen as a "virtual source" position or a "virtual chopper" position. This is "the chopper position" in the code.
Can you change the name to reflect that and add a docstring?
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.
What about other modes? The code doesn't seem to only run for pulse shaping.
For the multiplexing modes the neutron has to pass through one of a number of openings. But the concept of a virtual source with a position is still there.
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 pretty sure we won't have lambda in the file. But isn't it a constant for a given chopper setting?
I'm not sure, I'll ask Celine about it.
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.
Can you change the name to reflect that and add a docstring?
👍
Co-authored-by: Jan-Lukas Wynen <[email protected]>
Yes that's one option. |
…into beer-pulse-shaping
Fixes #205