예제 #1
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
예제 #2
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
예제 #3
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)
예제 #4
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
예제 #5
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()')
예제 #6
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"))
예제 #7
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
예제 #8
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)
예제 #9
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
예제 #10
0
def test_load_lines_pops(plot=False,
                         verbose=True,
                         warnings=True,
                         *args,
                         **kwargs):
    """Test load / save

    Full version: save lines, populations (hundreds of MB for CO2, much less
    for CO), compare everything
    """

    temp_file_name = "_test_database_co_tempfile.spec"
    assert not exists(temp_file_name)

    try:
        sf = SpectrumFactory(
            wavelength_min=4500,
            wavelength_max=4800,
            mole_fraction=400e-6,
            path_length=0.1,  # cm
            isotope=[1, 2],
            db_use_cached=True,
            cutoff=1e-20,
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        sf.load_databank("HITRAN-CO-TEST")
        s1 = sf.non_eq_spectrum(Tvib=300, Trot=300)
        s1.apply_slit(2, verbose=False)
        s1.update()
        s2 = load_spec(
            s1.store(
                temp_file_name,
                discard=[],  # we're actually saving lines and
                # populations here! expect hundreds
                # of megabytes for big molecules
                # :line CO2 ... here CO is fine
                # (by default lines and populations
                # are discarded)
                compress=True  # only removes some spectral
                # quantities, cant change population
                # or lines size
            ),
            binary=True,  # uncompress
        )
        s2.update()

        assert s1.compare_with(s2, spectra_only=False, plot=False)

        # Test with json-tricks directly
        # Does not work yet
    #        from json_tricks import dumps, loads
    #        s2b = loads(dumps(s1))
    #        assert s1.compare_with(s2b, spectra_only=False, plot=False)

    finally:  # cleaning
        if exists(temp_file_name):
            os.remove(temp_file_name)

    return True
예제 #11
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)
예제 #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")
예제 #13
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
예제 #14
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'))
예제 #15
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)
예제 #16
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
예제 #17
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
예제 #18
0
def test_plot_by_parts(plot=True, *args, **kwargs):
    """Test :py:func:`~radis.spectrum.utils.split_and_plot_by_parts`
    and plot_by_parts=True in :py:meth:`~radis.spectrum.spectrum.Spectrum.plot`
    """

    import matplotlib.pyplot as plt

    plt.ion()

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

    load_spec(getTestFile("CO2_measured_spectrum_4-5um.spec"),
              binary=True).plot(plot_by_parts=True,
                                nfig="plot by parts (non continuous spectrum)")

    if not plot:
        plt.close("plot by parts (non continuous spectrum)")
예제 #19
0
def test_TestBaseline(plot=False, *args, **kwargs):

    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True)
    s.update("radiance_noslit", verbose=False)
    s.apply_slit(0.1)
    s = Radiance_noslit(s)
    assert s.units["radiance"] == "mW/cm2/sr/nm"

    s2 = sub_baseline(s, 2e-4, -2e-4)
    if plot:
        plot_diff(s, s2)
    assert s2.get_radiance_noslit()[-1] == s.get_radiance_noslit()[-1] + 2e-4
    assert s2.get_radiance_noslit()[0] == s.get_radiance_noslit()[0] - 2e-4
예제 #20
0
def test_load_spectrum(plot=False,
                       verbose=True,
                       warnings=True,
                       *args,
                       **kwargs):
    """Test load / save

    Fast version: dont save lines / populations, compare spectra only
    """

    setup_test_line_databases()

    temp_file_name = "_test_database_co2_tempfile.spec"
    assert not exists(temp_file_name)

    try:
        sf = SpectrumFactory(
            wavelength_min=4190,
            wavelength_max=4200,
            mole_fraction=400e-6,
            path_length=0.1,  # cm
            isotope=[1],
            db_use_cached=True,
            cutoff=1e-20,
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        sf.load_databank("HITRAN-CO2-TEST")
        s1 = sf.eq_spectrum(Tgas=300)
        s1.apply_slit(2, verbose=False)
        s1.update()
        s2 = load_spec(s1.store(temp_file_name, compress=True))
        s2.update()
        if plot:
            fig = plt.figure(fig_prefix + "Calculated vs stored+retrieved")
            s1.plot("absorbance", nfig=fig.number, lw=3, label="calculated")
            s2.plot(
                "absorbance",
                nfig=fig.number,
                color="r",
                label="stored (compressed) and retrieved",
            )
            plt.legend()

        assert s1.compare_with(s2, spectra_only=True, plot=False)

    finally:  # cleaning
        if exists(temp_file_name):
            os.remove(temp_file_name)

    return True
예제 #21
0
def test_load_spectrum(plot=False,
                       verbose=True,
                       warnings=True,
                       *args,
                       **kwargs):
    ''' Test load / save 

    Fast version: dont save lines / populations, compare spectra only 
    '''

    setup_test_line_databases()

    temp_file_name = '_test_database_co2_tempfile.spec'
    assert (not exists(temp_file_name))

    try:
        sf = SpectrumFactory(
            wavelength_min=4190,
            wavelength_max=4200,
            mole_fraction=400e-6,
            path_length=0.1,  # cm
            isotope=[1],
            db_use_cached=True,
            cutoff=1e-20,
            verbose=verbose)
        sf.warnings['MissingSelfBroadeningWarning'] = 'ignore'
        sf.load_databank('HITRAN-CO2-TEST')
        s1 = sf.eq_spectrum(Tgas=300)
        s1.apply_slit(2, verbose=False)
        s1.update()
        s2 = load_spec(s1.store(temp_file_name, compress=True))
        s2.update()
        if plot:
            fig = plt.figure(fig_prefix + 'Calculated vs stored+retrieved')
            s1.plot('absorbance', nfig=fig.number, lw=3, label='calculated')
            s2.plot('absorbance',
                    nfig=fig.number,
                    color='r',
                    label='stored (compressed) and retrieved')
            plt.legend()

        assert s1.compare_with(s2, spectra_only=True, plot=False)

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)

    finally:  # cleaning
        if exists(temp_file_name):
            os.remove(temp_file_name)

    return True
