Skip to content

Commit b5bd527

Browse files
And a few more tests
1 parent af9b7d9 commit b5bd527

File tree

2 files changed

+169
-32
lines changed

2 files changed

+169
-32
lines changed

src/easydynamics/sample/components.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ def __init__(
364364

365365
def evaluate(self, x: Union[Numeric, sc.Variable]) -> Union[float, np.ndarray]:
366366
if self.width.value <= 0:
367-
raise ValueError("Width must be greater than zero for Lorentzian.")
367+
raise ValueError("The width of a Lorentzian must be greater than zero.")
368368
if self.area.value < 0:
369369
warnings.warn(
370370
"The area of the Lorentzian with name {} is negative, which may not be physically meaningful.".format(
@@ -522,12 +522,10 @@ def __init__(
522522

523523
def evaluate(self, x: Union[Numeric, sc.Variable]) -> Union[float, np.ndarray]:
524524
if self.gaussian_width.value <= 0:
525-
raise ValueError(
526-
"gaussian_width must be greater than zero for Voigt profile."
527-
)
525+
raise ValueError("The gaussian_width of a Voigt must be greater than zero.")
528526
if self.lorentzian_width.value <= 0:
529527
raise ValueError(
530-
"lorentzian_width must be greater than zero for Voigt profile."
528+
"The lorentzian_width of a Voigt must be greater than zero."
531529
)
532530
if self.area.value < 0:
533531
warnings.warn(
@@ -768,11 +766,11 @@ def __init__(
768766
def evaluate(self, x: Union[Numeric, sc.Variable]) -> Union[float, np.ndarray]:
769767
if self.width.value <= 0:
770768
raise ValueError(
771-
"Width of a Damped Harmonic Oscillator must be greater than zero."
769+
"The width of a DampedHarmonicOscillator must be greater than zero."
772770
)
773771
if self.area.value < 0:
774772
warnings.warn(
775-
"The area of the Damped Harmonic Oscillator with name {} is negative, which may not be physically meaningful.".format(
773+
"The area of the DampedHarmonicOscillator with name {} is negative, which may not be physically meaningful.".format(
776774
self.name
777775
)
778776
)

tests/unit_tests/sample/test_components.py

Lines changed: 164 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,28 @@ def test_negative_width_raises(self):
178178
):
179179
Gaussian(name="TestGaussian", area=2.0, center=0.5, width=-0.6, unit="meV")
180180

181+
def test_negative_width_raises_in_evaluate(self):
182+
test_gaussian = Gaussian(
183+
name="TestGaussian", area=2.0, center=0.5, width=0.6, unit="meV"
184+
)
185+
test_gaussian.width.value = -0.6
186+
with pytest.raises(
187+
ValueError, match="The width of a Gaussian must be greater than zero."
188+
):
189+
test_gaussian.evaluate(np.array([0.0, 0.5, 1.0]))
190+
181191
def test_negative_area_warns(self):
182192
with pytest.warns(UserWarning, match="may not be physically meaningful"):
183193
Gaussian(name="TestGaussian", area=-2.0, center=0.5, width=0.6, unit="meV")
184194

195+
def test_negative_area_warns_in_evaluate(self):
196+
test_gaussian = Gaussian(
197+
name="TestGaussian", area=2.0, center=0.5, width=0.6, unit="meV"
198+
)
199+
test_gaussian.area.value = -2.0
200+
with pytest.warns(UserWarning, match="may not be physically meaningful"):
201+
test_gaussian.evaluate(np.array([0.0, 0.5, 1.0]))
202+
185203
def test_evaluate(self, gaussian: Gaussian):
186204
x = np.array([0.0, 0.5, 1.0])
187205
expected = gaussian.evaluate(x)
@@ -249,6 +267,14 @@ def test_area_matches_parameter(self, gaussian: Gaussian):
249267
# THEN EXPECT
250268
assert np.isclose(numerical_area, gaussian.area.value, rtol=1e-3)
251269

270+
def test_convert_unit(self, gaussian: Gaussian):
271+
gaussian.convert_unit("microeV")
272+
273+
assert gaussian.unit == "microeV"
274+
assert gaussian.area.value == 2 * 1e3
275+
assert gaussian.center.value == 0.5 * 1e3
276+
assert gaussian.width.value == 0.6 * 1e3
277+
252278
def test_copy(self, gaussian: Gaussian):
253279
gaussian_copy = gaussian.copy()
254280
assert gaussian_copy is not gaussian
@@ -318,12 +344,30 @@ def test_negative_width_raises(self):
318344
name="TestLorentzian", area=2.0, center=0.5, width=-0.6, unit="meV"
319345
)
320346

347+
def test_negative_width_raises_in_evaluate(self):
348+
test_lorentzian = Lorentzian(
349+
name="TestLorentzian", area=2.0, center=0.5, width=0.6, unit="meV"
350+
)
351+
test_lorentzian.width.value = -0.6
352+
with pytest.raises(
353+
ValueError, match="The width of a Lorentzian must be greater than zero."
354+
):
355+
test_lorentzian.evaluate(np.array([0.0, 0.5, 1.0]))
356+
321357
def test_negative_area_warns(self):
322358
with pytest.warns(UserWarning, match="may not be physically meaningful"):
323359
Lorentzian(
324360
name="TestLorentzian", area=-2.0, center=0.5, width=0.6, unit="meV"
325361
)
326362

363+
def test_negative_area_warns_in_evaluate(self):
364+
test_lorentzian = Lorentzian(
365+
name="TestLorentzian", area=2.0, center=0.5, width=0.6, unit="meV"
366+
)
367+
test_lorentzian.area.value = -2.0
368+
with pytest.warns(UserWarning, match="may not be physically meaningful"):
369+
test_lorentzian.evaluate(np.array([0.0, 0.5, 1.0]))
370+
327371
def test_evaluate(self, lorentzian: Lorentzian):
328372
x = np.array([0.0, 0.5, 1.0])
329373
expected = lorentzian.evaluate(x)
@@ -387,6 +431,14 @@ def test_area_matches_parameter(self, lorentzian: Lorentzian):
387431
# THEN EXPECT
388432
assert numerical_area == pytest.approx(lorentzian.area.value, rel=2e-3)
389433

434+
def test_convert_unit(self, lorentzian: Lorentzian):
435+
lorentzian.convert_unit("microeV")
436+
437+
assert lorentzian.unit == "microeV"
438+
assert lorentzian.area.value == 2 * 1e3
439+
assert lorentzian.center.value == 0.5 * 1e3
440+
assert lorentzian.width.value == 0.6 * 1e3
441+
390442
def test_copy(self, lorentzian: Lorentzian):
391443
lorentzian_copy = lorentzian.copy()
392444
assert lorentzian_copy is not lorentzian
@@ -501,6 +553,21 @@ def test_negative_gaussian_width_raises(self):
501553
unit="meV",
502554
)
503555

556+
def test_negative_gaussian_width_raises_in_evaluate(self):
557+
test_voigt = Voigt(
558+
name="TestVoigt",
559+
area=2.0,
560+
center=0.5,
561+
gaussian_width=0.6,
562+
lorentzian_width=0.7,
563+
unit="meV",
564+
)
565+
test_voigt.gaussian_width.value = -0.6
566+
with pytest.raises(
567+
ValueError, match="The gaussian_width of a Voigt must be greater than."
568+
):
569+
test_voigt.evaluate(np.array([0.0, 0.5, 1.0]))
570+
504571
def test_negative_lorentzian_width_raises(self):
505572
with pytest.raises(
506573
ValueError,
@@ -515,6 +582,22 @@ def test_negative_lorentzian_width_raises(self):
515582
unit="meV",
516583
)
517584

585+
def test_negative_lorentzian_width_raises_in_evaluate(self):
586+
test_voigt = Voigt(
587+
name="TestVoigt",
588+
area=2.0,
589+
center=0.5,
590+
gaussian_width=0.6,
591+
lorentzian_width=0.7,
592+
unit="meV",
593+
)
594+
test_voigt.lorentzian_width.value = -0.7
595+
with pytest.raises(
596+
ValueError,
597+
match="The lorentzian_width of a Voigt must be greater than zero.",
598+
):
599+
test_voigt.evaluate(np.array([0.0, 0.5, 1.0]))
600+
518601
def test_negative_area_warns(self):
519602
with pytest.warns(UserWarning, match="may not be physically meaningful"):
520603
Voigt(
@@ -526,6 +609,19 @@ def test_negative_area_warns(self):
526609
unit="meV",
527610
)
528611

612+
def test_negative_area_warns_in_evaluate(self):
613+
test_voigt = Voigt(
614+
name="TestVoigt",
615+
area=2.0,
616+
center=0.5,
617+
gaussian_width=0.6,
618+
lorentzian_width=0.7,
619+
unit="meV",
620+
)
621+
test_voigt.area.value = -2.0
622+
with pytest.warns(UserWarning, match="may not be physically meaningful"):
623+
test_voigt.evaluate(np.array([0.0, 0.5, 1.0]))
624+
529625
def test_evaluate(self, voigt: Voigt):
530626
x = np.array([0.0, 0.5, 1.0])
531627
expected = voigt.evaluate(x)
@@ -580,31 +676,14 @@ def test_input_as_parameter(self):
580676
assert test_voigt.gaussian_width == param_gaussian_width
581677
assert test_voigt.lorentzian_width == param_lorentzian_width
582678

583-
def test_negative_width_raises(self):
584-
with pytest.raises(
585-
ValueError, match="The gaussian_width of a Voigt must be greater than zero"
586-
):
587-
Voigt(
588-
name="TestVoigt",
589-
area=2.0,
590-
center=0.5,
591-
gaussian_width=-0.6,
592-
lorentzian_width=0.7,
593-
unit="meV",
594-
)
679+
def test_convert_unit(self, voigt: Voigt):
680+
voigt.convert_unit("microeV")
595681

596-
with pytest.raises(
597-
ValueError,
598-
match="The lorentzian_width of a Voigt must be greater than zero",
599-
):
600-
Voigt(
601-
name="TestVoigt",
602-
area=2.0,
603-
center=0.5,
604-
gaussian_width=0.6,
605-
lorentzian_width=-0.7,
606-
unit="meV",
607-
)
682+
assert voigt.unit == "microeV"
683+
assert voigt.area.value == 2 * 1e3
684+
assert voigt.center.value == 0.5 * 1e3
685+
assert voigt.gaussian_width.value == 0.6 * 1e3
686+
assert voigt.lorentzian_width.value == 0.7 * 1e3
608687

609688
def test_get_parameters(self, voigt: Voigt):
610689
params = voigt.get_parameters()
@@ -730,6 +809,13 @@ def test_get_parameters(self, delta_function: DeltaFunction):
730809
assert params[1].name == "TestDeltaFunction center"
731810
assert all(isinstance(param, Parameter) for param in params)
732811

812+
def test_convert_unit(self, delta_function: DeltaFunction):
813+
delta_function.convert_unit("microeV")
814+
815+
assert delta_function.unit == "microeV"
816+
assert delta_function.area.value == 2 * 1e3
817+
assert delta_function.center.value == 0.5 * 1e3
818+
733819
def test_copy(self, delta_function: DeltaFunction):
734820
delta_copy = delta_function.copy()
735821
assert delta_copy is not delta_function
@@ -816,6 +902,21 @@ def test_negative_width_raises(self):
816902
unit="meV",
817903
)
818904

905+
def test_negative_width_raises_in_evaluate(self):
906+
test_dho = DampedHarmonicOscillator(
907+
name="TestDampedHarmonicOscillator",
908+
area=2.0,
909+
center=0.5,
910+
width=0.6,
911+
unit="meV",
912+
)
913+
test_dho.width.value = -0.6
914+
with pytest.raises(
915+
ValueError,
916+
match="The width of a DampedHarmonicOscillator must be greater than zero.",
917+
):
918+
test_dho.evaluate(np.array([0.0, 1.5, 3.0]))
919+
819920
def test_negative_area_warns(self):
820921
with pytest.warns(UserWarning, match="may not be physically meaningful"):
821922
DampedHarmonicOscillator(
@@ -826,6 +927,18 @@ def test_negative_area_warns(self):
826927
unit="meV",
827928
)
828929

930+
def test_negative_area_warns_in_evaluate(self):
931+
test_dho = DampedHarmonicOscillator(
932+
name="TestDampedHarmonicOscillator",
933+
area=2.0,
934+
center=0.5,
935+
width=0.6,
936+
unit="meV",
937+
)
938+
test_dho.area.value = -2.0
939+
with pytest.warns(UserWarning, match="may not be physically meaningful"):
940+
test_dho.evaluate(np.array([0.0, 1.5, 3.0]))
941+
829942
def test_evaluate(self, dho: DampedHarmonicOscillator):
830943
x = np.array([0.0, 1.5, 3.0])
831944
expected = dho.evaluate(x)
@@ -902,6 +1015,14 @@ def test_area_matches_parameter(self, dho: DampedHarmonicOscillator):
9021015
# THEN EXPECT
9031016
assert numerical_area == pytest.approx(dho.area.value, rel=2e-3)
9041017

1018+
def test_convert_unit(self, dho: DampedHarmonicOscillator):
1019+
dho.convert_unit("microeV")
1020+
1021+
assert dho.unit == "microeV"
1022+
assert dho.area.value == 2 * 1e3
1023+
assert dho.center.value == 1.5 * 1e3
1024+
assert dho.width.value == 0.3 * 1e3
1025+
9051026
def test_copy(self, dho: DampedHarmonicOscillator):
9061027
dho_copy = dho.copy()
9071028
assert dho_copy is not dho
@@ -956,7 +1077,7 @@ def test_input_type_validation_raises(self):
9561077
):
9571078
Polynomial(name="TestPolynomial", coefficients=[])
9581079

959-
def test_negative_value_warns(self):
1080+
def test_negative_value_warns_in_evaluate(self):
9601081
with pytest.warns(UserWarning, match="may not be physically meaningful"):
9611082
test_polynomial = Polynomial(name="TestPolynomial", coefficients=[-1.0])
9621083
test_polynomial.evaluate(np.array([0.0, 1.0, 2.0]))
@@ -967,6 +1088,24 @@ def test_evaluate(self, polynomial: Polynomial):
9671088
expected_result = 1.0 - 2.0 * x + 3.0 * x**2
9681089
np.testing.assert_allclose(expected, expected_result, rtol=1e-5)
9691090

1091+
def test_evaluate_scipp_array(self, polynomial: Polynomial):
1092+
x = sc.array(dims=["x"], values=[0.0, 1.0, 2.0], unit="meV")
1093+
expected = polynomial.evaluate(x)
1094+
expected_result = 1.0 - 2.0 * x.values + 3.0 * x.values**2
1095+
np.testing.assert_allclose(expected, expected_result, rtol=1e-5)
1096+
1097+
def test_evaluate_with_different_unit_error(self, polynomial: Polynomial):
1098+
x = sc.array(dims=["x"], values=[0.0, 1.0, 2.0], unit="microeV")
1099+
1100+
with pytest.raises(
1101+
ValueError,
1102+
match="Change the unit of the Polynomial and try again",
1103+
):
1104+
polynomial.evaluate(x)
1105+
1106+
def test_degree(self, polynomial: Polynomial):
1107+
assert polynomial.degree() == 2
1108+
9701109
def test_get_parameters(self, polynomial: Polynomial):
9711110
params = polynomial.get_parameters()
9721111
assert len(params) == 3

0 commit comments

Comments
 (0)