The MD Workspace [MDWorkspace] (short for “Multi-Dimensional” Workspace) is a generic data structure holdings points (MDEvents) that are defined by their position in several dimensions.
See also
The MDWorkspace is a container that can hold a large number of MDEvents. The events are organized into “boxes”: types are MDBox and MDGridBox. At the simplest level, an MDWorkspace will be a single MDBox with an unsorted bunch of events.
In order to allow for efficient searching and binning of these events, the boxes are organized into a recursive boxing structure (adaptive mesh refinement). During MDWorkspace construction, if a MDBox is found to contain too many events, it will be split into smaller boxes.
MDWorkspace_structure.png
The threshold for splitting is defined in CreateMDWorkspace as the SplitThreshold parameter. Each parent box will get split into N sub-boxes in each dimension. For example, in a 2D workspace, you might split a parent box into 4x4 sub-boxes, creating 16 MDBoxes under the parent box (which becomes a MDGridBox). The level of splitting is defined in the SplitInto parameter.
There are several algorithms that will create a MDWorkspace:
For workspaces with a large number of events that would not fit in memory, it is possible to use a NXS file back-end as a data store. The box structure will always remain in memory, but the underlying events will be stored in a file and retrieved only when required. This can be set at creation (CreateMDWorkspace) or when loading from a file, or an in-memory MDWorkspace can be converted to file-backed with the SaveMD algorithm.
Because of disk IO, file-backed MDWorkspaces are slower to process for some operations (e.g. binning or slicing). Some types of visualization and analysis, however, are just as fast with file-backed MDWorkspaces as their in-memory equivalent.
Or, you can load a MDWorkspace .nxs file in Paraview if the proper plugin is installed.
The methods for getting a variable to an MDWorkspace is the same as shown in the Workspace help page.
If you want to check if a variable points to something that is an MDWorkspace Workspace you can use this:
from mantid.api import IMDEventWorkspace
mdws = CreateMDWorkspace(Dimensions=3, Extents='-10,10,-10,10,-10,10', Names='A,B,C', Units='U,U,U')
if isinstance(mdws, IMDEventWorkspace):
print(mdws.name() + " is a " + mdws.id())
Output:
mdws is a MDEventWorkspace<MDLeanEvent,3>
For a full list of the available properties and operation look at the IMDEventWorkspace api page.
ws = CreateMDWorkspace(Dimensions='2', EventType='MDEvent', Extents='-10,10,-10,10',
Names='Q_lab_x,Q_lab_y', Units='A,B')
FakeMDEventData(ws, UniformParams="1000000")
print("Number of events = {}".format(ws.getNEvents()))
print("Number of dimensions = {}".format(ws.getNumDims()))
print("Normalization = {}".format(ws.displayNormalization()))
for i in range(ws.getNumDims()):
dimension = ws.getDimension(i)
print("\tDimension {0} Name: {1}".format(i,
dimension.name))
bc =ws.getBoxController()
print("Is the workspace using a file back end? {}".format(bc.isFileBacked()))
backEndFilename = bc.getFilename()
As a generic multi dimensional container being able to access information about the dimensions is very important.
ws = CreateMDWorkspace(Dimensions='3', EventType='MDEvent', Extents='-10,10,-5,5,-1,1',
Names='Q_lab_x,Q_lab_y,Q_lab_z', Units='1\A,1\A,1\A')
FakeMDEventData(ws, UniformParams="1000000")
print("Number of dimensions = {}".format(ws.getNumDims()))
for i in range(ws.getNumDims()):
dimension = ws.getDimension(i)
print("\tDimension {0} Name: {1} id: {2} Range: {3}-{4} {5}".format(i,
dimension.getDimensionId(),
dimension.name,
dimension.getMinimum(),
dimension.getMaximum(),
dimension.getUnits()))
print("The dimension assigned to X = {}".format(ws.getXDimension().name))
print("The dimension assigned to Y = {}".format(ws.getYDimension().name))
try:
print("The dimension assigned to Z = {}".format(ws.getZDimension().name))
except RuntimeError:
# if the dimension does not exist you will get a RuntimeError
print("Workspace does not have a Z dimension")
# you can also get a dimension by it's id
dim = ws.getDimensionIndexById("Q_lab_x")
# or name
dim = ws.getDimensionIndexByName("Q_lab_x")
To access the data of an MDWorkspace you need to convert it to a regular grid, or MD Histogram Workspace.
# Setup
mdWS = CreateMDWorkspace(Dimensions=4, Extents=[-1,1,-1,1,-1,1,-10,10], Names="H,K,L,E", Units="U,U,U,V")
FakeMDEventData(InputWorkspace=mdWS, PeakParams='500000,0,0,0,0,3')
# Create a histogrammed (binned) workspace with 100 bins in each of the H, K and L dimensions
histoWS = BinMD(InputWorkspace=mdWS, AlignedDim0='H,-1,1,100', AlignedDim1='K,-1,1,100', AlignedDim2='L,-1,1,100')
# Or you can also use CutMD, to define bin widths and the cut projection
from mantid.api import Projection
SetUB(Workspace=mdWS, a=1, b=1, c=1, alpha=90, beta=90, gamma=90)
SetSpecialCoordinates(InputWorkspace=mdWS, SpecialCoordinates='HKL')
projection = Projection([1,1,0], [-1,1,0])
proj_ws = projection.createWorkspace()
# Apply the cut with bin widths of 0.1 in H,K and L and integrating over -5 to +5 in E
out_md = CutMD(mdWS, Projection=proj_ws, PBins=([0.1], [0.1], [0.1], [-5,5]), NoPix=True)
Category: Concepts