-
Notifications
You must be signed in to change notification settings - Fork 5
Conversation
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.
Thanks, I think this is getting towards the right direction. Some comments in code. We can have a chat about the geometry thing, not sure what a better representation is off the top of my head.
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 really like this, this new parameter model is much more intuitive. I think a section on the wiki summarising how it works and what various keywords mean would be very useful for onboarding too.
Also, it would be good to have some tests for the gridscan.py
properties, like scan_points
and scan_indicies
"experiment_param_type": PinCentreThenXrayCentreParams, | ||
"callbacks_factory": create_gridscan_callbacks, | ||
}, | ||
"wait_for_robot_load_then_centre": { | ||
"setup": wait_for_robot_load_then_centre_plan.create_devices, | ||
"internal_param_type": WaitForRobotLoadThenCentreInternalParameters, | ||
"internal_param_type": RobotLoadThenCentre, |
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.
When I started in Hyperion, I found it confusing that we sometimes call it 'centring' and sometimes 'xray-centing' - I thought they were different things
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.
They sort of are. In this case centre
means pin tip centre centre then xray centre. I think it's ok to basically assume "centre" means do the full centring. But I appreciate it's not obvious
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 more comments, sorry. I think we are getting there though...
class I03Constants: | ||
BEAMLINE = "BL03S" if TEST_MODE else "BL03I" | ||
INSERTION_PREFIX = "SR03S" if TEST_MODE else "SR03I" | ||
BASE_DATA_DIR = "/tmp/dls/i03/data/" if TEST_MODE else "/dls/i03/data/" | ||
DETECTOR = "EIGER2_X_16M" | ||
SHUTTER_TIME_S = 0.06 |
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 point still stands I think, we can just use the object now rather than a string with a lookup? Appreciate we probably need them for now for the conversion to old params but can we write an issue to move to just the object then?
src/hyperion/parameters/gridscan.py
Outdated
@property | ||
def normal_axis(self) -> XyzAxis: | ||
"""The axis not used in the gridscan, e.g. Z for a scan in Y and X""" | ||
return ({XyzAxis.X, XyzAxis.Y, XyzAxis.Z} ^ {self.axis_1, self.axis_2}).pop() | ||
|
||
@property | ||
def axis_1_start_um(self) -> float: | ||
return self.axis_1.for_axis(self.x_start_um, self.y_start_um, self.z_start_um) | ||
|
||
@property | ||
def axis_2_start_um(self) -> float: | ||
return self.axis_2.for_axis(self.x_start_um, self.y_start_um, self.z_start_um) | ||
|
||
@property | ||
def normal_axis_start(self) -> float: | ||
return self.normal_axis.for_axis( | ||
self.x_start_um, self.y_start_um, self.z_start_um | ||
) | ||
|
||
@property | ||
def axis_1_end_um(self) -> float: | ||
return self.axis_1_start_um + self.axis_1_step_size_um * self.axis_1_steps | ||
|
||
@property | ||
def axis_2_end_um(self) -> float: | ||
return self.axis_2_start_um + self.axis_2_step_size_um * self.axis_2_steps |
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: normal_axis
isn't used, can we remove? I then also find the self.axis_2.for_axis
thing a bit awkward to understand. Could we instead have the function on the XyzStarts
?
class XyzStarts(BaseModel):
x_start_um: float
y_start_um: float
z_start_um: float
def _start_for_axis(self, axis: XyzAxis) -> float:
match axis:
case XyzAxis.X:
return self.x_start_um
case XyzAxis.Y:
return self.y_start_um
case XyzAxis.Z:
return self.z_start_um
Then this becomes:
@property | |
def normal_axis(self) -> XyzAxis: | |
"""The axis not used in the gridscan, e.g. Z for a scan in Y and X""" | |
return ({XyzAxis.X, XyzAxis.Y, XyzAxis.Z} ^ {self.axis_1, self.axis_2}).pop() | |
@property | |
def axis_1_start_um(self) -> float: | |
return self.axis_1.for_axis(self.x_start_um, self.y_start_um, self.z_start_um) | |
@property | |
def axis_2_start_um(self) -> float: | |
return self.axis_2.for_axis(self.x_start_um, self.y_start_um, self.z_start_um) | |
@property | |
def normal_axis_start(self) -> float: | |
return self.normal_axis.for_axis( | |
self.x_start_um, self.y_start_um, self.z_start_um | |
) | |
@property | |
def axis_1_end_um(self) -> float: | |
return self.axis_1_start_um + self.axis_1_step_size_um * self.axis_1_steps | |
@property | |
def axis_2_end_um(self) -> float: | |
return self.axis_2_start_um + self.axis_2_step_size_um * self.axis_2_steps | |
@property | |
def axis_1_start_um(self) -> float: | |
return self._start_for_axis(self.axis_1) | |
@property | |
def axis_2_start_um(self) -> float: | |
return self._start_for_axis(self.axis_2) | |
@property | |
def axis_1_end_um(self) -> float: | |
return self.axis_1_start_um + self.axis_1_step_size_um * self.axis_1_steps | |
@property | |
def axis_2_end_um(self) -> float: | |
return self.axis_2_start_um + self.axis_2_step_size_um * self.axis_2_steps |
You could even argue axis_1_start_um
is then a bit of a redundant function and instead just use self._start_for_axis(self.axis_1)
everywhere
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.
On discussion removed 2D grid scan params entirely, we will know what it should look like when we need to add it back
src/hyperion/parameters/gridscan.py
Outdated
omega_start_deg: float = Field(default=CONST.PARAM.GRIDSCAN.OMEGA_1) # type: ignore | ||
omega2_start_deg: float = Field(default=CONST.PARAM.GRIDSCAN.OMEGA_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: The start
here kind of implies that omega
is moving throughout the grid, which it isnt.
return ScanPath(self.scan_spec.calculate()).consume().midpoints | ||
|
||
|
||
class ThreeDGridScan(SpecifiedGridScan, SplitScan): |
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: Can we add a docstring on what a 3D gridscan is, as it's not obvious. E.g. do a 2d grid, rotate in omega then do another grid
src/hyperion/parameters/gridscan.py
Outdated
def scan_1(self): | ||
x_end = self.x_start_um + self.x_step_size_um * self.x_steps | ||
y1_end = self.y_start_um + self.y_step_size_um * self.y_steps | ||
|
||
scan_1_x = Line("sam_x", self.x_start_um, x_end, self.x_steps) | ||
scan_1_omega = Line( | ||
"omega", self.omega_start_deg, self.omega_start_deg, self.x_steps | ||
) | ||
scan_1_z = Line("sam_z", self.z_start_um, self.z_start_um, self.x_steps) | ||
scan_1_y = Line("sam_y", self.y_start_um, y1_end, self.y_steps) | ||
return scan_1_x.zip(scan_1_z).zip(scan_1_omega) * ~scan_1_y | ||
|
||
@property | ||
def scan_2(self): | ||
x_end = self.x_start_um + self.x_step_size_um * self.x_steps | ||
z2_end = self.z2_start_um + self.z_step_size_um * self.z_steps | ||
|
||
scan_2_x = Line("sam_x", self.x_start_um, x_end, self.x_steps) | ||
scan_2_omega = Line( | ||
"omega", self.omega2_start_deg, self.omega2_start_deg, self.x_steps | ||
) | ||
scan_2_y = Line("sam_y", self.y2_start_um, self.y2_start_um, self.x_steps) | ||
scan_2_z = Line("sam_z", self.z2_start_um, z2_end, self.z_steps) | ||
return scan_2_x.zip(scan_2_y).zip(scan_2_omega) * ~scan_2_z |
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: Can we change to grid_1
/grid_2
rather than scan_1
/scan_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: For the fixed things, rather than e.g. Line("sam_z", self.z_start_um, self.z_start_um, self.x_steps)
I think we can just do Static("sam_z", self.z_start_um)
? See https://dls-controls.github.io/scanspec/main/reference/api.html#scanspec.specs.Static. After that we should probably just run it past @coretl or @callumforrester to confirm it's the simplest it can be.
src/hyperion/parameters/rotation.py
Outdated
|
||
@property | ||
def directory(self): | ||
directory = str(self.visit_directory / "auto" / str(self.sample_id)) |
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.
Must: This certainly isn't right. From looking round on the file system it looks like some use sample name some use something else. We may have to provide the prefix
as in http://agamemnon.diamond.ac.uk/example/collect for now then discuss with SIMS/Analysis how that is actually built.
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.
We could just redefine it for UDC and say it is always the sample_id but we should shout a bit louder before we do that
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.
Will take in the storage_directory
as a param for now
src/hyperion/parameters/rotation.py
Outdated
omega_start_deg: float = Field(default=0) # type: ignore | ||
rotation_axis: RotationAxis = Field(default=RotationAxis.OMEGA) | ||
shutter_opening_time_s: float = Field(default=CONST.I03.SHUTTER_TIME_S) | ||
rotation_angle_deg: float |
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: rotation_angle_deg
wasn't immediately obvious to me when I looked at it. Could you add a docstring to say what it is?
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 renamed it to scan_width_deg
src/hyperion/parameters/rotation.py
Outdated
scan_spec = Line( | ||
axis="omega", | ||
start=self.omega_start_deg, | ||
stop=(self.rotation_angle_deg + self.omega_start_deg), |
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.
Nit: The addition being the other way round makes more sense to me but whatever
Additionally, can we update https://github.com/DiamondLightSource/hyperion/wiki/Parameter-model a bit? |
1029fb8
to
3588167
Compare
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.
Thanks! Please update the docs at https://github.com/DiamondLightSource/hyperion/wiki/Parameter-model to something close to where we want to be with this and then happy to approve.
@DominicOram will this do for now? https://github.com/DiamondLightSource/hyperion/wiki/Parameter-model |
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 docs, ta!
…Source/698_new_external_param_model New external parameter model
Fixes #698
Introduces a new set of pydantic classes to replace the old external params. Eventually these will replace the internal params too.
Associated GDA changes at https://gerrit.diamond.ac.uk/c/gda/gda-mx/+/41445
To test: