From f672d1b8e17f506576cdadb7d9ca0d1359978a77 Mon Sep 17 00:00:00 2001 From: Pietro Berkes Date: Thu, 28 Nov 2024 14:20:47 +0100 Subject: [PATCH] Add `Results.standard_parameters_estimate` --- psignifit/_result.py | 22 ++++++++++++++++++++++ psignifit/tests/test_result.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/psignifit/_result.py b/psignifit/_result.py index 85d04f8..29a8426 100644 --- a/psignifit/_result.py +++ b/psignifit/_result.py @@ -170,3 +170,25 @@ def slope_at_proportion_correct(self, proportion_correct: np.ndarray, unscaled: """ stimulus_levels = self.threshold(proportion_correct, unscaled, return_ci=False, estimate_type=estimate_type) return self.slope(stimulus_levels) + + def standard_parameters_estimate(self, estimate_type: Optional[EstimateType]=None): + """ Get the parameters of the psychometric function in the standard format. + + `psignifit` uses the same intuitive parametrization, threshold and width, for all + sigmoid types. However, each different type of sigmoid has its own standard parametrization. + + The interpretation of the standard parameters, location and scale, depends on the sigmoid class used. + For instance, for a Gaussian sigmoid, the location corresponds to the mean and the scale to the standard + deviation of the distribution. + + For negative slope sigmoids, we return the same parameters as for the positive ones. + + Args: + proportion_correct: proportion correct at the threshold you want to calculate + Returns: + Standard parameters (loc, scale) for the sigmoid subclass. + """ + sigmoid = self.configuration.make_sigmoid() + estimate = self.get_parameters_estimate(estimate_type) + loc, scale = sigmoid.standard_parameters(estimate['threshold'], estimate['width']) + return loc, scale diff --git a/psignifit/tests/test_result.py b/psignifit/tests/test_result.py index e53bc9a..f5deb71 100644 --- a/psignifit/tests/test_result.py +++ b/psignifit/tests/test_result.py @@ -185,3 +185,32 @@ def test_estimate_type_default(result): result.estimate_type = 'mean' estimate = result.get_parameters_estimate() assert _close_numpy_dict(estimate, result.parameters_estimate_mean) + + +def test_standard_parameters_estimate(): + width = 2.1 + threshold = 0.87 + parameter_estimate = { + 'threshold': threshold, + 'width': width, + 'lambda': 0.0, + 'gamma': 0.0, + 'eta': 0.0, + } + confidence_intervals = { + 'threshold': [[threshold, threshold]], + 'width': [[width, width]], + 'lambda': [[0.05, 0.2]], + 'gamma': [[0.1, 0.3]], + 'eta': [[0.0, 0.0]] + } + result = _build_result(parameter_estimate, parameter_estimate, confidence_intervals) + + # For a Gaussian sigmoid with alpha=0.05, PC=0.5 + expected_loc = threshold + # 1.644853626951472 is the normal PPF at alpha=0.95 + expected_scale = width / (2 * 1.644853626951472) + + loc, scale = result.standard_parameters_estimate() + np.testing.assert_allclose(loc, expected_loc) + np.testing.assert_allclose(scale, expected_scale)