368 generalise ispyb handling to rotation scans#711
Conversation
and instead pass references to active connection
Codecov Report
@@ Coverage Diff @@
## main #711 +/- ##
==========================================
- Coverage 94.45% 94.38% -0.07%
==========================================
Files 37 40 +3
Lines 1875 2013 +138
==========================================
+ Hits 1771 1900 +129
- Misses 104 113 +9
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
|
|
||
| @pytest.mark.s03() | ||
| @patch("bluesky.plan_stubs.wait") | ||
| def test_ispyb_deposition_in_plan( |
There was a problem hiding this comment.
Great test, thank you!
Should: Can we set the dev config here like we do in the test_ispyb_dev_connection so that it runs with the environment variable being set. We should move the path to the dev config into the constants area at the same time.
| with ispyb.open(self.ISPYB_CONFIG_PATH) as conn: | ||
| return self._store_scan_data(conn) | ||
|
|
||
| def end_deposition(self, success: str, reason: str): |
There was a problem hiding this comment.
Should: Is the only difference between this and the grid one how many dcids we have? Feels like we can move some more logic into the parent here
| data_collection_group_id = self._store_data_collection_group_table(conn) | ||
| self.data_collection_group_id = data_collection_group_id | ||
| data_collection_id = self._store_data_collection_table( | ||
| conn, data_collection_group_id | ||
| ) | ||
| self.data_collection_id = data_collection_id | ||
| self._store_position_table(conn, data_collection_id) |
There was a problem hiding this comment.
Should: The logic of "store group, store dc, store position" is the same for all these. Can that go in the parent class?
There was a problem hiding this comment.
I guess, but I think it would be more complicated given subtle differences - 3d grid scan does dc and position twice, and they have different return types. I personally think it's not worth changing three sets of three simple statements for one set of logic based on how many dcids we have.
| self.datacollection_ids = None | ||
| self.datacollection_group_id = None | ||
| self.grid_ids = None | ||
| def __init__(self, ispyb_config, parameters=None) -> None: |
There was a problem hiding this comment.
Nit: The parent class doesn't need parameters to be passed in
There was a problem hiding this comment.
Should: Every subclass needs an experiment_type, let's pass this in here
DominicOram
left a comment
There was a problem hiding this comment.
Mostly good, thanks. Some suggestions for improvements in the code. Also, when running the new system test I get src/artemis/experiment_plans/tests/test_rotation_scan_plan.py::test_ispyb_deposition_in_plan - AttributeError: armed
| "zebra": zebra, | ||
| "detector_motion": detector_motion, | ||
| "backlight": backlight, | ||
| "eiger": i03.eiger(wait_for_connection=False), |
There was a problem hiding this comment.
Could: I should have advertised this more widely but I think this is no longer necessary. Feel free to modify here or we can wait for #825
| zebra.pc.arm_demand.set = mock_arm_disarm | ||
|
|
||
| devices = { | ||
| "eiger": i03.eiger(wait_for_connection=False, fake_with_ophyd_sim=True), |
There was a problem hiding this comment.
Could: As above with waiting for connection
There was a problem hiding this comment.
yes, this one wasn't necessary anyway, it's an ophyd sim device... haha...
| self.ispyb.append_to_comment(crystal_summary) | ||
|
|
||
| raw_centre = np.array([*(raw_results[0]["centre_of_mass"])]) | ||
| adjusted_centre = raw_centre - np.array([0.5, 0.5, 0.5]) |
| E.g.: | ||
| nexus_file_handler_callback = NexusFileHandlerCallback(parameters) | ||
| RE.subscribe(nexus_file_handler_callback) | ||
| Or decorate a plan using bluesky.preprocessors.subs_decorator. | ||
|
|
||
| See: https://blueskyproject.io/bluesky/callbacks.html#ways-to-invoke-callbacks | ||
|
|
||
| Usually used as part of an FGSCallbackCollection. |
There was a problem hiding this comment.
Should: This has incorrect references to Nexus/FGS
| from artemis.parameters.plan_specific.fgs_internal_params import FGSInternalParameters | ||
|
|
||
|
|
||
| class RotationISPyBHandlerCallback(CallbackBase): |
There was a problem hiding this comment.
Should: 90% of the code in here is the same as the FGS one, I feel like we could have a common inheritence for them?
|
|
||
| @patch("ispyb.open", new_callable=mock_open) | ||
| def test_store_grid_scan(ispyb_conn, dummy_ispyb, dummy_params): | ||
| def test_store_rotation_scan( |
There was a problem hiding this comment.
Should: I think we're mocking out a bit too much here, which is why we're getting such poor coverage on StoreRotationInIspyb. Can we either in this test or in a new test mock just the upserts?
There was a problem hiding this comment.
I don't really understand. As fast as I can tell we are only mocking the connection (which is necessary at least for tests which run in CI) and nothing else? low coverage seems more down to not testing _mutate_data_collection_params_for_experiment
There was a problem hiding this comment.
I mean that later in this test we have lots of when(x).y().thenReturn(z), which means we're never really testing any of the functionality of x.y(). I think it's fine to leave it for now though,given we have the additional tests on the mutate
| LOGGER.warning("No xtal snapshot paths sent to ISPyB!") | ||
| super().__init__(ispyb_config, "SAD") | ||
|
|
||
| def _mutate_data_collection_params_for_experiment( |
There was a problem hiding this comment.
Should: I think a few additional simple tests just covering this function would be good
| ispyb_params: GridscanIspybParams | None = None | ||
| data_collection_ids: tuple[int, ...] | None = None | ||
| upper_left: list[int] | None = None | ||
| y_steps: int | None = None | ||
| y_step_size: int | None = None | ||
| grid_ids: tuple[int, ...] | None = None |
There was a problem hiding this comment.
Should: As above, avoid class variables
| # not an annotation but specified as field encoder in DetectorParams: | ||
| detector_field_keys.append("detector") | ||
| ispyb_field_keys = list(IspybParams.__annotations__.keys()) + list( | ||
| GridscanIspybParams.__annotations__.keys() |
There was a problem hiding this comment.
Should: This should be the RotationIspybParams right?
There was a problem hiding this comment.
Can you write a test that would have caught this too
| super().__init__(**args) | ||
|
|
||
| @staticmethod | ||
| def _artemis_param_key_definitions() -> tuple[list[str], list[str], list[str]]: |
There was a problem hiding this comment.
Should: I feel like we've moved too much of this function to be in each different class, when only a small part of it is different for each. Could we only move the different part please?
DominicOram
left a comment
There was a problem hiding this comment.
Minor issue in logging but once I fixed that this worked. Thank you very much, sorry for the long delay on it!
Fixes #368
To test:
test_rotation_scan_plan.py