Skip to content

Commit f7053ec

Browse files
committed
Adds new dataset type "angle_dim"
1 parent 068ee67 commit f7053ec

7 files changed

Lines changed: 64 additions & 35 deletions

File tree

sasdata/data.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ def __init__(
3939
@property
4040
def ordinate(self) -> Quantity:
4141
match self.dataset_type:
42-
case dataset_types.one_dim | dataset_types.two_dim:
42+
case (dataset_types.one_dim |
43+
dataset_types.two_dim |
44+
dataset_types.angle_dim):
4345
return self._data_contents["I"]
4446
case dataset_types.sesans:
4547
return self._data_contents["Depolarisation"]
@@ -70,6 +72,8 @@ def abscissae(self) -> Quantity:
7072
# probably want to avoid creating a new Quantity but at the moment I
7173
# can't see a way around it.
7274
return Quantity(data_contents, reference_data_content.units, name=self._data_contents["Qx"].name, id_header=self._data_contents["Qx"]._id_header)
75+
case dataset_types.angle_dim:
76+
return self._data_contents["Phi"]
7377
case dataset_types.sesans:
7478
return self._data_contents["SpinEchoLength"]
7579
case _:

sasdata/data_util/averaging.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
from sasdata.data_util.binning import DirectionalAverage
1010
from sasdata.data_util.interval import IntervalType
1111
from sasdata.data_util.roi import CartesianROI, PolarROI
12-
from sasdata.dataset_types import one_dim
12+
from sasdata.dataset_types import angle_dim, one_dim
1313
from sasdata.quantities.constants import Pi, TwoPi
1414
from sasdata.quantities.quantity import Quantity
15+
from sasdata.quantities.units import radians
1516

1617

1718
def get_dq_data(data2d: SasData) -> npt.NDArray[np.floating]:
@@ -503,10 +504,10 @@ def __call__(self, data2D: SasData) -> SasData:
503504
raise ValueError(msg)
504505

505506
data_contents = {
506-
"Q": Quantity(phi_values[idx], data2D._data_contents["Qx"].units, None),
507+
"Phi": Quantity(phi_values[idx], radians, None),
507508
"I": Quantity(phi_bins[idx], data2D._data_contents["I"].units, phi_err[idx]),
508509
}
509-
return SasData(f"{data2D.name}: Ring Average", data_contents, one_dim, data2D.metadata)
510+
return SasData(f"{data2D.name}: Ring Average", data_contents, angle_dim, data2D.metadata)
510511

511512

512513
class SectorQ(PolarROI):
@@ -665,9 +666,9 @@ class WedgeQ(PolarROI):
665666
the positive x-axis.
666667
667668
This class is initialised by specifying lower and upper limits on both the
668-
magnitude of Q and the angle φ.
669-
When called, this class is supplied with a SasData object. It returns a
670-
sasData object where intensity is given as a function of Q only.
669+
magnitude of Q and the angle φ. When called, this class is supplied with a
670+
SasData object. It returns a sasData object where intensity is given as a
671+
function of Q only.
671672
"""
672673

673674
def __init__(
@@ -752,7 +753,7 @@ class WedgePhi(PolarROI):
752753
This class is initialised by specifying lower and upper limits on both the
753754
magnitude of Q and the angle φ, measured anticlockwise from the positive
754755
x-axis. When called, this class is supplied with a SasData object. It returns
755-
a SasData object where intensity is given as a function of Q only.
756+
a SasData object where intensity is given as a function of φ only.
756757
"""
757758

758759
def __init__(
@@ -818,7 +819,7 @@ def __call__(self, data2d: SasData = None) -> SasData:
818819
nbins=self.nbins,
819820
base=self.base,
820821
)
821-
phi_data, intensity, error = directional_average(data=self.data, err_data=self.err_data)
822+
_, intensity, error = directional_average(data=self.data, err_data=self.err_data)
822823

823824
# Compute phi bin starts to match legacy behaviour (Ring / old SectorPhi)
824825
# phi_min has been normalized to 0 earlier; phi_offset stores original start.
@@ -844,10 +845,10 @@ def __call__(self, data2d: SasData = None) -> SasData:
844845

845846
# intensity and error returned by DirectionalAverage are already filtered to the populated/finite bins
846847
data_contents = {
847-
"Q": Quantity(phi_centers, data2d._data_contents["Qx"].units, None),
848+
"Phi": Quantity(phi_centers, radians, None),
848849
"I": Quantity(intensity, data2d._data_contents["I"].units, error),
849850
}
850-
return SasData(f"{data2d.name}: Wedge Phi Average", data_contents, one_dim, data2d.metadata)
851+
return SasData(f"{data2d.name}: Wedge Phi Average", data_contents, angle_dim, data2d.metadata)
851852

852853

853854
class SectorPhi(WedgePhi):

sasdata/data_util/manipulations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ def _agv(self, data2D, run='phi'):
544544
if not ("Qx" in data2D._data_contents and
545545
"Qy" in data2D._data_contents and
546546
"I" in data2D._data_contents):
547-
raise RuntimeError("For ring averaging the SasData object must contain 'Qx', 'Qy', and 'I' data.")
547+
raise RuntimeError("For averaging the SasData object must contain 'Qx', 'Qy', and 'I' data.")
548548

549549
# Get all the data & info
550550
finite_mask = np.isfinite(data2D._data_contents["I"].value)

sasdata/dataset_types.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,21 @@ class DatasetType:
4242
["Qx", "Qy", "Qz", "I", "dI"],
4343
["Qx", "Qy", "Qz", "dQx", "dQy", "dQz", "I", "dI"]])
4444

