Exemple #1
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)
Exemple #2
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)
Exemple #3
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
Exemple #4
0
def test_populations(verbose=True, *args, **kwargs):
    """ Test that vib and rovib populations are calculated correctly """

    from radis.lbl import SpectrumFactory
    from radis.misc.basics import all_in

    export = ["vib", "rovib"]
    sf = SpectrumFactory(
        2000,
        2300,
        export_populations=export,
        db_use_cached=True,
        cutoff=1e-25,
        isotope="1",
    )
    sf.warnings.update({
        "MissingSelfBroadeningWarning": "ignore",
        "VoigtBroadeningWarning": "ignore"
    })
    sf.load_databank("HITRAN-CO-TEST")

    s = sf.non_eq_spectrum(2000, 2000)

    pops = sf.get_populations(export)
    if not all_in(["rovib", "vib"], list(pops["CO"][1]["X"].keys())):
        raise AssertionError(
            "vib and rovib levels should be defined after non_eq_spectrum calculation!"
        )
    if not "nvib" in list(pops["CO"][1]["X"]["vib"].keys()):
        raise AssertionError(
            "Vib populations should be defined after non_eq_spectrum calculation!"
        )

    s = sf.eq_spectrum(300)

    pops = sf.get_populations(export)
    if "nvib" in list(pops["CO"][1]["X"]["vib"].keys()):
        raise AssertionError(
            "Vib levels should not be defined anymore after eq_spectrum calculation!"
        )

    # Any of these is True and something went wrong
    s = sf.non_eq_spectrum(2000, 2000)
    s2 = sf.non_eq_spectrum(300, 300)

    # printm(all(s2.get_vib_levels(isotope=1) == s.get_vib_levels(isotope=1)))
    assert not (s2.get_vib_levels() is s.get_vib_levels())
    assert not (s2.get_rovib_levels() == s.get_rovib_levels()).all().all()
    assert not (s2.get_rovib_levels() is s.get_rovib_levels())

    return True  # if no AssertionError
Exemple #5
0
def test_rescaling_mole_fraction(debug=False,
                                 plot=False,
                                 verbose=True,
                                 warnings=True,
                                 *args,
                                 **kwargs):
    """ Test rescaling functions """

    from radis.lbl import SpectrumFactory

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

    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=1,
        path_length=0.1,
        mole_fraction=0.01,
        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")
    error = []
    N = [1e-3, 1e-2, 1e-1, 0.3, 0.6, 1]  # first is ref
    for Ni in N:
        s1 = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=N[0])
        sN = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=Ni)
        s1.rescale_mole_fraction(Ni)
        error.append(sN.get_power() / s1.get_power())

    if plot:
        plt.figure(fig_prefix + "Rescaling mole fractions")
        plt.plot(N, error, "-ok")
        plt.scatter(
            N[0],
            error[0],
            s=200,
            facecolors="none",
            edgecolors="r",
            label="reference",
        )
        plt.xlabel("Mole fraction")
        plt.ylabel("scaled energy / ab initio energy")
        plt.xscale("log")
        plt.legend()
        plt.title("Effect of scaling mole fraction w/o lineshape update")
        plt.tight_layout()

    # less than 1% error when rescaling from 1e-3 to 0.6
    assert abs(error[-2] - 1) < 0.01
