Skip to content

Commit

Permalink
fix IQazimuthal.to_workspace() needed for saving to NXcanSAS
Browse files Browse the repository at this point in the history
  • Loading branch information
backmari committed Jan 16, 2025
1 parent 6fc28bd commit 869c5bb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 17 deletions.
43 changes: 36 additions & 7 deletions src/drtsans/dataobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"verify_same_q_bins",
]

QBINS_EQUAL_DECIMALS = 8


class DataType(Enum):
WORKSPACE2D = "Workspace2D"
Expand Down Expand Up @@ -563,8 +565,8 @@ class IQazimuthal(namedtuple("IQazimuthal", "intensity error qx qy delta_qx delt
if intensity is 2D, and qx and qy are 1D: In this constructor, it is assumed that intensity 2D array
will match
qx = [[qx0, qx1, ...], [qx0, qx1, ...], ...]
qy = [[qy0, qy0, ...], [qy1, qy1, ...], ...]
qx = [[qx0, qx0, ...], [qx1, qx1, ...], ...]
qy = [[qy0, qy1, ...], [qy0, qy1, ...], ...]
because qx and qy will be created in such style.
"""

Expand Down Expand Up @@ -711,14 +713,41 @@ def to_workspace(self, name=None):
if name is None:
name = mtd.unique_hidden_name()

def flatten_unique_vals(a: np.ndarray):
"""
Helper function to get the unique values with a tolerance preserving order
Steps:
1. Flatten the array
2. Round the array to QBINS_EQUAL_DECIMALS decimals
3. Find the indices of the first location of each unique element in the rounded array
4. Use the indices to return the unique elements from the original array
"""
b = a.flatten()
return b[np.unique(b.round(QBINS_EQUAL_DECIMALS), return_index=True)[1]]

# get the unique qx and qy values
qx_ws = flatten_unique_vals(self.qx)
qy_ws = flatten_unique_vals(self.qy)

# reshape intensity and error as needed for CreateWorkspace with qy as vertical axis
qx_ws_len = len(qx_ws)
qy_ws_len = len(qy_ws)
if len(self.intensity.shape) == 1 and len(self.intensity) == len(qx_ws):
intensity_ws = self.intensity
error_ws = self.error
else:
intensity_ws = self.intensity.ravel().reshape((qx_ws_len, qy_ws_len)).T
error_ws = self.error.ravel().reshape((qx_ws_len, qy_ws_len)).T

ws = CreateWorkspace(
DataX=self.qx,
DataX=qx_ws,
UnitX="MomentumTransfer",
VerticalAxisValues=self.qy,
VerticalAxisValues=qy_ws,
VerticalAxisUnit="MomentumTransfer",
NSpec=self.qy.size,
DataY=self.intensity,
DataE=self.error,
NSpec=qy_ws.size,
DataY=intensity_ws,
DataE=error_ws,
OutputWorkspace=name,
# dx=
EnableLogging=False,
Expand Down
62 changes: 52 additions & 10 deletions tests/unit/drtsans/test_dataobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,28 +535,64 @@ def test_to_workspace_1D(self):
ws = iqaz.to_workspace()

ws_expected = CreateWorkspace(
DataX=qx, DataY=I, DataE=E, VerticalAxisValues=qy, VerticalAxisUnit="MomentumTransfer", NSpec=len(qy)
DataX=qx,
DataY=I,
DataE=E,
UnitX="MomentumTransfer",
VerticalAxisValues=qy,
VerticalAxisUnit="MomentumTransfer",
NSpec=len(qy),
)

assert CompareWorkspaces(ws, ws_expected)
assert CompareWorkspaces(ws, ws_expected).Result is True

def test_to_workspace_1D_flattened_Q2D(self):
"""test with one-dimensional Qx, Qy, I where Qx and Qy have been flattened from 2D"""

i = np.array([1, 2, 3, 4, 5, 6])
e = np.array([4, 5, 6, 7, 8, 9])
qx = np.array([7, 7, 8, 8, 9, 9])
qy = np.array([11, 12, 11, 12, 11, 12])

iqaz = IQazimuthal(i, e, qx, qy)

ws = iqaz.to_workspace()

ws_expected = CreateWorkspace(
DataX=[7, 8, 9],
DataY=[1, 3, 5, 2, 4, 6],
DataE=[4, 6, 8, 5, 7, 9],
NSpec=2,
UnitX="MomentumTransfer",
VerticalAxisValues=[11, 12],
VerticalAxisUnit="MomentumTransfer",
)

assert CompareWorkspaces(ws, ws_expected).Result is True

def test_to_workspace_2D(self):
"""test with two-dimensional Qx, Qy, I"""

i = np.array([[1, 2], [3, 4]])
e = np.array([[4, 5], [6, 7]])
qx = np.array([[7, 8], [9, 10]])
qy = np.array([[11, 12], [12, 13]])
i = np.array([[1, 2], [3, 4], [5, 6]])
e = np.array([[4, 5], [6, 7], [8, 9]])
qx = np.array([[7, 7], [8, 8], [9, 9]])
qy = np.array([[11, 12], [11, 12], [11, 12]])

iqaz = IQazimuthal(i, e, qx, qy)

ws = iqaz.to_workspace()

ws_expected = CreateWorkspace(
DataX=qx, DataY=i, DataE=e, NSpec=4, VerticalAxisValues=qy, VerticalAxisUnit="MomentumTransfer"
DataX=qx[:, 0],
DataY=i.T,
DataE=e.T,
NSpec=2,
UnitX="MomentumTransfer",
VerticalAxisValues=qy[0, :],
VerticalAxisUnit="MomentumTransfer",
)

assert CompareWorkspaces(ws, ws_expected)
assert CompareWorkspaces(ws, ws_expected).Result is True

def test_to_workspace_I2D_Q1D(self):
"""test with two-dimensional I, one-dimensional Qx, Qy"""
Expand All @@ -571,10 +607,16 @@ def test_to_workspace_I2D_Q1D(self):
ws = iqaz.to_workspace()

ws_expected = CreateWorkspace(
DataX=qx, DataY=i, DataE=e, Nspec=3, VerticalAxisValues=qy, VerticalAxisUnit="MomentumTransfer"
DataX=qx,
DataY=i.T,
DataE=e.T,
Nspec=3,
UnitX="MomentumTransfer",
VerticalAxisValues=qy,
VerticalAxisUnit="MomentumTransfer",
)

assert CompareWorkspaces(ws, ws_expected)
assert CompareWorkspaces(ws, ws_expected).Result is True


class TestTesting:
Expand Down

0 comments on commit 869c5bb

Please sign in to comment.