예제 #22
0
def test_serial_slabs_transmittance(verbose=True,
                                    plot=False,
                                    warnings=True,
                                    debug=False,
                                    *args,
                                    **kwargs):
    """Add some slabs in serie, ensure that overall transmittance decreases
    Also check that some quantities are propagated (like path length?)

    """

    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

    # Get Some spectra
    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.5.spec"),
                  binary=True)
    #    s.update('all')
    assert "transmittance_noslit" not in s.get_vars()

    s_los = SerialSlabs(s, s, s)

    w, T = s_los.get("transmittance_noslit")
    # note that it was calculated despite transmittance not in the initial
    # spectrum

    s.update("transmittance_noslit")  # get from abscoeff
    w1, T1 = s.get("transmittance_noslit")

    # Check it looks alright
    assert (T <= T1).all()
    assert (T != T1).any()
    assert (w == w1).all()

    # because they were the same slabs, intensive conditions should have been propagated
    assert s.conditions["Tgas"] == s_los.conditions["Tgas"]
    # but extensive shouldnt:
    assert s.conditions["path_length"] * 3 == s_los.conditions["path_length"]

    if verbose:
        print("Tested Serialslabs transmittance decreases s1>s2: OK")

    return True
예제 #23
0
def test_invariants(*args, **kwargs):
    """ Ensures adding 0 or multiplying by 1 does not change the spectra """
    from radis import load_spec
    from radis.test.utils import getTestFile

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

    assert s.compare_with(
        add_constant(s, 0, "W/cm2/sr/nm"), plot=False, spectra_only="radiance_noslit"
    )
    assert s.compare_with(multiply(s, 1), plot=False, spectra_only="radiance_noslit")

    assert 3 * s / 3 == s
    assert (1 + s) - 1 == s
예제 #24
0
def test_dimensioned_operations(*args, **kwargs):

    import astropy.units as u
    import numpy as np

    from radis import Radiance, load_spec
    from radis.spectrum import sub_baseline
    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
    assert s.units["radiance"] == "mW/cm2/sr/nm"
    Imax = s.get("radiance")[1].max()

    # add a baseline
    s += 0.1 * u.Unit("W/cm2/sr/nm")

    assert np.isclose(s.get("radiance")[1].max(), Imax + 100)

    # remove a baseline (we could also have used s=-0.1, but we're testing another function here)
    s = sub_baseline(s, 0.1 * u.Unit("W/cm2/sr/nm"),
                     0.1 * u.Unit("W/cm2/sr/nm"))

    assert np.isclose(s.get("radiance")[1].max(), Imax)

    # Test division
    # Example : a manual normalization
    s /= s.max() * u.Unit("mW/cm2/sr/nm")

    assert s.units["radiance"] == ""  # normalized
    assert s.max() == 1.0

    # Test Multiplication
    # example : a manual Calibration
    s.units["radiance"] = "count"
    s *= 100 * u.Unit("mW/cm2/sr/nm/count")

    assert u.Unit(s.units["radiance"]) == u.Unit(
        "mW/cm2/sr/nm")  # check units are valid
    assert s.units[
        "radiance"] == "mW / (cm2 nm sr)"  # check units have been simplified
예제 #25
0
def test_noplot_different_quantities(*args, **kwargs):
    ''' Prevents User Errors: Ensures an error is raised if plotting different
    quantities on the same graph'''

    import matplotlib.pyplot as plt
    plt.ion()

    from radis import load_spec
    from radis.test.utils import getTestFile
    s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'),
                  binary=True)
    s.update()
    s.plot('abscoeff', nfig='test_noplot_different_quantities')
    with pytest.raises(ValueError):  # expect an error
        s.plot('emisscoeff', nfig='same')

    plt.close('test_noplot_different_quantities')
