Пример #1
0
def test_interpolated_eval(modes_all):
    if eradiate.mode().has_flags(ModeFlags.ANY_MONO):
        spectral_ctx = SpectralContext.new(wavelength=550.0)
        expected = 0.5

    elif eradiate.mode().has_flags(ModeFlags.ANY_CKD):
        bin = BinSet.from_db("10nm").select_bins("550")[0]
        spectral_ctx = SpectralContext.new(bindex=bin.bindexes[0])
        expected = 0.5

    else:
        assert False

    # Spectrum without quantity performs linear interpolation and yields units
    # consistent with values
    spectrum = InterpolatedSpectrum(wavelengths=[500.0, 600.0], values=[0.0, 1.0])
    assert spectrum.eval(spectral_ctx) == expected
    spectrum.values *= ureg("W/m^2/nm")
    assert spectrum.eval(spectral_ctx) == expected * ureg("W/m^2/nm")

    # Spectrum with quantity performs linear interpolation and yields units
    # consistent with quantity
    spectrum = InterpolatedSpectrum(
        quantity="irradiance", wavelengths=[500.0, 600.0], values=[0.0, 1.0]
    )
    # Interpolation returns quantity
    assert spectrum.eval(spectral_ctx) == expected * ucc.get("irradiance")
Пример #2
0
def test_spectral_context_new(modes_all):
    """
    Unit tests for :meth:`SpectralContext.new`.
    """

    # Empty call to new() should yield the appropriate SpectralContext instance
    if eradiate.mode().has_flags(ModeFlags.ANY_MONO):
        assert isinstance(SpectralContext.new(), MonoSpectralContext)
    elif eradiate.mode().has_flags(ModeFlags.ANY_CKD):
        assert isinstance(SpectralContext.new(), CKDSpectralContext)
    else:
        # All modes must have a context: this test fails if the mode has no
        # associated spectral context
        assert False
Пример #3
0
def test_afgl_1986_rad_profile_concentrations(
        mode_mono, afgl_1986_test_absorption_data_sets):
    """
    Absorption coefficient is twice larger when H2O concentration is doubled.
    """

    thermoprops = make_profile_afgl_1986()
    column_amount_H2O = compute_column_number_density(ds=thermoprops,
                                                      species="H2O")
    p1 = AFGL1986RadProfile(
        thermoprops=thermoprops,
        absorption_data_sets=afgl_1986_test_absorption_data_sets,
    )

    p2 = AFGL1986RadProfile(
        thermoprops=dict(concentrations={
            "H2O": 2 * column_amount_H2O,
        }),
        absorption_data_sets=afgl_1986_test_absorption_data_sets,
    )
    spectral_ctx = SpectralContext.new(wavelength=1500.0 * ureg.nm)

    sigma_a_initial = p1.eval_sigma_a(spectral_ctx)
    sigma_a_doubled = p2.eval_sigma_a(spectral_ctx)

    assert np.allclose(sigma_a_doubled, 2 * sigma_a_initial, rtol=1e-2)
Пример #4
0
def test_homogeneous_sigma_s(mode_mono):
    """
    Assigns custom 'sigma_s' value.
    """
    spectral_ctx = SpectralContext.new()
    r = HomogeneousAtmosphere(sigma_s=1e-5)
    assert r.eval_sigma_s(spectral_ctx) == ureg.Quantity(1e-5, ureg.m ** -1)
Пример #5
0
def test_us76_approx_rad_profile_ckd_sigma_s(mode_ckd):
    """
    Scattering coefficient evaluation methods return pint.Quantity object.
    """
    p = US76ApproxRadProfile()

    spectral_ctx = SpectralContext.new()

    assert isinstance(p.eval_sigma_s_ckd(spectral_ctx.bindex), ureg.Quantity)
Пример #6
0
def test_molecular_atmosphere_default(mode_mono, tmpdir,
                                      ussa76_approx_test_absorption_data_set):
    """Default MolecularAtmosphere constructor produces a valid kernel
    dictionary."""
    spectral_ctx = SpectralContext.new(wavelength=550.0)
    ctx = KernelDictContext(spectral_ctx=spectral_ctx)
    atmosphere = MolecularAtmosphere(absorption_data_sets=dict(
        us76_u86_4=ussa76_approx_test_absorption_data_set))
    assert KernelDict.from_elements(atmosphere, ctx=ctx).load() is not None
