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.") +