45+
angle_dim = DatasetType(
46+
name="I vs Phi",
47+
required=["Phi", "I"],
48+
optional=["dI", "dPhi", "Shadowfactor"],
49+
expected_orders=[
50+
["Phi", "I", "dI"],
51+
["Phi", "dPhi", "I", "dI"]])
52+
4553
sesans = DatasetType(
4654
name="SESANS",
4755
required=["SpinEchoLength", "Depolarisation", "Wavelength"],
4856
optional=["Transmission", "Polarisation"],
4957
expected_orders=[["z", "G"]])
5058

51-
dataset_types = {dataset.name for dataset in [one_dim, two_dim, sesans]}
59+
dataset_types = {dataset.name for dataset in [one_dim, two_dim, angle_dim, sesans]}
5260

5361

5462
#

test/sasmanipulations/utest_averaging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ def test_ring(self):
155155

156156
self.assertEqual(len(answer_list), 1)
157157
for i in range(r.nbins_phi - 1):
158-
self.assertAlmostEqual(o._data_contents["Q"].value[i], answer._data_contents["Q"].value[i], 4)
158+
# Current ascii reader implementation assumes file data is "one_dim"
159+
self.assertAlmostEqual(o._data_contents["Phi"].value[i], answer._data_contents["Q"].value[i], 4)
159160
self.assertAlmostEqual(o._data_contents["I"].value[i], answer._data_contents["I"].value[i], 4)
160161
self.assertAlmostEqual(o._data_contents["I"].variance.value[i], answer._data_contents["I"].variance.value[i], 4)
161162

test/sasmanipulations/utest_averaging_circle.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def test_ring_averages_azimuthally(self):
169169
data1d = ring_object(averager_data.data)
170170

171171
expected_area = test_data.area_under_region(r_min=r_min, r_max=r_max)
172-
actual_area = integrate.simpson(data1d._data_contents["I"].value, data1d._data_contents["Q"].value)
172+
actual_area = integrate.simpson(data1d._data_contents["I"].value, data1d._data_contents["Phi"].value)
173173

174174
self.assertAlmostEqual(actual_area, expected_area, 1)
175175

@@ -223,9 +223,9 @@ def test_sectorq_averaging_without_fold(self):
223223

224224
r_min = 0
225225
r_max = 0.9 * averager_data.qmax
226-
phi_min = Pi/6
227-
phi_max = 5*Pi/6
228-
nbins = int(test_data.matrix_size * np.sqrt(2)/4) # usually reliable
226+
phi_min = Pi / 6.0
227+
phi_max = 5.0 * Pi / 6.0
228+
nbins = int(0.25 * test_data.matrix_size * np.sqrt(2)) # usually reliable
229229

230230
wedge_object = SectorQ(r_range=(r_min, r_max), phi_range=(phi_min,phi_max), nbins=nbins)
231231
# Explicitly set fold to False - results span full +/- range
@@ -256,9 +256,9 @@ def test_sectorq_averaging_with_fold(self):
256256

257257
r_min = 0
258258
r_max = 0.9 * averager_data.qmax
259-
phi_min = Pi/6
260-
phi_max = 5*Pi/6
261-
nbins = int(test_data.matrix_size * np.sqrt(2)/4) # usually reliable
259+
phi_min = Pi / 6.0
260+
phi_max = 5.0 * Pi / 6.0
261+
nbins = int(0.25 * test_data.matrix_size * np.sqrt(2)) # usually reliable
262262

263263
wedge_object = SectorQ(r_range=(r_min, r_max), phi_range=(phi_min,phi_max), nbins=nbins)
264264
# Explicitly set fold to True - points either side of 0,0 are averaged
@@ -317,16 +317,15 @@ def test_wedgeq_averaging(self):
317317

