Skip to content

Commit

Permalink
Merge pull request #485 from neutrons/EWM7760_mask_unfocused_data
Browse files Browse the repository at this point in the history
reduction: apply pixelmask to unfocused data
  • Loading branch information
ekapadi authored Oct 29, 2024
2 parents ef1bdf9 + 41023a8 commit c629472
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 27 deletions.
28 changes: 19 additions & 9 deletions src/snapred/backend/recipe/ReductionRecipe.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Set, Tuple, Type
from typing import Any, Dict, List, Optional, Set, Tuple, Type

from snapred.backend.dao.ingredients import ReductionIngredients as Ingredients
from snapred.backend.log.logger import snapredLogger
Expand Down Expand Up @@ -87,7 +87,9 @@ def _deleteWorkspace(self, workspace: str):
)
self.mantidSnapper.executeQueue()

def _cloneAndConvertWorkspace(self, workspace: WorkspaceName, units: str) -> WorkspaceName:
def _prepareUnfocusedData(
self, workspace: WorkspaceName, mask: Optional[WorkspaceName], units: str
) -> WorkspaceName:
unitsAbrev = ""
match units:
case "Wavelength":
Expand All @@ -102,17 +104,24 @@ def _cloneAndConvertWorkspace(self, workspace: WorkspaceName, units: str) -> Wor
raise ValueError(f"cannot convert to unit '{units}'")

runNumber, liteMode = workspace.tokens("runNumber", "lite")
self.unfocWS = wng.run().runNumber(runNumber).lite(liteMode).unit(unitsAbrev).group(wng.Groups.UNFOC).build()
self._cloneWorkspace(workspace, self.unfocWS)
self.unfocWs = wng.run().runNumber(runNumber).lite(liteMode).unit(unitsAbrev).group(wng.Groups.UNFOC).build()
self._cloneWorkspace(workspace, self.unfocWs)

if mask:
self.mantidSnapper.MaskDetectorFlags(
"Applying pixel mask to unfocused data",
MaskWorkspace=mask,
OutputWorkspace=self.unfocWs,
)

self.mantidSnapper.ConvertUnits(
f"Convert unfocused workspace to {units} units",
InputWorkspace=workspace,
OutputWorkspace=self.unfocWS,
f"Converting unfocused data to {units} units",
InputWorkspace=self.unfocWs,
OutputWorkspace=self.unfocWs,
Target=units,
)
self.mantidSnapper.executeQueue()
return self.unfocWS
return self.unfocWs

def _applyRecipe(self, recipe: Type[Recipe], ingredients_, **kwargs):
if "inputWorkspace" in kwargs:
Expand Down Expand Up @@ -164,8 +173,9 @@ def queueAlgos(self):
def execute(self):
data: Dict[str, Any] = {"result": False}

# Retain unfocused data for comparison.
if self.keepUnfocused:
data["unfocusedWS"] = self._cloneAndConvertWorkspace(self.sampleWs, self.convertUnitsTo)
data["unfocusedWS"] = self._prepareUnfocusedData(self.sampleWs, self.maskWs, self.convertUnitsTo)

# 1. PreprocessReductionRecipe
outputs = []
Expand Down
63 changes: 45 additions & 18 deletions tests/unit/backend/recipe/test_ReductionRecipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,55 +80,82 @@ def test_deleteWorkspace(self):
recipe.mantidSnapper.DeleteWorkspace.assert_called_once_with(mock.ANY, Workspace=workspace)
recipe.mantidSnapper.executeQueue.assert_called()

def test_cloneAndConvertWorkspace(self):
def test_prepareUnfocusedData(self):
recipe = ReductionRecipe()
recipe.mantidSnapper = mock.Mock()
workspace = wng.run().runNumber("555").lite(True).build()

# TODO: All units are tested here for now, this will be changed when EWM 6615 is completed
units = "dSpacing"
msg = f"Convert unfocused workspace to {units} units"
recipe._cloneAndConvertWorkspace(workspace, units)
msg = f"Converting unfocused data to {units} units"
recipe._prepareUnfocusedData(workspace, None, units)
outputWs = wng.run().runNumber("555").lite(True).unit(wng.Units.DSP).group(wng.Groups.UNFOC).build()
recipe.mantidSnapper.ConvertUnits.assert_called_once_with(
msg, InputWorkspace=workspace, OutputWorkspace=outputWs, Target=units
msg, InputWorkspace=outputWs, OutputWorkspace=outputWs, Target=units
)
recipe.mantidSnapper.executeQueue.assert_called()
recipe.mantidSnapper.reset_mock()

units = "MomentumTransfer"
msg = f"Convert unfocused workspace to {units} units"
recipe._cloneAndConvertWorkspace(workspace, units)
msg = f"Converting unfocused data to {units} units"
recipe._prepareUnfocusedData(workspace, None, units)
outputWs = wng.run().runNumber("555").lite(True).unit(wng.Units.QSP).group(wng.Groups.UNFOC).build()
recipe.mantidSnapper.ConvertUnits.assert_called_once_with(
msg, InputWorkspace=workspace, OutputWorkspace=outputWs, Target=units
msg, InputWorkspace=outputWs, OutputWorkspace=outputWs, Target=units
)
recipe.mantidSnapper.executeQueue.assert_called()
recipe.mantidSnapper.reset_mock()

