Example #1
0
def test_simultaneous_fit_basic(logging_mixin: Any,
                                setup_simultaneous_fit_data: Any) -> None:
    """ Test basic Simultaneous fit functionality. """
    # Setup
    h, h_shifted, _, _ = setup_simultaneous_fit_data

    # Check with cost functions
    cost_func1 = cost_function.ChiSquared(func_1, data=h)
    cost_func2 = cost_function.ChiSquared(func_2, data=h_shifted)
    s2 = cost_function.SimultaneousFit(cost_func1, cost_func2)
    assert s2.func_code == fit_base.FuncCode(["a", "b", "c", "d"])

    # Check with manually added functions
    s3 = cost_func1 + cost_func2
    assert s3.func_code == fit_base.FuncCode(["a", "b", "c", "d"])
    assert s3 == s2
Example #2
0
def test_nested_simultaneous_fit_objects(
        logging_mixin: Any, setup_simultaneous_fit_data: Any) -> None:
    """ Test for unraveling nested simultaneous fit objects. """
    # Setup
    h, h_shifted, _, _ = setup_simultaneous_fit_data

    # Check with cost functions
    cost_func1 = cost_function.ChiSquared(func_1, data=h)
    cost_func2 = cost_function.ChiSquared(func_2, data=h_shifted)
    cost_func3 = cost_function.ChiSquared(lambda x, e, f: x + e + f, data=h)
    s = cost_func1 + cost_func2
    s2 = s + cost_func3
    assert s2.func_code == fit_base.FuncCode(["a", "b", "c", "d", "e", "f"])

    # Test out using sum
    s3 = sum([cost_func1, cost_func2, cost_func3])
    # Help out mypy...
    assert isinstance(s3, cost_function.SimultaneousFit)
    assert s3.func_code == fit_base.FuncCode(["a", "b", "c", "d", "e", "f"])
Example #3
0
    def __init__(self, *functions: Callable[..., float], prefixes: Optional[Sequence[str]] = None,
                 skip_prefixes: Optional[Sequence[str]] = None) -> None:
        # Store the functions
        self.functions = list(functions)

        # Determine the arguments for the functions.
        merged_args, argument_positions = fit_base.merge_func_codes(
            self.functions, prefixes = prefixes, skip_prefixes = skip_prefixes
        )
        logger.debug(f"merged_args: {merged_args}")
        self.func_code = fit_base.FuncCode(merged_args)
        self.argument_positions = argument_positions
Example #4
0
 def __init__(
     self,
     f: Callable[..., float],
     data: Union[npt.NDArray[Any], histogram.Histogram1D],
     **additional_call_options: Any,
 ):
     # If using numba, we would need to JIT the function to be able to pass it to the cost function.
     self.f = f
     # We need to drop the leading x argument
     self.func_code = fit_base.FuncCode(iminuit.util.describe(self.f)[1:])
     self.data = data
     self._additional_call_options: Dict[str, Any] = additional_call_options
Example #5
0
def test_func_code(logging_mixin: Any, simple_test_functions: Any) -> None:
    """ Test creating function codes with FuncCode. """
    # Setup
    func_1, func_2 = simple_test_functions

    # Define the func code and check the properties
    func_code = fit_base.FuncCode(iminuit.util.describe(func_1))
    assert func_code.co_varnames == ["x", "a", "b"]
    assert func_code.co_argcount == 3

    # Alternatively create via static method
    func_code_2 = fit_base.FuncCode.from_function(func_1)
    assert func_code == func_code_2
Example #6
0
    def __init__(self, *cost_functions: Union[T_CostFunction,
                                              "SimultaneousFit"]):
        # Validation
        # Ensure that we unravel any SimultaneousFit objects to their base cost functions.
        funcs = list(unravel_simultaneous_fits(list(cost_functions)))

        self.cost_functions = funcs
        logger.debug("Simultaneous Fit")
        merged_args, argument_positions = fit_base.merge_func_codes(
            self.cost_functions)
        # We don't drop any of the arguments here because the cost functions already did it.
        self.func_code = fit_base.FuncCode(merged_args)
        self.argument_positions = argument_positions
def test_simultaneous_fit(logging_mixin: Any,
                          setup_simultaneous_fit_data: Any) -> None:
    """ Test Simultaneous Fit functionality vs probfit with an integration test. """
    # Setup
    h, h_shifted, _, _ = setup_simultaneous_fit_data
    cost_func1 = cost_function.ChiSquared(parabola, data=h)
    cost_func2 = cost_function.ChiSquared(parabola, data=h_shifted)
    minuit_args: Dict[str, Union[float, Tuple[float, float]]] = {
        "scale": 1.5,
        "error_scale": 0.15,
        "limit_scale": (-1000, 1000),
    }

    # Setup the probfit version
    probfit = pytest.importorskip("probfit")
    s_probfit = probfit.SimultaneousFit(*[cost_func1, cost_func2])

    # Setup the comparison version
    s = cost_func1 + cost_func2

    # First, basic checks
    logger.debug(
        f"func_code: {s.func_code}, co_varnames: {s.func_code.co_varnames}")
    assert s.func_code == fit_base.FuncCode(["scale"])
    assert s.func_code.co_varnames == list(s_probfit.func_code.co_varnames)

    # Now perform the fits
    fit_result, _ = fit_integration.fit_with_minuit(cost_func=s,
                                                    minuit_args=minuit_args,
                                                    x=h.x)
    fit_result_probfit, _ = fit_integration.fit_with_minuit(
        cost_func=s_probfit, minuit_args=minuit_args, x=h.x)
    # And check that the fit results agree
    logger.debug(
        f"scale: {fit_result.values_at_minimum['scale']} +/- {fit_result.errors_on_parameters['scale']}"
    )
    logger.info(f"type: {type(fit_result)}, {type(fit_result_probfit)}")
    assert fit_result == fit_result_probfit