def test_populations(verbose=True, *args, **kwargs):
    ''' Test that vib and rovib populations are calculated correctly '''

    from radis.lbl import SpectrumFactory
    from radis.misc.basics import all_in

    export = ['vib', 'rovib']
    sf = SpectrumFactory(2000,
                         2300,
                         export_populations=export,
                         db_use_cached=True,
                         cutoff=1e-25,
                         isotope='1')
    sf.warnings.update({
        'MissingSelfBroadeningWarning': 'ignore',
        'VoigtBroadeningWarning': 'ignore'
    })
    sf.load_databank('HITRAN-CO-TEST')

    s = sf.non_eq_spectrum(2000, 2000)

    pops = sf.get_populations(export)
    if not all_in(['rovib', 'vib'], list(pops['CO'][1]['X'].keys())):
        raise AssertionError(
            'vib and rovib levels should be defined after non_eq_spectrum calculation!'
        )
    if not 'nvib' in list(pops['CO'][1]['X']['vib'].keys()):
        raise AssertionError(
            'Vib populations should be defined after non_eq_spectrum calculation!'
        )

    s = sf.eq_spectrum(300)

    pops = sf.get_populations(export)
    if 'nvib' in list(pops['CO'][1]['X']['vib'].keys()):
        raise AssertionError(
            'Vib levels should not be defined anymore after eq_spectrum calculation!'
        )

    # Any of these is True and something went wrong
    s = sf.non_eq_spectrum(2000, 2000)
    s2 = sf.non_eq_spectrum(300, 300)

    #printm(all(s2.get_vib_levels(isotope=1) == s.get_vib_levels(isotope=1)))
    assert not (s2.get_vib_levels() is s.get_vib_levels())
    assert not (s2.get_rovib_levels() == s.get_rovib_levels()).all().all()
    assert not (s2.get_rovib_levels() is s.get_rovib_levels())

    return True  # if no AssertionError
Exemple #7
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)
Exemple #8
0
def _distribute_noneq_spectrum(args):
    ''' Clone the Factory and calculate non_eq_spectrum over several clones '''
    cast_factory, Tvib, Trot, mole_fraction, path_length = args
    # ... (dev) must match p.map(_distribute_noneq_spectrum...) order
    factory = deepcopy(cast_factory)
    # Update id
    factory._id = uuid1()
    return SpectrumFactory.non_eq_spectrum(factory, Tvib, Trot, mole_fraction=mole_fraction, 
                                           path_length=path_length)
Exemple #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)
Exemple #10
0
def test_pathlength_units_conversion(
    input_pathlength, expected_pathlength_cm, 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,
        path_length=input_pathlength,
        mole_fraction=1,
        isotope=[1],
        verbose=verbose,
    )
    sf.load_databank("HITRAN-CO-TEST")
    s = sf.eq_spectrum(Tgas=300)
    assert np.isclose(s.conditions["path_length"], expected_pathlength_cm)
Exemple #11
0
def test_rescaling_mole_fraction(debug=False, plot=False, verbose=True, warnings=True,
                                 *args, **kwargs):
    ''' Test rescaling functions '''

    from radis.lbl import SpectrumFactory

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

    try:
        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=1,
            path_length=0.1,
            mole_fraction=0.01,
            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')
        error = []
        N = [1e-3, 1e-2, 1e-1, 0.3, 0.6, 1]  # first is ref
        for Ni in N:
            s1 = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=N[0])
            sN = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=Ni)
            s1.rescale_mole_fraction(Ni)
            error.append(sN.get_power() / s1.get_power())

        if plot:
            plt.figure(fig_prefix+'Rescaling mole fractions')
            plt.plot(N, error, '-ok')
            plt.scatter(N[0], error[0], s=200, facecolors='none',
                        edgecolors='r', label='reference')
            plt.xlabel('Mole fraction')
            plt.ylabel('scaled energy / ab initio energy')
            plt.xscale('log')
            plt.legend()
            plt.title('Effect of scaling mole fraction w/o lineshape update')
            plt.tight_layout()

        # less than 1% error when rescaling from 1e-3 to 0.6
        assert abs(error[-2]-1) < 0.01

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
Exemple #12
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
Exemple #13
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
Exemple #14
0
def test_wavenumber_units_conversion(
    input_wavenumbers, expected_wavenumbers_cm1, verbose=True, *args, **kwargs
):
    setup_test_line_databases()  # add HITRAN-CO-TEST in ~/.radis if not there

    wmin, wmax = input_wavenumbers
    expected_wmin, expected_wmax = expected_wavenumbers_cm1
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        wstep=0.01,
        cutoff=1e-30,
        pressure=1,
        path_length=1,
        mole_fraction=1,
        isotope=[1],
        verbose=verbose,
    )
    sf.load_databank("HITRAN-CO-TEST")
    s = sf.eq_spectrum(Tgas=300)
    assert np.isclose(s.get_wavenumber().min(), expected_wmin)
    assert np.isclose(s.get_wavenumber().max(), expected_wmax)