Пример #7
0
def test_particle_layer_eval_radprops(modes_all_single, test_dataset):
    """Method 'eval_radprops' returns dataset with expected datavars and coords."""
    layer = ParticleLayer(dataset=test_dataset)
    spectral_ctx = SpectralContext.new()
    ds = layer.eval_radprops(spectral_ctx)
    expected_data_vars = ["sigma_t", "albedo"]
    expected_coords = ["z_layer"]
    assert all([coord in ds.coords for coord in expected_coords]) and all(
        [var in ds.data_vars for var in expected_data_vars]
    )
Пример #8
0
def test_us76_approx_rad_profile(mode_mono,
                                 us76_approx_test_absorption_data_set):
    """
    Collision coefficient evaluation methods return pint.Quantity objects.
    """
    p = US76ApproxRadProfile(
        absorption_data_set=us76_approx_test_absorption_data_set)

    spectral_ctx = SpectralContext.new()
    for field in ["sigma_a", "sigma_s", "sigma_t", "albedo"]:
        x = getattr(p, f"eval_{field}")(spectral_ctx)
        assert isinstance(x, ureg.Quantity)
Пример #9
0
def test_afgl_1986_rad_profile_default(mode_mono,
                                       afgl_1986_test_absorption_data_sets):
    """
    Collision coefficient evaluation methods return pint.Quantity objects.
    """
    p = AFGL1986RadProfile(
        absorption_data_sets=afgl_1986_test_absorption_data_sets)

    spectral_ctx = SpectralContext.new(wavelength=1500.0)
    for field in ["sigma_a", "sigma_s", "sigma_t", "albedo"]:
        x = getattr(p, f"eval_{field}")(spectral_ctx)
        assert isinstance(x, ureg.Quantity)
Пример #10
0
def test_us76_approx_rad_profile_has_scattering_default(
        mode_mono, us76_approx_test_absorption_data_set):
    """
    Default value for 'has_scattering' is True, hence the scattering
    coefficient is computed and is not zero everywhere at 550 nm.
    """
    p = US76ApproxRadProfile(
        absorption_data_set=us76_approx_test_absorption_data_set)
    assert p.has_scattering
    spectral_ctx = SpectralContext.new(wavelength=550.0)
    ds = p.eval_dataset(spectral_ctx)
    assert (ds.sigma_s.values != 0.0).any()
Пример #11
0
def test_array_rad_props_profile_eval_dataset(mode_mono):
    """
    Returns a data set.
    """
    p = ArrayRadProfile(
        levels=ureg.Quantity(np.linspace(0, 100, 12), "km"),
        albedo_values=ureg.Quantity(np.linspace(0.0, 1.0, 11),
                                    ureg.dimensionless),
        sigma_t_values=ureg.Quantity(np.linspace(0.0, 1e-5, 11), "m^-1"),
    )
    spectral_ctx = SpectralContext.new()
    assert isinstance(p.eval_dataset(spectral_ctx), xr.Dataset)
Пример #12
0
def test_afgl_1986_rad_profile_has_scattering_default(
        mode_mono, afgl_1986_test_absorption_data_sets):
    """
    Default value for 'has_scattering' is True, hence the absorption
    coefficient is computed and is not zero everywhere at 550 nm.
    """
    p = AFGL1986RadProfile(
        absorption_data_sets=afgl_1986_test_absorption_data_sets)
    assert p.has_scattering
    spectral_ctx = SpectralContext.new(wavelength=550.0)
    ds = p.eval_dataset(spectral_ctx)
    assert (ds.sigma_s.values != 0.0).any()
Пример #13
0
def test_molecular_atmosphere_afgl_1986(
    mode_mono,
    tmpdir,
    afgl_1986_test_absorption_data_sets,
):
    """MolecularAtmosphere 'afgl_1986' constructor produces a valid kernel
    dictionary."""
    spectral_ctx = SpectralContext.new(wavelength=550.0)
    ctx = KernelDictContext(spectral_ctx=spectral_ctx)
    atmosphere = MolecularAtmosphere.afgl_1986(
        absorption_data_sets=afgl_1986_test_absorption_data_sets)
    assert KernelDict.from_elements(atmosphere, ctx=ctx).load() is not None
Пример #14
0
def test_solar_irradiance_eval(modes_all):
    # Irradiance is correctly interpolated in mono mode
    s = SolarIrradianceSpectrum(dataset="thuillier_2003")

    if eradiate.mode().has_flags(ModeFlags.ANY_MONO):
        spectral_ctx = SpectralContext.new(wavelength=550.0)
        # Reference value computed manually
        assert np.allclose(s.eval(spectral_ctx),
                           ureg.Quantity(1.87938, "W/m^2/nm"))

    elif eradiate.mode().has_flags(ModeFlags.ANY_CKD):
        bin_set = BinSet.from_db("10nm")
        bin = bin_set.select_bins("550")[0]
        bindex = bin.bindexes[0]
        spectral_ctx = SpectralContext.new(bindex=bindex)
        # Reference value computed manually
        assert np.allclose(s.eval(spectral_ctx),
                           ureg.Quantity(1.871527, "W/m^2/nm"))

    else:
        assert False
