-
Notifications
You must be signed in to change notification settings - Fork 130
Add and remove peaks in new Instrument View #40508
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?
Add and remove peaks in new Instrument View #40508
Conversation
If one peaks workspace is selected in the list then add peaks to it, otherwise add peaks in a special workspace like the old instrument view.
This will delete the peak nearest to the place where the user clicks in the line plot.
Every peak on any selected detector will be deleted from the respective peaks workspace. Exposed removePeaks() to Python so I could remove multiple peaks at once. This makes it easier because otherwise after every peak removal I would have to recalculate the peak indices, plus the interface would be refreshed on the peaks workspace changing.
Calling CreatePeaksWorkspace without StoreInADS=False will result the add callback on the ADS observer being called before CreatePeaksWorkspace has exited. This will end up calling a different algorithm which cannot proceed because CreatePeaksWorkspace is still running, hence a deadlock. The fix is to add the peaks workspace manually, then CreatePeaksWorkspace won't be running and other algorithms will be free to run.
RichardWaiteSTFC
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.
Thanks for this - I've had a look through but not tested yet sorry!
qt/python/instrumentview/instrumentview/ConvertUnitsCalculator.py
Outdated
Show resolved
Hide resolved
qt/python/instrumentview/instrumentview/FullInstrumentViewModel.py
Outdated
Show resolved
Hide resolved
| return ads.retrieveWorkspaces(selected_peaks_workspaces)[0] | ||
| if self._instrument_view_peaks_ws_name in ads.getObjectNames(): | ||
| return ads.retrieveWorkspaces([self._instrument_view_peaks_ws_name])[0] | ||
| peaks_ws = CreatePeaksWorkspace(self._workspace, 0, OutputWorkspace=self._instrument_view_peaks_ws_name, StoreInADS=False) |
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 not set StoreInADS=True as you add it to ADS in the next line? If you do need to keep it out of the ADS then I think with StoreInADS=False you don't need to specify OutputWorkspace
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 because with StoreInADS=True it will trigger the ADS callbacks before the algorithm has exited, causing a hang.
| if peaks_ws.name() not in peaks_grouped_by_ws: | ||
| continue | ||
| peaks_by_detector = peaks_grouped_by_ws[peaks_ws.name()] | ||
| picked_detector_peaks = [p for p in peaks_by_detector if p.detector_id in detector_ids] |
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.
The peaks workspace has a DetID column which means this search for matching detector indices could be vectorised? It might not make much difference!
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.
Bit of a big refactor to do that, can be tested out another time I think
|
|
||
| def _update_peak_buttons(self) -> None: | ||
| self._view.set_add_peak_button_enabled( | ||
| len(self._model.picked_detector_ids) == 1 and self._peak_interaction_status != PeakInteractionStatus.Adding |
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 confused why we need the check for self._peak_interaction_status != PeakInteractionStatus.Adding - surely if this is set then the add button should be/is enabled? Is this because you expect it to be in the state PeakInteractionStatus.Disabled?
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.
If you click the add button then the button is disabled until you've selected the peak in the line plot. When going into this method it could be either adding or deleting peaks.
| def closeEvent(self, QCloseEvent: QEvent) -> None: | ||
| """When closing, make sure to close the plotters and figure correctly to prevent errors""" | ||
| super().closeEvent(QCloseEvent) | ||
| with suppress(TypeError): |
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 looks like it fixes an unrelated bug - does it require a separate release note?
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.
Never actually ran into this bug, this is just bombproofing.
qt/python/instrumentview/instrumentview/test/test_convert_units_calculator.py
Outdated
Show resolved
Hide resolved
These are updated by the calibration, and will give different numbers to the values from the detector info. Co-authored-by: RichardWaiteSTFC
Co-authored-by: RichardWaiteSTFC
Co-authored-by: <RichardWaiteSTFC>
bce00a9 to
dc0c8f9
Compare
RichardWaiteSTFC
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.
Sorry, small bug with unit conversion still!
Also a usability thing - you often need to zoom into a peak on 1D plot before adding. Here you have to remember to do that before clicking Add.
If you do zoom into the 1d plot but leave the zoom button clicked and add a peak the red line doesn't show up in the plot - is that easy to fix?
| if source_unit == target_unit: | ||
| return value | ||
| diffraction_constants = self._spectrum_info.diffractometerConstants(int(spectrum_no)) | ||
| return UnitConversion.run(source_unit, target_unit, value, self._l1, DeltaEModeType.Elastic, diffraction_constants) |
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.
As per previous comment (albeit edited yesterday - sorry for not drawing your attention to it earlier) I think for conversion TOF <-> wavelength you still need L2 as well!
I now see this error when x unit of 1D plot set to wavelength and workspace has units of TOF.
RuntimeError: An l2 value must be supplied in the extra parameters when initialising Wavelength for conversion via TOF
FYI For conversion between wavelength <-> d-spacing you'd think it needs the two-theta, but it looks like it goes via TOF because I get the same error above with a workspace in wavelength and 1D plot in d-spacing and vice versa. So L2 alone should suffice!
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 spotting this, fixed now hopefully.
| self._workspace_x_unit = x_unit.unitID() | ||
| self._workspace_x_unit_display = f"{str(x_unit.caption())} ({str(x_unit.symbol())})" | ||
| self._selected_peaks_workspaces = [] | ||
| self._instrument_view_peaks_ws_name = f"instrument_view_peaks_{self._workspace.name()}" |
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.
Is there any reason to preserve backward compatibility by naming the workspace SingleCrystalPeakTable?
I do like however the table doesn't overwrite a table produced on another workspace.
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 don't know of a specific reason
Trying to zoom or do anything else is not possible because the interface is waiting for the peak to be picked.
If the user is in the middle of adding a peak, then they select a detector, then stop the adding peak process. You can only add a peak if exactly one detector is selected, otherwise we don't know which detector the peak is on.
It looks to me like the red line doesn't show up, but it does add the peak in the correct place. I've changed it slightly so that if you click 'Add Peak' then it disables the toolbar until the peak is added, otherwise could be some odd behaviour if the zoom tool is selected with the red line enabled as well. For getting the red line to appear while zoomed in, wasn't immediately obvious how to fix that, perhaps a separate PR? |
Add and remove peaks in the new Instrument View. If a single detector is selected then one can now select
Add Peakand select the peak location in the line plot. If a single peaks workspace is already selected to overlay then the peak will be added to that workspace, otherwise it will be added to a separate Instrument View peaks workspace. When one or more detectors are selected, one can selectDelete Single Peakand click in the line plot, then the peak closest to where you clicked will be removed from its peaks workspace. The final option is to delete all peaks on all selected detectors.Closes #40045 .
To test:
Add peaks, delete peaks (including in the old Instrument View, I suggest having both open), do some masking at the same time. Use the old Instrument View to check that peaks have been added and removed correctly.
Reviewer
Your comments will be used as part of the gatekeeper process. Comment clearly on what you have checked and tested during your review. Provide an audit trail for any changes requested.
As per the review guidelines:
mantid-developersormantid-contributorsteams, add a review commentrerun cito authorize/rerun the CIGatekeeper
As per the gatekeeping guidelines: