def test_broadening_DLM_noneq(verbose=True, plot=False, *args, **kwargs):
    '''
    Test Noneq version of DLM and makes sure it gives the same results as the eq
    one when used with Tvib=Trot 
    
    '''

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

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

    # Conditions
    p = 1
    wstep = 0.002
    wmin = 2380  # cm-1
    wmax = 2400  # cm-1
    broadening_max_width = 10  # cm-1

    # %% Calculate with RADIS
    # ----------
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=1,
        path_length=1,   # doesnt change anything
        wstep=wstep,
        pressure=p,
        broadening_max_width=broadening_max_width,
        isotope='1',
        verbose=3,
        warnings={'MissingSelfBroadeningWarning':'ignore',
                  'NegativeEnergiesWarning':'ignore',
                  'HighTemperatureWarning':'ignore',
                  'GaussianBroadeningWarning':'ignore'}
        )  # 0.2)
    sf.load_databank('HITRAN-CO2-TEST')
    
    # DLM:
    sf.misc['chunksize'] = 'DLM'
    s_dlm_eq = sf.eq_spectrum(Tgas=3000)
    s_dlm_eq.name = 'DLM eq ({0:.2f}s)'.format(s_dlm_eq.conditions['calculation_time'])
    
    s_dlm_noneq = sf.non_eq_spectrum(Tvib=3000, Trot=3000)
    s_dlm_noneq.name = 'DLM noneq ({0:.2f}s)'.format(s_dlm_noneq.conditions['calculation_time'])
    
    # Compare
    res = get_residual(s_dlm_eq, s_dlm_noneq, 'radiance_noslit')
    
    if verbose:
        print('Residual:', res)

    # plot
    if plot:
        plot_diff(s_dlm_eq, s_dlm_noneq)
    
    assert res <= 4e-5 
def test_broadening_methods_different_wstep(verbose=True, plot=False, *args, **kwargs):
    '''
    Test direct Voigt broadening vs convolution of Gaussian x Lorentzian
    for different spectral grid resolution
    '''

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

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

    # Conditions
    T = 3000
    p = 1
    wmin = 2150  # cm-1
    wmax = 2152  # cm-1
    broadening_max_width = 10  # cm-1
    
    for i, wstep in enumerate([0.01, 0.1, 0.5]):

        # %% Calculate with RADIS
        # ----------
        sf = SpectrumFactory(
            wavenum_min=wmin,
            wavenum_max=wmax,
            mole_fraction=1,
            path_length=1,   # doesnt change anything
            wstep=wstep,
            pressure=p,
            broadening_max_width=broadening_max_width,
            isotope='1',
            verbose=False,
            warnings={'MissingSelfBroadeningWarning':'ignore',
                      'NegativeEnergiesWarning':'ignore',
                      'HighTemperatureWarning':'ignore',
                      'GaussianBroadeningWarning':'ignore'}
            )  # 0.2)
        sf.load_databank('HITRAN-CO-TEST')
    #    s = pl.non_eq_spectrum(Tvib=T, Trot=T, Ttrans=T)
        sf._broadening_method = 'voigt'
        s_voigt = sf.eq_spectrum(Tgas=T, name='direct')
        
        sf._broadening_method = 'convolve'
        s_convolve = sf.eq_spectrum(Tgas=T, name='convolve')
    
        res = get_residual(s_voigt, s_convolve, 'abscoeff')
        
        if verbose:
            print('Residual:', res)

        # plot the last one    
        if plot:
            plot_diff(s_voigt, s_convolve, 'abscoeff', nfig='test_voigt_broadening_methods'+str(i),
                      title='P {0} bar, T {1} K, wstep {2} cm-1'.format(p, T, wstep))
        
        assert res < 2e-4
示例#3
0
def test_visualTestBaseline(plot=True, *args, **kwargs):

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

    s2 = sub_baseline(s, 2e-4, -2e-4, name='sub_arb_baseline')
    if plot:
        plot_diff(s, s2)
示例#4
0
def test_offset(plot=True):

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

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

    # Test inplace version
    s.offset(10, 'nm')
    assert np.allclose(s2.get_wavelength(which='convoluted'),
                       s.get_wavelength(which='convoluted'))
示例#5
0
def test_broadening_methods_different_wstep(verbose=True,
                                            plot=False,
                                            *args,
                                            **kwargs):
    """
    Test direct Voigt broadening vs convolution of Gaussian x Lorentzian
    for different spectral grid resolution
    """

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

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

    # Conditions
    T = 3000
    p = 1
    wmin = 2150  # cm-1
    wmax = 2152  # cm-1
    broadening_max_width = 10  # cm-1

    for i, wstep in enumerate([0.01, 0.1, 0.5]):

        # %% Calculate with RADIS
        # ----------
        sf = SpectrumFactory(
            wavenum_min=wmin,
            wavenum_max=wmax,
            mole_fraction=1,
            path_length=1,  # doesnt change anything
            wstep=wstep,
            pressure=p,
            broadening_max_width=broadening_max_width,
            isotope="1",
            optimization=None,
            verbose=False,
            warnings={
                "MissingSelfBroadeningWarning": "ignore",
                "NegativeEnergiesWarning": "ignore",
                "HighTemperatureWarning": "ignore",
                "GaussianBroadeningWarning": "ignore",
                "AccuracyError": "ignore",
                "AccuracyWarning": "ignore",
            },
        )  # 0.2)
        sf.load_databank("HITRAN-CO-TEST")
        #    s = pl.non_eq_spectrum(Tvib=T, Trot=T, Ttrans=T)
        sf.params.broadening_method = "voigt"
        s_voigt = sf.eq_spectrum(Tgas=T, name="direct")

        sf.params.broadening_method = "convolve"
        s_convolve = sf.eq_spectrum(Tgas=T, name="convolve")

        res = get_residual(s_voigt, s_convolve, "abscoeff")

        if verbose:
            print("Residual:", res)

        # plot the last one
        if plot:
            plot_diff(
                s_voigt,
                s_convolve,
                "abscoeff",
                nfig="test_voigt_broadening_methods" + str(i),
                title="P {0} bar, T {1} K, wstep {2} cm-1".format(p, T, wstep),
            )

        assert res < 2e-4
示例#6
0
def test_broadening_methods_different_conditions(verbose=True,
                                                 plot=False,
                                                 *args,
                                                 **kwargs):
    """
    Test direct Voigt broadening vs convolution of Gaussian x Lorentzian
    for different spectral grid resolution

    Notes
    -----

    Reference broadening calculated manually with the HWHM formula of
    `HITRAN.org <https://hitran.org/docs/definitions-and-units/>`_
    """

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

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

    # Conditions
    wstep = 0.005
    wmin = 2150.4  # cm-1
    wmax = 2151.4  # cm-1
    broadening_max_width = 2  # cm-1

    for (T, p, fwhm_lorentz, fwhm_gauss) in [
            # K, bar, expected FWHM for Lotentz, gauss (cm-1)
        (3000, 1, 0.02849411, 0.01594728),
        (300, 1, 0.16023415, 0.00504297),
        (3000, 0.01, 0.00028494, 0.01594728),
    ]:

        # %% Calculate with RADIS
        # ----------
        sf = SpectrumFactory(
            wavenum_min=wmin,
            wavenum_max=wmax,
            mole_fraction=1,
            path_length=1,  # doesnt change anything
            wstep=wstep,
            pressure=p,
            broadening_max_width=broadening_max_width,
            isotope="1",
            verbose=False,
            warnings={
                "MissingSelfBroadeningWarning": "ignore",
                "NegativeEnergiesWarning": "ignore",
                "HighTemperatureWarning": "ignore",
                "OutOfRangeLinesWarning": "ignore",
                "GaussianBroadeningWarning": "ignore",
                "CollisionalBroadeningWarning": "ignore",
            },
        )
        sf.load_databank("HITRAN-CO-TEST")
        # Manually filter line database, keep one line only:
        sf.df0.drop(sf.df0[sf.df0.vu != 1].index, inplace=True)
        assert isclose(sf.df0.wav, 2150.856008)

        # Calculate spectra (different broadening methods)
        sf.params.broadening_method = "voigt"
        s_voigt = sf.eq_spectrum(Tgas=T, name="direct")

        # assert broadening FWHM are correct
        assert isclose(2 * float(sf.df1.hwhm_gauss), fwhm_gauss)
        assert isclose(2 * float(sf.df1.hwhm_lorentz), fwhm_lorentz)

        sf.params.broadening_method = "convolve"
        s_convolve = sf.eq_spectrum(Tgas=T, name="convolve")

        # assert broadening FWHM are correct
        assert isclose(2 * float(sf.df1.hwhm_gauss), fwhm_gauss)
        assert isclose(2 * float(sf.df1.hwhm_lorentz), fwhm_lorentz)

        res = get_residual(s_voigt, s_convolve, "abscoeff")

        if verbose:
            print(
                "{0} K, {1} bar: FWHM lorentz = {2:.3f} cm-1, FWHM gauss = {3:.3f} cm-1"
                .format(T, p, 2 * float(sf.df1.hwhm_lorentz),
                        2 * float(sf.df1.hwhm_gauss)))

        if plot:
            plot_diff(
                s_voigt,
                s_convolve,
                "abscoeff",
                title=
                r"T {0} K, p {1} bar: w$_\mathrm{{L}}$ {2:.3f}, w$_\mathrm{{G}}$ {3:.3f} cm$^{{-1}}$"
                .format(T, p, 2 * float(sf.df1.hwhm_lorentz),
                        float(sf.df1.hwhm_gauss)),
            )

        # assert all broadening methods match
        assert res < 2e-4