Пример #15
0
def test_afgl_1986_rad_profile_has_absorption_true(
        mode_mono, afgl_1986_test_absorption_data_sets):
    """
    When 'has_absorption' is True, the absorption coefficient is computed
    and is not zero everywhere at 1650 nm.
    """
    p = AFGL1986RadProfile(
        has_absorption=True,
        absorption_data_sets=afgl_1986_test_absorption_data_sets)
    assert p.has_absorption
    spectral_ctx = SpectralContext.new(wavelength=1650.0)
    ds = p.eval_dataset(spectral_ctx)
    assert (ds.sigma_a.values != 0.0).any()
Пример #16
0
def test_afgl_1986_rad_profile_has_scattering_false(
        mode_mono, afgl_1986_test_absorption_data_sets):
    """
    When 'has_scattering' is False, the scattering coefficient is not
    computed and is zero everywhere.
    """
    p = AFGL1986RadProfile(
        has_scattering=False,
        absorption_data_sets=afgl_1986_test_absorption_data_sets)
    assert not p.has_scattering
    spectral_ctx = SpectralContext.new(wavelength=550.0)
    ds = p.eval_dataset(spectral_ctx)
    assert (ds.sigma_s.values == 0.0).all()
Пример #17
0
def test_us76_approx_rad_profile_has_absorption_false(
        mode_mono, us76_approx_test_absorption_data_set):
    """
    When 'has_absorption' is False, the absorption coefficient is not
    computed and is zero everywhere.
    """
    p = US76ApproxRadProfile(
        has_absorption=False,
        absorption_data_set=us76_approx_test_absorption_data_set)
    assert not p.has_absorption
    spectral_ctx = SpectralContext.new(wavelength=1650.0)
    ds = p.eval_dataset(spectral_ctx)
    assert (ds.sigma_a.values == 0.0).all()
Пример #18
0
def test_us76_approx_rad_profile_levels(mode_mono,
                                        us76_approx_test_absorption_data_set):
    """
    Collision coefficients' shape match altitude levels shape.
    """
    p = US76ApproxRadProfile(
        thermoprops=dict(levels=ureg.Quantity(np.linspace(0, 120, 121), "km")),
        absorption_data_set=us76_approx_test_absorption_data_set,
    )

    spectral_ctx = SpectralContext.new()
    for field in ["sigma_a", "sigma_s", "sigma_t", "albedo"]:
        x = getattr(p, f"eval_{field}")(spectral_ctx)
        assert x.shape == (120, )
Пример #19
0
def test_afgl_1986_rad_profile_default_ckd(mode_ckd):
    """
    Collision coefficient evaluation methods return pint.Quantity objects.
    """
    p = AFGL1986RadProfile()

    spectral_ctx = SpectralContext.new(bin_set="10nm")
    for field in ["albedo", "sigma_a", "sigma_t"]:
        x = getattr(p, f"eval_{field}_ckd")(spectral_ctx.bindex,
                                            bin_set_id=spectral_ctx.bin_set.id)
        assert isinstance(x, ureg.Quantity)

    sigma_s = p.eval_sigma_s_ckd(spectral_ctx.bindex)
    assert isinstance(sigma_s, ureg.Quantity)
Пример #20
0
def test_mono_spectral_context(mode_mono):
    """
    Unit tests for :class:`MonoSpectralContext`.
    """

    ctx = SpectralContext.new(wavelength=550.0)

    # Wavelength is stored as a Pint quantity
    assert ctx.wavelength == 550.0 * ureg.nm

    # Index is a plain float
    assert ctx.spectral_index == 550.0

    # Index string repr is nice and compact
    assert ctx.spectral_index_formatted == "550 nm"
Пример #21
0
def test_afgl_1986_rad_profile_levels(mode_mono,
                                      afgl_1986_test_absorption_data_sets):
    """
    Collision coefficients' shape match altitude levels shape.
    """
    n_layers = 101
    p = AFGL1986RadProfile(
        thermoprops=dict(
            levels=ureg.Quantity(np.linspace(0.0, 100.0, n_layers + 1), "km")),
        absorption_data_sets=afgl_1986_test_absorption_data_sets,
    )

    spectral_ctx = SpectralContext.new(wavelength=550.0)
    for field in ["sigma_a", "sigma_s", "sigma_t", "albedo"]:
        x = getattr(p, f"eval_{field}")(spectral_ctx)
        assert x.shape == (n_layers, )
