def test_auto_correct_dispersion(f=750, phi=-6, gr=2400, verbose=True, plot=True, close_plots=True, *args, **kwargs): ''' A test case to show the effect of wavelength dispersion (cf spectrometer reciprocal function) on the slit function Parameters ---------- f: focal length (mm) default 750 (SpectraPro 2750i) phi: angle in degrees (°) default -6 gr: grooves spacing (gr/mm) default 2400 ''' from radis.test.utils import getTestFile from publib import set_style, fix_style from radis.misc.warning import SlitDispersionWarning if plot: plt.ion() # dont get stuck with Matplotlib if executing through pytest if close_plots: plt.close('all') w_slit_632, I_slit_632 = import_experimental_slit(getTestFile('slitfunction.txt')) slit_measured_632nm = getTestFile('slitfunction.txt') w, I = np.loadtxt(getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt')).T s = calculated_spectrum(w, I, conditions={'Tvib': 3000, 'Trot': 1200}, Iunit='mW/cm2/sr/µm') slit_dispersion = lambda w: linear_dispersion(w, f=f, phi=phi, m=1, gr=gr) s.apply_slit(slit_measured_632nm) if plot: w_full_range = np.linspace(w.min(), w_slit_632.max()) set_style('origin') plt.figure('Spectrometer Dispersion (f={0}mm, phi={1}°, gr={2}'.format( f, phi, gr)) plt.plot(w_full_range, slit_dispersion(w_full_range)) plt.xlabel('Wavelength (nm)') plt.ylabel('Reciprocal Linear Dispersion') # Compare 2 spectra s.plot(nfig='Linear dispersion effect', color='r', label='not corrected') with pytest.warns(SlitDispersionWarning): # expect a "large slit dispersion" warning s.apply_slit(slit_measured_632nm, slit_dispersion=slit_dispersion) if plot: s.plot(nfig='same', color='k', label='corrected') plt.legend() # Plot different slits: s.plot_slit() # plt.plot(w_slit_632, I_slit_632, color='r', label='Not corrected') # plt.legend() return True # nothing defined yet
def test_crop(verbose=True, *args, **kwargs): """ Test that update can correctly recompute missing quantities """ # 1) A crop example in the same unit as the one stored # Work with a Spectrum object that was generated by Specair s = load_spec(getTestFile("N2C_specair_380nm.spec")) # Focus on N2(C->B), v'=0, v''=2 band: s.crop(376, 381, "nm") w = s.get_wavelength() assert w.min() >= 360 assert w.max() <= 382 # 2) A crop example in different unit as the one stored # Work with a Spectrum object that was generated by Specair s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) # Focus on N2(C->B), v'=0, v''=2 band: s1.crop(4530, 4533, "nm") w = s1.get_wavelength() assert w.min() >= 4530 assert w.max() <= 4533 return True
def run_example(): setup_test_line_databases( verbose=True) # add HITEMP-CO2-HAMIL-TEST in ~/.radis if not there sf = SpectrumFactory( wavenum_min=2283.7, wavenum_max=2285.1, wstep=0.001, cutoff=1e-30, path_length=0.1, mole_fraction=400e-6, isotope=[1], db_use_cached=True, # important to test CAche file here verbose=2, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.load_databank("HITEMP-CO2-HAMIL-TEST") # Now generate vibrational energies for a 2-T model # ... Note that this is arbitrary. Lookup Pannier & Dubuet 2020 for more. levels = sf.parsum_calc["CO2"][1]["X"].df levels["Evib"] = levels.Evib1 + levels.Evib2 + levels.Evib3 # Calculate populations using the non-equilibrium module: # This will crash the first time because the Levels Database is just a fragment and does not include all levels. try: sf.non_eq_spectrum(300, 300) except AssertionError: # expected sf.df0.dropna(inplace=True) getTestFile("HITEMP-CO2-HAMIL-TEST") s = sf.non_eq_spectrum(300, 300) s.plot()
def test_all_slit_shapes(FWHM=0.4, verbose=True, plot=True, close_plots=True, *args, **kwargs): """ Test all slit generation functions and make sure we get the expected FWHM""" if plot: plt.ion() # dont get stuck with Matplotlib if executing through pytest if close_plots: plt.close("all") # get spectrum from radis.test.utils import getTestFile from radis.spectrum.spectrum import Spectrum s = Spectrum.from_txt( getTestFile("calc_N2C_spectrum_Trot1200_Tvib3000.txt"), quantity="radiance_noslit", waveunit="nm", unit="mW/cm2/sr/µm", ) wstep = np.diff(s.get_wavelength())[0] # Plot all slits # ... gaussian s.apply_slit(FWHM, unit="nm", shape="gaussian", plot_slit=plot) assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep) # ... triangular s.apply_slit(FWHM, unit="nm", shape="triangular", plot_slit=plot) assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep) # ... trapezoidal s.apply_slit((FWHM * 0.9, FWHM * 1.1), unit="nm", shape="trapezoidal", plot_slit=plot) assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=2 * wstep) # # ... trapezoidal # s.apply_slit(FWHM, unit='nm', shape='trapezoidal', plot_slit=plot, norm='max') # assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=1.1*wstep) # ... experimental s.apply_slit(getTestFile("slitfunction.txt"), unit="nm", plot_slit=plot) assert np.isclose(get_effective_FWHM(*s.get_slit()), FWHM, atol=0.01) # note that we're applying a slit function measured at 632.5 nm to a Spectrum # at 4.7 µm. It's just good for testing the functions # # ... experimental, convolve with max # s.apply_slit(getTestFile('slitfunction.txt'), unit='nm', norm_by='max', plot_slit=plot) # assert np.isclose(get_FWHM(*s.get_slit()), FWHM, atol=1.1*wstep) if verbose: print("\n>>> _test_all_slits yield correct FWHM (+- wstep) : OK\n") return True # nothing defined yet
def test_merge_slabs(verbose=True, plot=False, close_plots=True, warnings=True, debug=False, *args, **kwargs): """Merge 10 slabs with 1/10 of concentration, and compare the results. Ensure error is < 0.1% Note that we won't have exactly the same results as the broadening is not updated in MergeSlabs """ import matplotlib.pyplot as plt from radis.test.utils import getTestFile from radis.tools.database import load_spec if plot: plt.ion() # dont get stuck with Matplotlib if executing through pytest if close_plots: plt.close("all") for optically_thin in [True, False]: # Get Some spectra s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s2 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.5.spec"), binary=True) s1.update("all") s2.update("all") # Merge 50 times s1 in the same slab s50 = [s1] * 50 s1N = MergeSlabs(*s50, optically_thin=optically_thin, debug=debug) if plot: for k in ["radiance_noslit"]: # , 'transmittance_noslit']: s2.plot(k, lw=3, label="1x[CO=0.5]") s1N.plot(k, nfig="same", label="50x[CO=0.01]") plt.legend() plt.title("Optically thin: {0}".format(optically_thin)) plt.tight_layout() if verbose: print("test_merge_slabs") print( "... Compare 50x[CO=0.01] vs 1x[CON=0.5] (optically thin: {0})" .format(optically_thin)) print("... Difference: {0:.2f}%".format( abs(s1N.get_power() / s2.get_power() - 1) * 100)) assert np.isclose(s2.get_power(), s1N.get_power(), 1.5e-2) return True
def test_save_compressed2(verbose=True, *args, **kwargs): "Check if saving a spectrum with compress = 2 does not change something." import shutil from os.path import join from radis.test.utils import setup_test_line_databases from radis import calc_spectrum, SpecDatabase shutil.rmtree(join(dirname(getTestFile(".")), "newDb"), ignore_errors=True) # get the spectrum setup_test_line_databases() s = calc_spectrum( 2000, 2300, # cm-1 molecule="CO", isotope="1,2,3", pressure=1.01325, # bar Tgas=700, # K mole_fraction=0.1, path_length=1, # cm verbose=False, wstep=0.01, medium="vacuum", databank="HITRAN-CO-TEST", ) try: # load in one databse db = SpecDatabase(join(dirname(getTestFile(".")), "newDb")) db.add(s, compress=2, if_exists_then="error") # simulate an experimentalist who come later and load the spectrum db2 = SpecDatabase(join(dirname(getTestFile(".")), "newDb")) s_bis = db2.get_unique(Tgas=700) finally: # we want to make sure this folder is deleted shutil.rmtree(join(dirname(getTestFile(".")), "newDb")) # we check the loaded spectrum contains less information than the calculated one assert not s == s_bis assert s_bis.get_vars() == ["abscoeff" ] # only this spectral quantity was stored assert s_bis.lines is None assert s_bis.conditions is not None # we kept the metadata # now we check if it works s_bis.update() for var in s.get_vars(): assert s.compare_with(s_bis, spectra_only=var, plot=False, verbose=verbose)
def test_compare_methods(verbose=True, plot=True, close_plots=True, *args, **kwargs): ''' Just run all Spectrum compare methods to check they work''' if plot and close_plots: import matplotlib.pyplot as plt plt.close('all') s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec')) s.resample(np.linspace(2193, 2193.8, 100)) # limits to a single line, because get_distance() # is very computationaly heavy s.update('radiance_noslit') s_noabsorption = s.copy() s.name = 'solve RTE' s_noabsorption.name = 'optically thin' # rescale, normal # s.rescale_mole_fraction(10) s.rescale_path_length(10) # rescale, optically thin mode s_noabsorption.conditions['self_absorption'] = False # s_noabsorption.rescale_mole_fraction(10) s_noabsorption.rescale_path_length(10) # Compare get_distance(s, s_noabsorption, 'radiance_noslit') # should be added in an example with experimental fit of bandhead title = 'CO x={0:.2f}, L={1:.2f}cm'.format(s.conditions['mole_fraction'], s.conditions['path_length']) if plot: plot_diff(s, s_noabsorption, method='diff', title=title) plot_diff(s, s_noabsorption, method='ratio', normalize=True, title=title)
def test_compression(verbose=True, warnings=True, *args, **kwargs): """Test that redundant quantities are properly infered from already known spectral quantities""" # Get spectrum s1 = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s1.conditions["thermal_equilibrium"] = True s1.update() # Analyse redundant spectral quantities redundant = get_redundant(s1) if verbose: print(redundant) assert redundant == { "emissivity_noslit": True, "radiance_noslit": True, "emisscoeff": True, "transmittance_noslit": True, "absorbance": True, "abscoeff": False, } return True
def test_recompute_equilibrium(verbose=True, warnings=True, plot=True, *args, **kwargs): ''' Test that spectral quantities recomputed under equilibrium assumption yields the same output as with non equilibrium routines when Tvib = Trot ''' if plot: import matplotlib.pyplot as plt plt.ion() # dont get stuck with Matplotlib if executing through pytest # Get spectrum s1 = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec')) s1.rescale_path_length(100) # just for fun assert s1.is_at_equilibrium() s1.update('emisscoeff') # force non equilibrium calculation s2 = s1.copy() s2.conditions['thermal_equilibrium'] = False s2.update() assert 'emissivity_noslit' not in s2.get_vars() # just a check update() was done at nonequilibrium # update s1 now (at equilibrium) s1.update() assert 'emissivity_noslit' in s1.get_vars() # just a check update() was done at equilibrium s1.name = 'scaled with Kirchoff law' s2.name = 'scaled from emisscoeff + abscoeff with RTE' if verbose: print('Checked that scaling at equilibrium with Kirchoff law yields the ' + 'same radiance as by solving the RTE from emisscoeff and abscoeff') # Now Compare both update processes assert s1.compare_with(s2, spectra_only='radiance_noslit', plot=plot)
def test_get_recompute(verbose=True, *args, **kwargs): """Make sure :func:`~radis.spectrum.rescale.get_recompute` works as expected Here, we check which quantities are needed to recompute radiance_noslit""" # Equilibrium # ----------- s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) assert s.get_vars() == ["abscoeff"] assert s.conditions["thermal_equilibrium"] # At equilibrium, everything should be deduced from abscoeff assert set(get_recompute(s, ["radiance_noslit"])) == set( ("radiance_noslit", "abscoeff")) # Non Equilibrium # ---------------- s.conditions["Tvib"] = 2000 # a problem should be detected by is_at_equilibrium() with pytest.raises(AssertionError): assert not s.is_at_equilibrium(check="error") # force non equilibrium s.conditions["thermal_equilibrium"] = False # Now more data is needed: assert set(get_recompute(s, ["radiance_noslit"])) == set( ("abscoeff", "emisscoeff", "radiance_noslit"))
def test_normalization(*args, **kwargs): from radis import Radiance, load_spec from radis.test.utils import getTestFile # Generate the equivalent of an experimental spectrum s = load_spec(getTestFile(r"CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update() # add radiance, etc. s.apply_slit(0.5) # nm s = Radiance(s) # Test normalization assert s.units["radiance"] != "" s.normalize() assert s.max() != 1 s.normalize(inplace=True) assert s.max() == 1 assert s.normalize().units["radiance"] == "" s2 = s.normalize(normalize_how="area") assert np.isclose(s2.get_integral("radiance", wunit=s2.get_waveunit()), 1) # s3 = s.normalize(wrange=((2125, 2150)), normalize_how="area") assert np.isclose( s3.crop(2125, 2150).get_integral("radiance", wunit=s3.get_waveunit()), 1)
def test_copy(verbose=True, *args, **kwargs): """Test that a Spectrum is correctly copied We compare a Spectrum that has: - all available spectral quantities - a slit - many calculation conditions - no populations - no lines """ from radis.test.utils import getTestFile from radis.tools.database import load_spec s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec")) s.update() s.apply_slit(1.5) s2 = s.copy() # Test spectrum in general assert s == s2 assert s is not s2 # Test all quantities in detail for var in s._q.keys(): assert np.allclose(s._q[var], s2._q[var]) assert not (s._q[var] is s2._q[var]) for var in s._q_conv.keys(): assert np.allclose(s._q_conv[var], s2._q_conv[var]) assert not (s._q_conv[var] is s2._q_conv[var]) if verbose: print("Tested that s2 == s (but s2 is not s) after Spectrum copy")
def test_slit_unit_conversions_spectrum_in_cm(verbose=True, plot=True, close_plots=True, *args, **kwargs): """ Test that slit is consistently applied for different units Assert that: - calculated FWHM is the one that was applied """ from radis.test.utils import getTestFile from radis.tools.database import load_spec if plot: # dont get stuck with Matplotlib if executing through pytest plt.ion() if close_plots: plt.close("all") # %% Get a Spectrum (stored in cm-1) s_cm = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s_cm.rescale_mole_fraction(1) # just because it makes better units s_cm.update() wstep = s_cm.conditions["wstep"] assert s_cm.get_waveunit() == "cm-1" # ensures it's stored in cm-1 for shape in ["gaussian", "triangular"]: # Apply slit in cm-1 slit_cm = 2 s_cm.name = "Spec in cm-1, slit {0:.2f} cm-1".format(slit_cm) s_cm.apply_slit(slit_cm, unit="cm-1", shape=shape, mode="same") # ... mode=same to keep same output length. It helps compare both Spectra afterwards # in cm-1 as that's s.get_waveunit() fwhm = get_FWHM(*s_cm.get_slit()) assert np.isclose(slit_cm, fwhm, atol=2 * wstep) # Apply slit in nm this time s_nm = s_cm.copy() w_cm = s_nm.get_wavenumber(which="non_convoluted") slit_nm = dcm2dnm(slit_cm, w_cm[len(w_cm) // 2]) s_nm.name = "Spec in cm-1, slit {0:.2f} nm".format(slit_nm) s_nm.apply_slit(slit_nm, unit="nm", shape=shape, mode="same") plotargs = {} if plot: plotargs[ "title"] = "test_slit_unit_conversions: {0} ({1} cm-1)".format( shape, slit_cm) s_cm.compare_with(s_nm, spectra_only="radiance", rtol=1e-3, verbose=verbose, plot=plot, **plotargs)
def test_rescaling_function(verbose=True, *args, **kwargs): """ Test rescaling functions """ from radis.test.utils import getTestFile s = Spectrum.from_txt( getTestFile("calc_N2C_spectrum_Trot1200_Tvib3000.txt"), quantity="radiance_noslit", waveunit="nm", unit="mW/cm2/sr/µm", # Specair units: mW/cm2/sr/µm conditions={ "Tvib": 3000, "Trot": 1200, "path_length": 1, # arbitrary "medium": "air", }, populations={"molecules": { "N2C": 1e13 }}, # arbitrary # (just an example) ) s.update(optically_thin=True) s.rescale_path_length(10) assert np.isclose( s.get_radiance_noslit(Iunit="mW/cm2/sr/nm")[0], 352.57305783248)
def test_local_hitran_h2o(verbose=True, warnings=True, **kwargs): # 1. Load df = hit2df(getTestFile("hitran_2016_H2O_2iso_2000_2100cm.par"), cache="regen") if verbose: print("Read hitran_2016_H2O_2iso_2000_2100cm.par") print("-----------------------------------------") print(df.head()) # 2. Test assert list(df.loc[0, ["v1u", "v2u", "v3u", "v1l", "v2l", "v3l"]]) == [ 0, 2, 0, 0, 1, 0, ] assert df.loc[26, "ju"] == 5 # in .par : line 27, column 99-100 assert df.loc[27, "ju"] == 18 # in .par : line 28, column 99-100 assert df.dtypes["v1l"] == np.int64 assert df.dtypes["v3u"] == np.int64 assert df.dtypes["ju"] == np.int64 assert df.dtypes["Kau"] == np.int64 assert df.dtypes["Kcu"] == np.int64 assert df.dtypes["jl"] == np.int64 assert df.dtypes["Kal"] == np.int64 assert df.dtypes["Kcl"] == np.int64 return True
def test_hitran_h2o(verbose=True, warnings=True, **kwargs): # 1. Load df = hit2df(getTestFile('hitran_2016_H2O_2iso_2000_2100cm.par'), cache='regen') if verbose: print('Read hitran_2016_H2O_2iso_2000_2100cm.par') print('-----------------------------------------') print(df.head()) # 2. Test assert (list(df.loc[0, ['v1u', 'v2u', 'v3u', 'v1l', 'v2l', 'v3l']]) == [0, 2, 0, 0, 1, 0]) assert df.loc[26, 'ju'] == 5 # in .par : line 27, column 99-100 assert df.loc[27, 'ju'] == 18 # in .par : line 28, column 99-100 assert df.dtypes['v1l'] == np.int64 assert df.dtypes['v3u'] == np.int64 assert df.dtypes['ju'] == np.int64 assert df.dtypes['Kau'] == np.int64 assert df.dtypes['Kcu'] == np.int64 assert df.dtypes['jl'] == np.int64 assert df.dtypes['Kal'] == np.int64 assert df.dtypes['Kcl'] == np.int64 return True
def test_eq_spectrum_gpu(): T = 1000 p = 0.1 wstep = 0.001 wmin = 2284.0 # cm-1 wmax = 2285.0 # cm-1 sf = SpectrumFactory( wavenum_min=wmin, wavenum_max=wmax, mole_fraction=0.01, # until self and air broadening is implemented path_length=1, # doesnt change anything wstep=wstep, pressure=p, isotope="1", chunksize="DLM", warnings={ "MissingSelfBroadeningWarning": "ignore", "NegativeEnergiesWarning": "ignore", "HighTemperatureWarning": "ignore", "GaussianBroadeningWarning": "ignore", }, ) sf._broadening_method = "fft" sf.load_databank( path=getTestFile("cdsd_hitemp_09_fragment.txt"), format="cdsd-4000", parfuncfmt="hapi", ) s_cpu = sf.eq_spectrum(Tgas=T) s_gpu = sf.eq_spectrum_gpu(Tgas=T) s_cpu.crop(wmin=2284.2, wmax=2284.8) # remove edge lines s_gpu.crop(wmin=2284.2, wmax=2284.8) assert s_cpu.compare_with(s_gpu, spectra_only=True, rtol=0.07, plot=False) # set the appropriate tolerance
def test_get_recompute(verbose=True, *args, **kwargs): ''' Make sure :func:`~radis.spectrum.rescale.get_recompute` works as expected Here, we check which quantities are needed to recompute radiance_noslit''' # Equilibrium # ----------- s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True) assert s.get_vars() == ['abscoeff'] assert s.conditions['thermal_equilibrium'] # At equilibrium, everything should be deduced from abscoeff assert set(get_recompute(s, ['radiance_noslit'])) == set( ('radiance_noslit', 'abscoeff')) # Non Equilibrium # ---------------- s.conditions['Tvib'] = 2000 # a problem should be detected by is_at_equilibrium() with pytest.raises(AssertionError): assert not s.is_at_equilibrium(check='error') # force non equilibrium s.conditions['thermal_equilibrium'] = False # Now more data is needed: assert set(get_recompute(s, ['radiance_noslit'])) == set( ('abscoeff', 'emisscoeff', 'radiance_noslit'))
def test_spectrum_get_methods(verbose=True, plot=True, close_plots=True, *args, **kwargs): ''' Test all spectrum methods on a Spectrum generated in Specair ''' from radis.test.utils import getTestFile from radis.tools.database import load_spec from radis.tools.slit import get_FWHM if plot and close_plots: import matplotlib.pyplot as plt plt.close('all') s = load_spec(getTestFile('N2C_specair_380nm.spec')) # general methods if verbose: print(s) dir(s) # access properties assert s.get_name() == 'N2C_specair_380nm' assert all( s.get_radiance_noslit(Iunit='W/m2/sr/nm') == s.get( 'radiance_noslit', Iunit='W/m2/sr/nm')[1]) assert all(nm2cm(s.get_wavelength(medium='vacuum')) == s.get_wavenumber()) assert s.get_power(unit='W/cm2/sr') == 2631.6288408588148 assert s.get_waveunit() == 'nm' assert s.get_power(unit='W/cm2/sr') == s.get_integral('radiance_noslit', Iunit='W/cm2/sr/nm') assert s.get_conditions()['Tgas'] == 1500 assert s.get_medium() == 'air' assert len(s.get_vars()) == 2 assert s.is_at_equilibrium() == False assert s.is_optically_thin() == False # Check applied slit has the correct width s.apply_slit(0.5) wslit, Islit = s.get_slit() wstep = np.diff(wslit)[0] assert np.isclose(get_FWHM(*s.get_slit()), 0.5, atol=1.1 * wstep) if plot: s.plot_slit() if verbose: print('Tested Spectrum methods:') print('...print(Spectrum)') print('.. get_name()') print('.. get_radiance_noslit() vs get()') print('.. get_wavelength() vs get_wavenumber') print('.. get_power()') print('.. get_waveunit()') print('.. get_power() vs get_integral()') print('.. get_conditions()') print('.. get_vars()') print('.. is_at_equilibrium()') print('.. is_optically_thin()') print('.. get_slit()')
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
def _test(verbose=True, debug=False, plot=True, warnings=True, *args, **kwargs): """Test procedures. Parameters ---------- debug: boolean swamps the console namespace with local variables. Default ``False`` """ import matplotlib.pyplot as plt from numpy import linspace, loadtxt from radis.phys.convert import cm2nm, nm2cm from radis.test.utils import getTestFile # Test even resampling w_nm, I_nm = loadtxt(getTestFile("spectrum.txt")).T w_cm, I_cm = resample_even( nm2cm(w_nm), I_nm, resfactor=2, energy_threshold=1e-3, print_conservation=verbose, ) if plot: plt.figure() plt.xlabel("Wavelength (nm)") plt.ylabel("Intensity") plt.plot(w_nm, I_nm, "-ok", label="original") plt.plot(cm2nm(w_cm), I_cm, "-or", label="resampled") plt.legend() # Test resampling w_crop = linspace(376, 381, 100) I_crop = resample(w_nm, I_nm, w_crop, energy_threshold=0.01) if plot: plt.figure() plt.xlabel("Wavelength (nm)") plt.ylabel("Intensity") plt.plot(w_nm, I_nm, "-ok", label="original") plt.plot(w_crop, I_crop, "-or", label="resampled") plt.legend() if debug: globals().update(locals()) if warnings: warn("Testing resampling: no quantitative tests defined yet") return True # no standard tests yet
def test_rescaling_function(verbose=True, *args, **kwargs): ''' Test rescaling functions ''' from radis.test.utils import getTestFile s = Spectrum.from_txt( getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt'), quantity='radiance_noslit', waveunit='nm', unit='mW/cm2/sr/µm', # Specair units: mW/cm2/sr/µm conditions={ 'Tvib': 3000, 'Trot': 1200, 'path_length': 1, # arbitrary 'medium': 'air', }, populations={'molecules': { 'N2C': 1e13 }}, # arbitrary # (just an example) ) s.update(optically_thin=True) s.rescale_path_length(10) assert np.isclose( s.get_radiance_noslit(Iunit='mW/cm2/sr/nm')[0], 352.57305783248)
def test_store_functions(verbose=True, *args, **kwargs): ''' Test some store / retrieve functions ''' from radis.spectrum.spectrum import transmittance_spectrum from radis.test.utils import getTestFile from radis.tools.database import load_spec temp_file = 'test_radis_tempfile_transmittance.txt' assert not exists(temp_file) s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True) s.update() try: s.savetxt(temp_file, 'transmittance_noslit', wunit='nm', medium='vacuum') w, T = np.loadtxt(temp_file).T finally: os.remove(temp_file) s2 = transmittance_spectrum(w, T, wunit='nm', conditions={'medium': 'vacuum'}) assert s.compare_with(s2, spectra_only='transmittance_noslit', plot=False) return True
def test_store_functions(verbose=True, *args, **kwargs): """ Test some store / retrieve functions """ from radis.spectrum.models import transmittance_spectrum from radis.test.utils import getTestFile from radis.tools.database import load_spec temp_file = "test_radis_tempfile_transmittance.txt" assert not exists(temp_file) # Test that the transmittance stored on .txt and loaded again match s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update() try: s.savetxt(temp_file, "transmittance_noslit", wunit="nm_vac") w, T = np.loadtxt(temp_file).T finally: os.remove(temp_file) s2 = transmittance_spectrum(w, T, wunit="nm_vac") assert s.compare_with(s2, spectra_only="transmittance_noslit", plot=False) # TODO: add test that ensures we can load a binary file without binary=True # (and the warning should be captured) return True
def test_line_survey(verbose=True, plot=False, warnings=True, *args, **kwargs): """ Test line survey """ _temp_file = "radis_test_line_survey.html" if exists(_temp_file): os.remove(_temp_file) s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.line_survey(overlay="abscoeff", writefile=_temp_file) assert exists(_temp_file) with open(_temp_file) as f: d = f.read() assert "Linestrength" in d assert "Wavenumber" in d if verbose: print("test_line_survey: html file was correctly generated") if not plot: # clean after use os.remove(_temp_file) return True
def test_hitran_parser(verbose=True, warnings=True, **kwargs): ''' Analyse some default files to make sure everything still works''' t0 = time() df = hit2df(getTestFile('hitran_CO_fragment.par')) if verbose: print('File loaded in {0:.0f}s'.format(time()-t0)) if verbose: print(df.head()) assert (list(df.loc[0, ['v1u', 'v1l']]) == [4, 4]) t0 = time() df = hit2df(getTestFile('hitran_CO2_fragment.par')) if verbose: print('File loaded in {0:.0f}s'.format(time()-t0)) if verbose: print(df.head()) assert (list(df.loc[0, ['v1u', 'v2u', 'l2u', 'v3u', 'v1l', 'v2l', 'l2l', 'v3l']]) == [4, 0, 0, 0, 0, 0, 0, 1]) return True
def test_rescale_all_quantities(verbose=True, warnings=True, *args, **kwargs): new_mole_fraction = 0.5 new_path_length = 0.1 # Get spectrum s0 = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True) s0.update('all') # start with all possible quantities in s0 sscaled = s0.copy() sscaled.rescale_mole_fraction(new_mole_fraction) sscaled.rescale_path_length(new_path_length) s0.conditions['thermal_equilibrium'] = False # to prevent rescaling with Kirchoff # remove emissivity_no_slit (speciifc to equilibrium) del s0._q['emissivity_noslit'] # Determine all quantities that can be recomputed if verbose >= 2: import radis DEBUG_MODE = radis.DEBUG_MODE radis.DEBUG_MODE = True from radis.spectrum.rescale import get_reachable, ordered_keys, _build_update_graph # ordered_keys: all spectral quantities that can be rescaled can_be_recomputed = get_reachable(s0) # can_be_recomputed: all spectra quantities that can be rescaled for this # particular spectrum update_paths = _build_update_graph(s0) # update_paths: which quantities are needed to recompute the others rescale_list = [k for k in ordered_keys if can_be_recomputed[k]] for quantity in rescale_list: all_paths = update_paths[quantity] if verbose: printm('{0} can be recomputed from {1}'.format(quantity, ' or '.join( ['&'.join(combinations) for combinations in all_paths]))) # Now let's test all paths for combinations in all_paths: if verbose: printm('> computing {0} from {1}'.format(quantity, '&'.join(combinations))) s = s0.copy() # Delete all other quantities for k in s.get_vars(): if k not in combinations: del s._q[k] s.update(quantity, verbose=verbose) # Now rescale s.rescale_mole_fraction(new_mole_fraction) s.rescale_path_length(new_path_length) # Compare assert s.compare_with(sscaled, spectra_only=quantity, plot=False) if verbose >= 2: radis.DEBUG_MODE = DEBUG_MODE
def test_slit_unit_conversions_spectrum_in_nm(verbose=True, plot=True, close_plots=True, *args, **kwargs): ''' Test that slit is consistently applied for different units Assert that: - calculated FWHM is the one that was applied ''' from radis.test.utils import getTestFile from radis.spectrum.spectrum import Spectrum if plot: # dont get stuck with Matplotlib if executing through pytest plt.ion() if close_plots: plt.close('all') # %% Get a Spectrum (stored in nm) s_nm = Spectrum.from_txt(getTestFile('calc_N2C_spectrum_Trot1200_Tvib3000.txt'), quantity='radiance_noslit', waveunit='nm', unit='mW/cm2/sr/µm', conditions={'self_absorption': False}) with catch_warnings(): filterwarnings( 'ignore', 'Condition missing to know if spectrum is at equilibrium:') # just because it makes better units s_nm.rescale_path_length(1, 0.001) wstep = np.diff(s_nm.get_wavelength())[0] assert s_nm.get_waveunit() == 'nm' # ensures it's stored in cm-1 for shape in ['gaussian', 'triangular']: # Apply slit in nm slit_nm = 0.5 s_nm.name = 'Spec in nm, slit {0:.2f} nm'.format(slit_nm) s_nm.apply_slit(slit_nm, unit='nm', shape=shape, mode='same') # ... mode=same to keep same output length. It helps compare both Spectra afterwards # in cm-1 as that's s.get_waveunit() fwhm = get_FWHM(*s_nm.get_slit()) assert np.isclose(slit_nm, fwhm, atol=2*wstep) # Apply slit in nm this time s_cm = s_nm.copy() w_nm = s_nm.get_wavelength(which='non_convoluted') slit_cm = dnm2dcm(slit_nm, w_nm[len(w_nm)//2]) s_cm.name = 'Spec in nm, slit {0:.2f} cm-1'.format(slit_cm) s_cm.apply_slit(slit_cm, unit='cm-1', shape=shape, mode='same') plotargs = {} if plot: plotargs['title'] = 'test_slit_unit_conversions: {0} ({1} nm)'.format( shape, slit_nm) s_nm.compare_with(s_cm, spectra_only='radiance', rtol=1e-3, verbose=verbose, plot=plot, **plotargs)
def test_resampling_function(verbose=True, plot=True, close_plots=True, *args, **kwargs): ''' Test resampling functions Get a Spectrum calculated in cm-1, then resample on a smaller range in cm-1, and in approximately the same range (but in nm). Check that all 3 overlap ''' # %% from radis.test.utils import getTestFile from radis.tools.database import load_spec from radis.spectrum import get_residual_integral if plot and close_plots: import matplotlib.pyplot as plt plt.close('all') s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True) s.name = 'original' s2 = s.copy() s2b = s.copy() s3 = s.copy() s2.resample(np.linspace(4500, 4700, 10000), unit='nm', medium='vacuum') s2b.resample(np.linspace(4500, 4700, 10000), unit='nm', medium='air') s3.resample(np.linspace(2127.2, 2227.7, 10000), unit='cm-1') s2.name = 'resampled in nm (vacuum)' s2b.name = 'resampled in nm (air)' s3.name = 'resampled in cm-1' s.compare_with(s2, plot=plot, title='Residual: {0:.2g}'.format( get_residual_integral(s, s2, 'abscoeff', ignore_nan=True))) s.compare_with(s2b, plot=plot, title='Residual: {0:.2g}'.format( get_residual_integral(s, s2b, 'abscoeff', ignore_nan=True))) s.compare_with(s3, plot=plot, title='Residual: {0:.2g}'.format( get_residual_integral(s, s3, 'abscoeff', ignore_nan=True))) assert get_residual_integral(s, s2, 'abscoeff', ignore_nan=True) < 1e-4 assert get_residual_integral(s, s2b, 'abscoeff', ignore_nan=True) < 1e-3 assert get_residual_integral(s, s3, 'abscoeff', ignore_nan=True) < 1e-5
def test_database_functions(verbose=True, plot=True, close_plots=True, warnings=True, *args, **kwargs): ''' Test SpecDatabase functions ''' if plot: import matplotlib.pyplot as plt plt.ion() if close_plots: plt.close('all') import pytest db = SpecDatabase(dirname(getTestFile('.'))) # Database visualisation methods if verbose: print('{0} items in test database: {1}'.format( len(db), db.see(['Tvib', 'Trot']))) if plot: db.plot_cond('Tvib', 'Trot') # Database get methods db.get_closest(Tgas=1300, path_length=1) s = db.get_unique(Tgas=1500, path_length=0.01, mole_fraction=0.5) # there should be one only # ... note that this is just so we can test # ... get_unique(). If we were to add new # ... test cases with matching conditions # ... let's add more criteria to keep it unique match = db.get(**s.conditions) # assert len(match) == 1 # TODO: not working in Python 2.7 yet # Database add method s2 = s.copy() s2.conditions['Tgas'] = 0 # make it unique (for testing) matching_spectrum_in_db = (s2 in db) l = db.add(s2, add_info=['Tvib', 'Trot'], discard=[], compress=True, if_exists_then='increment') assert exists(l) try: assert s2 in db # .. ensures that you cant add it twice with pytest.raises(ValueError): db.add(s2, add_info=['Tvib', 'Trot']) # Now remove the Spectrum, update the database and ensures it's not there anymore finally: os.remove(l) db.update(force_reload=True) # update database assert not exists(l) # make sure we deleted it properly if not matching_spectrum_in_db: assert s2 not in db