예제 #26
0
def test_serial_slabs_radiance(verbose=True,
                               plot=False,
                               warnings=True,
                               debug=False,
                               *args,
                               **kwargs):
    """Add some slabs in serie under optically thin conditions, ensures
    that radiance is about the sum of all.
    """

    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

    # Get Some spectra
    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)
    s.update("radiance_noslit")

    s_los = SerialSlabs(s, s)

    w, I = s_los.get("radiance_noslit")
    w1, I1 = s.get("radiance_noslit")

    if plot:
        s.plot(nfig="test_serial_slabs_radiance", lw=2)
        plt.title("s>s for almost optically thin conditions")
        s_los.plot(nfig="same")

    # Check it looks alright
    assert np.allclose(I, 2 * I1, rtol=1e-3)

    if verbose:
        print(
            "Tested Serialslabs radiance is added when approximately optically thin: OK"
        )

    # Test operators
    s_serial = s > s
    assert s_serial == s_los

    return True
예제 #27
0
def test_other_algebraic_operations(verbose=True, plot=False, *args, **kwargs):

    # An implement of Spectrum Algebra
    # Reload:
    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"))
    s.update()

    # Test addition of Spectra
    s.plot(lw=2, nfig="Merge: s//s")
    (s // s).plot(nfig="same")

    # Test substraction of Spectra
    s_tr = Transmittance_noslit(s)
    assert (s_tr - 1.0 * s_tr).get_integral("transmittance_noslit") == 0

    # TODO: add test
    # @EP: the test fails at the moment because multiply only works with radiance,
    # and MergeSlabs only works with non convoluted quantities
    # Do we want that? Up for discussion...

    # There should be an error if algebraic operations are used when
    # multiple quantities are defined:
    with pytest.raises(KeyError):
        2 * s

    s.apply_slit(0.1, "nm")
    s_rad = Radiance(s)

    # Test multiplication with float
    s.plot(lw=2, nfig="Multiplication (by scalar): 2*s", wunit="nm")
    #    (s*s).plot(nfig='same')
    (2 * s_rad).plot(nfig="same", wunit="nm")

    # Test algebraic addition (vs multiplication)
    assert (s_rad + s_rad).compare_with(2 * s_rad,
                                        spectra_only="radiance",
                                        plot=False)

    # Test algebraic addition with different waveunits
    s_rad_nm = s_rad.resample(s_rad.get_wavelength(), "nm", inplace=False)
    s_sum = 2 * s_rad_nm - s_rad_nm
    s_sum.compare_with(s_rad, spectra_only="radiance", plot=True)
    assert (s_rad_nm + s_rad_nm).compare_with(2 * s_rad,
                                              spectra_only="radiance",
                                              plot=True,
                                              rtol=1e-3)
예제 #28
0
def test_multiplyAndAddition(verbose=True, plot=False, *args, **kwargs):

    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True)
    s.update("radiance_noslit", verbose=False)
    s.apply_slit(0.1)
    s = Radiance(s)
    assert s.units["radiance"] == "mW/cm2/sr/nm"

    s_bis = add_constant(s, 1, "mW/cm2/sr/nm")
    w, Idiff = get_diff(s_bis, s, "radiance")
    test = Idiff[1] - 1
    assert np.all(test < 1e-10)

    s_ter = multiply(multiply(s, 50), 1 / 50)
    #    plot_diff(s_ter, s_5)
    diff = get_diff(s_ter, s, "radiance")
    ratio = abs(np.trapz(diff[1], x=diff[0]) / s.get_integral("radiance"))
    assert ratio < 1e-10
예제 #29
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"),
                  binary=True)

    # limits to a single line, because get_distance()
    s.resample(np.linspace(2193, 2193.8, 100))
    # 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
    # should be added in an example with experimental fit of bandhead
    get_distance(s, s_noabsorption, "radiance_noslit")
    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", diff_window=1, title=title)
        plot_diff(s,
                  s_noabsorption,
                  method="ratio",
                  normalize=True,
                  title=title)
예제 #30
0
def test_offset(verbose=True, plot=False, *args, **kwargs):

    s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"),
                  binary=True)
    s.update('radiance_noslit', verbose=False)
    s.apply_slit(0.1)

    s2 = offset(s, 10, 'nm', name='offset_10nm')
    if plot:
        plot_diff(s, s2)
    assert np.allclose(s2.get_wavelength(which='convoluted'),
                       s.get_wavelength(which='convoluted') + 10)
    assert np.allclose(s2.get_wavelength(which='non_convoluted'),
                       s.get_wavelength(which='non_convoluted') + 10)

    # Test inplace version
    s.offset(10, 'nm')
    assert np.allclose(s2.get_wavelength(which='convoluted'),
                       s.get_wavelength(which='convoluted'))