示例#7
0
def test_noneq_continuum(plot=False,
                         verbose=2,
                         warnings=True,
                         *args,
                         **kwargs):
    ''' 
    Test calculation with pseudo-continuum under nonequilibrium

    Assert results on emisscoeff dont change

    
    Notes
    -----
    
    Uses HITRAN so it can deployed and tested on [Travis]_, but we should switch
    to HITEMP if some HITEMP files can be downloaded automatically at the 
    execution time. 

    '''

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

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

        sf = SpectrumFactory(wavelength_min=4200,
                             wavelength_max=4500,
                             parallel=False,
                             bplot=False,
                             cutoff=1e-23,
                             molecule='CO2',
                             isotope='1,2',
                             db_use_cached=True,
                             broadening_max_width=10,
                             path_length=0.1,
                             mole_fraction=1e-3,
                             medium='vacuum',
                             verbose=verbose)
        sf.warnings.update({
            'MissingSelfBroadeningWarning': 'ignore',
            'NegativeEnergiesWarning': 'ignore',
            'LinestrengthCutoffWarning': 'ignore',
            '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')       # to take a real advantage of abscoeff continuum, should calculate with HITEMP
        sf._export_continuum = True  # activate it

        # Calculate one without pseudo-continuum
        sf.params.pseudo_continuum_threshold = 0
        s1 = sf.non_eq_spectrum(Tvib=2000, Trot=1000)
        s1.name = 'All lines resolved ({0}) ({1:.1f}s)'.format(
            s1.conditions['lines_calculated'],
            s1.conditions['calculation_time'])
        assert s1.conditions['pseudo_continuum_threshold'] == 0

        # Calculate one with pseudo-continuum
        sf.params.pseudo_continuum_threshold = 0.05
        s2 = sf.non_eq_spectrum(Tvib=2000, Trot=1000)
        s2.name = 'Semi-continuum + {0} lines ({1:.1f}s)'.format(
            s2.conditions['lines_calculated'],
            s2.conditions['calculation_time'])
        assert s2.conditions['pseudo_continuum_threshold'] == 0.05
        assert 'abscoeff_continuum' in s2.get_vars()
        assert 'emisscoeff_continuum' in s2.get_vars()

        # Plot
        if plot:
            plot_diff(s1,
                      s2,
                      'radiance_noslit',
                      Iunit='µW/cm2/sr/nm',
                      nfig='test_noneq_continuum: diff')

            s2.plot('emisscoeff',
                    label=s2.name,
                    nfig='test_noneq_continuum: show continuum')
            s2.plot('emisscoeff_continuum',
                    nfig='same',
                    label='Pseudo-continuum (aggreg. {0:g} lines)'.format(
                        s2.conditions['lines_in_continuum']),
                    force=True)

        # Compare
        res = get_residual(s1, s2, 'abscoeff') + get_residual(
            s1, s2, 'emisscoeff')
        if verbose:
            printm('residual:', res)

        assert res < 5e-6

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
示例#8
0
def test_broadening(rtol=1e-2, verbose=True, plot=False, *args, **kwargs):
    '''
    Test broadening against HAPI and tabulated data

    We're looking at CO(0->1) line 'R1' at 2150.86 cm-1
    '''
    from radis.io.hapi import db_begin, fetch, tableList, absorptionCoefficient_Voigt

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

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

    # Conditions
    T = 3000
    p = 0.0001
    wstep = 0.001
    wmin = 2150  # cm-1
    wmax = 2152  # cm-1
    broadening_max_width = 10  # cm-1

    # %% HITRAN calculation
    # -----------

    # Generate HAPI database locally
    db_begin(join(dirname(__file__), __file__.replace('.py', '_HAPIdata')))
    if not 'CO' in tableList():  # only if data not downloaded already
        fetch('CO', 5, 1, wmin - broadening_max_width / 2,
              wmax + broadening_max_width / 2)
        # HAPI doesnt correct for side effects

    # Calculate with HAPI
    nu, coef = absorptionCoefficient_Voigt(
        SourceTables='CO',
        Environment={
            'T': T,  # K
            'p': p / 1.01325,  # atm
        },
        WavenumberStep=wstep,
        HITRAN_units=False)

    s_hapi = Spectrum.from_array(nu,
                                 coef,
                                 'abscoeff',
                                 'cm-1',
                                 'cm_1',
                                 conditions={'Tgas': T},
                                 name='HAPI')

    # %% Calculate with RADIS
    # ----------
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=1,
        path_length=1,  # doesnt change anything
        wstep=wstep,
        pressure=p,
        broadening_max_width=broadening_max_width,
        isotope=[1],
        warnings={
            'MissingSelfBroadeningWarning': 'ignore',
            'NegativeEnergiesWarning': 'ignore',
            'HighTemperatureWarning': 'ignore',
            'GaussianBroadeningWarning': 'ignore'
        })  # 0.2)
    sf.load_databank('HITRAN-CO-TEST')
    #    s = pl.non_eq_spectrum(Tvib=T, Trot=T, Ttrans=T)
    s = sf.eq_spectrum(Tgas=T, name='RADIS')

    if plot:  # plot broadening of line of largest linestrength
        sf.plot_broadening(i=sf.df1.S.idxmax())

    # Plot and compare
    res = abs(get_residual_integral(s, s_hapi, 'abscoeff'))
    if plot:
        plot_diff(s,
                  s_hapi,
                  var='abscoeff',
                  title='{0} bar, {1} K (residual {2:.2g}%)'.format(
                      p, T, res * 100),
                  show_points=False)
        plt.xlim((wmin, wmax))
    if verbose:
        printm('residual:', res)
    assert res < rtol
示例#9
0
            SourceTables=molecule,
            Environment={
                "T": T,
                "p": pressure_bar / 1.01315,
            },  # K  # atm
            GammaL="gamma_self",
            WavenumberStep=dnu,
            HITRAN_units=False,
        )
        return nu, coef

    t0 = time()
    nu, coef = calc_hapi()
    t0 = time() - t0
    print(("Calculated with HAPI in {0:.2f}s".format(t0)))

    s_hapi = Spectrum.from_array(nu,
                                 coef,
                                 "abscoeff",
                                 waveunit="cm-1",
                                 unit="cm-1")
    s_hapi.name = "HAPI ({0:.1f}s)".format(t0)

    plot_diff(s_hapi, s, "abscoeff")

    print(("Calculated with RADIS in {0:.2f}s".format(
        s.conditions["calculation_time"])))
    print(("Number of lines in RADIS:", len(sf.df0)))

