Beispiel #1
0
def test_auto_correct_dispersion(f=750, phi=-6, gr=2400, 
                                 verbose=True, plot=True, close_plots=True, *args, **kwargs):
    ''' A test case to show the effect of wavelength dispersion (cf spectrometer
    reciprocal function) on the slit function 
    
    Parameters
    ----------
    
    f: focal length (mm)
         default 750 (SpectraPro 2750i)

    phi: angle in degrees (°)
        default -6

    gr: grooves spacing (gr/mm)
        default 2400
    
    '''

    from radis.test.utils import getTestFile
    from publib import set_style, fix_style
    from radis.misc.warning import SlitDispersionWarning
    
    if plot:
        plt.ion()   # dont get stuck with Matplotlib if executing through pytest
        if close_plots:
            plt.close('all')

    w_slit_632, I_slit_632 = import_experimental_slit(getTestFile('slitfunction.txt'))
    slit_measured_632nm = getTestFile('slitfunction.txt')

    w, I = np.loadtxt(getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt')).T
    s = calculated_spectrum(w, I, conditions={'Tvib': 3000, 'Trot': 1200},
                            Iunit='mW/cm2/sr/µm')

    slit_dispersion = lambda w: linear_dispersion(w, f=f, phi=phi, m=1, gr=gr)

    s.apply_slit(slit_measured_632nm)
    if plot:
        w_full_range = np.linspace(w.min(), w_slit_632.max())
        set_style('origin')
        plt.figure('Spectrometer Dispersion (f={0}mm, phi={1}°, gr={2}'.format(
                            f, phi, gr))
        plt.plot(w_full_range, slit_dispersion(w_full_range))
        plt.xlabel('Wavelength (nm)')
        plt.ylabel('Reciprocal Linear Dispersion')
    
    # Compare 2 spectra
        s.plot(nfig='Linear dispersion effect', color='r', label='not corrected')
    with pytest.warns(SlitDispersionWarning):   # expect a "large slit dispersion" warning
        s.apply_slit(slit_measured_632nm, slit_dispersion=slit_dispersion)
    if plot:
        s.plot(nfig='same', color='k', label='corrected')
        plt.legend()
        # Plot different slits:
        s.plot_slit()
#    plt.plot(w_slit_632, I_slit_632, color='r', label='Not corrected')
#    plt.legend()

    return True  # nothing defined yet
Beispiel #2
0
def test_crop(verbose=True, *args, **kwargs):
    """ Test that update can correctly recompute missing quantities """

    # 1) A crop example in the same unit as the one stored

    # Work with a Spectrum object that was generated by Specair
    s = load_spec(getTestFile("N2C_specair_380nm.spec"))
    # Focus on N2(C->B), v'=0, v''=2 band:
    s.crop(376, 381, "nm")

    w = s.get_wavelength()
    assert w.min() >= 360
    assert w.max() <= 382

    # 2) A crop example in different unit as the one stored

    # Work with a Spectrum object that was generated by Specair
    s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                   binary=True)
    # Focus on N2(C->B), v'=0, v''=2 band:
    s1.crop(4530, 4533, "nm")

    w = s1.get_wavelength()
    assert w.min() >= 4530
    assert w.max() <= 4533

    return True
Beispiel #3
0
def run_example():
    setup_test_line_databases(
        verbose=True)  # add HITEMP-CO2-HAMIL-TEST in ~/.radis if not there

    sf = SpectrumFactory(
        wavenum_min=2283.7,
        wavenum_max=2285.1,
        wstep=0.001,
        cutoff=1e-30,
        path_length=0.1,
        mole_fraction=400e-6,
        isotope=[1],
        db_use_cached=True,  # important to test CAche file here
        verbose=2,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.load_databank("HITEMP-CO2-HAMIL-TEST")

    # Now generate vibrational energies for a 2-T model
    # ... Note that this is arbitrary. Lookup Pannier & Dubuet 2020 for more.
    levels = sf.parsum_calc["CO2"][1]["X"].df
    levels["Evib"] = levels.Evib1 + levels.Evib2 + levels.Evib3

    # Calculate populations using the non-equilibrium module:
    # This will crash the first time because the Levels Database is just a fragment and does not include all levels.
    try:
        sf.non_eq_spectrum(300, 300)
    except AssertionError:  # expected
        sf.df0.dropna(inplace=True)

    getTestFile("HITEMP-CO2-HAMIL-TEST")

    s = sf.non_eq_spectrum(300, 300)
    s.plot()
Beispiel #4
0
def test_all_slit_shapes(FWHM=0.4,
                         verbose=True,
                         plot=True,
                         close_plots=True,
                         *args,
                         **kwargs):
    """ Test all slit generation functions and make sure we get the expected FWHM"""

    if plot:
        plt.ion()  # dont get stuck with Matplotlib if executing through pytest
        if close_plots:
            plt.close("all")

    # get spectrum
    from radis.test.utils import getTestFile
    from radis.spectrum.spectrum import Spectrum

    s = Spectrum.from_txt(
        getTestFile("calc_N2C_spectrum_Trot1200_Tvib3000.txt"),
        quantity="radiance_noslit",
        waveunit="nm",
        unit="mW/cm2/sr/µm",
    )
    wstep = np.diff(s.get_wavelength())[0]

    # Plot all slits
    # ... gaussian
    s.apply_slit(FWHM, unit="nm", shape="gaussian", plot_slit=plot)
    assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep)

    # ... triangular
    s.apply_slit(FWHM, unit="nm", shape="triangular", plot_slit=plot)
    assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep)

    # ... trapezoidal
    s.apply_slit((FWHM * 0.9, FWHM * 1.1),
                 unit="nm",
                 shape="trapezoidal",
                 plot_slit=plot)
    assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep)

    #    # ... trapezoidal
    #    s.apply_slit(FWHM, unit='nm', shape='trapezoidal', plot_slit=plot, norm='max')
    #    assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=1.1*wstep)

    # ... experimental
    s.apply_slit(getTestFile("slitfunction.txt"), unit="nm", plot_slit=plot)
    assert np.isclose(get_effective_FWHM(*s.get_slit()), FWHM, atol=0.01)
    # note that we're applying a slit function measured at 632.5 nm to a Spectrum
    # at 4.7 µm. It's just good for testing the functions

    #    # ... experimental, convolve with max
    #    s.apply_slit(getTestFile('slitfunction.txt'), unit='nm', norm_by='max', plot_slit=plot)
    #    assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=1.1*wstep)

    if verbose:
        print("\n>>> _test_all_slits yield correct FWHM (+- wstep) : OK\n")

    return True  # nothing defined yet
