예제 #1
0
def test_calibration_domain_range():
    """Test setting the domain and range of a calibration."""
    cal = Calibration("p[0] + p[1] * x", [5.0, 4.0])

    # set the domain and range to defaults
    cal.domain = None
    cal.range = None

    # cannot set domain or range to infinite values
    with pytest.raises(CalibrationError):
        cal.domain = [-np.inf, np.inf]
    with pytest.raises(CalibrationError):
        cal.range = [-np.inf, np.inf]

    # set the domain and range to specific values
    x0 = 1
    cal.domain = [x0 - 1, x0 + 1]
    cal.range = [-1e6, 1e6]

    # evaluate for x inside domain and result inside range
    y0 = cal(x0)

    # evaluate for x outside domain (fails)
    x1 = cal.domain[1] + 3
    with pytest.raises(CalibrationError):
        cal(x1)

    # expand domain and reevaluate
    cal.domain = (cal.domain[0], x1 + 1)
    cal(x1)

    # evaluate for x inside domain and result outside range (warns)
    cal.domain = [x0 - 1, x0 + 1]
    cal.range = [y0 + 10, y0 + 20]
    with pytest.warns(CalibrationWarning):
        y2 = cal(x0)
    # y value is not clipped to the range so should be the same as before
    assert np.isclose(y0, y2)

    # expand range and reevaluate
    cal.range = [y0 - 1, y0 + 1]
    cal(x0)
예제 #2
0
def test_calibration_inverse():
    """Test calibrations with and without inverse expression."""
    fname = os.path.join(TEST_OUTPUTS, "calibration__inverse.h5")

    # cal1 has an explicit inverse expression, cal2 does not
    cal1 = Calibration("p[0] + p[1] * x", [5.0, 4.0],
                       inv_expression="(y - p[0]) / p[1]")
    cal2 = Calibration(cal1.expression, [5.0, 4.0])
    assert cal1 == cal2

    # evaluate the inverse for a scalar
    y = 100.0
    x1 = cal1.inverse(y)
    x2 = cal2.inverse(y)
    assert np.isclose(x1, (y - 5.0) / 4.0)
    assert np.isclose(x1, x2)

    # evaluate the inverse for a scalar with initial guess
    x1 = cal1.inverse(y, x0=25.0)
    x2 = cal2.inverse(y, x0=25.0)
    assert np.isclose(x1, (y - 5.0) / 4.0)
    assert np.isclose(x1, x2)

    # evaluate the inverse for an array
    y = np.linspace(20.0, 500.0, num=100)
    x1 = cal1.inverse(y)
    x2 = cal2.inverse(y)
    assert np.allclose(x1, (y - 5.0) / 4.0)
    assert np.allclose(x1, x2)

    # evaluate the inverse for an array with initial guesses
    y = np.linspace(20.0, 500.0, num=100)
    x0 = np.arange(len(y)) / 4.0
    x1 = cal1.inverse(y, x0=x0)
    x2 = cal2.inverse(y, x0=x0)
    assert np.allclose(x1, (y - 5.0) / 4.0)
    assert np.allclose(x1, x2)

    # evaluate inverse for values inside the range with result inside domain
    cal1.domain = [0, 1]
    cal1.range = [-1e6, 1e6]
    x0 = 0.5
    y0 = cal1(x0)
    cal1.range = [y0 - 1, y0 + 1]
    cal1.inverse(y0)

    # evaluate inverse for values inside the range with result outside domain
    cal1.domain = [0, 2]
    cal1.range = [-1e6, 1e6]
    x0 = 2.0
    y0 = cal1(x0)
    cal1.domain = [0, 1]
    cal1.range = [y0 - 1, y0 + 1]
    with pytest.raises(CalibrationError):
        cal1(x0)
    with pytest.raises(CalibrationError):
        cal1.inverse(y0)

    # evaluate the inverse for a value outside the range and the domain
    cal1.domain = [0, 2]
    cal1.range = [-1e6, 1e6]
    x0 = 2.0
    y0 = cal1(x0)
    cal1.domain = [x0 - 2, x0 - 1]
    cal1.range = [y0 - 2, y0 - 1]
    with pytest.raises(CalibrationError):
        cal1(x0)
    with pytest.raises(CalibrationError):
        cal1.inverse(y0)

    # test __str__() and __repr__()
    str(cal1)
    repr(cal1)

    # test write() and read()
    cal1.write(fname)
    cal3 = Calibration.read(fname)
    assert cal3.inv_expression is not None
    assert cal3.inv_expression == cal1.inv_expression