#    plt.savefig('radis_vs_hapi_test_large_ch4.pdf')
示例#10
0
def test_broadening_DLM_FT(verbose=True, plot=False, *args, **kwargs):
    """
    Test use of DLM with and without Fourier Transform

    Ensures that results are the same, and compare calculation times.
    """

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

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

    # Conditions
    T = 3000
    p = 1
    wstep = 0.002
    wmin = 2000  # cm-1
    wmax = 2300  # cm-1
    broadening_max_width = 10  # cm-1

    # %% Calculate with RADIS
    # ----------
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=1,
        path_length=1,  # doesnt change anything
        wstep=wstep,
        pressure=p,
        broadening_max_width=broadening_max_width,
        isotope="1",
        verbose=verbose,
        chunksize="DLM",
        warnings={
            "MissingSelfBroadeningWarning": "ignore",
            "NegativeEnergiesWarning": "ignore",
            "HighTemperatureWarning": "ignore",
            "GaussianBroadeningWarning": "ignore",
        },
    )  # 0.2)
    sf.load_databank("HITRAN-CO-TEST")

    # DLM, real space
    if verbose:
        print("\nConvolve version \n")
    sf._broadening_method = "convolve"
    s_dlm = sf.eq_spectrum(Tgas=T)
    s_dlm.name = "DLM ({0:.2f}s)".format(s_dlm.conditions["calculation_time"])

    # DLM , with Fourier
    if verbose:
        print("\nFFT version \n")
    sf.params.broadening_method = "fft"
    s_dlm_fft = sf.eq_spectrum(Tgas=T)
    s_dlm_fft.name = "DLM FFT ({0:.2f}s)".format(
        s_dlm_fft.conditions["calculation_time"])

    # Compare
    res = get_residual(s_dlm, s_dlm_fft, "abscoeff")

    if verbose:
        print("Residual:", res)

    # plot
    if plot:
        plot_diff(s_dlm, s_dlm_fft, "abscoeff")
        plt.legend()

    assert res < 5e-6
示例#11
0
def test_validation_vs_specair(rtol=1e-2,
                               verbose=True,
                               plot=False,
                               *args,
                               **kwargs):
    ''' Test RADIS output on CO IR bands against SPECAIR

    Test is only performed on integrals of absorption coefficient

    RADIS doesnt actually match Specair exactly, but this is due to line intensity
    differences (Specair has no rovibrational specific intensities) rather than 
    differences in populations calculations, as evidenced by the partition functions
    comparison in the RADIS presentation article. 

    '''

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

    # %% Specair calculation
    # -----------

    specair_300_300 = load_spec(getValidationCase(
        join('test_validation_vs_specair_noneqCO_data',
             'specair_CO_IR_Tvib300_Trot300.spec')),
                                binary=True)
    specair_300_2000 = load_spec(getValidationCase(
        join('test_validation_vs_specair_noneqCO_data',
             'specair_CO_IR_Tvib300_Trot2000.spec')),
                                 binary=True)
    specair_2000_300 = load_spec(getValidationCase(
        join('test_validation_vs_specair_noneqCO_data',
             'specair_CO_IR_Tvib2000_Trot300.spec')),
                                 binary=True)

    article_version = False  # just for the article

    # %% Compare with RADIS
    # ----------

    wstep = 0.002
    pl = SpectrumFactory(
        wavelength_min=4400,
        wavelength_max=4900,
        mole_fraction=1,
        pressure=0.01,  # bar
        path_length=1,  # we dont care for abscoeff anyway
        parallel=False,
        cutoff=1e-30,
        wstep=wstep,
        isotope=1,  # '1,2,3',
        medium='vacuum')  # 0.2)
    pl.warnings['MissingSelfBroadeningWarning'] = 'ignore'

    if article_version:
        pl.load_databank('HITEMP-CO-DUNHAM')
    else:
        pl.load_databank('HITRAN-CO-TEST')
        # Available on all systems, convenient for fast testing, but you
        # will be missing some small lines for T ~ 2000 K .
        print(
            'Using HITRAN: small lines will be missing at T ~ 2000K. Use HITEMP if you want them'
        )

    s_300_300 = pl.eq_spectrum(300, name='RADIS')

    s_2000_300 = pl.non_eq_spectrum(Tvib=2000,
                                    Trot=300,
                                    Ttrans=300,
                                    name='RADIS')

    s_300_2000 = pl.non_eq_spectrum(Tvib=300,
                                    Trot=2000,
                                    Ttrans=2000,
                                    name='RADIS')

    # %% Test

    # Compare integrals

    b1 = np.isclose(specair_300_300.get_integral('abscoeff'),
                    s_300_300.get_integral('abscoeff'),
                    rtol=rtol)
    b1 *= np.isclose(specair_2000_300.get_integral('abscoeff'),
                     s_2000_300.get_integral('abscoeff'),
                     rtol=rtol)
    b1 *= np.isclose(specair_300_2000.get_integral('abscoeff'),
                     s_300_2000.get_integral('abscoeff'),
                     rtol=rtol)

    # Compare partition functions to hardcoded values
    b2 = np.isclose(s_2000_300.lines.Q, 139, atol=1)  # Specair: 139
    b2 *= np.isclose(s_300_2000.lines.Q, 727, atol=1)  # Specair: 727

    if verbose:
        printm(
            '>>> comparing RADIS vs SPECAIR on CO: integrals of abscoeff is are close'
            + ' to within {0:.1f}%: {1} ({2:.1f}%, {3:.1f}%, {4:.1f}%)'.format(
                rtol * 100,
                bool(b1),
                abs(
                    specair_300_300.get_integral('abscoeff') /
                    s_300_300.get_integral('abscoeff') - 1) * 100,
                abs(
                    specair_2000_300.get_integral('abscoeff') /
                    s_2000_300.get_integral('abscoeff') - 1) * 100,
                abs(
                    specair_300_2000.get_integral('abscoeff') /
                    s_300_2000.get_integral('abscoeff') - 1) * 100,
            ))
        printm('>>> comparing RADIS vs SPECAIR on CO: partition functions ' +
               'are equal to round error: {0}'.format(bool(b2)))

    if plot:
        plot_diff(
            specair_300_300,
            s_300_300,
            title=r'T$_\mathregular{vib}$ 300 K, T$_\mathregular{rot}$ 300 K',
            diff_window=int(
                0.02 // wstep
            ),  # compensate for small shifts in both codes. we're comparing intensities here.
            lw_multiplier=1,  #0.75, 
            wunit='nm_vac',
            plot_medium=True,
        )
        plt.xlim((4500, 4900))
        if article_version:
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib300_Trot300.png')
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib300_Trot300.pdf')

        plot_diff(
            specair_2000_300,
            s_2000_300,
            title=r'T$_\mathregular{vib}$ 2000 K, T$_\mathregular{rot}$ 300 K',
            diff_window=int(
                0.02 // wstep
            ),  # compensate for small shifts in both codes. we're comparing intensities here.
            lw_multiplier=1,  #0.75, 
            wunit='nm_vac',
            plot_medium=True,
        )
        plt.xlim((4500, 4900))
        if article_version:
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib2000_Trot300.png')
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib2000_Trot300.pdf')

        plot_diff(
            specair_300_2000,
            s_300_2000,
            title=r'T$_\mathregular{vib}$ 300 K, T$_\mathregular{rot}$ 2000 K',
            diff_window=int(
                0.02 // wstep
            ),  # compensate for small shifts in both codes. we're comparing intensities here.
            lw_multiplier=1,  #0.75, 
            wunit='nm_vac',
            plot_medium=True,
        )
        plt.xlim((4500, 4900))
        if article_version:
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib300_Trot2000.png')
            plt.savefig(
                'out/test_validation_vs_specair_noneqCO_Tvib300_Trot2000.pdf')

    return bool(b1 * b2)