Beispiel #5
0
def test_merge_slabs(verbose=True,
                     plot=False,
                     close_plots=True,
                     warnings=True,
                     debug=False,
                     *args,
                     **kwargs):
    """Merge 10 slabs with 1/10 of concentration, and compare the results.
    Ensure error is < 0.1%

    Note that we won't have exactly the same results as the broadening is not
    updated in MergeSlabs
    """

    import matplotlib.pyplot as plt

    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec

    if plot:
        plt.ion()  # dont get stuck with Matplotlib if executing through pytest
        if close_plots:
            plt.close("all")

    for optically_thin in [True, False]:

        # Get Some spectra
        s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                       binary=True)
        s2 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.5.spec"),
                       binary=True)
        s1.update("all")
        s2.update("all")

        # Merge 50 times s1 in the same slab
        s50 = [s1] * 50
        s1N = MergeSlabs(*s50, optically_thin=optically_thin, debug=debug)

        if plot:
            for k in ["radiance_noslit"]:  # , 'transmittance_noslit']:
                s2.plot(k, lw=3, label="1x[CO=0.5]")
                s1N.plot(k, nfig="same", label="50x[CO=0.01]")
                plt.legend()
                plt.title("Optically thin: {0}".format(optically_thin))
                plt.tight_layout()

        if verbose:
            print("test_merge_slabs")
            print(
                "... Compare 50x[CO=0.01] vs 1x[CON=0.5] (optically thin: {0})"
                .format(optically_thin))
            print("... Difference: {0:.2f}%".format(
                abs(s1N.get_power() / s2.get_power() - 1) * 100))
        assert np.isclose(s2.get_power(), s1N.get_power(), 1.5e-2)

    return True
Beispiel #6
0
def test_save_compressed2(verbose=True, *args, **kwargs):
    "Check if saving a spectrum with compress = 2 does not change something."
    import shutil
    from os.path import join

    from radis.test.utils import setup_test_line_databases
    from radis import calc_spectrum, SpecDatabase

    shutil.rmtree(join(dirname(getTestFile(".")), "newDb"), ignore_errors=True)

    # get the spectrum
    setup_test_line_databases()
    s = calc_spectrum(
        2000,
        2300,  # cm-1
        molecule="CO",
        isotope="1,2,3",
        pressure=1.01325,  # bar
        Tgas=700,  # K
        mole_fraction=0.1,
        path_length=1,  # cm
        verbose=False,
        wstep=0.01,
        medium="vacuum",
        databank="HITRAN-CO-TEST",
    )
    try:

        # load in one databse
        db = SpecDatabase(join(dirname(getTestFile(".")), "newDb"))
        db.add(s, compress=2, if_exists_then="error")

        # simulate an experimentalist who come later and load the spectrum
        db2 = SpecDatabase(join(dirname(getTestFile(".")), "newDb"))
        s_bis = db2.get_unique(Tgas=700)

    finally:
        # we want to make sure this folder is deleted
        shutil.rmtree(join(dirname(getTestFile(".")), "newDb"))

    # we check the loaded spectrum contains less information than the calculated one
    assert not s == s_bis
    assert s_bis.get_vars() == ["abscoeff"
                                ]  # only this spectral quantity was stored
    assert s_bis.lines is None
    assert s_bis.conditions is not None  # we kept the metadata
    # now we check if it works
    s_bis.update()
    for var in s.get_vars():
        assert s.compare_with(s_bis,
                              spectra_only=var,
                              plot=False,
                              verbose=verbose)
Beispiel #7
0
def test_compare_methods(verbose=True, plot=True, close_plots=True, *args, **kwargs):
    ''' Just run all Spectrum compare methods to check they work'''

    if plot and close_plots:
        import matplotlib.pyplot as plt
        plt.close('all')
    
    s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'))
    s.resample(np.linspace(2193, 2193.8, 100))   # limits to a single line, because get_distance() 
                                                   # is very computationaly heavy 
    s.update('radiance_noslit')
    s_noabsorption = s.copy()
    s.name = 'solve RTE'
    s_noabsorption.name = 'optically thin'
    
    # rescale, normal 
#    s.rescale_mole_fraction(10)
    s.rescale_path_length(10)
    
    # rescale, optically thin mode
    s_noabsorption.conditions['self_absorption'] = False
#    s_noabsorption.rescale_mole_fraction(10)
    s_noabsorption.rescale_path_length(10)
    
    # Compare 
    get_distance(s, s_noabsorption, 'radiance_noslit')  # should be added in an example with experimental fit of bandhead
    title = 'CO x={0:.2f}, L={1:.2f}cm'.format(s.conditions['mole_fraction'], s.conditions['path_length'])
    if plot:
        plot_diff(s, s_noabsorption, method='diff', title=title)
        plot_diff(s, s_noabsorption, method='ratio', normalize=True, title=title)
Beispiel #8
0
def test_compression(verbose=True, warnings=True, *args, **kwargs):
    """Test that redundant quantities are properly infered from already known
    spectral quantities"""

    # Get spectrum
    s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                   binary=True)

    s1.conditions["thermal_equilibrium"] = True
    s1.update()

    # Analyse redundant spectral quantities
    redundant = get_redundant(s1)
    if verbose:
        print(redundant)

    assert redundant == {
        "emissivity_noslit": True,
        "radiance_noslit": True,
        "emisscoeff": True,
        "transmittance_noslit": True,
        "absorbance": True,
        "abscoeff": False,
    }

    return True
Beispiel #9
0
def test_recompute_equilibrium(verbose=True, warnings=True, plot=True,
                               *args, **kwargs):
    ''' Test that spectral quantities recomputed under equilibrium assumption
    yields the same output as with non equilibrium routines when Tvib = Trot '''

    if plot:
        import matplotlib.pyplot as plt
        plt.ion()   # dont get stuck with Matplotlib if executing through pytest

    # Get spectrum
    s1 = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'))
    s1.rescale_path_length(100)  # just for fun

    assert s1.is_at_equilibrium()
    s1.update('emisscoeff')

    # force non equilibrium calculation
    s2 = s1.copy()
    s2.conditions['thermal_equilibrium'] = False
    s2.update()
    assert 'emissivity_noslit' not in s2.get_vars()  # just a check update() was done at nonequilibrium

    # update s1 now (at equilibrium)
    s1.update()
    assert 'emissivity_noslit' in s1.get_vars()   # just a check update() was done at equilibrium

    s1.name = 'scaled with Kirchoff law'
    s2.name = 'scaled from emisscoeff + abscoeff with RTE'

    if verbose:
        print('Checked that scaling at equilibrium with Kirchoff law yields the ' +
              'same radiance as by solving the RTE from emisscoeff and abscoeff')

    # Now Compare both update processes
    assert s1.compare_with(s2, spectra_only='radiance_noslit', plot=plot)
Beispiel #10
0
def test_get_recompute(verbose=True, *args, **kwargs):
    """Make sure :func:`~radis.spectrum.rescale.get_recompute` works as expected

    Here, we check which quantities are needed to recompute radiance_noslit"""

    # Equilibrium
    # -----------
    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)

    assert s.get_vars() == ["abscoeff"]
    assert s.conditions["thermal_equilibrium"]
    # At equilibrium, everything should be deduced from abscoeff
    assert set(get_recompute(s, ["radiance_noslit"])) == set(
        ("radiance_noslit", "abscoeff"))

    # Non Equilibrium
    # ----------------
    s.conditions["Tvib"] = 2000
    # a problem should be detected by is_at_equilibrium()
    with pytest.raises(AssertionError):
        assert not s.is_at_equilibrium(check="error")
    # force non equilibrium
    s.conditions["thermal_equilibrium"] = False

    # Now more data is needed:
    assert set(get_recompute(s, ["radiance_noslit"])) == set(
        ("abscoeff", "emisscoeff", "radiance_noslit"))
