From 4119dc1635acff53b69fbaa3b4c0f8e393c7812c Mon Sep 17 00:00:00 2001 From: Michael Walsh Date: Thu, 12 Dec 2024 16:34:58 -0500 Subject: [PATCH] fix broken tests, still pending coverage --- .../recipe/GenerateFocussedVanadiumRecipe.py | 12 +++- tests/data/snapred-data | 2 +- .../test_CreateArtificialNormalizationAlgo.py | 15 ++++- .../recipe/test_ApplyNormalizationRecipe.py | 67 +++++-------------- .../test_GenerateFocussedVanadiumRecipe.py | 26 ++++--- .../backend/recipe/test_ReductionRecipe.py | 32 +++++---- .../backend/service/test_ReductionService.py | 5 +- tests/util/SculleryBoy.py | 4 ++ 8 files changed, 83 insertions(+), 80 deletions(-) diff --git a/src/snapred/backend/recipe/GenerateFocussedVanadiumRecipe.py b/src/snapred/backend/recipe/GenerateFocussedVanadiumRecipe.py index af09f3a39..41be49a61 100644 --- a/src/snapred/backend/recipe/GenerateFocussedVanadiumRecipe.py +++ b/src/snapred/backend/recipe/GenerateFocussedVanadiumRecipe.py @@ -61,15 +61,21 @@ def queueNaturalNormalization(self): SmoothingParameter=self.smoothingParameter, ) - def queueAlgos(self): + def _queueRebinInputWorkspace(self): """ - Queues up the procesing algorithms for the recipe. - Requires: unbagged groceries. + Rebins the input workspace to the pixel group. """ rebinRecipe = RebinFocussedGroupDataRecipe(self.utensils) rebinIngredients = RebinFocussedGroupDataRecipe.Ingredients(pixelGroup=self.pixelGroup) rebinRecipe.prep(rebinIngredients, {"inputWorkspace": self.inputWS}) + def queueAlgos(self): + """ + Queues up the procesing algorithms for the recipe. + Requires: unbagged groceries. + """ + self._queueRebinInputWorkspace() + if self.artificialNormalizationIngredients is not None: self.queueArtificialNormalization() else: diff --git a/tests/data/snapred-data b/tests/data/snapred-data index b6fbfbadf..bd6930ff5 160000 --- a/tests/data/snapred-data +++ b/tests/data/snapred-data @@ -1 +1 @@ -Subproject commit b6fbfbadfe8c080b96895e26c5153db344821a02 +Subproject commit bd6930ff57eef257a17adecdab9b7d9cea76850f diff --git a/tests/unit/backend/recipe/algorithm/test_CreateArtificialNormalizationAlgo.py b/tests/unit/backend/recipe/algorithm/test_CreateArtificialNormalizationAlgo.py index 7f9aa80ca..50e8c2d4f 100644 --- a/tests/unit/backend/recipe/algorithm/test_CreateArtificialNormalizationAlgo.py +++ b/tests/unit/backend/recipe/algorithm/test_CreateArtificialNormalizationAlgo.py @@ -42,7 +42,10 @@ def test_chop_ingredients(self): algo = Algo() algo.initialize() algo.setProperty("InputWorkspace", self.fakeRawData) - algo.setProperty("Ingredients", self.fakeIngredients.json()) + algo.setProperty("decreaseParameter", self.fakeIngredients.decreaseParameter) + algo.setProperty("lss", self.fakeIngredients.lss) + algo.setProperty("peakWindowClippingSize", self.fakeIngredients.peakWindowClippingSize) + algo.setProperty("smoothingParameter", self.fakeIngredients.smoothingParameter) algo.setProperty("OutputWorkspace", "test_output_ws") originalData = [] inputWs = mtd[self.fakeRawData] @@ -70,7 +73,10 @@ def test_execute(self): algo = Algo() algo.initialize() algo.setProperty("InputWorkspace", self.fakeRawData) - algo.setProperty("Ingredients", self.fakeIngredients.json()) + algo.setProperty("decreaseParameter", self.fakeIngredients.decreaseParameter) + algo.setProperty("lss", self.fakeIngredients.lss) + algo.setProperty("peakWindowClippingSize", self.fakeIngredients.peakWindowClippingSize) + algo.setProperty("smoothingParameter", self.fakeIngredients.smoothingParameter) algo.setProperty("OutputWorkspace", "test_output_ws") assert algo.execute() @@ -84,7 +90,10 @@ def test_output_data_characteristics(self): algo = Algo() algo.initialize() algo.setProperty("InputWorkspace", self.fakeRawData) - algo.setProperty("Ingredients", self.fakeIngredients.json()) + algo.setProperty("decreaseParameter", self.fakeIngredients.decreaseParameter) + algo.setProperty("lss", self.fakeIngredients.lss) + algo.setProperty("peakWindowClippingSize", self.fakeIngredients.peakWindowClippingSize) + algo.setProperty("smoothingParameter", self.fakeIngredients.smoothingParameter) algo.setProperty("OutputWorkspace", "test_output_ws") algo.execute() output_ws = mtd["test_output_ws"] diff --git a/tests/unit/backend/recipe/test_ApplyNormalizationRecipe.py b/tests/unit/backend/recipe/test_ApplyNormalizationRecipe.py index bea9c20fa..4b195121b 100644 --- a/tests/unit/backend/recipe/test_ApplyNormalizationRecipe.py +++ b/tests/unit/backend/recipe/test_ApplyNormalizationRecipe.py @@ -2,12 +2,10 @@ import pytest from mantid.simpleapi import CreateSingleValuedWorkspace, mtd -from util.Config_helpers import Config_override from util.SculleryBoy import SculleryBoy from snapred.backend.recipe.algorithm.Utensils import Utensils from snapred.backend.recipe.ApplyNormalizationRecipe import ApplyNormalizationRecipe, Ingredients -from snapred.meta.Config import Config class ApplyNormalizationRecipeTest(unittest.TestCase): @@ -32,17 +30,13 @@ def test_init_reuseUtensils(self): recipe = ApplyNormalizationRecipe(utensils=utensils) assert recipe.mantidSnapper == utensils.mantidSnapper - def test_chopIngredients(self): + @unittest.mock.patch("snapred.backend.recipe.ApplyNormalizationRecipe.RebinFocussedGroupDataRecipe") + def test_chopIngredients(self, mockRebinRecipe): # noqa: ARG002 recipe = ApplyNormalizationRecipe() ingredients = Ingredients(pixelGroup=self.sculleryBoy.prepPixelGroup()) recipe.chopIngredients(ingredients) assert recipe.pixelGroup == ingredients.pixelGroup - # Apply adjustment that happens in chopIngredients step - dMin = [x + Config["constants.CropFactors.lowdSpacingCrop"] for x in ingredients.pixelGroup.dMin()] - dMax = [x - Config["constants.CropFactors.highdSpacingCrop"] for x in ingredients.pixelGroup.dMax()] - assert recipe.dMin == dMin - assert recipe.dMax == dMax def test_unbagGroceries(self): recipe = ApplyNormalizationRecipe() @@ -84,8 +78,14 @@ def test_stirInputs(self): recipe.backgroundWs = "" recipe.stirInputs() - def test_queueAlgos(self): + @unittest.mock.patch("snapred.backend.recipe.ApplyNormalizationRecipe.RebinFocussedGroupDataRecipe") + def test_queueAlgos(self, mockRebinRecipe): recipe = ApplyNormalizationRecipe() + + mockRebinRecipe().prep().side_effect = lambda x, y: recipe.mantidSnapper.RebinRagged(x, y) + mockRebinIngredients = mockRebinRecipe.Ingredients( + pixelGroup=self.sculleryBoy.prepPixelGroup(), preserveEvents=False + ) ingredients = Ingredients(pixelGroup=self.sculleryBoy.prepPixelGroup()) groceries = self._make_groceries() recipe.prep(ingredients, groceries) @@ -93,25 +93,15 @@ def test_queueAlgos(self): queuedAlgos = recipe.mantidSnapper._algorithmQueue divideTuple = queuedAlgos[0] - rebinRaggedTuple = queuedAlgos[1] assert divideTuple[0] == "Divide" - assert rebinRaggedTuple[0] == "RebinRagged" - # Excessive testing maybe? - assert divideTuple[1] == "Dividing out the normalization.." - assert rebinRaggedTuple[1] == "Resampling X-axis..." - assert divideTuple[2]["LHSWorkspace"] == groceries["inputWorkspace"] - assert divideTuple[2]["RHSWorkspace"] == groceries["normalizationWorkspace"] - assert rebinRaggedTuple[2]["InputWorkspace"] == groceries["inputWorkspace"] - # Apply adjustment that happens in chopIngredients step - dMin = [x + Config["constants.CropFactors.lowdSpacingCrop"] for x in ingredients.pixelGroup.dMin()] - dMax = [x - Config["constants.CropFactors.highdSpacingCrop"] for x in ingredients.pixelGroup.dMax()] - assert rebinRaggedTuple[2]["XMin"] == dMin - assert rebinRaggedTuple[2]["XMax"] == dMax - - def test_cook(self): + mockRebinRecipe().prep.assert_called_with(mockRebinIngredients, {"inputWorkspace": groceries["inputWorkspace"]}) + + @unittest.mock.patch("snapred.backend.recipe.ApplyNormalizationRecipe.RebinFocussedGroupDataRecipe") + def test_cook(self, mockRebinRecipe): untensils = Utensils() mockSnapper = unittest.mock.Mock() + mockSnapper.mtd = unittest.mock.MagicMock() untensils.mantidSnapper = mockSnapper recipe = ApplyNormalizationRecipe(utensils=untensils) ingredients = Ingredients(pixelGroup=self.sculleryBoy.prepPixelGroup()) @@ -126,9 +116,10 @@ def test_cook(self): assert mockSnapper.executeQueue.called assert mockSnapper.Divide.called - assert mockSnapper.RebinRagged.called + assert mockRebinRecipe().prep.called - def test_cater(self): + @unittest.mock.patch("snapred.backend.recipe.ApplyNormalizationRecipe.RebinFocussedGroupDataRecipe") + def test_cater(self, mockRebinRecipe): untensils = Utensils() mockSnapper = unittest.mock.Mock() untensils.mantidSnapper = mockSnapper @@ -145,26 +136,4 @@ def test_cater(self): assert mockSnapper.executeQueue.called assert mockSnapper.Divide.called - assert mockSnapper.RebinRagged.called - - def test_badChopIngredients(self): - recipe = ApplyNormalizationRecipe() - ingredients = Ingredients(pixelGroup=self.sculleryBoy.prepPixelGroup()) - with ( - Config_override("constants.CropFactors.lowdSpacingCrop", 500.0), - Config_override("constants.CropFactors.highdSpacingCrop", 1000.0), - pytest.raises(ValueError, match="d-spacing crop factors are too large"), - ): - recipe.chopIngredients(ingredients) - - with ( - Config_override("constants.CropFactors.lowdSpacingCrop", -10.0), - pytest.raises(ValueError, match="Low d-spacing crop factor must be positive"), - ): - recipe.chopIngredients(ingredients) - - with ( - Config_override("constants.CropFactors.highdSpacingCrop", -10.0), - pytest.raises(ValueError, match="High d-spacing crop factor must be positive"), - ): - recipe.chopIngredients(ingredients) + assert mockRebinRecipe().prep.called diff --git a/tests/unit/backend/recipe/test_GenerateFocussedVanadiumRecipe.py b/tests/unit/backend/recipe/test_GenerateFocussedVanadiumRecipe.py index 6cb5a3934..d5746fb0f 100644 --- a/tests/unit/backend/recipe/test_GenerateFocussedVanadiumRecipe.py +++ b/tests/unit/backend/recipe/test_GenerateFocussedVanadiumRecipe.py @@ -1,7 +1,6 @@ import unittest from unittest import mock -import pytest from mantid.simpleapi import ( LoadNexusProcessed, mtd, @@ -56,6 +55,7 @@ def tearDown(self) -> None: return super().tearDown() def test_execute_successful(self): + self.recipe._queueRebinInputWorkspace = mock.Mock() mock_instance = self.mockSnapper.SmoothDataExcludingPeaksAlgo.return_value mock_instance.execute.return_value = None mock_instance.getPropertyValue.return_value = self.fakeOutputWorkspace @@ -66,14 +66,22 @@ def test_execute_successful(self): self.assertEqual(output, expected_output) # noqa: PT009 - def test_execute_unsuccessful(self): - mock_instance = self.mockSnapper.SmoothDataExcludingPeaksAlgo.return_value - mock_instance.execute.return_value = None - mock_instance.getPropertyValue.return_value = None - - with pytest.raises(NotImplementedError) as e: - self.recipe.cook(self.fakeIngredients, self.errorGroceryList) - assert str(e.value) == "Fake Vanadium not implemented yet." # noqa: PT009 + def test_execute_artificial(self): + self.recipe._queueRebinInputWorkspace = mock.Mock() + self.fakeIngredients.artificialNormalizationIngredients = SculleryBoy().prepArtificialNormalizationIngredients() + self.recipe.cook(self.fakeIngredients, self.groceryList) + + self.recipe.mantidSnapper.CreateArtificialNormalizationAlgo.assert_called_once() + self.recipe.mantidSnapper.SmoothDataExcludingPeaksAlgo.assert_not_called() + self.recipe.mantidSnapper.CreateArtificialNormalizationAlgo.assert_called_with( + "Create Artificial Normalization...", + InputWorkspace=self.fakeInputWorkspace, + OutputWorkspace=self.fakeOutputWorkspace, + peakWindowClippingSize=10, + smoothingParameter=0.1, + decreaseParameter=True, + LSS=True, + ) def test_catering(self): self.recipe.cook = mock.Mock() diff --git a/tests/unit/backend/recipe/test_ReductionRecipe.py b/tests/unit/backend/recipe/test_ReductionRecipe.py index 65ce78d4f..ac651f530 100644 --- a/tests/unit/backend/recipe/test_ReductionRecipe.py +++ b/tests/unit/backend/recipe/test_ReductionRecipe.py @@ -384,8 +384,8 @@ def test_execute(self, mockMtd): recipe = ReductionRecipe() recipe.mantidSnapper = mockMantidSnapper recipe.mantidSnapper.mtd = mockMtd - recipe._prepareArtificialNormalization = mock.Mock() - recipe._prepareArtificialNormalization.return_value = "norm_grouped" + recipe._getNormalizationWorkspaceName = mock.Mock() + recipe._getNormalizationWorkspaceName.return_value = "norm_grouped" # Set up ingredients and other variables for the recipe recipe.groceries = {} @@ -447,12 +447,14 @@ def test_execute(self, mockMtd): recipe._applyRecipe.assert_any_call( GenerateFocussedVanadiumRecipe, recipe.ingredients.generateFocussedVanadium(0), - inputWorkspace="norm_grouped", + inputWorkspace="sample_grouped", + outputWorkspace=recipe._getNormalizationWorkspaceName.return_value, ) recipe._applyRecipe.assert_any_call( GenerateFocussedVanadiumRecipe, recipe.ingredients.generateFocussedVanadium(1), - inputWorkspace="norm_grouped", + inputWorkspace="sample_grouped", + outputWorkspace=recipe._getNormalizationWorkspaceName.return_value, ) recipe._applyRecipe.assert_any_call( @@ -468,9 +470,9 @@ def test_execute(self, mockMtd): normalizationWorkspace="norm_grouped", ) - recipe._prepareArtificialNormalization.call_count == 2 - recipe._prepareArtificialNormalization.assert_any_call("sample_grouped", 0) - recipe._prepareArtificialNormalization.assert_any_call("sample_grouped", 1) + recipe._getNormalizationWorkspaceName.call_count == 2 + recipe._getNormalizationWorkspaceName.assert_any_call(0) + recipe._getNormalizationWorkspaceName.assert_any_call(1) recipe.ingredients.effectiveInstrument.assert_not_called() @@ -497,8 +499,8 @@ def test_execute_useEffectiveInstrument(self, mockMtd): recipe = ReductionRecipe() recipe.mantidSnapper = mockMantidSnapper recipe.mantidSnapper.mtd = mockMtd - recipe._prepareArtificialNormalization = mock.Mock() - recipe._prepareArtificialNormalization.return_value = "norm_grouped" + recipe._getNormalizationWorkspaceName = mock.Mock() + recipe._getNormalizationWorkspaceName.return_value = "norm_grouped" # Set up ingredients and other variables for the recipe recipe.groceries = {} @@ -560,12 +562,14 @@ def test_execute_useEffectiveInstrument(self, mockMtd): recipe._applyRecipe.assert_any_call( GenerateFocussedVanadiumRecipe, recipe.ingredients.generateFocussedVanadium(0), - inputWorkspace="norm_grouped", + inputWorkspace="sample_grouped", + outputWorkspace=recipe._getNormalizationWorkspaceName.return_value, ) recipe._applyRecipe.assert_any_call( GenerateFocussedVanadiumRecipe, recipe.ingredients.generateFocussedVanadium(1), - inputWorkspace="norm_grouped", + inputWorkspace="sample_grouped", + outputWorkspace=recipe._getNormalizationWorkspaceName.return_value, ) recipe._applyRecipe.assert_any_call( @@ -581,9 +585,9 @@ def test_execute_useEffectiveInstrument(self, mockMtd): normalizationWorkspace="norm_grouped", ) - recipe._prepareArtificialNormalization.call_count == 2 - recipe._prepareArtificialNormalization.assert_any_call("sample_grouped", 0) - recipe._prepareArtificialNormalization.assert_any_call("sample_grouped", 1) + recipe._getNormalizationWorkspaceName.call_count == 2 + recipe._getNormalizationWorkspaceName.assert_any_call(0) + recipe._getNormalizationWorkspaceName.assert_any_call(1) recipe._applyRecipe.assert_any_call( EffectiveInstrumentRecipe, diff --git a/tests/unit/backend/service/test_ReductionService.py b/tests/unit/backend/service/test_ReductionService.py index e66372a72..8eb6ac380 100644 --- a/tests/unit/backend/service/test_ReductionService.py +++ b/tests/unit/backend/service/test_ReductionService.py @@ -478,7 +478,10 @@ def test_artificialNormalization(self, mockArtificialNormalizationRecipe): mockArtificialNormalizationRecipe.return_value.executeRecipe.assert_called_once_with( InputWorkspace=request.diffractionWorkspace, - Ingredients=mock.ANY, + peakWindowClippingSize=request.peakWindowClippingSize, + smoothingParameter=request.smoothingParameter, + decreaseParameter=request.decreaseParameter, + lss=request.lss, OutputWorkspace=request.outputWorkspace, ) assert result == mockResult diff --git a/tests/util/SculleryBoy.py b/tests/util/SculleryBoy.py index 21167e55f..63b9a997e 100644 --- a/tests/util/SculleryBoy.py +++ b/tests/util/SculleryBoy.py @@ -6,6 +6,7 @@ from snapred.backend.dao.GroupPeakList import GroupPeakList from snapred.backend.dao.ingredients import ( + ArtificialNormalizationIngredients, DiffractionCalibrationIngredients, NormalizationIngredients, ReductionIngredients, @@ -106,6 +107,9 @@ def prepNormalizationIngredients(self, ingredients: FarmFreshIngredients) -> Nor detectorPeaks=self.prepDetectorPeaks(ingredients), ) + def prepArtificialNormalizationIngredients(self): + return ArtificialNormalizationIngredients(smoothingParameter=0.1) + def verifyCalibrationExists(self, runNumber: str, useLiteMode: bool) -> bool: # noqa ARG002 return True