units = "Wavelength"
msg = f"Convert unfocused workspace to {units} units"
recipe._cloneAndConvertWorkspace(workspace, units)
msg = f"Converting unfocused data to {units} units"
recipe._prepareUnfocusedData(workspace, None, units)
outputWs = wng.run().runNumber("555").lite(True).unit(wng.Units.LAM).group(wng.Groups.UNFOC).build()
recipe.mantidSnapper.ConvertUnits.assert_called_once_with(
msg, InputWorkspace=workspace, OutputWorkspace=outputWs, Target=units
msg, InputWorkspace=outputWs, OutputWorkspace=outputWs, Target=units
)
recipe.mantidSnapper.executeQueue.assert_called()
recipe.mantidSnapper.reset_mock()

units = "TOF"
msg = f"Convert unfocused workspace to {units} units"
recipe._cloneAndConvertWorkspace(workspace, units)
msg = f"Converting unfocused data to {units} units"
recipe._prepareUnfocusedData(workspace, None, units)
outputWs = wng.run().runNumber("555").lite(True).unit(wng.Units.TOF).group(wng.Groups.UNFOC).build()
recipe.mantidSnapper.ConvertUnits.assert_called_once_with(
msg, InputWorkspace=workspace, OutputWorkspace=outputWs, Target=units
msg, InputWorkspace=outputWs, OutputWorkspace=outputWs, Target=units
)
recipe.mantidSnapper.executeQueue.assert_called()
recipe.mantidSnapper.reset_mock()

units = "NOT_A_UNIT"
with pytest.raises(ValueError, match=r"cannot convert to unit.*"):
recipe._cloneAndConvertWorkspace(workspace, units)
recipe._prepareUnfocusedData(workspace, None, units)

def test_prepareUnfocusedData_masking(self):
recipe = ReductionRecipe()
recipe.mantidSnapper = mock.Mock()

units = "dSpacing"
workspace = wng.run().runNumber("555").lite(True).build()
maskWs = wng.reductionUserPixelMask().numberTag(2).build()
outputWs = wng.run().runNumber("555").lite(True).unit(wng.Units.DSP).group(wng.Groups.UNFOC).build()

recipe._prepareUnfocusedData(workspace, None, units)
recipe.mantidSnapper.MaskDetectorFlags.assert_not_called()
recipe.mantidSnapper.reset_mock()

recipe._prepareUnfocusedData(workspace, maskWs, units)

recipe.mantidSnapper.MaskDetectorFlags.assert_called_once_with(
"Applying pixel mask to unfocused data", MaskWorkspace=maskWs, OutputWorkspace=outputWs
)
recipe.mantidSnapper.ConvertUnits.assert_called_once_with(
f"Converting unfocused data to {units} units",
InputWorkspace=outputWs,
OutputWorkspace=outputWs,
Target=units,
)
recipe.mantidSnapper.executeQueue.assert_called()
recipe.mantidSnapper.reset_mock()

@mock.patch("mantid.simpleapi.mtd", create=True)
def test_keepUnfocusedData(self, mockMtd):
Expand Down Expand Up @@ -164,7 +191,7 @@ def test_keepUnfocusedData(self, mockMtd):
recipe._applyRecipe = mock.Mock()
recipe._cloneIntermediateWorkspace = mock.Mock()
recipe._deleteWorkspace = mock.Mock()
recipe._cloneAndConvertWorkspace = mock.Mock()
recipe._prepareUnfocusedData = mock.Mock()
recipe._prepGroupingWorkspaces = mock.Mock()
recipe._prepGroupingWorkspaces.return_value = ("sample_grouped", "norm_grouped")

Expand All @@ -180,7 +207,7 @@ def test_keepUnfocusedData(self, mockMtd):
result = recipe.execute()

# Assertions
recipe._cloneAndConvertWorkspace.assert_called_once_with("sample", "dSpacing")
recipe._prepareUnfocusedData.assert_called_once_with("sample", "mask", "dSpacing")
assert recipe._deleteWorkspace.call_count == len(recipe._prepGroupingWorkspaces.return_value)
recipe._deleteWorkspace.assert_called_with("norm_grouped")
assert result["outputs"][0] == "sample_grouped"
Expand Down Expand Up @@ -341,7 +368,7 @@ def test_execute(self, mockMtd):
recipe._applyRecipe = mock.Mock()
recipe._cloneIntermediateWorkspace = mock.Mock()
recipe._deleteWorkspace = mock.Mock()
recipe._cloneAndConvertWorkspace = mock.Mock()
recipe._prepareUnfocusedData = mock.Mock()
recipe._prepGroupingWorkspaces = mock.Mock()
recipe._prepGroupingWorkspaces.return_value = ("sample_grouped", "norm_grouped")

Expand Down Expand Up @@ -480,7 +507,7 @@ def test_execute_with_fully_masked_group(self, mockMtd):
recipe._applyRecipe = mock.Mock()
recipe._cloneIntermediateWorkspace = mock.Mock()
recipe._deleteWorkspace = mock.Mock()
recipe._cloneAndConvertWorkspace = mock.Mock()
recipe._prepareUnfocusedData = mock.Mock()
recipe._prepGroupingWorkspaces = mock.Mock()
recipe._prepGroupingWorkspaces.return_value = ("sample_grouped", "norm_grouped")

Expand Down

0 comments on commit c629472

Please sign in to comment.