Beispiel #11
0
def test_normalization(*args, **kwargs):

    from radis import Radiance, load_spec
    from radis.test.utils import getTestFile

    # Generate the equivalent of an experimental spectrum
    s = load_spec(getTestFile(r"CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)
    s.update()  # add radiance, etc.
    s.apply_slit(0.5)  # nm
    s = Radiance(s)

    # Test normalization
    assert s.units["radiance"] != ""
    s.normalize()
    assert s.max() != 1
    s.normalize(inplace=True)
    assert s.max() == 1
    assert s.normalize().units["radiance"] == ""

    s2 = s.normalize(normalize_how="area")
    assert np.isclose(s2.get_integral("radiance", wunit=s2.get_waveunit()), 1)

    #
    s3 = s.normalize(wrange=((2125, 2150)), normalize_how="area")
    assert np.isclose(
        s3.crop(2125, 2150).get_integral("radiance", wunit=s3.get_waveunit()),
        1)
Beispiel #12
0
def test_copy(verbose=True, *args, **kwargs):
    """Test that a Spectrum is correctly copied

    We compare a Spectrum that has:
    - all available spectral quantities
    - a slit
    - many calculation conditions
    - no populations
    - no lines
    """

    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec

    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"))

    s.update()
    s.apply_slit(1.5)
    s2 = s.copy()

    # Test spectrum in general
    assert s == s2
    assert s is not s2

    # Test all quantities in detail
    for var in s._q.keys():
        assert np.allclose(s._q[var], s2._q[var])
        assert not (s._q[var] is s2._q[var])
    for var in s._q_conv.keys():
        assert np.allclose(s._q_conv[var], s2._q_conv[var])
        assert not (s._q_conv[var] is s2._q_conv[var])

    if verbose:
        print("Tested that s2 == s (but s2 is not s) after Spectrum copy")
Beispiel #13
0
def test_slit_unit_conversions_spectrum_in_cm(verbose=True,
                                              plot=True,
                                              close_plots=True,
                                              *args,
                                              **kwargs):
    """ Test that slit is consistently applied for different units

    Assert that:

    - calculated FWHM is the one that was applied

    """

    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec

    if plot:  # dont get stuck with Matplotlib if executing through pytest
        plt.ion()
        if close_plots:
            plt.close("all")

    # %% Get a Spectrum (stored in cm-1)
    s_cm = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                     binary=True)

    s_cm.rescale_mole_fraction(1)  # just because it makes better units
    s_cm.update()
    wstep = s_cm.conditions["wstep"]

    assert s_cm.get_waveunit() == "cm-1"  # ensures it's stored in cm-1

    for shape in ["gaussian", "triangular"]:

        # Apply slit in cm-1
        slit_cm = 2
        s_cm.name = "Spec in cm-1, slit {0:.2f} cm-1".format(slit_cm)
        s_cm.apply_slit(slit_cm, unit="cm-1", shape=shape, mode="same")
        # ... mode=same to keep same output length. It helps compare both Spectra afterwards
        # in cm-1 as that's s.get_waveunit()
        fwhm = get_FWHM(*s_cm.get_slit())
        assert np.isclose(slit_cm, fwhm, atol=2 * wstep)

        # Apply slit in nm this time
        s_nm = s_cm.copy()
        w_cm = s_nm.get_wavenumber(which="non_convoluted")
        slit_nm = dcm2dnm(slit_cm, w_cm[len(w_cm) // 2])
        s_nm.name = "Spec in cm-1, slit {0:.2f} nm".format(slit_nm)
        s_nm.apply_slit(slit_nm, unit="nm", shape=shape, mode="same")

        plotargs = {}
        if plot:
            plotargs[
                "title"] = "test_slit_unit_conversions: {0} ({1} cm-1)".format(
                    shape, slit_cm)
        s_cm.compare_with(s_nm,
                          spectra_only="radiance",
                          rtol=1e-3,
                          verbose=verbose,
                          plot=plot,
                          **plotargs)
Beispiel #14
0
def test_rescaling_function(verbose=True, *args, **kwargs):
    """ Test rescaling functions """

    from radis.test.utils import getTestFile

    s = Spectrum.from_txt(
        getTestFile("calc_N2C_spectrum_Trot1200_Tvib3000.txt"),
        quantity="radiance_noslit",
        waveunit="nm",
        unit="mW/cm2/sr/µm",  # Specair units: mW/cm2/sr/µm
        conditions={
            "Tvib": 3000,
            "Trot": 1200,
            "path_length": 1,  # arbitrary
            "medium": "air",
        },
        populations={"molecules": {
            "N2C": 1e13
        }},  # arbitrary
        # (just an example)
    )
    s.update(optically_thin=True)
    s.rescale_path_length(10)

    assert np.isclose(
        s.get_radiance_noslit(Iunit="mW/cm2/sr/nm")[0], 352.57305783248)
Beispiel #15
0
def test_local_hitran_h2o(verbose=True, warnings=True, **kwargs):

    # 1. Load
    df = hit2df(getTestFile("hitran_2016_H2O_2iso_2000_2100cm.par"),
                cache="regen")
    if verbose:
        print("Read hitran_2016_H2O_2iso_2000_2100cm.par")
        print("-----------------------------------------")
        print(df.head())

    # 2. Test
    assert list(df.loc[0, ["v1u", "v2u", "v3u", "v1l", "v2l", "v3l"]]) == [
        0,
        2,
        0,
        0,
        1,
        0,
    ]

    assert df.loc[26, "ju"] == 5  # in .par : line 27, column 99-100
    assert df.loc[27, "ju"] == 18  # in .par : line 28, column 99-100

    assert df.dtypes["v1l"] == np.int64
    assert df.dtypes["v3u"] == np.int64

    assert df.dtypes["ju"] == np.int64
    assert df.dtypes["Kau"] == np.int64
    assert df.dtypes["Kcu"] == np.int64
    assert df.dtypes["jl"] == np.int64
    assert df.dtypes["Kal"] == np.int64
    assert df.dtypes["Kcl"] == np.int64

    return True
Beispiel #16
0
def test_hitran_h2o(verbose=True, warnings=True, **kwargs):
    
    # 1. Load
    df = hit2df(getTestFile('hitran_2016_H2O_2iso_2000_2100cm.par'), cache='regen')
    if verbose:
        print('Read hitran_2016_H2O_2iso_2000_2100cm.par')
        print('-----------------------------------------')
        print(df.head())
        
    # 2. Test
    assert (list(df.loc[0, ['v1u', 'v2u', 'v3u', 'v1l', 'v2l', 'v3l']]) ==
            [0, 2, 0, 0, 1, 0])
    
    assert df.loc[26, 'ju'] == 5    # in .par : line 27, column 99-100
    assert df.loc[27, 'ju'] == 18   # in .par : line 28, column 99-100
    
    
    assert df.dtypes['v1l'] == np.int64
    assert df.dtypes['v3u'] == np.int64
    
    assert df.dtypes['ju'] == np.int64
    assert df.dtypes['Kau'] == np.int64
    assert df.dtypes['Kcu'] == np.int64
    assert df.dtypes['jl'] == np.int64
    assert df.dtypes['Kal'] == np.int64
    assert df.dtypes['Kcl'] == np.int64
    
    return True
Beispiel #17
0
def test_eq_spectrum_gpu():
    T = 1000
    p = 0.1
    wstep = 0.001
    wmin = 2284.0  # cm-1
    wmax = 2285.0  # cm-1
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=0.01,  # until self and air broadening is implemented
        path_length=1,  # doesnt change anything
        wstep=wstep,
        pressure=p,
        isotope="1",
        chunksize="DLM",
        warnings={
            "MissingSelfBroadeningWarning": "ignore",
            "NegativeEnergiesWarning": "ignore",
            "HighTemperatureWarning": "ignore",
            "GaussianBroadeningWarning": "ignore",
        },
    )
    sf._broadening_method = "fft"
    sf.load_databank(
        path=getTestFile("cdsd_hitemp_09_fragment.txt"),
        format="cdsd-4000",
        parfuncfmt="hapi",
    )
    s_cpu = sf.eq_spectrum(Tgas=T)
    s_gpu = sf.eq_spectrum_gpu(Tgas=T)
    s_cpu.crop(wmin=2284.2, wmax=2284.8)  # remove edge lines
    s_gpu.crop(wmin=2284.2, wmax=2284.8)
    assert s_cpu.compare_with(s_gpu, spectra_only=True, rtol=0.07,
                              plot=False)  # set the appropriate tolerance
Beispiel #18
0
def test_get_recompute(verbose=True, *args, **kwargs):
    ''' Make sure :func:`~radis.spectrum.rescale.get_recompute` works as expected

    Here, we check which quantities are needed to recompute radiance_noslit'''

    # Equilibrium
    # -----------
    s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True)
    
    assert s.get_vars() == ['abscoeff']
    assert s.conditions['thermal_equilibrium']
    # At equilibrium, everything should be deduced from abscoeff
    assert set(get_recompute(s, ['radiance_noslit'])) == set(
        ('radiance_noslit', 'abscoeff'))

    # Non Equilibrium
    # ----------------
    s.conditions['Tvib'] = 2000  
    # a problem should be detected by is_at_equilibrium()
    with pytest.raises(AssertionError):
        assert not s.is_at_equilibrium(check='error')
    # force non equilibrium
    s.conditions['thermal_equilibrium'] = False
    
    # Now more data is needed:
    assert set(get_recompute(s, ['radiance_noslit'])) == set(
        ('abscoeff', 'emisscoeff', 'radiance_noslit'))
Beispiel #19
0
def test_spectrum_get_methods(verbose=True,
                              plot=True,
                              close_plots=True,
                              *args,
                              **kwargs):
    ''' Test all spectrum methods on a Spectrum generated in Specair '''

    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec
    from radis.tools.slit import get_FWHM

    if plot and close_plots:
        import matplotlib.pyplot as plt
        plt.close('all')

    s = load_spec(getTestFile('N2C_specair_380nm.spec'))

    # general methods
    if verbose: print(s)
    dir(s)

    # access properties
    assert s.get_name() == 'N2C_specair_380nm'
    assert all(
        s.get_radiance_noslit(Iunit='W/m2/sr/nm') == s.get(
            'radiance_noslit', Iunit='W/m2/sr/nm')[1])
    assert all(nm2cm(s.get_wavelength(medium='vacuum')) == s.get_wavenumber())
    assert s.get_power(unit='W/cm2/sr') == 2631.6288408588148
    assert s.get_waveunit() == 'nm'
    assert s.get_power(unit='W/cm2/sr') == s.get_integral('radiance_noslit',
                                                          Iunit='W/cm2/sr/nm')
    assert s.get_conditions()['Tgas'] == 1500
    assert s.get_medium() == 'air'
    assert len(s.get_vars()) == 2
    assert s.is_at_equilibrium() == False
    assert s.is_optically_thin() == False

    # Check applied slit has the correct width
    s.apply_slit(0.5)
    wslit, Islit = s.get_slit()
    wstep = np.diff(wslit)[0]
    assert np.isclose(get_FWHM(*s.get_slit()), 0.5, atol=1.1 * wstep)

    if plot:
        s.plot_slit()

    if verbose:
        print('Tested Spectrum methods:')
        print('...print(Spectrum)')
        print('.. get_name()')
        print('.. get_radiance_noslit() vs get()')
        print('.. get_wavelength() vs get_wavenumber')
        print('.. get_power()')
        print('.. get_waveunit()')
        print('.. get_power() vs get_integral()')
        print('.. get_conditions()')
        print('.. get_vars()')
        print('.. is_at_equilibrium()')
        print('.. is_optically_thin()')
        print('.. get_slit()')
Beispiel #20
0
def test_ignore_cached_files():
    """
    Previous implementation of RADIS saved the cached h5 files generated while reading the
    dataset in the same directory from where the data was being read. Using a wildcard input
    such as `path = "cdsd_hitemp_09_frag*"` in such case led to the cached files present
    in directory to also being loaded and treated as the dataset files. This resulted in
    an error due to the differences in the way data is stored in h5 files versus in dataset
    files such as par, txt, etc.

    Reference: `https://github.com/radis/radis/issues/121`
    """

    sf = SpectrumFactory(wavenum_min=2000, wavenum_max=3000, pressure=1)

    file_dir = getTestFile("cdsd_hitemp_09_fragment.txt")
    test_file = file_dir[:-8] + "*"
    sf.load_databank(path=test_file, format="cdsd-hitemp", parfuncfmt="hapi")

    try:
        sf.load_databank(path=test_file,
                         format="cdsd-hitemp",
                         parfuncfmt="hapi")
    except UnicodeDecodeError as err:
        raise UnicodeDecodeError(
            "Couldn't load database the 2nd time. This may be due to cache files trying to be read as normal files"
        ) from err
Beispiel #21
0
def _test(verbose=True,
          debug=False,
          plot=True,
          warnings=True,
          *args,
          **kwargs):
    """Test procedures.

    Parameters
    ----------

    debug: boolean
        swamps the console namespace with local variables. Default ``False``
    """

    import matplotlib.pyplot as plt
    from numpy import linspace, loadtxt

    from radis.phys.convert import cm2nm, nm2cm
    from radis.test.utils import getTestFile

    # Test even resampling

    w_nm, I_nm = loadtxt(getTestFile("spectrum.txt")).T
    w_cm, I_cm = resample_even(
        nm2cm(w_nm),
        I_nm,
        resfactor=2,
        energy_threshold=1e-3,
        print_conservation=verbose,
    )

    if plot:
        plt.figure()
        plt.xlabel("Wavelength (nm)")
        plt.ylabel("Intensity")
        plt.plot(w_nm, I_nm, "-ok", label="original")
        plt.plot(cm2nm(w_cm), I_cm, "-or", label="resampled")
        plt.legend()

    # Test resampling

    w_crop = linspace(376, 381, 100)
    I_crop = resample(w_nm, I_nm, w_crop, energy_threshold=0.01)

    if plot:
        plt.figure()
        plt.xlabel("Wavelength (nm)")
        plt.ylabel("Intensity")
        plt.plot(w_nm, I_nm, "-ok", label="original")
        plt.plot(w_crop, I_crop, "-or", label="resampled")
        plt.legend()

    if debug:
        globals().update(locals())

    if warnings:
        warn("Testing resampling: no quantitative tests defined yet")

    return True  # no standard tests yet
Beispiel #22
0
def test_rescaling_function(verbose=True, *args, **kwargs):
    ''' Test rescaling functions '''

    from radis.test.utils import getTestFile

    s = Spectrum.from_txt(
        getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt'),
        quantity='radiance_noslit',
        waveunit='nm',
        unit='mW/cm2/sr/µm',  # Specair units: mW/cm2/sr/µm
        conditions={
            'Tvib': 3000,
            'Trot': 1200,
            'path_length': 1,  # arbitrary
            'medium': 'air',
        },
        populations={'molecules': {
            'N2C': 1e13
        }},  # arbitrary
        # (just an example)
    )
    s.update(optically_thin=True)
    s.rescale_path_length(10)

    assert np.isclose(
        s.get_radiance_noslit(Iunit='mW/cm2/sr/nm')[0], 352.57305783248)
Beispiel #23
0
def test_store_functions(verbose=True, *args, **kwargs):
    ''' Test some store / retrieve functions '''

    from radis.spectrum.spectrum import transmittance_spectrum
    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec

    temp_file = 'test_radis_tempfile_transmittance.txt'
    assert not exists(temp_file)

    s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'),
                  binary=True)
    s.update()
    try:
        s.savetxt(temp_file,
                  'transmittance_noslit',
                  wunit='nm',
                  medium='vacuum')
        w, T = np.loadtxt(temp_file).T
    finally:
        os.remove(temp_file)

    s2 = transmittance_spectrum(w,
                                T,
                                wunit='nm',
                                conditions={'medium': 'vacuum'})
    assert s.compare_with(s2, spectra_only='transmittance_noslit', plot=False)

    return True
