-
Notifications
You must be signed in to change notification settings - Fork 3
Beer powdiff workflow #262
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?
Changes from all commits
8af5b19
4baea39
faa7675
920b4a5
83ce19e
602a5f7
18b0a83
2b91577
951a26d
b3da276
81f1fd9
04b6cb0
ac26cd4
d0f7b6c
ca9a051
9a2e1dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,25 +2,26 @@ | |
| import scipp.constants | ||
| from scippneutron.conversion import graph | ||
|
|
||
| from ess.powder.types import ElasticCoordTransformGraph, RunType | ||
|
|
||
| from .types import ( | ||
| DHKLList, | ||
| GeometryCoordTransformGraph, | ||
| ModulationPeriod, | ||
| PulseLength, | ||
| RawDetector, | ||
| RunType, | ||
| StreakClusteredData, | ||
| TofCoordTransformGraph, | ||
| TofDetector, | ||
| WavelengthDefinitionChopperDelay, | ||
| WavelengthDetector, | ||
| ) | ||
|
|
||
|
|
||
| def compute_tof_in_each_cluster( | ||
| def compute_wavelength_in_each_cluster( | ||
| da: StreakClusteredData[RunType], | ||
| chopper_delay: WavelengthDefinitionChopperDelay, | ||
| mod_period: ModulationPeriod, | ||
| ) -> TofDetector[RunType]: | ||
| graph: GeometryCoordTransformGraph, | ||
| ) -> WavelengthDetector[RunType]: | ||
| """Fits a line through each cluster, the intercept of the line is t0. | ||
| The line is fitted using linear regression with an outlier removal procedure. | ||
|
|
||
|
|
@@ -37,7 +38,10 @@ def compute_tof_in_each_cluster( | |
| """ | ||
| if isinstance(da, sc.DataGroup): | ||
| return sc.DataGroup( | ||
| {k: compute_tof_in_each_cluster(v, mod_period) for k, v in da.items()} | ||
| { | ||
| k: compute_wavelength_in_each_cluster(v, mod_period) | ||
| for k, v in da.items() | ||
| } | ||
| ) | ||
|
|
||
| max_distance_from_streak_line = mod_period / 3 | ||
|
|
@@ -185,17 +189,48 @@ def _tof_from_dhkl( | |
| return out | ||
|
|
||
|
|
||
| def t0_estimate( | ||
| wavelength_estimate: sc.Variable, | ||
| L0: sc.Variable, | ||
| Ltotal: sc.Variable, | ||
| ) -> sc.Variable: | ||
| """Estimates the time-at-chopper by assuming the wavelength.""" | ||
| return ( | ||
| sc.constants.m_n | ||
| / sc.constants.h | ||
| * wavelength_estimate | ||
| * (L0 - Ltotal).to(unit=wavelength_estimate.unit) | ||
| ).to(unit='s') | ||
|
|
||
|
|
||
| def tof_from_t0_estimate_graph( | ||
| da: RawDetector[RunType], | ||
| gg: GeometryCoordTransformGraph, | ||
| ) -> ElasticCoordTransformGraph[RunType]: | ||
| """Graph for computing ``wavelength`` in pulse shaping chopper modes.""" | ||
| return { | ||
| **gg, | ||
| 't0': t0_estimate, | ||
| 'tof': lambda time_of_arrival, t0: time_of_arrival - t0, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you clarify why we still have
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Beer currently does not use the LUT approach to compute wavelengths. Eventually we will move to that approach for the pulse shaping modes (the modulation modes are incompatible with the LUT approach).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But I saw a lot of changes that replaced Tof with Wavelength?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the workflow is still using the generic unwrap workflow which does not have any public
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So where does TOF come into play? Is it TOA->TOF->Wavelength, or TOA->Wavelength->TOF as for DREAM final result, or something else?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's toa->tof->wavelength.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So what is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used so that the interface of the workflow matches what it will look like once we have lookup tables for the pulse skipping modes. That the wavelengths are currently not computed using lookup tables is an implementation detail, it does not need to be reflected in the public interface.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eventually we will replace this mechanism for computing wavelengths in beer pulse shaping modes with the lookup table approach to make it consistent with the other techniques. |
||
| 'time_of_arrival': time_of_arrival, | ||
| } | ||
|
|
||
|
|
||
| def geometry_graph() -> GeometryCoordTransformGraph: | ||
| return graph.beamline.beamline(scatter=True) | ||
| return { | ||
| **graph.beamline.beamline(scatter=True), | ||
| **graph.tof.elastic("tof"), | ||
| } | ||
|
|
||
|
|
||
| def tof_from_known_dhkl_graph( | ||
| da: RawDetector[RunType], | ||
| mod_period: ModulationPeriod, | ||
| pulse_length: PulseLength, | ||
| chopper_delay: WavelengthDefinitionChopperDelay, | ||
| dhkl_list: DHKLList, | ||
| gg: GeometryCoordTransformGraph, | ||
| ) -> TofCoordTransformGraph: | ||
| ) -> ElasticCoordTransformGraph[RunType]: | ||
| """Graph computing ``tof`` in modulation chopper modes using | ||
| list of peak positions.""" | ||
|
|
||
|
|
@@ -221,7 +256,6 @@ def _compute_coarse_dspacing( | |
|
|
||
| return { | ||
| **gg, | ||
| **graph.tof.elastic("tof"), | ||
| 'pulse_length': lambda: pulse_length, | ||
| 'mod_period': lambda: mod_period, | ||
| 'chopper_delay': lambda: chopper_delay, | ||
|
|
@@ -232,56 +266,21 @@ def _compute_coarse_dspacing( | |
| } | ||
|
|
||
|
|
||
| def t0_estimate( | ||
| wavelength_estimate: sc.Variable, | ||
| L0: sc.Variable, | ||
| Ltotal: sc.Variable, | ||
| ) -> sc.Variable: | ||
| """Estimates the time-at-chopper by assuming the wavelength.""" | ||
| return ( | ||
| sc.constants.m_n | ||
| / sc.constants.h | ||
| * wavelength_estimate | ||
| * (L0 - Ltotal).to(unit=wavelength_estimate.unit) | ||
| ).to(unit='s') | ||
|
|
||
|
|
||
| def _tof_from_t0( | ||
| time_of_arrival: sc.Variable, | ||
| t0: sc.Variable, | ||
| ) -> sc.Variable: | ||
| """Computes time-of-flight by subtracting a start time.""" | ||
| return time_of_arrival - t0 | ||
|
|
||
|
|
||
| def tof_from_t0_estimate_graph( | ||
| gg: GeometryCoordTransformGraph, | ||
| ) -> TofCoordTransformGraph: | ||
| """Graph for computing ``tof`` in pulse shaping chopper modes.""" | ||
| return { | ||
| **gg, | ||
| **graph.tof.elastic("tof"), | ||
| 't0': t0_estimate, | ||
| 'tof': _tof_from_t0, | ||
| 'time_of_arrival': time_of_arrival, | ||
| } | ||
|
|
||
|
|
||
| def compute_tof( | ||
| da: RawDetector[RunType], graph: TofCoordTransformGraph | ||
| ) -> TofDetector[RunType]: | ||
| """Uses the transformation graph to compute ``tof``.""" | ||
| return da.transform_coords(('tof',), graph=graph) | ||
| def wavelength_detector( | ||
| da: RawDetector[RunType], graph: ElasticCoordTransformGraph[RunType] | ||
| ) -> WavelengthDetector[RunType]: | ||
| """Applies the transformation graph to compute ``wavelength``.""" | ||
| return da.transform_coords(('wavelength',), graph=graph) | ||
|
|
||
|
|
||
| convert_from_known_peaks_providers = ( | ||
| geometry_graph, | ||
| tof_from_known_dhkl_graph, | ||
| compute_tof, | ||
| wavelength_detector, | ||
| ) | ||
| convert_pulse_shaping = ( | ||
| geometry_graph, | ||
| tof_from_t0_estimate_graph, | ||
| compute_tof, | ||
| wavelength_detector, | ||
| ) | ||
| providers = (compute_tof_in_each_cluster, geometry_graph) | ||
| providers = (compute_wavelength_in_each_cluster, geometry_graph) | ||
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.
scippneutronbe used for this conversion?