Exemple #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,
    )
Exemple #16
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
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
Exemple #18
0
def _test(verbose=True, plot=False, *args, **kwargs):
    """ Generate scalable LevelList at 1500K. Rescale at 2000K and compare with
    spectrum directly calculated at 2000K 
    """

    from radis.lbl import SpectrumFactory

    iso = 1
    sf = SpectrumFactory(
        wavelength_min=4170,
        wavelength_max=4200,
        mole_fraction=1,
        path_length=0.05,
        cutoff=1e-25,
        #                     isotope=[1,2],
        isotope=iso,
        db_use_cached=True,
        wstep=0.01,
        broadening_max_width=10,
        medium="air",
        verbose=verbose,
    )

    sf.load_databank("CDSD")

    parfunc = sf.parsum_calc["CO2"][iso]["X"]

    # %% Fill levels for all bands

    Tref = 1500
    s_bands = sf.non_eq_bands(Tvib=Tref, Trot=Tref)
    lvlist = LevelsList(parfunc, s_bands, sf.params.levelsfmt)

    # %% Test
    Tvib = 2000
    s_resc = lvlist.non_eq_spectrum(Tvib=Tvib, Trot=Tref)
    s0 = sf.non_eq_spectrum(Tvib, Tref)

    return s0.compare_with(s_resc, spectra_only=True, plot=plot)
Exemple #19
0
def test_plot_all_CO2_bandheads(verbose=True, plot=False, *args, **kwargs):
    ''' In this test we use the :meth:`~radis.lbl.bands.BandFactory.non_eq_bands`
    method to calculate separately all vibrational bands of CO2, and compare
    them with the final Spectrum. 

    '''

    # Note: only with iso1 at the moment

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

    verbose = True
    Tgas = 1000

    sf = SpectrumFactory(wavelength_min=4160,
                         wavelength_max=4220,
                         mole_fraction=1,
                         path_length=0.3,
                         cutoff=1e-23,
                         molecule='CO2',
                         isotope=1,
                         db_use_cached=True,
                         lvl_use_cached=True,
                         verbose=verbose)
    sf.warnings['MissingSelfBroadeningWarning'] = 'ignore'
    sf.warnings['NegativeEnergiesWarning'] = 'ignore'
    sf.warnings['HighTemperatureWarning'] = 'ignore'
    sf.fetch_databank()

    s_tot = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas)
    s_bands = sf.non_eq_bands(Tvib=Tgas, Trot=Tgas)

    if verbose:
        printm('{0} bands in spectrum'.format(len(s_bands)))

    assert len(s_bands) == 6

    # Ensure that recombining gives the same
    s_merged = MergeSlabs(*list(s_bands.values()))
    assert s_tot.compare_with(s_merged, 'radiance_noslit', plot=False)

    if verbose:
        printm('Recombining bands give the same Spectrum')

    # %%
    if plot:
        s_tot.apply_slit(1, 'nm')
        s_tot.name = 'Full spectrum'
        s_tot.plot(wunit='nm', lw=3)
        for band, s in s_bands.items():
            s.plot(wunit='nm', nfig='same')
        plt.legend(loc='upper left')
        plt.ylim(ymax=0.25)

    # %% Compare with equilibrium bands now
    s_bands_eq = sf.eq_bands(Tgas)
    s_merged_eq = MergeSlabs(*list(s_bands_eq.values()))

    assert get_residual(s_tot, s_merged_eq, 'radiance_noslit') < 1e-5

    return True
