-
Notifications
You must be signed in to change notification settings - Fork 129
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
38863 Update Engineering Diffraction Calibration region of interest functionality #38870
base: main
Are you sure you want to change the base?
Conversation
77549a4
to
eaac41a
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.
I have not functionally tested yet, but from an initial pass through the proposed changes, everything looks good! - only a few minor suggestions.
I wonder if it would be worthwhile updating dev-docs/source/Testing/EngineeringDiffraction/EngineeringDiffractionTestGuide.rst
to add a test to validate that #38879 and #38863 are not accidentally reintroduced in the future. I feel like this would be a good smoke test.
...nterfaces/Engineering/gui/engineering_diffraction/tabs/common/cropping/cropping_presenter.py
Outdated
Show resolved
Hide resolved
self.set_grouping_filepath_from_prm_filepath() | ||
self.extra_group_suffix = "_" + path.split(self.grouping_filepath)[1].split(".")[0] | ||
except TypeError: | ||
self.extra_group_suffix = "" | ||
|
||
# getters |
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.
While we are touching this section of code anyway, I think the logic here could be extracted into a separate method called something like _get_suffix
to reduce duplication, maybe into something like this:
# getters | |
# getters | |
def get_foc_ws_suffix(self) -> str: | |
return self._get_suffix(GROUP_FOC_WS_SUFFIX) | |
def get_group_suffix(self) -> str: | |
return self._get_suffix(GROUP_SUFFIX) | |
def get_group_ws_name(self) -> str: | |
return self._get_suffix(GROUP_WS_NAMES) | |
def _get_suffix(self, suffix_dict: dict) -> str: | |
"""Get the suffix for the current group""" | |
if self.group: | |
if self.group != GROUP.CUSTOM: | |
return suffix_dict[self.group] | |
else: | |
self.set_extra_group_suffix() | |
return f"{suffix_dict[GROUP.CUSTOM]}{self.extra_group_suffix}" | |
return "" |
I can't comment of whether or not it makes sense to return "" if not self.group
, as It may be better to return an warning instead.
|
||
def set_group(self, group): | ||
self.group = group | ||
|
||
# functional | ||
def set_grouping_filepath_from_prm_filepath(self): | ||
if self.prm_filepath is not None: |
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 think this may read nicer as: if self.prm_filepath:
@@ -226,14 +256,18 @@ def get_group_ws(self): | |||
elif self.group == GROUP.CROPPED: | |||
self.create_grouping_workspace_from_spectra_list() | |||
elif self.group == GROUP.CUSTOM: | |||
self.create_grouping_workspace_from_calfile() | |||
ext = self.grouping_filepath.split(".")[-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.
NIPICK: Because self.grouping_filepath
can be set to None
which .split
would not be a valid attribute of, we should probably first assert that self.grouping_filepath
is not None
.
I would also be tempted to extract this into a separate method to reduce the number of if statements in this method and add some extra validation checks - maybe something like:
def get_group_ws(self):
"""
Returns grouping workspace for ROI (creates if not present)
:return: group workspace
"""
if not self.group_ws or not ADS.doesExist(self.group_ws.name()):
if self.group.banks:
self.create_bank_grouping_workspace()
elif self.group == GROUP.CROPPED:
self.create_grouping_workspace_from_spectra_list()
elif self.group == GROUP.CUSTOM:
self.create_grouping_workspace_from_file()
return self.group_ws
def create_grouping_workspace_from_file(self) -> None:
"""
Create grouping workspace from a custom file (.cal or .xml)
"""
if not self.grouping_filepath:
raise ValueError("Grouping file path is not set.")
ext = path.splitext(self.grouping_filepath)[-1].lower()
if ext == ".cal":
self.create_grouping_workspace_from_calfile()
elif ext == ".xml":
self.group_ws = LoadDetectorsGroupingFile(InputFile=self.grouping_filepath, OutputWorkspace=self.get_group_ws_name())
else:
raise ValueError(f"Unsupported file extension: {ext}")
Genuine docs failure |
A bit of a further update, especially re: manual testing. I was reluctant to add a manual test as it felt like it could be automatically tested and I know people don't love doing the manual testing. I have added a system test that is essentially carrying out the procedure of running a calibration and focus with one custom group file, then running it again with a different group - and checking that this results in a different final spec. This, combined with the new tests in Re doc failure: I tried to change so the release notes link always has the algorithm name, but forgot to remove the |
5549dd4
to
0baff4b
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 for the changes and additional tests! A system test is a good idea to save on adding another smoke test.
Would you be happy to rebase you're commits to squash them down? From looking through them, I think we can reduce them and possible re-order here and there. Here's a nice blog by GitHub I have used as a reference for structuring my own commits in the past: https://github.blog/developer-skills/github/write-better-commits-build-better-projects/
I've added a few minor suggestions to condense some methods slightly. but overall, your changes look really good and work as expected from manual testing.
|
||
# Connect view signals to local functions | ||
self.view.set_on_combo_changed(self.on_combo_changed) | ||
self.view.set_on_custom_calfile_changed(self.on_calfile_changed) | ||
self.view.set_on_custom_groupingfile_changed(self.on_groupingfile_changed) | ||
self.view.set_on_custom_spectra_changed(self.on_spectra_changed) | ||
|
||
self.on_combo_changed(0) | ||
|
||
# Signal Activated Functions | ||
|
||
def on_combo_changed(self, index): |
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.
Sorry for not picking this one up in the initial review. While we are here, I think we can actually simplify on_combo_changed
quite a lot to condense it down so we don't have so many elif
statements to hopefully make the method easier to read at a glance by using a dictionary to map groups and passing boolean comparisons of the indexes to configure custom_calfile_enabled
, custom_spectra_enabled
and set_custom_widgets_visibility
def on_combo_changed(self, index: int) -> None:
"""
Handles the event when the combo box selection is changed.
GROUP.TEXTURE30 is the default group if no cropping is requested.
:param index: The index of the selected item in the combo box.
"""
group_mapping = {
0: GROUP.CUSTOM,
1: GROUP.NORTH,
2: GROUP.SOUTH,
3: GROUP.CROPPED,
4: GROUP.TEXTURE20,
5: GROUP.TEXTURE30
}
self.group = group_mapping.get(index, GROUP.TEXTURE30)
self.custom_groupingfile_enabled = (index == 0)
self.custom_spectra_enabled = (index == 3)
self.set_custom_widgets_visibility(index == 0, index == 3)
As this refactor suggestion is technically out of scope for the assigned issue, feel free to ignore. This is more of a personal preference thing for trying to clean up code as I'm modifying it so a codebase can slowly be cleaned up/kept up to date over time.
return self.prm_filepath | ||
|
||
# setters | ||
def set_prm_filepath(self, prm_filepath): | ||
def set_extra_group_suffix(self) -> None: |
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.
NITPICK: I would be tempted to re-order the logic here a little and to add a description of the type error should this get triggered - maybe to something similar to:
def set_extra_group_suffix(self) -> None:
self.extra_group_suffix = ""
if not isinstance(self.grouping_filepath, str):
raise TypeError("The grouping file path must be a string")
if self.group == GROUP.CUSTOM:
self.set_grouping_filepath_from_prm_filepath()
filename = path.basename(self.grouping_filepath)
self.extra_group_suffix = f"_{path.splitext(filename)[0]}"
elif self.group == GROUP.CROPPED and self.spectra_list_str:
self.extra_group_suffix = f"_{self.spectra_list_str}"
What are your thoughts on this?
# BANKS can be "all_banks, "bank_1", "bank_2", "Cropped", "Custom", "Texture20", "Texture30" | ||
fname_words = fname.split("_") | ||
suffix = fname_words[-1].split(".")[0] # take last element and remove extension | ||
# fname has form INSTRUMENT_ceriaRunNo_BANKS.ext |
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 we move the comments into the docstring
Description of work
Summary of work
Added support so the Custom File provided to Engineering Diffraction Calibration can be an
xml
, such as those output bySaveDetectorsGrouping
Fixes #38863 .
Also fixes a bug I found in testing new implementation #38879
Further detail of work
Changed it so the interface now accepts
xml
files of the grouping. Additionally changed both the user facing and internal reference to this fromCalFile
(or variations upon this) toGroupingFile
and in the UICrop Calibration
toSet Calibration Region of Interest
, these provide more accurate names to actual functionality and should make the interface more intuitive to use.Changed the naming suffix for custom file
example_group.xml
from_Custom
to_Custom_example_group
so they don't get overwritten when custom grouping is changed (also more clear to the user what grouping is being used).Changed the naming suffix for custom crop
example_spec
from_Cropped
to_Cropped_example_spec
so they don't get overwritten when custom grouping is changed (also more clear to the user what grouping is being used).Finally changed it for the vanadium normalisation so a warning is flagged if
GROUP.CUSTOM
orGROUP.CROPPED
are loaded in from the ADS, which, together with more unique naming, should cover the bug #38879To test:
Open the Engineering Diffraction Interface
Select
Create New Calibration
Set the sample as
305738
Select
Set Calibration Region of Interest
Set Region of Interest to
Custom Grouping File
in the drop downTry setting a custom grouping in
xml
format (code to create one provided below)Calibration should be successful
Try using calibration to focus on the next tab
If you use the customs below should get: 2 spectra for
"bank"
, 10 for"module"
, and 90 for"block"
(Bank should give identical results to Test 1 in the manual testing:
https://developer.mantidproject.org/Testing/EngineeringDiffraction/EngineeringDiffractionTestGuide.html
)You can also run through the reproduction instructions here: #38879 and check that the bug is no longer there.
Reviewer
Please comment on the points listed below (full description).
Your comments will be used as part of the gatekeeper process, so please comment clearly on what you have checked during your review. If changes are made to the PR during the review process then your final comment will be the most important for gatekeepers. In this comment you should make it clear why any earlier review is still valid, or confirm that all requested changes have been addressed.
Code Review
Functional Tests
Does everything look good? Mark the review as Approve. A member of
@mantidproject/gatekeepers
will take care of it.Gatekeeper
If you need to request changes to a PR then please add a comment and set the review status to "Request changes". This will stop the PR from showing up in the list for other gatekeepers.