예제 #1
0
def test_reduced_CDSD_calc_noneq(verbose=True, warnings=True, *args, **kwargs):
    """ Compare calculated partition function at equilibrium and nonequilibrium
    using the CDSD-format """

    from radis.misc.config import getDatabankEntries

    iso = 1
    database = "HITEMP-CO2-HAMIL-TEST"

    # Compare tab to calculated
    energies = getDatabankEntries(database)["levels"]
    levelsfmt = getDatabankEntries(database)["levelsfmt"]
    Qfc = PartFuncCO2_CDSDcalc(
        energies[iso],
        levelsfmt=levelsfmt,
        isotope=iso,
        use_cached=True,
        verbose=verbose,
    )
    assert np.isclose(Qfc.at(300),
                      Qfc.at_noneq_3Tvib((300, 300, 300), 300),
                      rtol=0.001)

    if verbose:
        printm(
            "Tested CDSD Q_calc at equilibrium and nonequilibrium give same output: OK"
        )
예제 #2
0
def test_CDSD_calc_vs_ref(warnings=True, verbose=True, *args, **kwargs):
    ''' Test partition functions calculated with CDSD energy levels against 
    hardcoded values '''

    from radis.misc.config import getDatabankEntries

    iso = 1

    try:
        energies = getDatabankEntries('CDSD-HITEMP-PC')['levels']
        levelsfmt = getDatabankEntries('CDSD-HITEMP-PC')['levelsfmt']
        Qf = PartFuncCO2_CDSDcalc(energy_levels=energies[iso],
                                  isotope=iso,
                                  use_cached=True,
                                  levelsfmt=levelsfmt)
        assert np.isclose(Qf.at(300), 291.0447781984652, rtol=0.001)
        assert np.isclose(Qf.at(3000), 114689.88454184022, rtol=0.001)
        assert np.isclose(Qf.at_noneq(300, 300), 291.0447781984652, rtol=0.001)
        assert np.isclose(Qf.at_noneq(3000, 3000),
                          114689.88454184022,
                          rtol=0.001)
        assert np.isclose(Qf.at_noneq(3000,
                                      3000,
                                      overpopulation={'(0,1)': 3},
                                      returnQvibQrot=True)[0],
                          120053.34252537244,
                          rtol=0.001)

        if verbose:
            printm('Tested Q_CDSD values are correct : OK')

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #3
0
def test_media_line_shift(plot=False,
                          verbose=True,
                          warnings=True,
                          *args,
                          **kwargs):
    ''' See wavelength difference in air and vacuum '''

    if plot:  # Make sure matplotlib is interactive so that test are not stuck in pytest
        plt.ion()

    try:
        if verbose:
            printm('>>> _test_media_line_shift')

        setup_test_line_databases(
        )  # add HITRAN-CO-TEST in ~/.radis if not there

        sf = SpectrumFactory(wavelength_min=4500,
                             wavelength_max=4600,
                             wstep=0.001,
                             parallel=False,
                             bplot=False,
                             cutoff=1e-30,
                             path_length=0.1,
                             mole_fraction=400e-6,
                             isotope=[1],
                             db_use_cached=True,
                             medium='vacuum',
                             broadening_max_width=10,
                             verbose=verbose)
        sf.warnings['MissingSelfBroadeningWarning'] = 'ignore'
        sf.warnings['GaussianBroadeningWarning'] = 'ignore'
        sf.load_databank('HITRAN-CO-TEST')

        # Calculate a spectrum
        s = sf.eq_spectrum(2000)

        # Compare
        if plot:
            fig = plt.figure(fig_prefix + 'Propagating media line shift')
            s.plot('radiance_noslit',
                   wunit='nm_vac',
                   nfig=fig.number,
                   lw=2,
                   label='Vacuum')
            plt.title('CO spectrum (2000 K)')
            s.plot('radiance_noslit',
                   wunit='nm',
                   nfig=fig.number,
                   lw=2,
                   color='r',
                   label='Air')

        # ... there should be about ~1.25 nm shift at 4.5 µm:
        assert np.isclose(
            s.get('radiance_noslit', wunit='nm_vac')[0][0] -
            s.get('radiance_noslit', wunit='nm')[0][0], 1.2540436086346745)

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #4
0
def test_line_survey_CO2(verbose=True,
                         plot=True,
                         warnings=True,
                         *args,
                         **kwargs):

    setup_test_line_databases()

    try:
        pl = SpectrumFactory(
            wavenum_min=2380,
            wavenum_max=2400,
            #                         wavelength_min=4170,
            #                         wavelength_max=4200,
            mole_fraction=400e-6,
            path_length=100,  # cm
            parallel=False,
            cutoff=1e-30,
            isotope=[1],
            save_memory=True,
            db_use_cached=True,
        )  # 0.2)
        pl.warnings["MissingSelfBroadeningWarning"] = "ignore"
        pl.load_databank("HITRAN-CO2-TEST")
        s = pl.eq_spectrum(Tgas=1500)
        s.apply_slit(0.5)
        if plot:
            s.line_survey(overlay="transmittance", barwidth=0.01)

        if verbose:
            printm("no boolean defined for test_line_survey")
        return True  # test not defined (just testing methods work)

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #5
0
def test_CDSD_calc_vs_tab(verbose=True, warnings=True, *args, **kwargs):
    """ Test 1: compare calculated PartFunc to the tabulated one """

    from radis.misc.config import getDatabankEntries

    iso = 1
    database = "CDSD-HITEMP-PC"

    # Compare tab to hardcoded
    parfunc = getDatabankEntries(database)["parfunc"]
    Qf = PartFuncCO2_CDSDtab(iso, parfunc)
    assert np.isclose(Qf.at(300), 291.0447781984652, rtol=0.001)
    assert np.isclose(Qf.at(3000), 114689.88454184022, rtol=0.001)

    if verbose:
        printm("Tested CDSD tabulated is correct: OK")

    # Compare tab to calculated
    energies = getDatabankEntries(database)["levels"]
    levelsfmt = getDatabankEntries(database)["levelsfmt"]
    Qfc = PartFuncCO2_CDSDcalc(energies[iso],
                               levelsfmt=levelsfmt,
                               isotope=iso,
                               use_cached=True)
    assert np.isclose(Qf.at(300), Qfc.at(300), rtol=0.001)
    assert np.isclose(Qf.at(3000), Qfc.at(3000), rtol=0.001)

    if verbose:
        printm("Tested CDSD Q_calc vs Q_tab give same output: OK")

    return True
예제 #6
0
def test_CDSD_calc_vs_ref(warnings=True, verbose=True, *args, **kwargs):
    """Test partition functions calculated with CDSD energy levels against
    hardcoded values"""

    from radis.misc.config import getDatabankEntries

    iso = 1

    energies = getDatabankEntries("CDSD-HITEMP-PC")["levels"]
    levelsfmt = getDatabankEntries("CDSD-HITEMP-PC")["levelsfmt"]
    Qf = PartFuncCO2_CDSDcalc(
        energy_levels=energies[iso],
        isotope=iso,
        use_cached=True,
        levelsfmt=levelsfmt,
    )
    assert np.isclose(Qf.at(300), 291.0447781984652, rtol=0.001)
    assert np.isclose(Qf.at(3000), 114689.88454184022, rtol=0.001)
    assert np.isclose(Qf.at_noneq(300, 300), 291.0447781984652, rtol=0.001)
    assert np.isclose(Qf.at_noneq(3000, 3000), 114689.88454184022, rtol=0.001)
    assert np.isclose(
        Qf.at_noneq(3000,
                    3000,
                    overpopulation={"(0,1)": 3},
                    returnQvibQrot=True)[0],
        120053.34252537244,
        rtol=0.001,
    )

    if verbose:
        printm("Tested Q_CDSD values are correct : OK")
예제 #7
0
파일: test_calc.py 프로젝트: radis/radis
def check_wavelength_range(verbose=True, warnings=True, *args, **kwargs):
    """Check that input wavelength is correctly taken into account.
    See https://github.com/radis/radis/issues/214
    """
    if verbose:
        printm("Testing calc_spectrum wavelength range")

    wstep = 0.01

    s = calc_spectrum(
        wavelength_min=4348,  # nm
        wavelength_max=5000,
        molecule="CO",
        isotope="1,2,3",
        pressure=1.01325,  # bar
        Tvib=1700,  # K
        Trot=1700,  # K
        databank="HITRAN-CO-TEST",
        wstep=wstep,
    )
    w, I = s.get("radiance_noslit", wunit="nm", Iunit="mW/sr/cm2/nm")

    assert np.isclose(w.min(), 4348, atol=wstep)
    assert np.isclose(w.max(), 5000, atol=wstep)

    return True
예제 #8
0
def test_CDSD_calc_vs_tab(verbose=True, warnings=True, *args, **kwargs):
    ''' Test 1: compare calculated PartFunc to the tabulated one '''

    from radis.misc.config import getDatabankEntries

    try:

        iso = 1
        database = 'CDSD-HITEMP-PC'
        
        # Compare tab to hardcoded
        parfunc = getDatabankEntries(database)['parfunc']
        Qf = PartFuncCO2_CDSDtab(iso, parfunc)
        assert np.isclose(Qf.at(300), 291.0447781984652, rtol=0.001)
        assert np.isclose(Qf.at(3000), 114689.88454184022, rtol=0.001)

        if verbose:
            printm('Tested CDSD tabulated is correct: OK')

        # Compare tab to calculated
        energies = getDatabankEntries(database)['levels']
        levelsfmt = getDatabankEntries(database)['levelsfmt']
        Qfc = PartFuncCO2_CDSDcalc(energies[iso], levelsfmt=levelsfmt, isotope=iso, use_cached=True)
        assert np.isclose(Qf.at(300), Qfc.at(300), rtol=0.001)
        assert np.isclose(Qf.at(3000), Qfc.at(3000), rtol=0.001)

        if verbose:
            printm('Tested CDSD Q_calc vs Q_tab give same output: OK')

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #9
0
def test_rescaling_path_length(debug=False,
                               plot=False,
                               verbose=True,
                               warnings=True,
                               *args,
                               **kwargs):
    """ Test rescaling functions """

    if plot:  # Make sure matplotlib is interactive so that test are not stuck
        plt.ion()

    try:
        from radis.lbl import SpectrumFactory

        setup_test_line_databases(
        )  # add HITRAN-CO-TEST in ~/.radis if not there

        Tgas = 1500
        sf = SpectrumFactory(
            wavelength_min=4400,
            wavelength_max=4800,
            mole_fraction=0.01,
            #                         path_length=0.1,
            cutoff=1e-25,
            wstep=0.005,
            isotope=[1],
            db_use_cached=True,
            self_absorption=True,
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        #        sf.warnings['NegativeEnergiesWarning'] = 'ignore'
        sf.load_databank("HITRAN-CO-TEST")
        s1 = sf.non_eq_spectrum(Tgas, Tgas, path_length=0.01)
        s2 = sf.non_eq_spectrum(Tgas, Tgas, path_length=3)
        s1.rescale_path_length(3)

        if plot:
            fig = plt.figure(fig_prefix + "Rescaling path length")
            s2.plot("radiance_noslit", nfig=fig.number, lw=3, label="L=3m")
            s1.plot(
                "radiance_noslit",
                nfig=fig.number,
                color="r",
                label="L=0.01m, rescaled to 3m",
            )
            plt.title("Non optically thin rescaling")
            plt.legend()
            plt.tight_layout()

        if verbose:
            printm("Test rescaling:")
            printm("... Difference: {0:.2f}%".format(
                abs(s1.get_power() / s2.get_power() - 1) * 100))

        assert np.isclose(s2.get_power(), s1.get_power(), 2e-3)

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #10
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
예제 #11
0
def test_eq_vs_noneq_isotope(verbose=True,
                             plot=False,
                             warnings=True,
                             *args,
                             **kwargs):
    ''' Test same spectrum for 2 different calculation codes (equilibrium, 
    non-equilibrium) in the presence of isotopes 
    
    Notes
    -----
    
    On the old NeQ package the test used [HITEMP-2010]_
    
    Starting from RADIS 1.0.1, the test is run on [HITRAN-2016]_, which 
    is not valid for these temperatures but can be more conveniently 
    downloaded automatically and thus executed everytime with [Travis]_
    
    '''

    try:
        Tgas = 1500

        sf = SpectrumFactory(wavelength_min=4250,
                             wavelength_max=4350,
                             mole_fraction=1,
                             path_length=1,
                             cutoff=1e-25,
                             molecule='CO2',
                             isotope='1,2',
                             db_use_cached=True,
                             verbose=verbose)
        sf.warnings['MissingSelfBroadeningWarning'] = 'ignore'
        sf.warnings['NegativeEnergiesWarning'] = 'ignore'
        sf.warnings['HighTemperatureWarning'] = 'ignore'
        sf.fetch_databank(
        )  # uses HITRAN: not really valid at this temperature, but runs on all machines without install
        #        sf.load_databank('HITEMP-CO2-DUNHAM')
        s_nq = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas, name='Non-eq')
        s_eq = sf.eq_spectrum(Tgas=Tgas, name='Eq')

        rtol = 5e-3  # 2nd isotope calculated with placeholder energies
        match_eq_vs_non_eq = s_eq.compare_with(s_nq,
                                               spectra_only='abscoeff',
                                               rtol=rtol,
                                               plot=plot)
        match_eq_vs_non_eq *= s_eq.compare_with(s_nq,
                                                spectra_only='radiance_noslit',
                                                rtol=rtol,
                                                plot=plot)

        if verbose:
            printm('Tested eq vs non-eq (<{0:.1f}% error) with isotopes: {1}'.
                   format(rtol * 100, bool(match_eq_vs_non_eq)))

        assert match_eq_vs_non_eq

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #12
0
def test_eq_vs_noneq_isotope(verbose=True,
                             plot=False,
                             warnings=True,
                             *args,
                             **kwargs):
    """Test same spectrum for 2 different calculation codes (equilibrium,
    non-equilibrium) in the presence of isotopes

    Notes
    -----

    On the old NeQ package the test used [HITEMP-2010]_

    Starting from RADIS 1.0.1, the test is run on [HITRAN-2016]_, which
    is not valid for these temperatures but can be more conveniently
    downloaded automatically and thus executed everytime with `Travis CI <https://travis-ci.com/radis/radis>`_

    """

    Tgas = 1500

    sf = SpectrumFactory(
        wavelength_min=4250,
        wavelength_max=4350,
        mole_fraction=1,
        path_length=1,
        cutoff=1e-25,
        molecule="CO2",
        isotope="1,2",
        db_use_cached=True,
        verbose=verbose,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.warnings["NegativeEnergiesWarning"] = "ignore"
    sf.warnings["HighTemperatureWarning"] = "ignore"
    sf.fetch_databank(
    )  # uses HITRAN: not really valid at this temperature, but runs on all machines without install
    #        sf.load_databank('HITEMP-CO2-DUNHAM')
    s_nq = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas, name="Non-eq")
    s_eq = sf.eq_spectrum(Tgas=Tgas, name="Eq")

    rtol = 5e-3  # 2nd isotope calculated with placeholder energies
    match_eq_vs_non_eq = s_eq.compare_with(s_nq,
                                           spectra_only="abscoeff",
                                           rtol=rtol,
                                           plot=plot)
    match_eq_vs_non_eq *= s_eq.compare_with(s_nq,
                                            spectra_only="radiance_noslit",
                                            rtol=rtol,
                                            plot=plot)

    if verbose:
        printm(
            "Tested eq vs non-eq (<{0:.1f}% error) with isotopes: {1}".format(
                rtol * 100, bool(match_eq_vs_non_eq)))

    assert match_eq_vs_non_eq