318318
r_min = 0.1 * averager_data.qmax
319319
r_max = 0.9 * averager_data.qmax
320-
phi_min = Pi/6
321-
phi_max = 5*Pi/6
320+
phi_min = Pi / 6.0
321+
phi_max = 5.0 * Pi / 6.0
322322
nbins = int(test_data.matrix_size * np.sqrt(2)/4) # usually reliable
323323

324324
wedge_object = WedgeQ(r_range=(r_min, r_max), phi_range=(phi_min,phi_max), nbins=nbins)
325325
data1d = wedge_object(averager_data.data)
326326

327327
expected_area = test_data.area_under_region(r_min=r_min, r_max=r_max,
328-
phi_min=phi_min,
329-
phi_max=phi_max)
328+
phi_min=phi_min, phi_max=phi_max)
330329
actual_area = integrate.simpson(data1d._data_contents["I"].value, data1d._data_contents["Q"].value)
331330

332331
self.assertAlmostEqual(actual_area, expected_area, 1)
@@ -351,8 +350,6 @@ def test_wedgephi_init(self):
351350
nbins = 100
352351
# base = 10
353352

354-
# wedge_object = WedgePhi(r_min=r_min, r_max=r_max, phi_min=phi_min,
355-
# phi_max=phi_max, nbins=nbins, base=base)
356353
wedge_object = WedgePhi(r_range=(r_min, r_max), phi_range=(phi_min,phi_max), nbins=nbins)
357354

358355
self.assertEqual(wedge_object.r_min, r_min)
@@ -380,17 +377,17 @@ def test_wedgephi_averaging(self):
380377

381378
r_min = 0.1 * averager_data.qmax
382379
r_max = 0.9 * averager_data.qmax
383-
phi_min = Pi/6
384-
phi_max = 5*Pi/6
385-
nbins = int(test_data.matrix_size * np.sqrt(2)/4) # usually reliable
380+
phi_min = Pi / 6.0
381+
phi_max = 5.0 * Pi / 6.0
382+
nbins = int(0.25 *test_data.matrix_size * np.sqrt(2)) # usually reliable
386383

387384
wedge_object = WedgePhi(r_range=(r_min, r_max), phi_range=(phi_min,phi_max), nbins=nbins)
388385
data1d = wedge_object(averager_data.data)
389386

390387
expected_area = test_data.area_under_region(r_min=r_min, r_max=r_max,
391-
phi_min=phi_min,
392-
phi_max=phi_max)
393-
actual_area = integrate.simpson(data1d._data_contents["I"].value, data1d._data_contents["Q"].value)
388+
phi_min=phi_min, phi_max=phi_max)
389+
390+
actual_area = integrate.simpson(data1d._data_contents["I"].value, data1d._data_contents["Phi"].value)
394391

395392
self.assertAlmostEqual(actual_area, expected_area, 1)
396393

test/utest_new_sasdata.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
from sasdata.data import SasData
44
from sasdata.data_backing import Group
5-
from sasdata.dataset_types import one_dim, three_dim, two_dim
5+
from sasdata.dataset_types import angle_dim, one_dim, three_dim, two_dim
66
from sasdata.metadata import Instrument, Metadata, Source
77
from sasdata.postprocess import deduce_qz
8+
from sasdata.quantities.constants import Pi
89
from sasdata.quantities.quantity import Quantity
9-
from sasdata.quantities.units import angstroms, per_angstrom, per_centimeter
10+
from sasdata.quantities.units import angstroms, per_angstrom, per_centimeter, radians
1011

1112

1213
def test_1d():
@@ -105,3 +106,20 @@ def test_3d():
105106
deduce_qz(data)
106107

107108
assert (data._data_contents['Qz'].value != (0*data._data_contents['Qx'].value)).all()
109+
110+
def test_angle():
111+
phi = [0.4 * Pi, 0.8 * Pi, 1.2 * Pi, 1.6 * Pi, 2 * Pi]
112+
i = [5, 4, 3, 2, 1]
113+
114+
phi_quantity = Quantity(np.array(phi), radians)
115+
i_quantity = Quantity(np.array(i), per_centimeter)
116+
117+
data_contents = {
118+
'Phi': phi_quantity,
119+
'I': i_quantity
120+
}
121+
122+
data = SasData('TestData', data_contents, angle_dim, Group('root', {}), True)
123+
124+
assert all(data.abscissae.value == np.array(phi))
125+
assert all(data.ordinate.value == np.array(i))

0 commit comments

Comments
 (0)