Beispiel #24
0
def test_store_functions(verbose=True, *args, **kwargs):
    """ Test some store / retrieve functions """

    from radis.spectrum.models import transmittance_spectrum
    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec

    temp_file = "test_radis_tempfile_transmittance.txt"
    assert not exists(temp_file)

    # Test that the transmittance stored on .txt and loaded again match
    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)
    s.update()
    try:
        s.savetxt(temp_file, "transmittance_noslit", wunit="nm_vac")
        w, T = np.loadtxt(temp_file).T
    finally:
        os.remove(temp_file)

    s2 = transmittance_spectrum(w, T, wunit="nm_vac")
    assert s.compare_with(s2, spectra_only="transmittance_noslit", plot=False)

    # TODO: add test that ensures we can load a binary file without binary=True
    # (and the warning should be captured)

    return True
Beispiel #25
0
def test_line_survey(verbose=True, plot=False, warnings=True, *args, **kwargs):
    """ Test line survey """

    _temp_file = "radis_test_line_survey.html"
    if exists(_temp_file):
        os.remove(_temp_file)

    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)
    s.line_survey(overlay="abscoeff", writefile=_temp_file)

    assert exists(_temp_file)

    with open(_temp_file) as f:
        d = f.read()
    assert "Linestrength" in d
    assert "Wavenumber" in d

    if verbose:
        print("test_line_survey: html file was correctly generated")

    if not plot:
        # clean after use
        os.remove(_temp_file)

    return True