示例#12
0
    def calc_hapi():
        nu, coef = absorptionCoefficient_Voigt(
            SourceTables=molecule,
            Environment={
                'T': T,  # K
                'p': pressure_bar / 1.01315,  # atm
            },
            GammaL='gamma_self',
            WavenumberStep=dnu,
            HITRAN_units=False)
        return nu, coef

    t0 = time()
    nu, coef = calc_hapi()
    t0 = time() - t0
    print(('Calculated with HAPI in {0:.2f}s'.format(t0)))

    s_hapi = Spectrum.from_array(nu,
                                 coef,
                                 'abscoeff',
                                 waveunit='cm-1',
                                 unit='cm-1')
    s_hapi.name = 'HAPI ({0:.1f}s)'.format(t0)

    plot_diff(s_hapi, s, 'abscoeff')

    print(('Calculated with RADIS in {0:.2f}s'.format(
        s.conditions['calculation_time'])))
    print(('Number of lines in RADIS:', len(sf.df0)))

#    plt.savefig('radis_vs_hapi_test_large_ch4.pdf')
示例#13
0
def test_abscoeff_continuum(plot=False,
                            verbose=2,
                            warnings=True,
                            threshold=0.1,
                            *args,
                            **kwargs):
    """ 
    Test calculation with pseudo-continuum

    Assert results on abscoeff dont change
    
    
    Notes
    -----
    
    Uses HITRAN so it can deployed and tested on [Travis]_, but we should switch
    to HITEMP if some HITEMP files can be downloaded automatically at the 
    execution time. 

    """

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

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

        sf = SpectrumFactory(
            wavelength_min=4200,
            wavelength_max=4500,
            parallel=False,
            bplot=False,
            cutoff=1e-23,
            molecule="CO2",
            isotope="1,2",
            db_use_cached=True,
            broadening_max_width=10,
            path_length=0.1,
            mole_fraction=1e-3,
            medium="vacuum",
            verbose=verbose,
        )
        sf.warnings.update({
            "MissingSelfBroadeningWarning": "ignore",
            "NegativeEnergiesWarning": "ignore",
            "LinestrengthCutoffWarning": "ignore",
            "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')       # to take a real advantage of abscoeff continuum, should calculate with HITEMP
        sf._export_continuum = True  # activate it

        # Calculate one without pseudo-continuum
        sf.params.pseudo_continuum_threshold = 0
        s1 = sf.eq_spectrum(Tgas=2000)
        s1.name = "All lines resolved ({0}) ({1:.1f}s)".format(
            s1.conditions["lines_calculated"],
            s1.conditions["calculation_time"])
        assert s1.conditions["pseudo_continuum_threshold"] == 0

        # Calculate one with pseudo-continuum
        sf.params.pseudo_continuum_threshold = threshold
        s2 = sf.eq_spectrum(Tgas=2000)
        s2.name = "Semi-continuum + {0} lines ({1:.1f}s)".format(
            s2.conditions["lines_calculated"],
            s2.conditions["calculation_time"])
        assert s2.conditions["pseudo_continuum_threshold"] == threshold
        assert "abscoeff_continuum" in s2.get_vars()

        # Plot
        if plot:
            plot_diff(
                s1,
                s2,
                "radiance_noslit",
                Iunit="µW/cm2/sr/nm",
                nfig="test_abscoeff_continuum: diff",
            )

            s2.plot(
                "abscoeff",
                label="Full spectrum",
                nfig="test_abscoeff_continuum: show continuum",
                force=True,
            )
            s2.plot(
                "abscoeff_continuum",
                nfig="same",
                label="Pseudo-continuum".format(
                    s2.conditions["lines_in_continuum"]),
                force=True,
            )
            plt.legend()

        # Compare
        res = get_residual(s1, s2, "abscoeff")
        if verbose:
            printm("residual:", res)

        globals().update(locals())

        assert res < 1.32e-6

    except DatabankNotFound as err:
        assert IgnoreMissingDatabase(err, __file__, warnings)
def test_line_broadening(rtol=1e-3, verbose=True, plot=False, *args, **kwargs):
    r"""
    Plot absorption coefficient (cm-1) of CO at high temperature (2000 K) with
    RADIS, and compare with calculations from HAPI using the HITRAN database

    Notes
    -----

    In this example no data is needed. Everything is downloaded from the HITRAN
    database directly using either the HAPI ``fetch`` function, or the RADIS
    :meth:`~neq.spec.factory.fetch_databank` method.

    """

    from hapi import (
        absorptionCoefficient_Voigt,
        db_begin,
        fetch,
        tableList,
        transmittanceSpectrum,
    )

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

    # Conditions
    molecule = "CO2"
    mol_id = get_molecule_identifier(molecule)
    iso = 1
    T = 1500
    p = 0.1
    L = 0.1
    #    M = 0.001           # mole fraction  (dont know where to put that )
    dnu = 0.0001
    wmin = nm2cm(4372.69 + 0.2)  # cm-1
    wmax = nm2cm(4372.69 - 0.2)  # cm-1
    #    broadening_max_width = 6  # cm-1
    broadening_max_width = 0.5  # cm-1

    # %% HITRAN calculation
    # -----------

    # Generate HAPI database locally

    HAPIdb = join(dirname(__file__), __file__.replace(".py", "_HAPIdata"))

    def calc_hapi():
        """ Calc spectrum under HAPI """

        clean_after_run = not exists(HAPIdb) and False

        try:
            db_begin(HAPIdb)
            if not molecule in tableList(
            ):  # only if data not downloaded already
                fetch(
                    molecule,
                    mol_id,
                    iso,
                    wmin - broadening_max_width / 2,
                    wmax + broadening_max_width / 2,
                )
                # HAPI doesnt correct for side effects

            # Calculate with HAPI
            nu, coef = absorptionCoefficient_Voigt(
                SourceTables="CO2",
                Environment={
                    "T": T,
                    "p": p / 1.01325,
                },  # K  # atm
                WavenumberStep=dnu,
                HITRAN_units=False,
                GammaL="gamma_self",
            )
            nu, trans = transmittanceSpectrum(
                nu,
                coef,
                Environment={
                    "l": L,
                },
            )  # cm
            s_hapi = Spectrum.from_array(
                nu,
                trans,
                "transmittance_noslit",
                "cm-1",
                "1",
                conditions={"Tgas": T},
                name="HAPI",
            )

        except:
            raise

        finally:
            if clean_after_run:
                shutil.rmtree(HAPIdb)
        return s_hapi

    s_hapi = calc_hapi()

    def calc_radis():

        # %% Calculate with RADIS
        # ----------
        pl = SpectrumFactory(
            wavenum_min=wmin,
            wavenum_max=wmax,
            mole_fraction=1,
            path_length=L,
            wstep=dnu,
            molecule=molecule,
            pressure=p,
            broadening_max_width=broadening_max_width,
            cutoff=1e-23,
            isotope=iso,
        )
        pl.warnings["MissingSelfBroadeningWarning"] = "ignore"
        pl.warnings["HighTemperatureWarning"] = "ignore"
        pl.fetch_databank(
            source="hitran",
            load_energies=False,
            db_use_cached=True,
        )

        s = pl.eq_spectrum(Tgas=T)  # , Ttrans=300)
        s.name = "RADIS"

        if plot:
            pl.plot_broadening()

        return s

    s = calc_radis()

    # %% Compare
    # also shrinks HAPI range to the valid one
    s_hapi.resample(s.get_wavenumber(), unit="cm-1", energy_threshold=0.1)

    save = False  # just used in the article
    if plot or save:
        from radis import plot_diff

        #        title = '{0} bar, {1} K, {2} cm'.format(p, T, L)  if save else None
        fig, [ax0, ax1] = plot_diff(s,
                                    s_hapi,
                                    var="transmittance_noslit",
                                    method="ratio",
                                    show=plot)

        ax0.annotate(
            r"[P64](00$^\mathregular{0}$0)$\rightarrow $(00$^\mathregular{0}$1)",
            (2286.945, 0.76),
            (2286.94, 0.8),
            arrowprops=dict(arrowstyle="->", facecolor="black"),
        )
        ax0.annotate(
            r"[P53](01$^\mathregular{1}$0)$\rightarrow $(01$^\mathregular{1}$1)",
            (2286.9, 0.78),
            (2286.9, 0.82),
            arrowprops=dict(arrowstyle="->", facecolor="black"),
            horizontalalignment="right",
        )
        ax1.set_ylim(0.95, 1.05)

        if save:
            fig.savefig("out/test_RADIS_vs_HAPI_line_broadening.pdf")

    # Compare integrals
    diff = abs(
        s.get_integral("transmittance_noslit") /
        s_hapi.get_integral("transmittance_noslit") - 1)
    b = diff < rtol

    if verbose:
        printm("Integral difference ({0:.2f}%) < {1:.2f}%: {2}".format(
            diff * 100, rtol * 100, b))

    return b
s_opt.update()

# compare times
t_ref = s_ref.conditions['calculation_time']
t_opt = s_opt.conditions['calculation_time']
t_dlm = s_dlm.conditions['calculation_time']
#%%
plt.ion()

#%%

_, [ax0, ax1] = plot_diff(
    s_ref,
    s_dlm,
    'transmittance_noslit',
    method='ratio',
    label1='Reference {1} lines ({0:.0f}s)'.format(
        t_ref, str_fmt(s_ref.conditions['lines_calculated'])),
    label2='New method {1} lines ({0:.0f}s)'.format(
        t_dlm, str_fmt(s_dlm.conditions['lines_calculated'])),
)  #legendargs={'loc':'lower left', 'handlelength':1, 'fontsize':16.5})
ax0.set_ylim((0.87, 1))
ax1.set_ylim((0.999, 1.001))

handles, labels = ax0.get_legend_handles_labels()
leg = ax0.legend(frameon=False, fontsize=16, loc=3)

axins = ax0.inset_axes([0.60, 0.125, 0.35, 0.45])
axins.ticklabel_format(useOffset=False, axis='x')
axins.tick_params(which='major', labelsize=14)
axins.get_yaxis().set_visible(False)
axins.plot(*s_ref.get('transmittance_noslit', wunit='cm-1'), color='k', lw=2)
示例#16
0
def test_broadening_vs_hapi(rtol=1e-2,
                            verbose=True,
                            plot=False,
                            *args,
                            **kwargs):
    """
    Test broadening against HAPI and tabulated data

    We're looking at CO(0->1) line 'R1' at 2150.86 cm-1
    """
    from hapi import absorptionCoefficient_Voigt, db_begin, fetch, tableList

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

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

    # Conditions
    T = 3000
    p = 0.0001
    wstep = 0.001
    wmin = 2150  # cm-1
    wmax = 2152  # cm-1
    broadening_max_width = 10  # cm-1

    # %% HITRAN calculation
    # -----------

    # Generate HAPI database locally
    hapi_data_path = join(dirname(__file__),
                          __file__.replace(".py", "_HAPIdata"))

    db_begin(hapi_data_path)
    if not "CO" in tableList():  # only if data not downloaded already
        fetch("CO", 5, 1, wmin - broadening_max_width / 2,
              wmax + broadening_max_width / 2)
        # HAPI doesnt correct for side effects

    # Calculate with HAPI
    nu, coef = absorptionCoefficient_Voigt(
        SourceTables="CO",
        Environment={
            "T": T,
            "p": p / 1.01325,
        },  # K  # atm
        WavenumberStep=wstep,
        HITRAN_units=False,
    )

    s_hapi = Spectrum.from_array(nu,
                                 coef,
                                 "abscoeff",
                                 "cm-1",
                                 "cm-1",
                                 conditions={"Tgas": T},
                                 name="HAPI")

    # %% Calculate with RADIS
    # ----------
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=1,
        path_length=1,  # doesnt change anything
        wstep=wstep,
        pressure=p,
        broadening_max_width=broadening_max_width,
        isotope=[1],
        warnings={
            "MissingSelfBroadeningWarning": "ignore",
            "NegativeEnergiesWarning": "ignore",
            "HighTemperatureWarning": "ignore",
            "GaussianBroadeningWarning": "ignore",
        },
    )  # 0.2)
    sf.load_databank(path=join(hapi_data_path, "CO.data"),
                     format="hitran",
                     parfuncfmt="hapi")
    #    s = pl.non_eq_spectrum(Tvib=T, Trot=T, Ttrans=T)
    s = sf.eq_spectrum(Tgas=T, name="RADIS")

    if plot:  # plot broadening of line of largest linestrength
        sf.plot_broadening(i=sf.df1.S.idxmax())

    # Plot and compare
    res = abs(get_residual_integral(s, s_hapi, "abscoeff"))
    if plot:
        plot_diff(
            s,
            s_hapi,
            var="abscoeff",
            title="{0} bar, {1} K (residual {2:.2g}%)".format(p, T, res * 100),
            show_points=False,
        )
        plt.xlim((wmin, wmax))
    if verbose:
        printm("residual:", res)
    assert res < rtol
示例#17
0
def test_broadening_DLM(verbose=True, plot=False, *args, **kwargs):
    """
    Test use of lineshape template for broadening calculation.

    Ensures that results are the same with and without DLM.
    """

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

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

    # Conditions
    T = 3000
    p = 1
    wstep = 0.002
    wmin = 2150  # cm-1
    wmax = 2152  # cm-1
    broadening_max_width = 10  # cm-1

    # %% Calculate with RADIS
    # ----------
    sf = SpectrumFactory(
        wavenum_min=wmin,
        wavenum_max=wmax,
        mole_fraction=1,
        path_length=1,  # doesnt change anything
        wstep=wstep,
        pressure=p,
        broadening_max_width=broadening_max_width,
        isotope="1",
        verbose=False,
        warnings={
            "MissingSelfBroadeningWarning": "ignore",
            "NegativeEnergiesWarning": "ignore",
            "HighTemperatureWarning": "ignore",
            "GaussianBroadeningWarning": "ignore",
        },
    )  # 0.2)
    sf.load_databank("HITRAN-CO-TEST")

    # Reference: calculate without DLM
    assert sf.misc["chunksize"] is None
    s_ref = sf.eq_spectrum(Tgas=T)
    s_ref.name = "Reference ({0:.2f}s)".format(
        s_ref.conditions["calculation_time"])

    # DLM:
    sf.misc["chunksize"] = "DLM"
    sf.params.broadening_method = "convolve"
    s_dlm = sf.eq_spectrum(Tgas=T)
    s_dlm.name = "DLM ({0:.2f}s)".format(s_dlm.conditions["calculation_time"])
    # DLM Voigt with Whiting approximation:
    sf.params.broadening_method = "voigt"
    s_dlm_voigt = sf.eq_spectrum(Tgas=T)
    s_dlm_voigt.name = "DLM Whiting ({0:.2f}s)".format(
        s_dlm_voigt.conditions["calculation_time"])

    # Compare
    res = get_residual(s_ref, s_dlm, "abscoeff")
    res_voigt = get_residual(s_dlm, s_dlm_voigt, "abscoeff")

    if verbose:
        print("Residual:", res)

    # plot the last one
    if plot:
        plot_diff(s_ref, s_dlm, "abscoeff")
        plt.legend()
        plot_diff(s_dlm, s_dlm_voigt, "abscoeff")

    assert res < 1.2e-5
    assert res_voigt < 1e-5
示例#18
0
Nlines = 1e4

#%% Calculate normal

for width in broadening_max_widths:
        
    spectra_default[width] = load_spec('../spec_fig78/spectra_default[{0}].spec'.format(width), binary=True)
    spectra_convolve[width] = load_spec('../spec_fig78/spectra_convolve[{0}].spec'.format(width), binary=True)

spectra_DLM_opt = load_spec('../spec_fig78/spectra_DLM_opt.spec')


plt.ion()

##fig, [ax0, ax1] = plot_diff(spectra_default[broadening_max_widths[1]], spectra_DLM_opt, 'abscoeff', figsize=(10,6))
fig, [ax0, ax1] = plot_diff(spectra_default[broadening_max_widths[1]], spectra_DLM_opt, 'abscoeff', figsize=(10,6))
                           
ax0.set_ylim((0, 0.9))
ax1.set_ylim((-0.0025, 0.0025))

from mpl_toolkits.axes_grid1.inset_locator import inset_axes

axins = ax0.inset_axes([0.115, 0.25, 0.35, 0.45])
axins.ticklabel_format(useOffset=False, axis='x')
axins.tick_params(which='major', labelsize=14)
axins.get_yaxis().set_visible(False)
axins.plot(*spectra_default[broadening_max_widths[1]].get('abscoeff', wunit='cm-1'), color='k', lw=2)
axins.plot(*spectra_DLM_opt.get('abscoeff', wunit='cm-1'), color='r', lw=1)

axins.set_xlim((2235, 2238.5))
示例#19
0
def test_noneq_continuum(plot=False,
                         verbose=2,
                         warnings=True,
                         *args,
                         **kwargs):
    """
    Test calculation with pseudo-continuum under nonequilibrium

    Assert results on emisscoeff dont change


    Notes
    -----

    Uses HITRAN so it can deployed and tested on `Travis CI <https://travis-ci.com/radis/radis>`_, but we should switch
    to HITEMP if some HITEMP files can be downloaded automatically at the
    execution time.

    """

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

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

    sf = SpectrumFactory(
        wavelength_min=4200,
        wavelength_max=4500,
        cutoff=1e-23,
        molecule="CO2",
        isotope="1,2",
        broadening_max_width=10,
        path_length=0.1,
        mole_fraction=1e-3,
        medium="vacuum",
        optimization=None,
        verbose=verbose,
    )
    sf.warnings.update({
        "MissingSelfBroadeningWarning": "ignore",
        "NegativeEnergiesWarning": "ignore",
        "LinestrengthCutoffWarning": "ignore",
        "HighTemperatureWarning": "ignore",
    })
    sf.fetch_databank(
        "hitran"
    )  # uses HITRAN: not really valid at this temperature, but runs on all machines without install
    #        sf.load_databank('HITEMP-CO2-DUNHAM')       # to take a real advantage of abscoeff continuum, should calculate with HITEMP
    sf._export_continuum = True  # activate it

    # Calculate one without pseudo-continuum
    sf.params.pseudo_continuum_threshold = 0
    s1 = sf.non_eq_spectrum(Tvib=2000, Trot=1000)
    s1.name = "All lines resolved ({0}) ({1:.1f}s)".format(
        s1.conditions["lines_calculated"], s1.conditions["calculation_time"])
    assert s1.conditions["pseudo_continuum_threshold"] == 0

    # Calculate one with pseudo-continuum
    sf.params.pseudo_continuum_threshold = 0.05
    s2 = sf.non_eq_spectrum(Tvib=2000, Trot=1000)
    s2.name = "Semi-continuum + {0} lines ({1:.1f}s)".format(
        s2.conditions["lines_calculated"], s2.conditions["calculation_time"])
    assert s2.conditions["pseudo_continuum_threshold"] == 0.05
    assert "abscoeff_continuum" in s2.get_vars()
    assert "emisscoeff_continuum" in s2.get_vars()

    # Plot
    if plot:
        plot_diff(
            s1,
            s2,
            "radiance_noslit",
            Iunit="µW/cm2/sr/nm",
            nfig="test_noneq_continuum: diff",
        )

        plt.figure("test_noneq_continuum: show continuum").clear()
        s2.plot("emisscoeff",
                label=s2.name,
                nfig="test_noneq_continuum: show continuum")
        s2.plot(
            "emisscoeff_continuum",
            nfig="same",
            label="Pseudo-continuum (aggreg. {0:g} lines)".format(
                s2.conditions["lines_in_continuum"]),
            force=True,
        )

    # Compare
    res = get_residual(s1, s2, "abscoeff") + get_residual(s1, s2, "emisscoeff")
    if verbose:
        printm("residual:", res)

    assert res < 5.2e-6
示例#20
0
spectra_default = {}
spectra_DLM = {}
spectra_DLM_opt = {}

Nlines = [101, 1001, 10017, 100725, 1813040, 1813040]
plt.ion()

for N in Nlines:
    spectra_default[N] = load_spec(
        '../spec/spectra_default_[{0}].spec'.format(N), binary=True)
    spectra_DLM_opt[N] = load_spec(
        '../spec/spectra_DLM_opt[{0}].spec'.format(N), binary=True)

# %% Plot last spectra (opt)

fig, [ax0, ax1] = plot_diff(spectra_default[N], spectra_DLM_opt[N], 'abscoeff')

ax0.set_ylim((0, 0.5))
ax1.set_ylim((-0.005, 0.005))

axins = ax0.inset_axes([0.06, 0.3, 0.3, 0.4])
axins.ticklabel_format(useOffset=False, axis='x')
axins.tick_params(which='major', labelsize=14)
axins.get_yaxis().set_visible(False)
axins.plot(*spectra_default[N].get('abscoeff', wunit='cm-1'), color='k', lw=2)
axins.plot(*spectra_DLM_opt[N].get('abscoeff', wunit='cm-1'), color='r', lw=1)
axins.set_xlim((2200, 2205))
axins.set_ylim((0.0125, 0.32))
ax0.indicate_inset_zoom(axins)

fig.savefig('output/Fig6a.pdf')