Пример #22
0
def test_ckd_spectral_context(mode_ckd):
    """
    Unit tests for :class:`CKDSpectralContext`.
    """
    quad = Quad.gauss_legendre(16)
    bin = Bin.convert({
        "id": "510",
        "wmin": 505.0,
        "wmax": 515.0,
        "quad": quad
    })
    ctx = SpectralContext.new(bindex=bin.bindexes[8])

    # Wavelength is equal to bin central wavelength
    assert ctx.wavelength == 510.0 * ureg.nm

    # Index is a (str, int) pair
    assert ctx.spectral_index == ("510", 8)

    # Index string repr is a compact "{bin_id}:{quad_point_index}" string
    assert ctx.spectral_index_formatted == "510:8"
Пример #23
0
def test_interpolated_kernel_dict(modes_all_mono):
    from mitsuba.core.xml import load_dict

    ctx = KernelDictContext(spectral_ctx=SpectralContext.new(wavelength=550.0))

    spectrum = InterpolatedSpectrum(
        id="spectrum",
        quantity="irradiance",
        wavelengths=[500.0, 600.0],
        values=[0.0, 1.0],
    )

    # Produced kernel dict is valid
    assert load_dict(spectrum.kernel_dict(ctx)["spectrum"]) is not None

    # Unit scaling is properly applied
    with ucc.override({"radiance": "W/m^2/sr/nm"}):
        s = InterpolatedSpectrum(
            quantity="radiance", wavelengths=[500.0, 600.0], values=[0.0, 1.0]
        )
    with uck.override({"radiance": "kW/m^2/sr/nm"}):
        d = s.kernel_dict(ctx)
        assert np.allclose(d["spectrum"]["value"], 5e-4)
Пример #24
0
def test_tabulated_order(mode_mono, tmpdir):
    """
    TabulatedPhaseFunction returns phase function values by increasing order of
    scattering angle cosine values, regardless how its input is ordered.
    """
    def make_da(mu, phase):
        return xr.DataArray(
            phase[:, :, np.newaxis, np.newaxis],
            coords={
                "w": ("w", [240.0, 2800.0], dict(units="nm")),
                "mu": ("mu", mu),
                "i": ("i", [0]),
                "j": ("j", [0]),
            },
        )

    da_mu_increasing = make_da(mu=np.linspace(-1, 1, 3),
                               phase=np.array(
                                   [np.arange(1, 4),
                                    np.arange(1, 4)]))

    da_mu_decreasing = make_da(
        mu=np.linspace(1, -1, 3),
        phase=np.array([np.arange(3, 0, -1),
                        np.arange(3, 0, -1)]),
    )

    spectral_ctx = SpectralContext.new()

    layer_mu_increasing = TabulatedPhaseFunction(data=da_mu_increasing)
    phase_mu_increasing = layer_mu_increasing.eval(spectral_ctx)

    layer_mu_decreasing = TabulatedPhaseFunction(data=da_mu_decreasing)
    phase_mu_decreasing = layer_mu_decreasing.eval(spectral_ctx)

    assert np.all(phase_mu_increasing == phase_mu_decreasing)
Пример #25
0
def test_array_rad_props_profile(mode_mono):
    """
    Assigns attributes.
    """
    levels = ureg.Quantity(np.linspace(0, 100, 12), "km")
    albedo_values = ureg.Quantity(np.linspace(0.0, 1.0, 11),
                                  ureg.dimensionless)
    sigma_t_values = ureg.Quantity(np.linspace(0.0, 1e-5, 11), "m^-1")
    p = ArrayRadProfile(
        levels=levels,
        albedo_values=albedo_values,
        sigma_t_values=sigma_t_values,
    )

    spectral_ctx = SpectralContext.new()
    assert isinstance(p.levels, ureg.Quantity)
    assert isinstance(p.eval_albedo(spectral_ctx=spectral_ctx), ureg.Quantity)
    assert isinstance(p.eval_sigma_t(spectral_ctx=spectral_ctx), ureg.Quantity)
    assert isinstance(p.eval_sigma_a(spectral_ctx=spectral_ctx), ureg.Quantity)
    assert isinstance(p.eval_sigma_s(spectral_ctx=spectral_ctx), ureg.Quantity)
    assert np.allclose(p.levels, levels)
    assert np.allclose(p.eval_albedo(spectral_ctx=spectral_ctx), albedo_values)
    assert np.allclose(p.eval_sigma_t(spectral_ctx=spectral_ctx),
                       sigma_t_values)