Beispiel #26
0
def test_hitran_parser(verbose=True, warnings=True, **kwargs):
    ''' Analyse some default files to make sure everything still works'''
    
    t0 = time()
    df = hit2df(getTestFile('hitran_CO_fragment.par'))
    if verbose: print('File loaded in {0:.0f}s'.format(time()-t0))
    if verbose: print(df.head())
    assert (list(df.loc[0, ['v1u', 'v1l']]) == [4, 4])

    t0 = time()
    df = hit2df(getTestFile('hitran_CO2_fragment.par'))
    if verbose: print('File loaded in {0:.0f}s'.format(time()-t0))
    if verbose: print(df.head())
    assert (list(df.loc[0, ['v1u', 'v2u', 'l2u', 'v3u', 'v1l', 'v2l', 'l2l', 'v3l']]) ==
              [4, 0, 0, 0, 0, 0, 0, 1])
    
    return True
Beispiel #27
0
def test_rescale_all_quantities(verbose=True, warnings=True, *args, **kwargs):

    new_mole_fraction = 0.5
    new_path_length = 0.1
    
    # Get spectrum
    s0 = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True)
    s0.update('all')     # start with all possible quantities in s0
    sscaled = s0.copy()
    sscaled.rescale_mole_fraction(new_mole_fraction)
    sscaled.rescale_path_length(new_path_length)
    s0.conditions['thermal_equilibrium'] = False   # to prevent rescaling with Kirchoff
    # remove emissivity_no_slit (speciifc to equilibrium)
    del s0._q['emissivity_noslit']
     
    
    # Determine all quantities that can be recomputed
    if verbose >= 2:
        import radis
        DEBUG_MODE = radis.DEBUG_MODE
        radis.DEBUG_MODE = True
    from radis.spectrum.rescale import get_reachable, ordered_keys, _build_update_graph
    # ordered_keys: all spectral quantities that can be rescaled
    can_be_recomputed = get_reachable(s0)
    # can_be_recomputed: all spectra quantities that can be rescaled for this 
    # particular spectrum
    update_paths = _build_update_graph(s0)
    # update_paths: which quantities are needed to recompute the others
    
    rescale_list = [k for k in ordered_keys if can_be_recomputed[k]]
    
    for quantity in rescale_list:
        all_paths = update_paths[quantity]
        if verbose:
            printm('{0} can be recomputed from {1}'.format(quantity, ' or '.join(
                    ['&'.join(combinations) for combinations in all_paths])))
        
        # Now let's test all paths
        for combinations in all_paths:
            if verbose:
                printm('> computing {0} from {1}'.format(quantity, '&'.join(combinations)))
            s = s0.copy()
            # Delete all other quantities
            for k in s.get_vars():
                if k not in combinations:
                    del s._q[k]
            
            s.update(quantity, verbose=verbose)
            
            # Now rescale
            s.rescale_mole_fraction(new_mole_fraction)
            s.rescale_path_length(new_path_length)
            
            # Compare
            assert s.compare_with(sscaled, spectra_only=quantity, plot=False)
            
    if verbose >= 2:
        radis.DEBUG_MODE = DEBUG_MODE
