From b63fca0cebded4758a22105c5acb5beaf944d832 Mon Sep 17 00:00:00 2001 From: Owen Arnold Date: Fri, 14 Nov 2014 14:25:37 +0000 Subject: [PATCH] refs #10530. Use binning boundaries as extents. Use binning boundaries as extents if they define inner limit. Otherwise the original dimension boundaries are used as extents. In either case, the extents need to be transformed into the new basis. --- .../algorithms/WorkflowAlgorithms/CutMD.py | 21 ++++++--- .../test/python/mantid/api/CutMDTest.py | 44 +++++++++++++++++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py index 179704cdd7b3..509ad46c23a6 100644 --- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py +++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py @@ -69,15 +69,22 @@ def __to_mantid_slicing_binning(self, horace_binning, to_cut, dimension_index): raise ValueError("Number of bins calculated to be < 1") return (min, max, n_bins) + def __innermost_boundary(self, a, b): + if np.absolute(a) < np.absolute(b): + return b + return b - def __calculate_extents(self, v, u, w, ws): + + def __calculate_extents(self, v, u, w, ws, h_bins, k_bins, l_bins): M=np.array([u,v,w]) Minv=np.linalg.inv(M) # We are assuming that the workspace has dimensions H, K, L in that order. The workspace MUST have 3 dimensions at least for the following to work. - Hrange=[ws.getDimension(0).getMinimum(), ws.getDimension(0).getMaximum()] - Krange=[ws.getDimension(1).getMinimum(), ws.getDimension(1).getMaximum()] - Lrange=[ws.getDimension(2).getMinimum(), ws.getDimension(2).getMaximum()] + Hrange=[self.__innermost_boundary(ws.getDimension(0).getMinimum(), h_bins[0]), self.__innermost_boundary(ws.getDimension(0).getMaximum(), h_bins[1])] + Krange=[self.__innermost_boundary(ws.getDimension(1).getMinimum(), k_bins[0]), self.__innermost_boundary(ws.getDimension(1).getMaximum(), k_bins[1])] + Lrange=[self.__innermost_boundary(ws.getDimension(2).getMinimum(), l_bins[0]), self.__innermost_boundary(ws.getDimension(2).getMaximum(), l_bins[1])] + + print "Ranges", Hrange, Krange, Lrange # Create a numpy 2D array. Makes finding minimums and maximums for each transformed coordinates over every corner easier. new_coords = np.empty([8, 3]) @@ -193,8 +200,8 @@ def PyExec(self): # TODO. THESE ARE WRONG. Need to consider the acutal transformed extents as part of this. xbins = self.__to_mantid_slicing_binning(p1_bins, to_cut, 0); - ybins = self.__to_mantid_slicing_binning(p1_bins, to_cut, 1); - zbins = self.__to_mantid_slicing_binning(p1_bins, to_cut, 2); + ybins = self.__to_mantid_slicing_binning(p2_bins, to_cut, 1); + zbins = self.__to_mantid_slicing_binning(p3_bins, to_cut, 2); bins = [ int(xbins[2]), int(ybins[2]), int(zbins[2]) ] if p4_bins: if (ndims == 4): @@ -206,7 +213,7 @@ def PyExec(self): projection = self.__uvw_from_projection_table(projection_table) u,v,w = projection - extents = self.__calculate_extents(v, u, w, to_cut) + extents = self.__calculate_extents(v, u, w, to_cut, xbins, ybins, zbins) projection_labels = self.__make_labels(projection) diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py index a7c84c6af252..027c530ef852 100644 --- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py +++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py @@ -70,7 +70,7 @@ def test_wrong_table_workspace_format_wrong_row_numbers(self): self.assertRaises(RuntimeError, CutMD, InputWorkspace=self.__in_md, Projection=projection, OutputWorkspace="out_ws", P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], CheckAxes=False) def test_orthogonal_slice_with_scaling(self): - # We create a fake workspace around and check to see that the extents get scaled with the new coordinate system when sliced + # We create a fake workspace and check to see that the extents get scaled with the new coordinate system when sliced to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') @@ -105,8 +105,8 @@ def test_orthogonal_slice_with_scaling(self): self.assertEquals("[0, 0, '-4.00xi']", out_md.getDimension(2).getName() ) - def test_non_orthogonal_slice_with_scaling(self): - # We create a fake workspace around and check to see that the extents get scaled with the new coordinate system when sliced + def test_non_orthogonal_slice(self): + # We create a fake workspace and check to see that the extents get transformed to the new coordinate system. to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') @@ -140,6 +140,44 @@ def test_non_orthogonal_slice_with_scaling(self): self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") + def test_orthogonal_slice_with_cropping(self): + # We create a fake workspace and check to see that using bin inputs for cropping works + to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U') + + SetSpecialCoordinates(InputWorkspace=to_cut, SpecialCoordinates='HKL') + + projection = CreateEmptyTableWorkspace() + # Correct number of columns, and names + projection.addColumn("double", "u") + projection.addColumn("double", "v") + projection.addColumn("double", "w") + projection.addColumn("double", "offsets") + projection.addColumn("str", "type") + projection.addRow([1, 0, 0, 0, "aaa"]) + projection.addRow([0, 1, 0, 0, "aaa"]) + projection.addRow([0, 0, 1, 0, "aaa"]) + + ''' + Specify the cropping boundaries as part of the bin inputs. + ''' + out_md = CutMD(to_cut, Projection=projection, P1Bin=[-0.5,0.5], P2Bin=[-0.1,0.1], P3Bin=[-0.3,0.3], NoPix=True) + + ''' + Here we check that the corners in HKL end up in the expected positions when transformed into the new scaled basis + provided by the W transform (projection table) + ''' + self.assertAlmostEqual(-0.5, out_md.getDimension(0).getMinimum(), 6) + self.assertAlmostEqual(0.5, out_md.getDimension(0).getMaximum(), 6) + self.assertAlmostEqual(-0.1, out_md.getDimension(1).getMinimum(), 6) + self.assertAlmostEqual(0.1, out_md.getDimension(1).getMaximum(), 6) + self.assertAlmostEqual(-0.3, out_md.getDimension(2).getMinimum(), 6) + self.assertAlmostEqual(0.3, out_md.getDimension(2).getMaximum(), 6) + self.assertEquals("['zeta', 0, 0]", out_md.getDimension(0).getName() ) + self.assertEquals("[0, 'eta', 0]", out_md.getDimension(1).getName() ) + self.assertEquals("[0, 0, 'xi']", out_md.getDimension(2).getName() ) + + self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.") +