Exemple #20
0
def test_retrieve_from_database(plot=True,
                                verbose=True,
                                warnings=True,
                                *args,
                                **kwargs):
    """Test autoretrieve from a database:

    first generate an empty :py:class:`~radis.tools.database.SpecDatabase`
    associated to a :py:class`~radis.lbl.factory.SpectrumFactory`,
    then calculate a first spectrum, then calculate it again and make sure
    it is retrieved from the database
    """

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

    temp_database_name = "temp_spec_database"

    try:
        if verbose:
            printm(">>> test_retrieve_from_database")

        assert not exists(temp_database_name)

        setup_test_line_databases(
        )  # add HITEMP-CO2-TEST in ~/.radis if not there

        sf = SpectrumFactory(
            2284.2,
            2284.6,
            wstep=0.001,  # cm-1
            pressure=20 * 1e-3,  # bar
            cutoff=0,
            path_length=0.1,
            mole_fraction=400e-6,
            molecule="CO2",
            isotope=[1],
            db_use_cached=True,
            medium="vacuum",
            broadening_max_width=10,
            export_populations="rovib",
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        sf.init_databank(
            "HITEMP-CO2-TEST"
        )  # unlike load_databank, will automatically be built when needed
        db = sf.init_database(temp_database_name, autoretrieve=True)

        assert len(db) == 0

        # Calculate a first spectrum
        s1 = sf.non_eq_spectrum(2000, 1000)

        assert len(db) == 1
        # Note that the Spectrum in database is not s1 because populations
        # are not stored by default

        # hack: now change the `autoretrieve` status to `force` to make sure
        # the spectrum is retrieved. Else, an error will be raised
        sf.autoretrievedatabase = "force"

        # Calculate spectrum under the same conditions
        s2 = sf.non_eq_spectrum(2000, 1000)

        # Note that s1 == s2 won't work because populations are not stored
        # by default in the database
        assert s1.compare_with(s2, spectra_only=True)

        return True

    finally:
        rmtree(temp_database_name)
Exemple #21
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
Exemple #22
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
Exemple #23
0
def test_medium(plot=False, verbose=True, debug=False, warnings=True, *args, **kwargs):
    ''' Test effect of propagating medium '''

    from radis.lbl.factory import SpectrumFactory

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

    T = 300

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

        pl = SpectrumFactory(
            wavenum_min=2171.5,
            wavenum_max=2174,
            mole_fraction=0.01,
            medium='vacuum',
            isotope='1,2')
        pl.warnings['MissingSelfBroadeningWarning'] = 'ignore'
        pl.load_databank('HITRAN-CO-TEST')
        s = pl.non_eq_spectrum(Tvib=T, Trot=T)  # , Ttrans=300)

        pla = SpectrumFactory(
            wavenum_min=2171.5,
            wavenum_max=2174,
            mole_fraction=0.01,
            medium='air',
            isotope='1,2')
        pla.load_databank('HITRAN-CO-TEST')
        s_air = pla.non_eq_spectrum(Tvib=T, Trot=T)  # , Ttrans=300)

        if plot:
            plt.figure(fig_prefix+'Propagating medium conversions')
            s.plot(nfig='same', lw=3, medium='vacuum', label='vacuum')
            s.plot(nfig='same', medium='air', label='air')

        assert np.allclose(s.get_wavenumber(), s_air.get_wavenumber())
        assert np.allclose(s.get_wavelength(medium='vacuum'),
                           s_air.get_wavelength(medium='vacuum'))
        assert np.allclose(s.get_wavelength(medium='air'),
                           s_air.get_wavelength(medium='air'))
        assert all(s.get_wavelength(medium='vacuum')
                   > s.get_wavelength(medium='air'))

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
Exemple #24
0
def test_3Tvib_vs_1Tvib(verbose=True,
                        plot=False,
                        warnings=True,
                        *args,
                        **kwargs):

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

    setup_test_line_databases()

    try:
        T = 1500

        iso = [1]
        sf = SpectrumFactory(
            wavenum_min=2380,
            wavenum_max=2400,
            pressure=20 * 1e-3,
            db_use_cached=True,
            cutoff=1e-25,
            isotope=iso,  # ,2',
            path_length=10,
            mole_fraction=0.1,
            broadening_max_width=1,
            medium="vacuum",
            verbose=verbose,
        )
        sf.warnings.update({
            "MissingSelfBroadeningWarning": "ignore",
            "VoigtBroadeningWarning": "ignore",
        })
        sf.load_databank("HITRAN-CO2-TEST")

        # Compare energies
        for I in iso:
            energies = sf.get_energy_levels("CO2", I, "X")
            assert (energies.Evib == energies.Evib1 + energies.Evib2 +
                    energies.Evib3).all()
        if verbose:
            printm("Tested Evib == Evib1+Evib2+Evib3: OK")

        s3 = sf.non_eq_spectrum((T, T, T), T)
        s1 = sf.non_eq_spectrum(T, T)
        s3.name = "Tvib=({0},{0},{0}) K, Trot={0} K".format(T)
        s1.name = "Tvib={0} K, Trot={0} K".format(T)

        if plot:
            s1.plot(
                "transmittance_noslit",
                wunit="cm-1",
                color="k",
                lw=3,
                label="Tvib = {0}K".format(T),
            )

            s3.plot(
                "transmittance_noslit",
                wunit="cm-1",
                color="r",
                lw=3,
                nfig="same",
                label="Tvib1 = Tvib2 = Tvib3 = {0}K".format(T),
            )

        assert s1.compare_with(s3,
                               spectra_only=True,
                               verbose=verbose,
                               plot=plot)
        if verbose:
            printm(
                "Tested Spectra 3Tvib(T1=T2=T3=T) and 1Tvib(T) are the same: OK"
            )

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
Exemple #25
0
def test_direct_overpopulation_vs_recombined_bands(verbose=True,
                                                   plot=False,
                                                   warnings=True,
                                                   rtol=0.05,
                                                   *args,
                                                   **kwargs):
    """ Compare a non-equilibrium spectrum calculated directly with overpopulations, 
    or by recombining pre-calculated vibrational bands. 

    The later allows for almost instantaneous changes of the overpopulation factors, 
    (mostly useful in fitting algorithms), but is only valid for optically thin emission spectra

    Expected output:

    when x_CO2 = 1e-3, radiance in both cases match
    when x_CO2 = 1, they dont

    """

    #    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]_
    #

    # Note: only with iso1 at the moment

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

    try:

        # Generate factory
        iso = 1
        sf = SpectrumFactory(
            wavelength_min=4220,
            wavelength_max=4280,
            mole_fraction=1e-3,
            path_length=10,
            cutoff=1e-25,
            molecule="CO2",
            isotope=iso,
            db_use_cached=True,
            wstep=0.01,
            broadening_max_width=5,
            medium="air",
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        sf.warnings["NegativeEnergiesWarning"] = "ignore"
        sf.load_databank("CDSD-HITEMP-PCN")
        #        sf.fetch_databank()   # uses HITRAN: not really valid at this temperature, but runs on all machines without install

        # Generate bands to recombine
        parfunc = sf.parsum_calc["CO2"][iso]["X"]
        Tref = 1500
        # , return_lines=False)
        s_bands = sf.non_eq_bands(Tvib=Tref, Trot=Tref)
        lvlist = LevelsList(parfunc, s_bands, sf.params.levelsfmt)

        # Compare ab initio and recombined from bands at M = 1e-3
        s_recombined = lvlist.non_eq_spectrum(Tvib=Tref,
                                              Trot=Tref,
                                              overpopulation={"(4,1,3)": 3})
        sref = sf.non_eq_spectrum(Tvib=Tref,
                                  Trot=Tref,
                                  overpopulation={"(4,1,3)": 1})

        if verbose:
            printm(
                "Testing x_CO2 = 1e-3: ab initio ~ recombined bands (<{0:.1f}%):\t"
                .format(rtol * 100))

        if plot:
            plot_diff(
                sref,
                s_recombined,
                var="radiance_noslit",
                label1="ab initio",
                label2="recombined bands",
                title="x_CO2 = 1e-3",
            )

        assert np.allclose(s_recombined.get_radiance_noslit(),
                           sref.get_radiance_noslit(),
                           rtol=rtol)

        # Rescale and try again for x_CO2 = 1
        s_recombined.rescale_mole_fraction(1)
        sref.rescale_mole_fraction(1)

        if plot:
            plot_diff(
                sref,
                s_recombined,
                var="radiance_noslit",
                label1="ab initio",
                label2="recombined bands",
                title="x_CO2 = 1",
            )

        if verbose:
            printm(
                "Testing x_CO2 = 1: ab initio ~ recombined bands (<{0:.1f}%):\t{1}"
                .format(
                    rtol * 100,
                    np.allclose(
                        s_recombined.get_radiance_noslit(),
                        sref.get_radiance_noslit(),
                        rtol=rtol,
                    ),
                ))

        with pytest.raises(AssertionError):
            assert np.allclose(
                s_recombined.get_radiance_noslit(),
                sref.get_radiance_noslit(),
                rtol=rtol,
            )

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
Exemple #26
0
def test_plot_all_CO2_bandheads(verbose=True, plot=False, *args, **kwargs):
    """In this test we use the :meth:`~radis.lbl.bands.BandFactory.non_eq_bands`
    method to calculate separately all vibrational bands of CO2, and compare
    them with the final Spectrum.

    """

    # Note: only with iso1 at the moment

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

    Tgas = 1000

    sf = SpectrumFactory(
        wavelength_min=4160,
        wavelength_max=4220,
        mole_fraction=1,
        path_length=0.3,
        cutoff=1e-23,
        molecule="CO2",
        isotope=1,
        optimization=None,
        verbose=verbose,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.warnings["NegativeEnergiesWarning"] = "ignore"
    sf.warnings["HighTemperatureWarning"] = "ignore"
    sf.fetch_databank("hitran")

    s_tot = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas)
    s_bands = sf.non_eq_bands(Tvib=Tgas, Trot=Tgas)

    if verbose:
        printm("{0} bands in spectrum".format(len(s_bands)))

    assert len(s_bands) == 6

    # Ensure that recombining gives the same
    s_merged = MergeSlabs(*list(s_bands.values()))
    assert s_tot.compare_with(s_merged, "radiance_noslit", plot=False)

    if verbose:
        printm("Recombining bands give the same Spectrum")

    # %%
    if plot:
        s_tot.apply_slit(1, "nm")
        s_tot.name = "Full spectrum"
        s_tot.plot(wunit="nm", lw=3)
        for band, s in s_bands.items():
            s.plot(wunit="nm", nfig="same")
        plt.legend(loc="upper left")
        plt.ylim(ymax=0.25)

    # %% Compare with equilibrium bands now
    s_bands_eq = sf.eq_bands(Tgas)
    s_merged_eq = MergeSlabs(*list(s_bands_eq.values()))

    assert get_residual(s_tot, s_merged_eq, "radiance_noslit") < 1.5e-5

    return True
Exemple #27
0
def test_medium(plot=False, verbose=True, debug=False, warnings=True, *args, **kwargs):
    """ Test effect of propagating medium """

    from radis.lbl.factory import SpectrumFactory

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

    T = 300

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

    pl = SpectrumFactory(
        wavenum_min=2171.5,
        wavenum_max=2174,
        mole_fraction=0.01,
        medium="vacuum",
        isotope="1,2",
    )
    pl.warnings["MissingSelfBroadeningWarning"] = "ignore"
    pl.load_databank("HITRAN-CO-TEST")
    s = pl.non_eq_spectrum(Tvib=T, Trot=T)  # , Ttrans=300)

    pla = SpectrumFactory(
        wavenum_min=2171.5,
        wavenum_max=2174,
        mole_fraction=0.01,
        medium="air",
        isotope="1,2",
    )
    pla.load_databank("HITRAN-CO-TEST")
    s_air = pla.non_eq_spectrum(Tvib=T, Trot=T)  # , Ttrans=300)

    if plot:
        plt.figure(fig_prefix + "Propagating medium conversions")
        s.plot(wunit="nm_vac", nfig="same", lw=3, label="vacuum")
        s.plot(wunit="nm", nfig="same", label="air")

    assert np.allclose(s.get_wavenumber(), s_air.get_wavenumber())
    assert np.allclose(
        s.get_wavelength(medium="vacuum"), s_air.get_wavelength(medium="vacuum")
    )
    assert np.allclose(
        s.get_wavelength(medium="air"), s_air.get_wavelength(medium="air")
    )
    assert all(s.get_wavelength(medium="vacuum") > s.get_wavelength(medium="air"))
Exemple #28
0
def test_populations_CO2_hamiltonian(
    plot=True, verbose=True, warnings=True, *args, **kwargs
):
    """Calculate nonequilibrium modes with the CO2 Hamiltonian

    ..warning::

        as we only use a reduced set of the CO2 effective Hamiltonian (< 3000 cm-1),
        many levels of the Line Database will not appear in the Levels Database.
        We will need to either filter the Line Database beforehand, or run it
        a first time and remove all levels not found.

        This database is obviously not to be used in a Production code!

    """

    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(
        wavenum_min=2283.7,
        wavenum_max=2285.1,
        wstep=0.001,
        cutoff=1e-30,
        path_length=0.1,
        mole_fraction=400e-6,
        isotope=[1],
        medium="vacuum",
        broadening_max_width=10,
        export_populations="rovib",
        verbose=verbose,
    )
    sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
    sf.load_databank("HITEMP-CO2-HAMIL-TEST")

    # First run a calculation at equilibrium
    s = sf.eq_spectrum(300)
    s.name = "equilibrium"

    # 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 (see error in docstrings of the function).
    with pytest.raises(AssertionError):
        sf.non_eq_spectrum(300, 300)

    sf.df0.dropna(inplace=True)

    # Retry:
    s_noneq = sf.non_eq_spectrum(300, 300)
    s_noneq.name = "nonequilibrium"

    # Tests:

    #    s.compare_with(s_noneq, plot=plot)
    assert s_noneq.get_power() > 0
    # TODO: implement actual Assertions (right now we're just checking that
    # functions are properly parsed)

    # TODO. Fix below (and move in dedicated test):
    #    s.line_survey()

    return True
Exemple #29
0
def test_populations(plot=True, 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,
            export_populations="rovib",
            verbose=verbose,
        )
        sf.warnings["MissingSelfBroadeningWarning"] = "ignore"
        sf.load_databank("HITRAN-CO-TEST")

        # Populations cannot be calculated at equilibrium (no access to energy levels)
        s = sf.eq_spectrum(300)
        with pytest.raises(ValueError):  # .. we expect this error here!
            pops = s.get_populations("CO", isotope=1, electronic_state="X")

        # Calculate populations using the non-equilibrium module:
        s = sf.non_eq_spectrum(300, 300)
        pops = s.get_populations("CO", isotope=1, electronic_state="X")
        if not "n" in list(pops["rovib"].keys()):
            raise ValueError("Populations not calculated")
        if plot:
            s.plot_populations()

        # Compare with factory
        # Plot populations:
        with pytest.raises(ValueError):
            sf.plot_populations()  # no isotope given: error expected
        if plot:
            sf.plot_populations("rovib", isotope=1)
            plt.close()  # no need to keep it open, we just tested the function

        # Test calculated quantities are there
        assert hasattr(sf.df1, "Qref")
        assert hasattr(sf.df1, "Qvib")
        assert hasattr(sf.df1, "Qrotu")
        assert hasattr(sf.df1, "Qrotl")

        # Test hardcoded populations
        assert np.isclose(pops["rovib"]["n"].iloc[0], 0.0091853446840826653)
        assert np.isclose(pops["rovib"]["n"].iloc[1], 0.027052543988733215)
        assert np.isclose(pops["rovib"]["n"].iloc[2], 0.04345502115897712)

        return True

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
Exemple #30
0
def test_optically_thick_limit_1iso(verbose=True, plot=True, *args, **kwargs):
    """ Test that we find Planck in the optically thick limit 
    
    In particular, this test will fail if :
        
    - linestrength are not properly calculated
    
    - at noneq, linestrength and emission integrals are mixed up
    
    The test should be run for 1 and several isotopes, because different
    calculations paths are used internally, and this can lead to different
    errors.
    
    Also, this test is used to run with DEBUG_MODE = True, which will 
    check that isotopes and molecule ids are what we expect in all the 
    groupby() loops that make the production code very fast. 
    
    Notes
    -----
    
    switched from large band calculation with [HITRAN-2016]_ to a calculation with 
    the embedded [HITEMP-2010]_ fragment (shorter range, but no need to download files)
    
    """

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

    # Force DEBUG_MODE
    DEBUG_MODE = radis.DEBUG_MODE
    radis.DEBUG_MODE = True

    try:

        wavenum_min = 2284.2
        wavenum_max = 2284.6

        P = 0.017  # bar
        wstep = 0.001  # cm-1

        Tgas = 1200

        # %% Generate some CO2 emission spectra
        # --------------
        sf = SpectrumFactory(
            wavenum_min=wavenum_min,
            wavenum_max=wavenum_max,
            molecule="CO2",
            mole_fraction=1,
            path_length=0.05,
            cutoff=1e-25,
            broadening_max_width=1,
            export_populations=False,  #'vib',
            export_lines=False,
            isotope=1,
            use_cached=True,
            wstep=wstep,
            pseudo_continuum_threshold=0,
            pressure=P,
            verbose=False,
        )
        #        sf.fetch_databank('astroquery')
        sf.warnings["NegativeEnergiesWarning"] = "ignore"
        sf.load_databank("HITEMP-CO2-TEST")
        pb = ProgressBar(3, active=verbose)
        s_eq = sf.eq_spectrum(Tgas=Tgas, mole_fraction=1, name="Equilibrium")
        pb.update(1)
        s_2T = sf.non_eq_spectrum(Tvib=Tgas,
                                  Trot=Tgas,
                                  mole_fraction=1,
                                  name="Noneq (2T)")
        pb.update(2)
        s_4T = sf.non_eq_spectrum(Tvib=(Tgas, Tgas, Tgas),
                                  Trot=Tgas,
                                  mole_fraction=1,
                                  name="Noneq (4T)")
        pb.update(3)
        s_plck = sPlanck(
            wavelength_min=2000,  # =wavelength_min,
            wavelength_max=
            5000,  # =wavelength_max - wstep,   # there is a border effect on last point
            T=Tgas,
        )
        pb.done()

        # %% Post process:
        # MAke optically thick, and compare with Planck

        for s in [s_eq, s_2T, s_4T]:

            s.rescale_path_length(1e6)

            if plot:

                nfig = "test_opt_thick_limit_1iso {0}".format(s.name)
                plt.figure(nfig).clear()
                s.plot(wunit="nm", nfig=nfig, lw=4)
                s_plck.plot(wunit="nm", nfig=nfig, Iunit="mW/cm2/sr/nm", lw=2)
                plt.legend()

            if verbose:
                printm(
                    "Residual between opt. thick CO2 spectrum ({0}) and Planck: {1:.2g}"
                    .format(
                        s.name,
                        get_residual(s,
                                     s_plck,
                                     "radiance_noslit",
                                     ignore_nan=True),
                    ))

            #            assert get_residual(s, s_plck, 'radiance_noslit', ignore_nan=True) < 1e-3
            assert get_residual(s, s_plck, "radiance_noslit",
                                ignore_nan=True) < 0.9e-4

        if verbose:
            printm("Tested optically thick limit is Planck (1 isotope): OK")

    finally:
        # Reset DEBUG_MODE
        radis.DEBUG_MODE = DEBUG_MODE