Beispiel #28
0
def test_slit_unit_conversions_spectrum_in_nm(verbose=True, plot=True, close_plots=True, *args, **kwargs):
    ''' Test that slit is consistently applied for different units

    Assert that:

    - calculated FWHM is the one that was applied

    '''

    from radis.test.utils import getTestFile
    from radis.spectrum.spectrum import Spectrum

    if plot:    # dont get stuck with Matplotlib if executing through pytest
        plt.ion()
        if close_plots:
            plt.close('all')

    # %% Get a Spectrum (stored in nm)

    s_nm = Spectrum.from_txt(getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt'),
                             quantity='radiance_noslit', waveunit='nm', unit='mW/cm2/sr/µm',
                             conditions={'self_absorption': False})

    with catch_warnings():
        filterwarnings(
            'ignore', 'Condition missing to know if spectrum is at equilibrium:')
        # just because it makes better units
        s_nm.rescale_path_length(1, 0.001)

    wstep = np.diff(s_nm.get_wavelength())[0]

    assert s_nm.get_waveunit() == 'nm'       # ensures it's stored in cm-1

    for shape in ['gaussian', 'triangular']:

        # Apply slit in nm
        slit_nm = 0.5
        s_nm.name = 'Spec in nm, slit {0:.2f} nm'.format(slit_nm)
        s_nm.apply_slit(slit_nm, unit='nm', shape=shape, mode='same')
        # ... mode=same to keep same output length. It helps compare both Spectra afterwards
        # in cm-1 as that's s.get_waveunit()
        fwhm = get_FWHM(*s_nm.get_slit())
        assert np.isclose(slit_nm, fwhm, atol=2*wstep)

        # Apply slit in nm this time
        s_cm = s_nm.copy()
        w_nm = s_nm.get_wavelength(which='non_convoluted')
        slit_cm = dnm2dcm(slit_nm, w_nm[len(w_nm)//2])
        s_cm.name = 'Spec in nm, slit {0:.2f} cm-1'.format(slit_cm)
        s_cm.apply_slit(slit_cm, unit='cm-1', shape=shape, mode='same')

        plotargs = {}
        if plot:
            plotargs['title'] = 'test_slit_unit_conversions: {0} ({1} nm)'.format(
                shape, slit_nm)
        s_nm.compare_with(s_cm, spectra_only='radiance', rtol=1e-3,
                          verbose=verbose, plot=plot, **plotargs)
Beispiel #29
0
def test_resampling_function(verbose=True,
                             plot=True,
                             close_plots=True,
                             *args,
                             **kwargs):
    ''' Test resampling functions 
    
    Get a Spectrum calculated in cm-1, then resample on a smaller range in cm-1, 
    and in approximately the same range (but in nm). Check that all 3 overlap 
    '''
    # %%
    from radis.test.utils import getTestFile
    from radis.tools.database import load_spec
    from radis.spectrum import get_residual_integral

    if plot and close_plots:
        import matplotlib.pyplot as plt
        plt.close('all')

    s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'),
                  binary=True)
    s.name = 'original'
    s2 = s.copy()
    s2b = s.copy()
    s3 = s.copy()
    s2.resample(np.linspace(4500, 4700, 10000), unit='nm', medium='vacuum')
    s2b.resample(np.linspace(4500, 4700, 10000), unit='nm', medium='air')
    s3.resample(np.linspace(2127.2, 2227.7, 10000), unit='cm-1')
    s2.name = 'resampled in nm (vacuum)'
    s2b.name = 'resampled in nm (air)'
    s3.name = 'resampled in cm-1'

    s.compare_with(s2,
                   plot=plot,
                   title='Residual: {0:.2g}'.format(
                       get_residual_integral(s,
                                             s2,
                                             'abscoeff',
                                             ignore_nan=True)))
    s.compare_with(s2b,
                   plot=plot,
                   title='Residual: {0:.2g}'.format(
                       get_residual_integral(s,
                                             s2b,
                                             'abscoeff',
                                             ignore_nan=True)))
    s.compare_with(s3,
                   plot=plot,
                   title='Residual: {0:.2g}'.format(
                       get_residual_integral(s,
                                             s3,
                                             'abscoeff',
                                             ignore_nan=True)))

    assert get_residual_integral(s, s2, 'abscoeff', ignore_nan=True) < 1e-4
    assert get_residual_integral(s, s2b, 'abscoeff', ignore_nan=True) < 1e-3
    assert get_residual_integral(s, s3, 'abscoeff', ignore_nan=True) < 1e-5
Beispiel #30
0
def test_database_functions(verbose=True, plot=True, close_plots=True, warnings=True, *args, **kwargs):
    ''' Test SpecDatabase functions '''

    if plot:
        import matplotlib.pyplot as plt
        plt.ion()
    if close_plots:
        plt.close('all')

    import pytest

    db = SpecDatabase(dirname(getTestFile('.')))

    # Database visualisation methods
    if verbose:
        print('{0} items in test database: {1}'.format(
            len(db), db.see(['Tvib', 'Trot'])))
    if plot:
        db.plot_cond('Tvib', 'Trot')

    # Database get methods
    db.get_closest(Tgas=1300, path_length=1)
    s = db.get_unique(Tgas=1500, path_length=0.01,
                      mole_fraction=0.5)  # there should be one only
    # ... note that this is just so we can test
    # ... get_unique(). If we were to add new
    # ... test cases with matching conditions
    # ... let's add more criteria to keep it unique
    match = db.get(**s.conditions)
#    assert len(match) == 1
    # TODO: not working in Python 2.7 yet

    # Database add method
    s2 = s.copy()
    s2.conditions['Tgas'] = 0  # make it unique (for testing)
    
    matching_spectrum_in_db = (s2 in db)
    
    l = db.add(s2, add_info=['Tvib', 'Trot'], discard=[],
               compress=True, if_exists_then='increment')
    assert exists(l)
    try:
        assert s2 in db
        # .. ensures that you cant add it twice
        with pytest.raises(ValueError):
            db.add(s2, add_info=['Tvib', 'Trot'])
            
    # Now remove the Spectrum, update the database and ensures it's not there anymore
    finally:
        os.remove(l)
    db.update(force_reload=True)            # update database
    assert not exists(l)
    
    # make sure we deleted it properly
    if not matching_spectrum_in_db:
        assert s2 not in db