diff --git a/src/lumicks/pyoptics/trapping/interface.py b/src/lumicks/pyoptics/trapping/interface.py index 8e5a142..e682589 100644 --- a/src/lumicks/pyoptics/trapping/interface.py +++ b/src/lumicks/pyoptics/trapping/interface.py @@ -222,6 +222,11 @@ def fields_focus( where the field needs to be evaluated. In that case, all vectors need to be of the same length. + Raises + ------ + ValueError: raised when the immersion medium of the bead does not match the medium of the + objective. + Returns ------- Ex : np.ndarray @@ -568,7 +573,6 @@ def forces_focus( bfp_sampling_n=31, num_orders=None, integration_orders=None, - verbose=False, ): """ Calculate the forces on a bead in the focus of an arbitrary input @@ -688,8 +692,6 @@ def absorbed_power_focus( ------- Pabs : the absorbed power in Watts. """ - if bead.n_medium != objective.n_medium: - raise ValueError("The immersion medium of the bead and the objective have to be the same") n_orders = bead.number_of_orders if num_orders is None else max(int(num_orders), 1) @@ -796,9 +798,6 @@ def scattered_power_focus( Psca : the scattered power in Watts. """ - if bead.n_medium != objective.n_medium: - raise ValueError("The immersion medium of the bead and the objective have to be the same") - n_orders = bead.number_of_orders if num_orders is None else max(int(num_orders), 1) if integration_orders is None: diff --git a/tests/trapping/test_trapping_api.py b/tests/trapping/test_trapping_api.py new file mode 100644 index 0000000..33932fd --- /dev/null +++ b/tests/trapping/test_trapping_api.py @@ -0,0 +1,66 @@ +"""Test the czt-based implementation against a trivial implementation which sums plane waves""" + +import re + +import pytest + +import lumicks.pyoptics.trapping as trp + +bead_diam = 1e-6 +n_bead = 1.6 +n_medium = 1.33 +n_wrong_medium = 1.3 +NA = 1.2 +focal_length = 4.43e-3 +n_bfp = 1.0 +bead = trp.Bead(bead_diameter=bead_diam, n_bead=n_bead, n_medium=n_wrong_medium) +objective = trp.Objective(NA=NA, focal_length=focal_length, n_bfp=n_bfp, n_medium=n_medium) + + +def dummy(*args): + pass # We should never get there + + +## Test bead immersion medium and objective medium have to be the same +@pytest.mark.parametrize( + "function", + [ + trp.fields_focus, + trp.force_factory, + ], +) +def test_throw_on_wrong_medium(function) -> None: + bead = trp.Bead(bead_diameter=bead_diam, n_bead=n_bead, n_medium=n_wrong_medium) + objective = trp.Objective(NA=NA, focal_length=focal_length, n_bfp=n_bfp, n_medium=n_medium) + with pytest.raises( + ValueError, + match=re.escape("The immersion medium of the bead and the objective have to be the same"), + ): + function(dummy, objective=objective, bead=bead) + + +@pytest.mark.parametrize( + "NA, focal_length, n_medium, n_bfp, error_msg", + [ + (1.1, 4.43e-3, 1.0, 1.0, "The NA of the objective cannot be larger than n_medium"), + ( + -1.9, + 4.43e-3, + -1.0, + 1.0, + "Only positive refractive indices are supported for n_bfp and n_medium", + ), + ( + 0.9, + 4.43e-3, + 1.0, + -1.0, + "Only positive refractive indices are supported for n_bfp and n_medium", + ), + (1.0, 0.0, 1.0, 1.0, "focal_length needs to be strictly positive"), + (0.0, 4.43e-3, 1.0, 1.0, "NA needs to be strictly positive"), + ], +) +def test_objective_value_errors(NA, focal_length, n_medium, n_bfp, error_msg): + with pytest.raises(ValueError, match=re.escape(error_msg)): + obj = trp.Objective(NA=NA, focal_length=focal_length, n_bfp=n_bfp, n_medium=n_medium)