예제 #13
0
def test_calculatedQ_match_HAPI_CO(vmax=11,
                                   jmax=300,
                                   plot=False,
                                   verbose=True,
                                   *args,
                                   **kwargs):
    """ Tested that Q ab_initio (Dunham) match HAPI for CO at different temperatures"""

    vmax = 11
    vmax_morse = 48
    jmax = 300
    iso = 1

    S = Molecules["CO"][iso]["X"]

    # Dont use cached: force recalculating
    db = PartFunc_Dunham(S,
                         vmax=vmax,
                         vmax_morse=vmax_morse,
                         Jmax=jmax,
                         use_cached=False)  # , ZPE=1081.584383)
    assert not db.use_cached

    #    if plot: db.plot_states()

    hapi = PartFuncHAPI(
        M=5,
        I=1,
    )  # CO  # isotope

    us = []
    hap = []
    T = np.linspace(300, 3000)
    for Ti in T:
        us.append(db.at(Ti))
        hap.append(hapi.at(Ti))

    if plot:
        plt.figure(fig_prefix + "Partition function Dunham vs Precomputed")
        plt.plot(T, us, "ok", label="NeQ")
        plt.plot(T, hap, "or", label="HAPI")
        plt.legend()
        plt.xlabel("Temperature (K)")
        plt.ylabel("Partition function")
        plt.title("Ab-initio partition function calculations\n" +
                  "(vmax:{0},jmax:{1})".format(vmax, jmax))
        plt.tight_layout()

    # Compare Calculated  vs HAPI
    assert np.allclose(us, hap, rtol=0.02)

    if verbose:
        printm(
            "Tested Q_CO ab_initio (Dunham) matches HAPI for 300 - 3000 K: OK")

    return True
예제 #14
0
def test_calculatedQ_match_HAPI(vmax=11,
                                jmax=300,
                                plot=False,
                                verbose=True,
                                *args,
                                **kwargs):
    ''' Tested that Q_CO ab_initio (Dunham) match HAPI '''

    vmax = 11
    vmax_morse = 48
    jmax = 300
    iso = 1

    S = Molecules['CO'][iso]['X']

    # Dont use cached: force recalculating
    db = PartFunc_Dunham(S,
                         vmax=vmax,
                         vmax_morse=vmax_morse,
                         Jmax=jmax,
                         use_cached=False)  # , ZPE=1081.584383)
    assert not db.use_cached

    #    if plot: db.plot_states()

    hapi = PartFuncHAPI(
        M=5,  # CO
        I=1,  # isotope
    )

    us = []
    hap = []
    T = np.linspace(300, 3000)
    for Ti in T:
        us.append(db.at(Ti))
        hap.append(hapi.at(Ti))

    if plot:
        plt.figure(fig_prefix + 'Partition function Dunham vs Precomputed')
        plt.plot(T, us, 'ok', label='NeQ')
        plt.plot(T, hap, 'or', label='HAPI')
        plt.legend()
        plt.xlabel('Temperature (K)')
        plt.ylabel('Partition function')
        plt.title('Ab-initio partition function calculations\n' +
                  '(vmax:{0},jmax:{1})'.format(vmax, jmax))
        plt.tight_layout()

    # Compare Calculated  vs HAPI
    assert np.allclose(us, hap, rtol=0.02)

    if verbose:
        printm('Tested Q_CO ab_initio (Dunham) matches HAPI: OK')

    return True
