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 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_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_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_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_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_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_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_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_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
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_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_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_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_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_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_plot_by_parts(plot=True, *args, **kwargs): """Test :py:func:`~radis.spectrum.utils.split_and_plot_by_parts` and plot_by_parts=True in :py:meth:`~radis.spectrum.spectrum.Spectrum.plot` """ import matplotlib.pyplot as plt plt.ion() from radis import load_spec from radis.test.utils import getTestFile load_spec(getTestFile("CO2_measured_spectrum_4-5um.spec"), binary=True).plot(plot_by_parts=True, nfig="plot by parts (non continuous spectrum)") if not plot: plt.close("plot by parts (non continuous spectrum)")
def test_TestBaseline(plot=False, *args, **kwargs): s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update("radiance_noslit", verbose=False) s.apply_slit(0.1) s = Radiance_noslit(s) assert s.units["radiance"] == "mW/cm2/sr/nm" s2 = sub_baseline(s, 2e-4, -2e-4) if plot: plot_diff(s, s2) assert s2.get_radiance_noslit()[-1] == s.get_radiance_noslit()[-1] + 2e-4 assert s2.get_radiance_noslit()[0] == s.get_radiance_noslit()[0] - 2e-4
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
def test_serial_slabs_transmittance(verbose=True, plot=False, warnings=True, debug=False, *args, **kwargs): """Add some slabs in serie, ensure that overall transmittance decreases Also check that some quantities are propagated (like path length?) """ import matplotlib.pyplot as plt from radis.test.utils import getTestFile from radis.tools.database import load_spec if plot: plt.ion() # dont get stuck with Matplotlib if executing through pytest # Get Some spectra s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.5.spec"), binary=True) # s.update('all') assert "transmittance_noslit" not in s.get_vars() s_los = SerialSlabs(s, s, s) w, T = s_los.get("transmittance_noslit") # note that it was calculated despite transmittance not in the initial # spectrum s.update("transmittance_noslit") # get from abscoeff w1, T1 = s.get("transmittance_noslit") # Check it looks alright assert (T <= T1).all() assert (T != T1).any() assert (w == w1).all() # because they were the same slabs, intensive conditions should have been propagated assert s.conditions["Tgas"] == s_los.conditions["Tgas"] # but extensive shouldnt: assert s.conditions["path_length"] * 3 == s_los.conditions["path_length"] if verbose: print("Tested Serialslabs transmittance decreases s1>s2: OK") return True
def test_invariants(*args, **kwargs): """ Ensures adding 0 or multiplying by 1 does not change the spectra """ from radis import load_spec from radis.test.utils import getTestFile s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec")) s.update() s = Radiance_noslit(s) assert s.compare_with( add_constant(s, 0, "W/cm2/sr/nm"), plot=False, spectra_only="radiance_noslit" ) assert s.compare_with(multiply(s, 1), plot=False, spectra_only="radiance_noslit") assert 3 * s / 3 == s assert (1 + s) - 1 == s
def test_dimensioned_operations(*args, **kwargs): import astropy.units as u import numpy as np from radis import Radiance, load_spec from radis.spectrum import sub_baseline from radis.test.utils import getTestFile # Generate the equivalent of an experimental spectrum s = load_spec(getTestFile(r"CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update() # add radiance, etc. s.apply_slit(0.5) # nm s = Radiance(s) # Test assert s.units["radiance"] == "mW/cm2/sr/nm" Imax = s.get("radiance")[1].max() # add a baseline s += 0.1 * u.Unit("W/cm2/sr/nm") assert np.isclose(s.get("radiance")[1].max(), Imax + 100) # remove a baseline (we could also have used s=-0.1, but we're testing another function here) s = sub_baseline(s, 0.1 * u.Unit("W/cm2/sr/nm"), 0.1 * u.Unit("W/cm2/sr/nm")) assert np.isclose(s.get("radiance")[1].max(), Imax) # Test division # Example : a manual normalization s /= s.max() * u.Unit("mW/cm2/sr/nm") assert s.units["radiance"] == "" # normalized assert s.max() == 1.0 # Test Multiplication # example : a manual Calibration s.units["radiance"] = "count" s *= 100 * u.Unit("mW/cm2/sr/nm/count") assert u.Unit(s.units["radiance"]) == u.Unit( "mW/cm2/sr/nm") # check units are valid assert s.units[ "radiance"] == "mW / (cm2 nm sr)" # check units have been simplified
def test_noplot_different_quantities(*args, **kwargs): ''' Prevents User Errors: Ensures an error is raised if plotting different quantities on the same graph''' import matplotlib.pyplot as plt plt.ion() from radis import load_spec from radis.test.utils import getTestFile s = load_spec(getTestFile('CO_Tgas1500K_mole_fraction0.01.spec'), binary=True) s.update() s.plot('abscoeff', nfig='test_noplot_different_quantities') with pytest.raises(ValueError): # expect an error s.plot('emisscoeff', nfig='same') plt.close('test_noplot_different_quantities')
def test_serial_slabs_radiance(verbose=True, plot=False, warnings=True, debug=False, *args, **kwargs): """Add some slabs in serie under optically thin conditions, ensures that radiance is about the sum of all. """ import matplotlib.pyplot as plt from radis.test.utils import getTestFile from radis.tools.database import load_spec if plot: plt.ion() # dont get stuck with Matplotlib if executing through pytest # Get Some spectra s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update("radiance_noslit") s_los = SerialSlabs(s, s) w, I = s_los.get("radiance_noslit") w1, I1 = s.get("radiance_noslit") if plot: s.plot(nfig="test_serial_slabs_radiance", lw=2) plt.title("s>s for almost optically thin conditions") s_los.plot(nfig="same") # Check it looks alright assert np.allclose(I, 2 * I1, rtol=1e-3) if verbose: print( "Tested Serialslabs radiance is added when approximately optically thin: OK" ) # Test operators s_serial = s > s assert s_serial == s_los return True
def test_other_algebraic_operations(verbose=True, plot=False, *args, **kwargs): # An implement of Spectrum Algebra # Reload: s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec")) s.update() # Test addition of Spectra s.plot(lw=2, nfig="Merge: s//s") (s // s).plot(nfig="same") # Test substraction of Spectra s_tr = Transmittance_noslit(s) assert (s_tr - 1.0 * s_tr).get_integral("transmittance_noslit") == 0 # TODO: add test # @EP: the test fails at the moment because multiply only works with radiance, # and MergeSlabs only works with non convoluted quantities # Do we want that? Up for discussion... # There should be an error if algebraic operations are used when # multiple quantities are defined: with pytest.raises(KeyError): 2 * s s.apply_slit(0.1, "nm") s_rad = Radiance(s) # Test multiplication with float s.plot(lw=2, nfig="Multiplication (by scalar): 2*s", wunit="nm") # (s*s).plot(nfig='same') (2 * s_rad).plot(nfig="same", wunit="nm") # Test algebraic addition (vs multiplication) assert (s_rad + s_rad).compare_with(2 * s_rad, spectra_only="radiance", plot=False) # Test algebraic addition with different waveunits s_rad_nm = s_rad.resample(s_rad.get_wavelength(), "nm", inplace=False) s_sum = 2 * s_rad_nm - s_rad_nm s_sum.compare_with(s_rad, spectra_only="radiance", plot=True) assert (s_rad_nm + s_rad_nm).compare_with(2 * s_rad, spectra_only="radiance", plot=True, rtol=1e-3)
def test_multiplyAndAddition(verbose=True, plot=False, *args, **kwargs): s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update("radiance_noslit", verbose=False) s.apply_slit(0.1) s = Radiance(s) assert s.units["radiance"] == "mW/cm2/sr/nm" s_bis = add_constant(s, 1, "mW/cm2/sr/nm") w, Idiff = get_diff(s_bis, s, "radiance") test = Idiff[1] - 1 assert np.all(test < 1e-10) s_ter = multiply(multiply(s, 50), 1 / 50) # plot_diff(s_ter, s_5) diff = get_diff(s_ter, s, "radiance") ratio = abs(np.trapz(diff[1], x=diff[0]) / s.get_integral("radiance")) assert ratio < 1e-10
def test_compare_methods(verbose=True, plot=True, close_plots=True, *args, **kwargs): """ Just run all Spectrum compare methods to check they work""" if plot and close_plots: import matplotlib.pyplot as plt plt.close("all") s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) # limits to a single line, because get_distance() s.resample(np.linspace(2193, 2193.8, 100)) # is very computationaly heavy s.update("radiance_noslit") s_noabsorption = s.copy() s.name = "solve RTE" s_noabsorption.name = "optically thin" # rescale, normal # s.rescale_mole_fraction(10) s.rescale_path_length(10) # rescale, optically thin mode s_noabsorption.conditions["self_absorption"] = False # s_noabsorption.rescale_mole_fraction(10) s_noabsorption.rescale_path_length(10) # Compare # should be added in an example with experimental fit of bandhead get_distance(s, s_noabsorption, "radiance_noslit") title = "CO x={0:.2f}, L={1:.2f}cm".format(s.conditions["mole_fraction"], s.conditions["path_length"]) if plot: plot_diff(s, s_noabsorption, method="diff", diff_window=1, title=title) plot_diff(s, s_noabsorption, method="ratio", normalize=True, title=title)
def test_offset(verbose=True, plot=False, *args, **kwargs): s = load_spec(getTestFile("CO_Tgas1500K_mole_fraction0.01.spec"), binary=True) s.update('radiance_noslit', verbose=False) s.apply_slit(0.1) s2 = offset(s, 10, 'nm', name='offset_10nm') if plot: plot_diff(s, s2) assert np.allclose(s2.get_wavelength(which='convoluted'), s.get_wavelength(which='convoluted') + 10) assert np.allclose(s2.get_wavelength(which='non_convoluted'), s.get_wavelength(which='non_convoluted') + 10) # Test inplace version s.offset(10, 'nm') assert np.allclose(s2.get_wavelength(which='convoluted'), s.get_wavelength(which='convoluted'))