예제 #15
0
def test_media_line_shift(plot=False, verbose=True, warnings=True, *args, **kwargs):
    """ See wavelength difference in air and vacuum """

    if plot:  # Make sure matplotlib is interactive so that test are not stuck in pytest
        plt.ion()

    if verbose:
        printm(">>> _test_media_line_shift")

    setup_test_line_databases()  # add HITRAN-CO-TEST in ~/.radis if not there

    sf = SpectrumFactory(
        wavelength_min=4500,
        wavelength_max=4600,
        wstep=0.001,
        parallel=False,
        bplot=False,
        cutoff=1e-30,
        path_length=0.1,
        mole_fraction=400e-6,
        isotope=[1],
        db_use_cached=True,
        medium="vacuum",
        broadening_max_width=10,
        verbose=verbose,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.warnings["GaussianBroadeningWarning"] = "ignore"
    sf.load_databank("HITRAN-CO-TEST")

    # Calculate a spectrum
    s = sf.eq_spectrum(2000)

    # Compare
    if plot:
        fig = plt.figure(fig_prefix + "Propagating media line shift")
        s.plot("radiance_noslit", wunit="nm_vac", nfig=fig.number, lw=2, label="Vacuum")
        plt.title("CO spectrum (2000 K)")
        s.plot(
            "radiance_noslit",
            wunit="nm",
            nfig=fig.number,
            lw=2,
            color="r",
            label="Air",
        )

    # ... there should be about ~1.25 nm shift at 4.5 µm:
    assert np.isclose(
        s.get("radiance_noslit", wunit="nm_vac")[0][0]
        - s.get("radiance_noslit", wunit="nm")[0][0],
        1.2540436086346745,
    )
예제 #16
0
def test_calculatedQ_match_HAPI(plot=False, verbose=True, *args, **kwargs):
    """Tested that Q ab_initio (Dunham) match HAPI for different molecules
    and isotopes"""

    # molecule, isotope, temperature, absolute tolerance
    for molecule, iso, T, atol, rtol in [
        ("CO2", 1, 300, 0.9, 0.02),
        ("CO2", 1, 1000, 5.0, 0.02),
        ("CO2", 1, 3000, 2150, 0.02),
        ("CO2", 2, 300, 1.8, 0.02),
        ("CO2", 2, 1000, 25, 0.02),
        ("CO2", 2, 3000, 4962, 0.02),
        ("CO", 1, 300, 0.16, 0.02),
        ("CO", 1, 1000, 1.9, 0.02),
        ("CO", 1, 3000, 27, 0.02),
        ("CO", 2, 300, 0.31, 0.02),
        ("CO", 2, 1000, 4.1, 0.02),
        ("CO", 2, 3000, 56.9, 0.02),
        ("CO", 3, 300, 0.16, 0.02),
        ("CO", 3, 1000, 2.1, 0.02),
        ("CO", 3, 3000, 28.6, 0.02),
    ]:

        S = Molecules[molecule][iso]["X"]

        # Dont use cached: force recalculating
        db = PartFunc_Dunham(S)

        from radis.db.classes import get_molecule_identifier

        hapi = PartFuncHAPI(M=get_molecule_identifier(molecule), I=iso)

        Q_radis = db.at(T)
        Q_hapi = hapi.at(T)

        if verbose:
            print("Q({0},iso={1},{2}K)\tRADIS: {3:.2f}\tHAPI={4:.2f}".format(
                molecule, iso, T, Q_radis, Q_hapi))

        try:
            assert np.isclose(Q_radis, Q_hapi, atol=atol)
            assert np.isclose(Q_radis, Q_hapi, atol=atol)
        except AssertionError:
            raise AssertionError(
                "Partition function for {0}, iso={1} ".format(molecule, iso) +
                "at {0}K doesnt match in RADIS ".format(T) +
                "({0:.4f}) and HAPI ({1:.4f})".format(Q_radis, Q_hapi))

    if verbose:
        printm("Tested Q ab_initio (Dunham) matches HAPI: OK")

    return True
예제 #17
0
def test_calculatedQ_match_HAPI(plot=False, verbose=True,
                                *args, **kwargs):
    ''' Tested that Q ab_initio (Dunham) match HAPI for different molecules 
    and isotopes'''

    # molecule, isotope, temperature, absolute tolerance 
    for molecule, iso, T, atol in [('CO2', 1, 300,  0.9),
                                   ('CO2', 1, 1000, 2.0),
                                   ('CO2', 1, 3000, 2000),
                                   ('CO2', 2, 300,  1.8),
                                   ('CO2', 2, 1000, 25),
                                   ('CO2', 2, 3000, 4962),
                                   ('CO', 1, 300,   0.16),
                                   ('CO', 1, 1000,  1.9),
                                   ('CO', 1, 3000,  27),
                                   ('CO', 2, 300,   0.31),
                                   ('CO', 2, 1000,  4.1),
                                   ('CO', 2, 3000,  56.9),
                                   ('CO', 3, 300,   0.16),
                                   ('CO', 3, 1000,  2.1),
                                   ('CO', 3, 3000,  28.6),
                                   ]:

        S = Molecules[molecule][iso]['X']
    
        # Dont use cached: force recalculating
        db = PartFunc_Dunham(S)
    
        from radis.io.hitran import get_molecule_identifier
        hapi = PartFuncHAPI(M=get_molecule_identifier(molecule),
                            I=iso
                            )
        
        Q_radis = db.at(T)
        Q_hapi = hapi.at(T)

        if verbose:
            print('Q({0},iso={1},{2}K)\tRADIS: {3:.2f}\tHAPI={4:.2f}'.format(
                    molecule, iso, T, Q_radis, Q_hapi))
    
        try:
            assert np.isclose(Q_radis, Q_hapi, atol=atol)
        except AssertionError:
            raise AssertionError('Partition function for {0}, iso={1} '.format(molecule, iso)+\
                                 'at {0}K doesnt match in RADIS '.format(T)+\
                                 '({0:.4f}) and HAPI ({1:.4f})'.format(Q_radis, Q_hapi))

    if verbose:
        printm('Tested Q ab_initio (Dunham) matches HAPI: OK')

    return True
예제 #18
0
def test_Morse_Potential_effect_CO(T=3000, rtol=1e-4, verbose=True, warnings=True, *args, **kwargs):
    ''' Quantify effect of calculating upper levels near dissociation limit
    with Morse Potential 

    Returns True if difference is less than rtol
    '''

    vmax = 11
    vmax_morse = 48
    jmax = 300
    iso = 1
    S = Molecules['CO'][iso]['X']

    # TODO: remove vmax, vmax_morse from Dunham method. Only use the one in ElecState
    db = PartFunc_Dunham(S, vmax=vmax, vmax_morse=0,
                         Jmax=jmax, use_cached=False)
    Q_nomorse = db.at(T)

    db = PartFunc_Dunham(S, vmax=vmax, vmax_morse=vmax_morse,
                         Jmax=jmax, use_cached=False)
    Q_morse = db.at(T)

    if verbose:
        printm('Morse vs no Morse potential (T={0}K)'.format(T))
        printm('Q_morse: {0:.3f}'.format(Q_morse))
        printm('Q_nomorse: {0:.3f}'.format(Q_nomorse))
        printm('Difference: {0:.4f}%'.format(
            abs(Q_nomorse-Q_morse)/Q_morse*100))

    assert abs(Q_nomorse-Q_morse)/Q_morse < rtol
예제 #19
0
def test_sPlanck_conversions(verbose=True, *args, **kwargs):

    if verbose:
        printm("Testing sPlanck conversions: ")

    s_cm = sPlanck(1000, 10000, T=1500, eps=0.3)
    I_cm2cm = s_cm.get("radiance_noslit", Iunit="mW/cm2/sr/cm_1")[1]
    I_cm2nm = s_cm.get("radiance_noslit", Iunit="mW/cm2/sr/nm")[1]

    s_nm = sPlanck(1000, 10000, T=1500, eps=0.3)
    I_nm2nm = s_nm.get("radiance_noslit", Iunit="mW/cm2/sr/nm")[1]
    I_nm2cm = s_nm.get("radiance_noslit", Iunit="mW/cm2/sr/cm_1")[1]

    assert np.allclose(I_cm2cm, I_nm2cm)
    assert np.allclose(I_nm2nm, I_cm2nm)
예제 #20
0
def test_cache_file_generation_and_update(verbose=True, *args, **kwargs):
    ''' Test that cache file process works correctly, using CO as an example.

    Expected behavior:

    - generated when 'regen'
    - updated when using 'True' but input parameters have changed
    - an error is raised when 'force' is used but input parameters have changed

    '''
    # TODO: move it as a test of cache_files.py in RADIS

    S = Molecules['CO'][1]['X']

    from os.path import exists, getmtime

    if verbose:
        printm('Testing behavior for Energy cache file with use_cached=')

    # Create a first cache file (or use existing one)
    db = PartFunc_Dunham(S, vmax=12, vmax_morse=48,
                         Jmax=300, use_cached=True, verbose=verbose)

    # .. test file was created
    cachefile = db.cachefile
    assert exists(cachefile)
    last_modif = getmtime(cachefile)
    if verbose:
        printm('... True: energy cache file has been used/created (vmax=12)')

    # Force recalculating (using same inputs, but use_cached='regen')
    db = PartFunc_Dunham(S, vmax=12, vmax_morse=48,
                         Jmax=300, use_cached='regen', verbose=verbose)

    # ... test that cache file was updated
    cachefile = db.cachefile
    assert getmtime(cachefile) > last_modif
    last_modif = getmtime(cachefile)
    if verbose:
        print("... 'regen': energy cache file has been created again (vmax=12)")

    # Recompute with different parameters

    # ... if using 'force', ensures that an error is raised
    with pytest.raises(DeprecatedFileError):  # DeprecatedFileError is expected
        db = PartFunc_Dunham(S, vmax=11, vmax_morse=48,
                             Jmax=300, use_cached='force', verbose=verbose)
    if verbose:
        printm(
            "... 'force': an error was correctly triggered for new input parameters (vmax=11)")

    # ... if using 'True', ensures that cache file is updated
    db = PartFunc_Dunham(S, vmax=11, vmax_morse=48,
                         Jmax=300, use_cached=True, verbose=verbose)
    assert getmtime(cachefile) > last_modif
    if verbose:
        printm('... True: cache file was updated for new input parameters (vmax=11)')
예제 #21
0
def test_reduced_CDSD_calc_vs_tab(verbose=True,
                                  warnings=True,
                                  *args,
                                  **kwargs):
    """Test 1: compare calculated PartFunc to the tabulated one

    Version where we use the reduced set of CO2 levels (< 3000 cm-1)"""
    from radis.misc.config import getDatabankEntries

    iso = 1
    database = "HITEMP-CO2-HAMIL-TEST"

    # Compare tab to hardcoded
    parfunc = getDatabankEntries(database)["parfunc"]
    Qf = PartFuncCO2_CDSDtab(iso, parfunc)
    assert np.isclose(Qf.at(300), 291.0447781984652, rtol=0.001)
    assert np.isclose(Qf.at(3000), 114689.88454184022, rtol=0.001)

    if verbose:
        printm("Tested CDSD tabulated is correct: OK")

    # Compare tab to calculated
    energies = getDatabankEntries(database)["levels"]
    levelsfmt = getDatabankEntries(database)["levelsfmt"]
    Qfc = PartFuncCO2_CDSDcalc(
        energies[iso],
        levelsfmt=levelsfmt,
        isotope=iso,
        use_cached=True,
        verbose=verbose,
    )
    assert np.isclose(
        Qf.at(300), Qfc.at(300), rtol=0.01
    )  # reduced rtol to accommodate for the reduced set of levels in the test set
    # assert np.isclose(Qf.at(3000), Qfc.at(3000), rtol=0.001)  # of course doesnt work with the reduced set of levels in the test set

    if verbose:
        printm("Tested CDSD Q_calc vs Q_tab give same output: OK")
예제 #22
0
def test_recompute_Q_from_QvibQrot_CDSD_PC(verbose=True,
                                           warnings=True,
                                           *args,
                                           **kwargs):
    ''' 
    Calculate vibrational and rotational partition functions:
        
    - in CDSD with (p,c) convention for vibrational levels 
    - under nonequilibrium
    
    Recompute total partition function, and compare

    Test if partition function can be recomputed correctly from vibrational
    populations and rotational partition function (note that we are in a coupled
    case so partition function is not simply the product of Qvib, Qrot) 
    '''

    from radis.misc.config import getDatabankEntries

    iso = 1

    try:
        energies = getDatabankEntries('CDSD-HITEMP-PC')['levels']
        levelsfmt = getDatabankEntries('CDSD-HITEMP-PC')['levelsfmt']

        Tvib = 1500
        Trot = 300

        Qf = PartFuncCO2_CDSDcalc(energies[iso],
                                  isotope=iso,
                                  use_cached=True,
                                  levelsfmt=levelsfmt)
        Q = Qf.at_noneq(Tvib, Trot)
        _, Qvib, dfQrot = Qf.at_noneq(Tvib, Trot, returnQvibQrot=True)
        if verbose:
            printm('Q', Q)
        if verbose:
            printm('Qvib', Qvib)

        # 1) Test Q vs Q recomputed from Qrot, Qvib

        # Recompute Qtot
        df = dfQrot
        Q2 = ((df.gvib * exp(-df.Evib * hc_k / Tvib)) * df.Qrot).sum()
        # Todo: non Boltzmann case

        assert np.isclose(Q, Q2)

        if verbose:
            printm('Tested Q vs recomputed from (Qvib, Qrot) are the same: OK')

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
예제 #23
0
def test_Q_1Tvib_vs_Q_3Tvib(T=1500,
                            verbose=True,
                            warnings=True,
                            *args,
                            **kwargs):
    """Test if partition function calculated in 1-Tvib mode returns the same
    result as partition function calculated in 3-Tvib mode
    """

    b = True

    # input
    M = "CO2"
    I = 1  # isotope
    S = Molecules[M][I]["X"]

    Qf = PartFunc_Dunham(S, use_cached=True)
    df = Qf.df

    # First make sure energies match
    if not (df.Evib == df.Evib1 + df.Evib2 + df.Evib3).all():
        b *= False
        if warnings:
            printm(
                "WARNING in test_Q_1Tvib_vs_Q_3Tvib: Evib != Evib1 + Evib2 + Evib3"
            )

    # Then calculate Q vs Q3T
    Q = Qf.at_noneq(T, T)
    if verbose:
        printm("Q", Q)

    Q3T = Qf.at_noneq_3Tvib((T, T, T), T)
    if verbose:
        printm("Q3T", Q3T)

    assert np.isclose(Q, Q3T)
    if verbose:
        printm(
            "Tested Q in 1-Tvib vs Q in 3-Tvib modes (T={0:.0f}K): OK".format(
                T))

    return True
예제 #24
0
def test_recompute_Q_from_QvibQrot_Dunham_Evib123_Erot(verbose=True,
                                                       warnings=True,
                                                       *args,
                                                       **kwargs):
    """Calculate vibrational and rotational partition functions:

    - with Dunham expansions. Evib, Erot = (Evib1+Evib2+Evib3, Erot)
    - under nonequilibrium

    Calculate total rovibrational partition function, and compare

    Test if partition function can be recomputed correctly from vibrational
    populations and rotational partition function (note that we are in a coupled
    case so partition function is not simply the product of Qvib, Qrot)
    """

    iso = 1
    Tvib = 1500
    Trot = 300

    S = Molecules["CO2"][iso]["X"]

    Qf = PartFunc_Dunham(
        S,
        use_cached=True,
        group_energy_modes_in_2T_model={
            "CO2": (["Evib1", "Evib2", "Evib3"], ["Erot"])
        },
    )

    Q = Qf.at_noneq(Tvib, Trot)
    _, Qvib, dfQrot = Qf.at_noneq(Tvib, Trot, returnQvibQrot=True)
    if verbose:
        printm("Q", Q)
    if verbose:
        printm("Qvib", Qvib)

    # 1) Test Q vs Q recomputed from Qrot, Qvib

    # Recompute Qtot
    df = dfQrot
    Q2 = ((df.gvib * exp(-df.Evib * hc_k / Tvib)) * df.Qrot).sum()
    # Todo: non Boltzmann case

    assert np.isclose(Q, Q2)

    if verbose:
        printm("Tested Q vs recomputed from (Qvib, Qrot) are the same: OK")

    return True
예제 #25
0
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    #        sf.load_databank('HITEMP-CO2-DUNHAM')
    sf.load_databank("HITEMP-CO2-TEST")

    # Calculate with Klarenaar fitted values
    T12 = 517
    T3 = 2641
    Trot = 491

    s = sf.non_eq_spectrum((T12, T12, T3),
                           Trot,
                           Ttrans=Trot,
                           vib_distribution="treanor",
                           name="RADIS")

    if plot:
        plot_diff(s, s_exp, "transmittance_noslit")
    #        plt.savefig('test_CO2_3Tvib_vs_klarenaar.png')

    assert get_residual(s, s_exp, "transmittance_noslit",
                        ignore_nan=True) < 0.003

    return True


if __name__ == "__main__":
    printm(
        "test_CO2_3Tvib_vs_klarenaar:",
        test_klarenaar_validation_case(verbose=True, plot=True),
    )
예제 #26
0
def test_temperature_units_conversion(
    input_temperature, expected_temperature_K, verbose=True, *args, **kwargs
):
    setup_test_line_databases()  # add HITRAN-CO-TEST in ~/.radis if not there

    sf = SpectrumFactory(
        wavelength_min=4300,
        wavelength_max=4500,
        wstep=0.01,
        cutoff=1e-30,
        pressure=1,
        mole_fraction=1,
        isotope=[1],
        Tref=300 * u.K,
        verbose=verbose,
    )
    sf.load_databank("HITRAN-CO-TEST")
    s = sf.eq_spectrum(
        Tgas=input_temperature, pressure=20 * u.mbar, path_length=1 * u.mm
    )
    assert np.isclose(s.conditions["Tgas"], expected_temperature_K)
    assert np.isclose(s.conditions["path_length"], 0.1)  # cm
    assert np.isclose(s.conditions["pressure_mbar"], 20)


# --------------------------
if __name__ == "__main__":

    printm("Testing factory:", pytest.main(["test_factory.py"]))
#    printm('Testing factory:', pytest.main(['test_factory.py', '-k', 'test_wavenumber_units_conversion']))
예제 #27
0
def test_power_integral(verbose=True, warnings=True, *args, **kwargs):
    """ Test direct calculation of power integral from Einstein coefficients
    matches integration of broadened spectrum in the optically thin case

    We compare:

    - direct calculation of power integral with equilibrium code
        :meth:`~radis.lbl.SpectrumFactory.optically_thin_power` (T)
    - direct calculation of power integral with non equilibrium code  
        :meth:`~radis.lbl.SpectrumFactory.optically_thin_power` (T,T)
    - numerical integration of non equilibrium spectrum under optically thin conditions: 
        :meth:`~radis.spectrum.spectrum.Spectrum.get_power`

    Test passes if error < 0.5%

    """

    if verbose:
        printm(">>> _test_power_integral")

    setup_test_line_databases()  # add HITRAN-CO-TEST in ~/.radis if not there

    sf = SpectrumFactory(
        wavelength_min=4300,
        wavelength_max=4666,
        wstep=0.001,
        parallel=False,
        bplot=False,
        cutoff=1e-30,
        path_length=10,
        mole_fraction=400e-6,
        isotope=[1],
        db_use_cached=True,
        broadening_max_width=10,
        verbose=verbose,
    )
    sf.warnings.update(
        {
            "MissingSelfBroadeningWarning": "ignore",
            "OutOfRangeLinesWarning": "ignore",
            "HighTemperatureWarning": "ignore",
        }
    )
    sf.load_databank("HITRAN-CO-TEST")
    unit = "µW/sr/cm2"
    T = 600

    # Calculate:

    # ... direct calculation of power integral with equilibrium code
    Peq = sf.optically_thin_power(Tgas=T, unit=unit)

    # ... direct calculation of power integral with non equilibrium code
    Pneq = sf.optically_thin_power(Tvib=T, Trot=T, unit=unit)

    # ... numerical integration of non equilibrium spectrum under optically thin
    # ... conditions
    sf.input.self_absorption = False
    s = sf.non_eq_spectrum(T, T)

    assert s.conditions["self_absorption"] == False

    # Compare
    err = abs(Peq - s.get_power(unit=unit)) / Peq
    if verbose:
        printm("Emission integral:\t{0:.4g}".format(Peq), unit)
        printm("Emission (noneq code):\t{0:.4g}".format(Pneq), unit)
        printm("Integrated spectrum:\t{0:.4g}".format(s.get_power(unit=unit)), unit)
        printm("Error: {0:.2f}%".format(err * 100))

    assert err < 0.005
예제 #28
0
    test_reduced_CDSD_calc_noneq(verbose=verbose, warnings=warnings)

    # Test 5a, 5b: recompute Q from QvibQrot
    test_recompute_Q_from_QvibQrot_Dunham_Evib123_Erot(verbose=verbose,
                                                       warnings=warnings)
    test_recompute_Q_from_QvibQrot_Dunham_Evib3_Evib12Erot(verbose=verbose,
                                                           warnings=warnings)
    test_recompute_Q_from_QvibQrot_CDSD_PC(verbose=verbose, warnings=warnings)
    # test_recompute_Q_from_QvibQrot_CDSD_PCN(verbose=verbose, warnings=warnings)  # ignore in released version

    # Test 6:
    test_Q_1Tvib_vs_Q_3Tvib(verbose=verbose, warnings=warnings)

    # Test 7:
    test_Morse_Potential_effect_CO(verbose=verbose, warnings=warnings)

    # Test 8: Regenerates levels file if it's manually changed
    test_levels_regeneration(verbose=True, warnings=True, *args, **kwargs)
    return True


if __name__ == "__main__":
    printm("Testing parfunc: {0}".format(_run_testcases()))

    verbose = True
    warnings = True

#    test_CDSD_calc_vs_tab(verbose=verbose, warnings=warnings)
#    test_recompute_Q_from_QvibQrot_CDSD_PC(verbose=verbose, warnings=warnings)
#    test_recompute_Q_from_QvibQrot_CDSD_PCN(verbose=verbose, warnings=warnings)
예제 #29
0
        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


# --------------------------
if __name__ == "__main__":

    printm("Testing GPU spectrum calculation:", pytest.main(["test_gpu.py"]))
예제 #30
0
def test_spec_generation(plot=True, verbose=2, warnings=True, *args, **kwargs):
    """ Test spectrum generation
    Can be used as a base to generate spectra in your codes

    Non-regression test: compare with past version (see conditions below)

    Compare results from a reference case to results calculated on 30/12/2017
    This is not a validation case (30/12/2017 results are not a physically validated
    case), but it makes sure results dont change over time

    Conditions (30/12/2017)::

        Physical Conditions
        ----------------------------------------
           Tgas                 300 K
           Trot                 300 K
           Tvib                 300 K
           pressure             1.01325 bar
           isotope              1,2
           mole_fraction        1
           molecule             CO2
           path_length          1 cm
           wavelength_max       4400.0 nm
           wavelength_min       4150.0 nm
           wavenum_max          2409.6385542168673 cm-1
           wavenum_min          2272.7272727272725 cm-1
        Computation Parameters
        ----------------------------------------
           Tref                 296 K
           broadening_max_width  10 cm-1
           cutoff               1e-25 cm-1/(#.cm-2)
           db_assumed_sorted    True
           db_use_cached        True
           dbformat             cdsd
           dbpath               # USER-DEPENDANT: CDSD-HITEMP
           fillmissinglevelswithzero  False
           levelsfmt            cdsd
           levelspath           # USER-DEPENDANT: CDSD-4000
           medium               vacuum
           parfuncfmt           cdsd
           parfuncpath          # USER-DEPENDANT: CDSD-4000
           rot_distribution     boltzmann
           self_absorption      True
           vib_distribution     boltzmann
           wavenum_max_calc     2414.6385542168673 cm-1
           wavenum_min_calc     2267.7272727272725 cm-1
           waveunit             cm-1
           wstep                0.01 cm-1
        ----------------------------------------

    Notes
    -----

    Performance test. How long it tooks to calculate this Spectrum?
    Test with cutoff 1e-25, broadening_max_width=10 

    - 0.9.15: >>> 33s

    - 0.9.16*: (replaced groupby().apply() with iteration over indexes) >>> 32s  
            [but large impact expected on big files]

    - 0.9.16*: (upgraded cache files to h5) >>> 25s 

    - 0.9.16*: (also added h5 cache file for levels) >>> 21s

    - 0.9.16*: (with Whiting slit voigt function) >>> 5.8s

    Test with cutoff 1e-27, broadening_max_width=50 :  
    ("Spectrum calculated in ... ", including database loading time)

    - 0.9.16*: (same code as last) >>> 12.5s including 7.6s of broadening

    - 0.9.16**: (with pseudo_continuum_threshold=0.01) >>> 7.8s including 2.3s of broadening

    - 0.9.18 (normal code, no pseudo continuum). >>> ?
    
    - 0.9.21 (normal code) >>> 13.7s, including 8.7s of broadening
             (with pseudo_continuum_threshold=0.01) >>> 4.3s, including 2.6s of broadening

    - 0.9.21*              >>> 14.0s  (added the manual lineshape normalization instead of
                                       Whitings's polynomial)
    
    - 0.9.22 (normal code) >>> 11.3s   (without energy level lookup, for eq. calculations)
             (with pseudo_continuum_threshold=0.01) >>> 5.9s

    - 0.9.23 (normal code) >>> 7.2s   (added jit in Voigt broadening)
                           >>> 7.1s   (chunksize = None)  (and much faster for more lines)
             (with pseudo_continuum_threshold=0.01) >>> 4.9s
             
    RADIS:
        
    - 0.9.19 (normal code) >>> 6.3 s
    
    - 0.9.20 (normal code) >>> 6.3 s
             (with pseudo_continuum_threshold=0.01) >>> ???
             (with DLM) >>> 2.3 s
    
    """

    if plot:  # Make sure matplotlib is interactive so that test are not stuck in pytest
        plt.ion()

    from time import time

    t0 = time()
    if verbose:
        printm(">>> _test_spec_generation")

    # This is how you get a spectrum (see calc.py for front-end functions
    # that do just that)
    sf = SpectrumFactory(
        wavelength_min=4150,
        wavelength_max=4400,
        parallel=False,
        bplot=False,
        cutoff=1e-27,
        isotope="1,2",
        db_use_cached=True,
        broadening_max_width=50,
        #                             chunksize='DLM',
        #                             pseudo_continuum_threshold=0.01,
        medium="vacuum",
        verbose=verbose,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.warnings["NegativeEnergiesWarning"] = "ignore"
    sf.load_databank(
        "HITEMP-CO2-DUNHAM",
        load_energies=False,  # no need to load energies at equilibrium
    )
    s = sf.eq_spectrum(Tgas=300)
    if verbose:
        printm(
            ">>> _test_spec_generation: Spectrum calculated in {0:.2f}s".format(
                time() - t0
            )
        )

    if plot:
        plt.figure(fig_prefix + "Reference spectrum CDSD-HITEMP (radiance)")
        # Iunit is arbitrary. Use whatever makes sense
        s.plot("radiance_noslit", Iunit="µW/cm2/sr/nm", nfig="same")
    s.rescale_path_length(0.01)

    # Here we get some extra informations:
    if plot:
        sf.plot_broadening(i=0)  # show broadening of one line
        plt.xlim((2267.20, 2268.30))

    # Compare with harcoded results
    # ... code previously used to export hardcoded results:
    # ... and header contains all input conditions:
    #        np.savetxt('output.txt', np.vstack(s.get('abscoeff', wunit='nm')).T[::10])
    #        print(s)
    # ................
    from radis.test.utils import getTestFile

    wref, Iref = np.loadtxt(getTestFile("CO2abscoeff_300K_4150_4400nm.txt")).T
    match_reference = np.allclose(s.get("abscoeff", wunit="nm")[1][::10], Iref)
    if not match_reference:
        # give some more information before raising error
        printm(
            "Error: {0:.2f}%".format(
                np.mean(abs(s.get("abscoeff", wunit="nm")[1][::10] / Iref - 1)) * 100
            )
        )
        # Store the faulty spectrum
        s.store(
            "test_factory_failed_{0}.spec".format(radis.get_version()),
            if_exists_then="replace",
        )

    # Plot comparison
    if plot:
        plt.figure(fig_prefix + "Reference spectrum (abscoeff)")
        # , show_points=True)  # show_points to have an
        s.plot(
            "abscoeff",
            wunit="nm",
            medium="air",
            nfig="same",
            lw=3,
            label="RADIS, this version",
        )
        # idea of the resolution
        plt.plot(wref, Iref, "or", ms=3, label="version NEQ 0.9.20 (12/05/18)")
        plt.legend()
        plt.title("All close: {0}".format(match_reference))
        plt.tight_layout()

    # Another example, at higher temperature.
    # Removed because no test is associated with it and it takes time for
    # nothing
    #        s2 = sf.non_eq_spectrum(Tvib=1000, Trot=300)
    #        if plot: s2.plot('abscoeff', wunit='nm')

    if verbose:
        printm(
            "Spectrum calculation (no database loading) took {0:.1f}s\n".format(
                s.conditions["calculation_time"]
            )
        )
        printm("_test_spec_generation finished in {0:.1f}s\n".format(time() - t0))

    assert match_reference