def test_temperature_units_conversion(input_temperature, expected_temperature_K, verbose=True, *args, **kwargs): setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavelength_min=4300, wavelength_max=4500, wstep=0.01, cutoff=1e-30, pressure=1, mole_fraction=1, isotope=[1], Tref=300 * u.K, verbose=verbose, ) sf.load_databank("HITRAN-CO-TEST") s = sf.eq_spectrum(Tgas=input_temperature, pressure=20 * u.mbar, path_length=1 * u.mm) assert np.isclose(s.conditions["Tgas"], expected_temperature_K) assert np.isclose(s.conditions["path_length"], 0.1) # cm assert np.isclose(s.conditions["pressure_mbar"], 20)
def test_eq_vs_noneq_isotope(verbose=True, plot=False, warnings=True, *args, **kwargs): ''' Test same spectrum for 2 different calculation codes (equilibrium, non-equilibrium) in the presence of isotopes Notes ----- On the old NeQ package the test used [HITEMP-2010]_ Starting from RADIS 1.0.1, the test is run on [HITRAN-2016]_, which is not valid for these temperatures but can be more conveniently downloaded automatically and thus executed everytime with [Travis]_ ''' try: Tgas = 1500 sf = SpectrumFactory(wavelength_min=4250, wavelength_max=4350, mole_fraction=1, path_length=1, cutoff=1e-25, molecule='CO2', isotope='1,2', db_use_cached=True, verbose=verbose) sf.warnings['MissingSelfBroadeningWarning'] = 'ignore' sf.warnings['NegativeEnergiesWarning'] = 'ignore' sf.warnings['HighTemperatureWarning'] = 'ignore' sf.fetch_databank( ) # uses HITRAN: not really valid at this temperature, but runs on all machines without install # sf.load_databank('HITEMP-CO2-DUNHAM') s_nq = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas, name='Non-eq') s_eq = sf.eq_spectrum(Tgas=Tgas, name='Eq') rtol = 5e-3 # 2nd isotope calculated with placeholder energies match_eq_vs_non_eq = s_eq.compare_with(s_nq, spectra_only='abscoeff', rtol=rtol, plot=plot) match_eq_vs_non_eq *= s_eq.compare_with(s_nq, spectra_only='radiance_noslit', rtol=rtol, plot=plot) if verbose: printm('Tested eq vs non-eq (<{0:.1f}% error) with isotopes: {1}'. format(rtol * 100, bool(match_eq_vs_non_eq))) assert match_eq_vs_non_eq except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_eq_vs_noneq_isotope(verbose=True, plot=False, warnings=True, *args, **kwargs): """Test same spectrum for 2 different calculation codes (equilibrium, non-equilibrium) in the presence of isotopes Notes ----- On the old NeQ package the test used [HITEMP-2010]_ Starting from RADIS 1.0.1, the test is run on [HITRAN-2016]_, which is not valid for these temperatures but can be more conveniently downloaded automatically and thus executed everytime with `Travis CI <https://travis-ci.com/radis/radis>`_ """ Tgas = 1500 sf = SpectrumFactory( wavelength_min=4250, wavelength_max=4350, mole_fraction=1, path_length=1, cutoff=1e-25, molecule="CO2", isotope="1,2", db_use_cached=True, verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.warnings["HighTemperatureWarning"] = "ignore" sf.fetch_databank( ) # uses HITRAN: not really valid at this temperature, but runs on all machines without install # sf.load_databank('HITEMP-CO2-DUNHAM') s_nq = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas, name="Non-eq") s_eq = sf.eq_spectrum(Tgas=Tgas, name="Eq") rtol = 5e-3 # 2nd isotope calculated with placeholder energies match_eq_vs_non_eq = s_eq.compare_with(s_nq, spectra_only="abscoeff", rtol=rtol, plot=plot) match_eq_vs_non_eq *= s_eq.compare_with(s_nq, spectra_only="radiance_noslit", rtol=rtol, plot=plot) if verbose: printm( "Tested eq vs non-eq (<{0:.1f}% error) with isotopes: {1}".format( rtol * 100, bool(match_eq_vs_non_eq))) assert match_eq_vs_non_eq
def test_populations(verbose=True, *args, **kwargs): """ Test that vib and rovib populations are calculated correctly """ from radis.lbl import SpectrumFactory from radis.misc.basics import all_in export = ["vib", "rovib"] sf = SpectrumFactory( 2000, 2300, export_populations=export, db_use_cached=True, cutoff=1e-25, isotope="1", ) sf.warnings.update({ "MissingSelfBroadeningWarning": "ignore", "VoigtBroadeningWarning": "ignore" }) sf.load_databank("HITRAN-CO-TEST") s = sf.non_eq_spectrum(2000, 2000) pops = sf.get_populations(export) if not all_in(["rovib", "vib"], list(pops["CO"][1]["X"].keys())): raise AssertionError( "vib and rovib levels should be defined after non_eq_spectrum calculation!" ) if not "nvib" in list(pops["CO"][1]["X"]["vib"].keys()): raise AssertionError( "Vib populations should be defined after non_eq_spectrum calculation!" ) s = sf.eq_spectrum(300) pops = sf.get_populations(export) if "nvib" in list(pops["CO"][1]["X"]["vib"].keys()): raise AssertionError( "Vib levels should not be defined anymore after eq_spectrum calculation!" ) # Any of these is True and something went wrong s = sf.non_eq_spectrum(2000, 2000) s2 = sf.non_eq_spectrum(300, 300) # printm(all(s2.get_vib_levels(isotope=1) == s.get_vib_levels(isotope=1))) assert not (s2.get_vib_levels() is s.get_vib_levels()) assert not (s2.get_rovib_levels() == s.get_rovib_levels()).all().all() assert not (s2.get_rovib_levels() is s.get_rovib_levels()) return True # if no AssertionError
def test_rescaling_mole_fraction(debug=False, plot=False, verbose=True, warnings=True, *args, **kwargs): """ Test rescaling functions """ from radis.lbl import SpectrumFactory if plot: # Make sure matplotlib is interactive so that test are not stuck plt.ion() setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there Tgas = 1500 sf = SpectrumFactory( wavelength_min=4400, wavelength_max=4800, # mole_fraction=1, path_length=0.1, mole_fraction=0.01, cutoff=1e-25, wstep=0.005, isotope=[1], db_use_cached=True, self_absorption=True, verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.load_databank("HITRAN-CO-TEST") error = [] N = [1e-3, 1e-2, 1e-1, 0.3, 0.6, 1] # first is ref for Ni in N: s1 = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=N[0]) sN = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=Ni) s1.rescale_mole_fraction(Ni) error.append(sN.get_power() / s1.get_power()) if plot: plt.figure(fig_prefix + "Rescaling mole fractions") plt.plot(N, error, "-ok") plt.scatter( N[0], error[0], s=200, facecolors="none", edgecolors="r", label="reference", ) plt.xlabel("Mole fraction") plt.ylabel("scaled energy / ab initio energy") plt.xscale("log") plt.legend() plt.title("Effect of scaling mole fraction w/o lineshape update") plt.tight_layout() # less than 1% error when rescaling from 1e-3 to 0.6 assert abs(error[-2] - 1) < 0.01
def test_populations(verbose=True, *args, **kwargs): ''' Test that vib and rovib populations are calculated correctly ''' from radis.lbl import SpectrumFactory from radis.misc.basics import all_in export = ['vib', 'rovib'] sf = SpectrumFactory(2000, 2300, export_populations=export, db_use_cached=True, cutoff=1e-25, isotope='1') sf.warnings.update({ 'MissingSelfBroadeningWarning': 'ignore', 'VoigtBroadeningWarning': 'ignore' }) sf.load_databank('HITRAN-CO-TEST') s = sf.non_eq_spectrum(2000, 2000) pops = sf.get_populations(export) if not all_in(['rovib', 'vib'], list(pops['CO'][1]['X'].keys())): raise AssertionError( 'vib and rovib levels should be defined after non_eq_spectrum calculation!' ) if not 'nvib' in list(pops['CO'][1]['X']['vib'].keys()): raise AssertionError( 'Vib populations should be defined after non_eq_spectrum calculation!' ) s = sf.eq_spectrum(300) pops = sf.get_populations(export) if 'nvib' in list(pops['CO'][1]['X']['vib'].keys()): raise AssertionError( 'Vib levels should not be defined anymore after eq_spectrum calculation!' ) # Any of these is True and something went wrong s = sf.non_eq_spectrum(2000, 2000) s2 = sf.non_eq_spectrum(300, 300) #printm(all(s2.get_vib_levels(isotope=1) == s.get_vib_levels(isotope=1))) assert not (s2.get_vib_levels() is s.get_vib_levels()) assert not (s2.get_rovib_levels() == s.get_rovib_levels()).all().all() assert not (s2.get_rovib_levels() is s.get_rovib_levels()) return True # if no AssertionError
def test_media_line_shift(plot=False, verbose=True, warnings=True, *args, **kwargs): ''' See wavelength difference in air and vacuum ''' if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() try: if verbose: printm('>>> _test_media_line_shift') setup_test_line_databases( ) # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory(wavelength_min=4500, wavelength_max=4600, wstep=0.001, parallel=False, bplot=False, cutoff=1e-30, path_length=0.1, mole_fraction=400e-6, isotope=[1], db_use_cached=True, medium='vacuum', broadening_max_width=10, verbose=verbose) sf.warnings['MissingSelfBroadeningWarning'] = 'ignore' sf.warnings['GaussianBroadeningWarning'] = 'ignore' sf.load_databank('HITRAN-CO-TEST') # Calculate a spectrum s = sf.eq_spectrum(2000) # Compare if plot: fig = plt.figure(fig_prefix + 'Propagating media line shift') s.plot('radiance_noslit', wunit='nm_vac', nfig=fig.number, lw=2, label='Vacuum') plt.title('CO spectrum (2000 K)') s.plot('radiance_noslit', wunit='nm', nfig=fig.number, lw=2, color='r', label='Air') # ... there should be about ~1.25 nm shift at 4.5 µm: assert np.isclose( s.get('radiance_noslit', wunit='nm_vac')[0][0] - s.get('radiance_noslit', wunit='nm')[0][0], 1.2540436086346745) except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def _distribute_noneq_spectrum(args): ''' Clone the Factory and calculate non_eq_spectrum over several clones ''' cast_factory, Tvib, Trot, mole_fraction, path_length = args # ... (dev) must match p.map(_distribute_noneq_spectrum...) order factory = deepcopy(cast_factory) # Update id factory._id = uuid1() return SpectrumFactory.non_eq_spectrum(factory, Tvib, Trot, mole_fraction=mole_fraction, path_length=path_length)
def test_rescaling_path_length(debug=False, plot=False, verbose=True, warnings=True, *args, **kwargs): """ Test rescaling functions """ if plot: # Make sure matplotlib is interactive so that test are not stuck plt.ion() try: from radis.lbl import SpectrumFactory setup_test_line_databases( ) # add HITRAN-CO-TEST in ~/.radis if not there Tgas = 1500 sf = SpectrumFactory( wavelength_min=4400, wavelength_max=4800, mole_fraction=0.01, # path_length=0.1, cutoff=1e-25, wstep=0.005, isotope=[1], db_use_cached=True, self_absorption=True, verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" # sf.warnings['NegativeEnergiesWarning'] = 'ignore' sf.load_databank("HITRAN-CO-TEST") s1 = sf.non_eq_spectrum(Tgas, Tgas, path_length=0.01) s2 = sf.non_eq_spectrum(Tgas, Tgas, path_length=3) s1.rescale_path_length(3) if plot: fig = plt.figure(fig_prefix + "Rescaling path length") s2.plot("radiance_noslit", nfig=fig.number, lw=3, label="L=3m") s1.plot( "radiance_noslit", nfig=fig.number, color="r", label="L=0.01m, rescaled to 3m", ) plt.title("Non optically thin rescaling") plt.legend() plt.tight_layout() if verbose: printm("Test rescaling:") printm("... Difference: {0:.2f}%".format( abs(s1.get_power() / s2.get_power() - 1) * 100)) assert np.isclose(s2.get_power(), s1.get_power(), 2e-3) except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_pathlength_units_conversion( input_pathlength, expected_pathlength_cm, verbose=True, *args, **kwargs ): setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavelength_min=4300, wavelength_max=4500, wstep=0.01, cutoff=1e-30, pressure=1, path_length=input_pathlength, mole_fraction=1, isotope=[1], verbose=verbose, ) sf.load_databank("HITRAN-CO-TEST") s = sf.eq_spectrum(Tgas=300) assert np.isclose(s.conditions["path_length"], expected_pathlength_cm)
def test_rescaling_mole_fraction(debug=False, plot=False, verbose=True, warnings=True, *args, **kwargs): ''' Test rescaling functions ''' from radis.lbl import SpectrumFactory if plot: # Make sure matplotlib is interactive so that test are not stuck plt.ion() try: setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there Tgas = 1500 sf = SpectrumFactory( wavelength_min=4400, wavelength_max=4800, # mole_fraction=1, path_length=0.1, mole_fraction=0.01, cutoff=1e-25, wstep=0.005, isotope=[1], db_use_cached=True, self_absorption=True, verbose=verbose) sf.warnings['MissingSelfBroadeningWarning'] = 'ignore' sf.warnings['NegativeEnergiesWarning'] = 'ignore' sf.load_databank('HITRAN-CO-TEST') error = [] N = [1e-3, 1e-2, 1e-1, 0.3, 0.6, 1] # first is ref for Ni in N: s1 = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=N[0]) sN = sf.non_eq_spectrum(Tgas, Tgas, mole_fraction=Ni) s1.rescale_mole_fraction(Ni) error.append(sN.get_power() / s1.get_power()) if plot: plt.figure(fig_prefix+'Rescaling mole fractions') plt.plot(N, error, '-ok') plt.scatter(N[0], error[0], s=200, facecolors='none', edgecolors='r', label='reference') plt.xlabel('Mole fraction') plt.ylabel('scaled energy / ab initio energy') plt.xscale('log') plt.legend() plt.title('Effect of scaling mole fraction w/o lineshape update') plt.tight_layout() # less than 1% error when rescaling from 1e-3 to 0.6 assert abs(error[-2]-1) < 0.01 except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
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_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_wavenumber_units_conversion( input_wavenumbers, expected_wavenumbers_cm1, verbose=True, *args, **kwargs ): setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there wmin, wmax = input_wavenumbers expected_wmin, expected_wmax = expected_wavenumbers_cm1 sf = SpectrumFactory( wavenum_min=wmin, wavenum_max=wmax, wstep=0.01, cutoff=1e-30, pressure=1, path_length=1, mole_fraction=1, isotope=[1], verbose=verbose, ) sf.load_databank("HITRAN-CO-TEST") s = sf.eq_spectrum(Tgas=300) assert np.isclose(s.get_wavenumber().min(), expected_wmin) assert np.isclose(s.get_wavenumber().max(), expected_wmax)
def test_media_line_shift(plot=False, verbose=True, warnings=True, *args, **kwargs): """ See wavelength difference in air and vacuum """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() if verbose: printm(">>> _test_media_line_shift") setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavelength_min=4500, wavelength_max=4600, wstep=0.001, parallel=False, bplot=False, cutoff=1e-30, path_length=0.1, mole_fraction=400e-6, isotope=[1], db_use_cached=True, medium="vacuum", broadening_max_width=10, verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["GaussianBroadeningWarning"] = "ignore" sf.load_databank("HITRAN-CO-TEST") # Calculate a spectrum s = sf.eq_spectrum(2000) # Compare if plot: fig = plt.figure(fig_prefix + "Propagating media line shift") s.plot("radiance_noslit", wunit="nm_vac", nfig=fig.number, lw=2, label="Vacuum") plt.title("CO spectrum (2000 K)") s.plot( "radiance_noslit", wunit="nm", nfig=fig.number, lw=2, color="r", label="Air", ) # ... there should be about ~1.25 nm shift at 4.5 µm: assert np.isclose( s.get("radiance_noslit", wunit="nm_vac")[0][0] - s.get("radiance_noslit", wunit="nm")[0][0], 1.2540436086346745, )
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(verbose=True, plot=False, *args, **kwargs): """ Generate scalable LevelList at 1500K. Rescale at 2000K and compare with spectrum directly calculated at 2000K """ from radis.lbl import SpectrumFactory iso = 1 sf = SpectrumFactory( wavelength_min=4170, wavelength_max=4200, mole_fraction=1, path_length=0.05, cutoff=1e-25, # isotope=[1,2], isotope=iso, db_use_cached=True, wstep=0.01, broadening_max_width=10, medium="air", verbose=verbose, ) sf.load_databank("CDSD") parfunc = sf.parsum_calc["CO2"][iso]["X"] # %% Fill levels for all bands Tref = 1500 s_bands = sf.non_eq_bands(Tvib=Tref, Trot=Tref) lvlist = LevelsList(parfunc, s_bands, sf.params.levelsfmt) # %% Test Tvib = 2000 s_resc = lvlist.non_eq_spectrum(Tvib=Tvib, Trot=Tref) s0 = sf.non_eq_spectrum(Tvib, Tref) return s0.compare_with(s_resc, spectra_only=True, plot=plot)
def test_plot_all_CO2_bandheads(verbose=True, plot=False, *args, **kwargs): ''' In this test we use the :meth:`~radis.lbl.bands.BandFactory.non_eq_bands` method to calculate separately all vibrational bands of CO2, and compare them with the final Spectrum. ''' # Note: only with iso1 at the moment if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() verbose = True Tgas = 1000 sf = SpectrumFactory(wavelength_min=4160, wavelength_max=4220, mole_fraction=1, path_length=0.3, cutoff=1e-23, molecule='CO2', isotope=1, db_use_cached=True, lvl_use_cached=True, verbose=verbose) sf.warnings['MissingSelfBroadeningWarning'] = 'ignore' sf.warnings['NegativeEnergiesWarning'] = 'ignore' sf.warnings['HighTemperatureWarning'] = 'ignore' sf.fetch_databank() s_tot = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas) s_bands = sf.non_eq_bands(Tvib=Tgas, Trot=Tgas) if verbose: printm('{0} bands in spectrum'.format(len(s_bands))) assert len(s_bands) == 6 # Ensure that recombining gives the same s_merged = MergeSlabs(*list(s_bands.values())) assert s_tot.compare_with(s_merged, 'radiance_noslit', plot=False) if verbose: printm('Recombining bands give the same Spectrum') # %% if plot: s_tot.apply_slit(1, 'nm') s_tot.name = 'Full spectrum' s_tot.plot(wunit='nm', lw=3) for band, s in s_bands.items(): s.plot(wunit='nm', nfig='same') plt.legend(loc='upper left') plt.ylim(ymax=0.25) # %% Compare with equilibrium bands now s_bands_eq = sf.eq_bands(Tgas) s_merged_eq = MergeSlabs(*list(s_bands_eq.values())) assert get_residual(s_tot, s_merged_eq, 'radiance_noslit') < 1e-5 return True
def test_retrieve_from_database(plot=True, verbose=True, warnings=True, *args, **kwargs): """Test autoretrieve from a database: first generate an empty :py:class:`~radis.tools.database.SpecDatabase` associated to a :py:class`~radis.lbl.factory.SpectrumFactory`, then calculate a first spectrum, then calculate it again and make sure it is retrieved from the database """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() temp_database_name = "temp_spec_database" try: if verbose: printm(">>> test_retrieve_from_database") assert not exists(temp_database_name) setup_test_line_databases( ) # add HITEMP-CO2-TEST in ~/.radis if not there sf = SpectrumFactory( 2284.2, 2284.6, wstep=0.001, # cm-1 pressure=20 * 1e-3, # bar cutoff=0, path_length=0.1, mole_fraction=400e-6, molecule="CO2", isotope=[1], db_use_cached=True, medium="vacuum", broadening_max_width=10, export_populations="rovib", verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.init_databank( "HITEMP-CO2-TEST" ) # unlike load_databank, will automatically be built when needed db = sf.init_database(temp_database_name, autoretrieve=True) assert len(db) == 0 # Calculate a first spectrum s1 = sf.non_eq_spectrum(2000, 1000) assert len(db) == 1 # Note that the Spectrum in database is not s1 because populations # are not stored by default # hack: now change the `autoretrieve` status to `force` to make sure # the spectrum is retrieved. Else, an error will be raised sf.autoretrievedatabase = "force" # Calculate spectrum under the same conditions s2 = sf.non_eq_spectrum(2000, 1000) # Note that s1 == s2 won't work because populations are not stored # by default in the database assert s1.compare_with(s2, spectra_only=True) return True finally: rmtree(temp_database_name)
def test_spec_generation(plot=True, verbose=2, warnings=True, *args, **kwargs): """ Test spectrum generation Can be used as a base to generate spectra in your codes Non-regression test: compare with past version (see conditions below) Compare results from a reference case to results calculated on 30/12/2017 This is not a validation case (30/12/2017 results are not a physically validated case), but it makes sure results dont change over time Conditions (30/12/2017):: Physical Conditions ---------------------------------------- Tgas 300 K Trot 300 K Tvib 300 K pressure 1.01325 bar isotope 1,2 mole_fraction 1 molecule CO2 path_length 1 cm wavelength_max 4400.0 nm wavelength_min 4150.0 nm wavenum_max 2409.6385542168673 cm-1 wavenum_min 2272.7272727272725 cm-1 Computation Parameters ---------------------------------------- Tref 296 K broadening_max_width 10 cm-1 cutoff 1e-25 cm-1/(#.cm-2) db_assumed_sorted True db_use_cached True dbformat cdsd dbpath # USER-DEPENDANT: CDSD-HITEMP fillmissinglevelswithzero False levelsfmt cdsd levelspath # USER-DEPENDANT: CDSD-4000 medium vacuum parfuncfmt cdsd parfuncpath # USER-DEPENDANT: CDSD-4000 rot_distribution boltzmann self_absorption True vib_distribution boltzmann wavenum_max_calc 2414.6385542168673 cm-1 wavenum_min_calc 2267.7272727272725 cm-1 waveunit cm-1 wstep 0.01 cm-1 ---------------------------------------- Notes ----- Performance test. How long it tooks to calculate this Spectrum? Test with cutoff 1e-25, broadening_max_width=10 - 0.9.15: >>> 33s - 0.9.16*: (replaced groupby().apply() with iteration over indexes) >>> 32s [but large impact expected on big files] - 0.9.16*: (upgraded cache files to h5) >>> 25s - 0.9.16*: (also added h5 cache file for levels) >>> 21s - 0.9.16*: (with Whiting slit voigt function) >>> 5.8s Test with cutoff 1e-27, broadening_max_width=50 : ("Spectrum calculated in ... ", including database loading time) - 0.9.16*: (same code as last) >>> 12.5s including 7.6s of broadening - 0.9.16**: (with pseudo_continuum_threshold=0.01) >>> 7.8s including 2.3s of broadening - 0.9.18 (normal code, no pseudo continuum). >>> ? - 0.9.21 (normal code) >>> 13.7s, including 8.7s of broadening (with pseudo_continuum_threshold=0.01) >>> 4.3s, including 2.6s of broadening - 0.9.21* >>> 14.0s (added the manual lineshape normalization instead of Whitings's polynomial) - 0.9.22 (normal code) >>> 11.3s (without energy level lookup, for eq. calculations) (with pseudo_continuum_threshold=0.01) >>> 5.9s - 0.9.23 (normal code) >>> 7.2s (added jit in Voigt broadening) >>> 7.1s (chunksize = None) (and much faster for more lines) (with pseudo_continuum_threshold=0.01) >>> 4.9s RADIS: - 0.9.19 (normal code) >>> 6.3 s - 0.9.20 (normal code) >>> 6.3 s (with pseudo_continuum_threshold=0.01) >>> ??? (with DLM) >>> 2.3 s """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() from time import time t0 = time() if verbose: printm(">>> _test_spec_generation") # This is how you get a spectrum (see calc.py for front-end functions # that do just that) sf = SpectrumFactory( wavelength_min=4150, wavelength_max=4400, parallel=False, bplot=False, cutoff=1e-27, isotope="1,2", db_use_cached=True, broadening_max_width=50, # chunksize='DLM', # pseudo_continuum_threshold=0.01, medium="vacuum", verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.load_databank( "HITEMP-CO2-DUNHAM", load_energies=False, # no need to load energies at equilibrium ) s = sf.eq_spectrum(Tgas=300) if verbose: printm( ">>> _test_spec_generation: Spectrum calculated in {0:.2f}s".format( time() - t0 ) ) if plot: plt.figure(fig_prefix + "Reference spectrum CDSD-HITEMP (radiance)") # Iunit is arbitrary. Use whatever makes sense s.plot("radiance_noslit", Iunit="µW/cm2/sr/nm", nfig="same") s.rescale_path_length(0.01) # Here we get some extra informations: if plot: sf.plot_broadening(i=0) # show broadening of one line plt.xlim((2267.20, 2268.30)) # Compare with harcoded results # ... code previously used to export hardcoded results: # ... and header contains all input conditions: # np.savetxt('output.txt', np.vstack(s.get('abscoeff', wunit='nm')).T[::10]) # print(s) # ................ from radis.test.utils import getTestFile wref, Iref = np.loadtxt(getTestFile("CO2abscoeff_300K_4150_4400nm.txt")).T match_reference = np.allclose(s.get("abscoeff", wunit="nm")[1][::10], Iref) if not match_reference: # give some more information before raising error printm( "Error: {0:.2f}%".format( np.mean(abs(s.get("abscoeff", wunit="nm")[1][::10] / Iref - 1)) * 100 ) ) # Store the faulty spectrum s.store( "test_factory_failed_{0}.spec".format(radis.get_version()), if_exists_then="replace", ) # Plot comparison if plot: plt.figure(fig_prefix + "Reference spectrum (abscoeff)") # , show_points=True) # show_points to have an s.plot( "abscoeff", wunit="nm", medium="air", nfig="same", lw=3, label="RADIS, this version", ) # idea of the resolution plt.plot(wref, Iref, "or", ms=3, label="version NEQ 0.9.20 (12/05/18)") plt.legend() plt.title("All close: {0}".format(match_reference)) plt.tight_layout() # Another example, at higher temperature. # Removed because no test is associated with it and it takes time for # nothing # s2 = sf.non_eq_spectrum(Tvib=1000, Trot=300) # if plot: s2.plot('abscoeff', wunit='nm') if verbose: printm( "Spectrum calculation (no database loading) took {0:.1f}s\n".format( s.conditions["calculation_time"] ) ) printm("_test_spec_generation finished in {0:.1f}s\n".format(time() - t0)) assert match_reference
def test_power_integral(verbose=True, warnings=True, *args, **kwargs): """ Test direct calculation of power integral from Einstein coefficients matches integration of broadened spectrum in the optically thin case We compare: - direct calculation of power integral with equilibrium code :meth:`~radis.lbl.SpectrumFactory.optically_thin_power` (T) - direct calculation of power integral with non equilibrium code :meth:`~radis.lbl.SpectrumFactory.optically_thin_power` (T,T) - numerical integration of non equilibrium spectrum under optically thin conditions: :meth:`~radis.spectrum.spectrum.Spectrum.get_power` Test passes if error < 0.5% """ if verbose: printm(">>> _test_power_integral") setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavelength_min=4300, wavelength_max=4666, wstep=0.001, parallel=False, bplot=False, cutoff=1e-30, path_length=10, mole_fraction=400e-6, isotope=[1], db_use_cached=True, broadening_max_width=10, verbose=verbose, ) sf.warnings.update( { "MissingSelfBroadeningWarning": "ignore", "OutOfRangeLinesWarning": "ignore", "HighTemperatureWarning": "ignore", } ) sf.load_databank("HITRAN-CO-TEST") unit = "µW/sr/cm2" T = 600 # Calculate: # ... direct calculation of power integral with equilibrium code Peq = sf.optically_thin_power(Tgas=T, unit=unit) # ... direct calculation of power integral with non equilibrium code Pneq = sf.optically_thin_power(Tvib=T, Trot=T, unit=unit) # ... numerical integration of non equilibrium spectrum under optically thin # ... conditions sf.input.self_absorption = False s = sf.non_eq_spectrum(T, T) assert s.conditions["self_absorption"] == False # Compare err = abs(Peq - s.get_power(unit=unit)) / Peq if verbose: printm("Emission integral:\t{0:.4g}".format(Peq), unit) printm("Emission (noneq code):\t{0:.4g}".format(Pneq), unit) printm("Integrated spectrum:\t{0:.4g}".format(s.get_power(unit=unit)), unit) printm("Error: {0:.2f}%".format(err * 100)) assert err < 0.005
def test_medium(plot=False, verbose=True, debug=False, warnings=True, *args, **kwargs): ''' Test effect of propagating medium ''' from radis.lbl.factory import SpectrumFactory if plot: # Make sure matplotlib is interactive so that test are not stuck plt.ion() T = 300 try: setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there pl = SpectrumFactory( wavenum_min=2171.5, wavenum_max=2174, mole_fraction=0.01, medium='vacuum', isotope='1,2') pl.warnings['MissingSelfBroadeningWarning'] = 'ignore' pl.load_databank('HITRAN-CO-TEST') s = pl.non_eq_spectrum(Tvib=T, Trot=T) # , Ttrans=300) pla = SpectrumFactory( wavenum_min=2171.5, wavenum_max=2174, mole_fraction=0.01, medium='air', isotope='1,2') pla.load_databank('HITRAN-CO-TEST') s_air = pla.non_eq_spectrum(Tvib=T, Trot=T) # , Ttrans=300) if plot: plt.figure(fig_prefix+'Propagating medium conversions') s.plot(nfig='same', lw=3, medium='vacuum', label='vacuum') s.plot(nfig='same', medium='air', label='air') assert np.allclose(s.get_wavenumber(), s_air.get_wavenumber()) assert np.allclose(s.get_wavelength(medium='vacuum'), s_air.get_wavelength(medium='vacuum')) assert np.allclose(s.get_wavelength(medium='air'), s_air.get_wavelength(medium='air')) assert all(s.get_wavelength(medium='vacuum') > s.get_wavelength(medium='air')) except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_3Tvib_vs_1Tvib(verbose=True, plot=False, warnings=True, *args, **kwargs): if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() setup_test_line_databases() try: T = 1500 iso = [1] sf = SpectrumFactory( wavenum_min=2380, wavenum_max=2400, pressure=20 * 1e-3, db_use_cached=True, cutoff=1e-25, isotope=iso, # ,2', path_length=10, mole_fraction=0.1, broadening_max_width=1, medium="vacuum", verbose=verbose, ) sf.warnings.update({ "MissingSelfBroadeningWarning": "ignore", "VoigtBroadeningWarning": "ignore", }) sf.load_databank("HITRAN-CO2-TEST") # Compare energies for I in iso: energies = sf.get_energy_levels("CO2", I, "X") assert (energies.Evib == energies.Evib1 + energies.Evib2 + energies.Evib3).all() if verbose: printm("Tested Evib == Evib1+Evib2+Evib3: OK") s3 = sf.non_eq_spectrum((T, T, T), T) s1 = sf.non_eq_spectrum(T, T) s3.name = "Tvib=({0},{0},{0}) K, Trot={0} K".format(T) s1.name = "Tvib={0} K, Trot={0} K".format(T) if plot: s1.plot( "transmittance_noslit", wunit="cm-1", color="k", lw=3, label="Tvib = {0}K".format(T), ) s3.plot( "transmittance_noslit", wunit="cm-1", color="r", lw=3, nfig="same", label="Tvib1 = Tvib2 = Tvib3 = {0}K".format(T), ) assert s1.compare_with(s3, spectra_only=True, verbose=verbose, plot=plot) if verbose: printm( "Tested Spectra 3Tvib(T1=T2=T3=T) and 1Tvib(T) are the same: OK" ) return True except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_direct_overpopulation_vs_recombined_bands(verbose=True, plot=False, warnings=True, rtol=0.05, *args, **kwargs): """ Compare a non-equilibrium spectrum calculated directly with overpopulations, or by recombining pre-calculated vibrational bands. The later allows for almost instantaneous changes of the overpopulation factors, (mostly useful in fitting algorithms), but is only valid for optically thin emission spectra Expected output: when x_CO2 = 1e-3, radiance in both cases match when x_CO2 = 1, they dont """ # Notes # ----- # # On the old NeQ package the test used [HITEMP-2010]_ # # Starting from RADIS 1.0.1, the test is run on [HITRAN-2016]_, which # is not valid for these temperatures but can be more conveniently # downloaded automatically and thus executed everytime with [Travis]_ # # Note: only with iso1 at the moment if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() try: # Generate factory iso = 1 sf = SpectrumFactory( wavelength_min=4220, wavelength_max=4280, mole_fraction=1e-3, path_length=10, cutoff=1e-25, molecule="CO2", isotope=iso, db_use_cached=True, wstep=0.01, broadening_max_width=5, medium="air", verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.load_databank("CDSD-HITEMP-PCN") # sf.fetch_databank() # uses HITRAN: not really valid at this temperature, but runs on all machines without install # Generate bands to recombine parfunc = sf.parsum_calc["CO2"][iso]["X"] Tref = 1500 # , return_lines=False) s_bands = sf.non_eq_bands(Tvib=Tref, Trot=Tref) lvlist = LevelsList(parfunc, s_bands, sf.params.levelsfmt) # Compare ab initio and recombined from bands at M = 1e-3 s_recombined = lvlist.non_eq_spectrum(Tvib=Tref, Trot=Tref, overpopulation={"(4,1,3)": 3}) sref = sf.non_eq_spectrum(Tvib=Tref, Trot=Tref, overpopulation={"(4,1,3)": 1}) if verbose: printm( "Testing x_CO2 = 1e-3: ab initio ~ recombined bands (<{0:.1f}%):\t" .format(rtol * 100)) if plot: plot_diff( sref, s_recombined, var="radiance_noslit", label1="ab initio", label2="recombined bands", title="x_CO2 = 1e-3", ) assert np.allclose(s_recombined.get_radiance_noslit(), sref.get_radiance_noslit(), rtol=rtol) # Rescale and try again for x_CO2 = 1 s_recombined.rescale_mole_fraction(1) sref.rescale_mole_fraction(1) if plot: plot_diff( sref, s_recombined, var="radiance_noslit", label1="ab initio", label2="recombined bands", title="x_CO2 = 1", ) if verbose: printm( "Testing x_CO2 = 1: ab initio ~ recombined bands (<{0:.1f}%):\t{1}" .format( rtol * 100, np.allclose( s_recombined.get_radiance_noslit(), sref.get_radiance_noslit(), rtol=rtol, ), )) with pytest.raises(AssertionError): assert np.allclose( s_recombined.get_radiance_noslit(), sref.get_radiance_noslit(), rtol=rtol, ) return True except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_plot_all_CO2_bandheads(verbose=True, plot=False, *args, **kwargs): """In this test we use the :meth:`~radis.lbl.bands.BandFactory.non_eq_bands` method to calculate separately all vibrational bands of CO2, and compare them with the final Spectrum. """ # Note: only with iso1 at the moment if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() Tgas = 1000 sf = SpectrumFactory( wavelength_min=4160, wavelength_max=4220, mole_fraction=1, path_length=0.3, cutoff=1e-23, molecule="CO2", isotope=1, optimization=None, verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.warnings["HighTemperatureWarning"] = "ignore" sf.fetch_databank("hitran") s_tot = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas) s_bands = sf.non_eq_bands(Tvib=Tgas, Trot=Tgas) if verbose: printm("{0} bands in spectrum".format(len(s_bands))) assert len(s_bands) == 6 # Ensure that recombining gives the same s_merged = MergeSlabs(*list(s_bands.values())) assert s_tot.compare_with(s_merged, "radiance_noslit", plot=False) if verbose: printm("Recombining bands give the same Spectrum") # %% if plot: s_tot.apply_slit(1, "nm") s_tot.name = "Full spectrum" s_tot.plot(wunit="nm", lw=3) for band, s in s_bands.items(): s.plot(wunit="nm", nfig="same") plt.legend(loc="upper left") plt.ylim(ymax=0.25) # %% Compare with equilibrium bands now s_bands_eq = sf.eq_bands(Tgas) s_merged_eq = MergeSlabs(*list(s_bands_eq.values())) assert get_residual(s_tot, s_merged_eq, "radiance_noslit") < 1.5e-5 return True
def test_medium(plot=False, verbose=True, debug=False, warnings=True, *args, **kwargs): """ Test effect of propagating medium """ from radis.lbl.factory import SpectrumFactory if plot: # Make sure matplotlib is interactive so that test are not stuck plt.ion() T = 300 setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there pl = SpectrumFactory( wavenum_min=2171.5, wavenum_max=2174, mole_fraction=0.01, medium="vacuum", isotope="1,2", ) pl.warnings["MissingSelfBroadeningWarning"] = "ignore" pl.load_databank("HITRAN-CO-TEST") s = pl.non_eq_spectrum(Tvib=T, Trot=T) # , Ttrans=300) pla = SpectrumFactory( wavenum_min=2171.5, wavenum_max=2174, mole_fraction=0.01, medium="air", isotope="1,2", ) pla.load_databank("HITRAN-CO-TEST") s_air = pla.non_eq_spectrum(Tvib=T, Trot=T) # , Ttrans=300) if plot: plt.figure(fig_prefix + "Propagating medium conversions") s.plot(wunit="nm_vac", nfig="same", lw=3, label="vacuum") s.plot(wunit="nm", nfig="same", label="air") assert np.allclose(s.get_wavenumber(), s_air.get_wavenumber()) assert np.allclose( s.get_wavelength(medium="vacuum"), s_air.get_wavelength(medium="vacuum") ) assert np.allclose( s.get_wavelength(medium="air"), s_air.get_wavelength(medium="air") ) assert all(s.get_wavelength(medium="vacuum") > s.get_wavelength(medium="air"))
def test_populations_CO2_hamiltonian( plot=True, verbose=True, warnings=True, *args, **kwargs ): """Calculate nonequilibrium modes with the CO2 Hamiltonian ..warning:: as we only use a reduced set of the CO2 effective Hamiltonian (< 3000 cm-1), many levels of the Line Database will not appear in the Levels Database. We will need to either filter the Line Database beforehand, or run it a first time and remove all levels not found. This database is obviously not to be used in a Production code! """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() if verbose: printm(">>> _test_media_line_shift") setup_test_line_databases() # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavenum_min=2283.7, wavenum_max=2285.1, wstep=0.001, cutoff=1e-30, path_length=0.1, mole_fraction=400e-6, isotope=[1], medium="vacuum", broadening_max_width=10, export_populations="rovib", verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.load_databank("HITEMP-CO2-HAMIL-TEST") # First run a calculation at equilibrium s = sf.eq_spectrum(300) s.name = "equilibrium" # Now generate vibrational energies for a 2-T model # ... Note that this is arbitrary. Lookup Pannier & Dubuet 2020 for more. levels = sf.parsum_calc["CO2"][1]["X"].df levels["Evib"] = levels.Evib1 + levels.Evib2 + levels.Evib3 # Calculate populations using the non-equilibrium module: # This will crash the first time (see error in docstrings of the function). with pytest.raises(AssertionError): sf.non_eq_spectrum(300, 300) sf.df0.dropna(inplace=True) # Retry: s_noneq = sf.non_eq_spectrum(300, 300) s_noneq.name = "nonequilibrium" # Tests: # s.compare_with(s_noneq, plot=plot) assert s_noneq.get_power() > 0 # TODO: implement actual Assertions (right now we're just checking that # functions are properly parsed) # TODO. Fix below (and move in dedicated test): # s.line_survey() return True
def test_populations(plot=True, verbose=True, warnings=True, *args, **kwargs): """ See wavelength difference in air and vacuum """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() try: if verbose: printm(">>> _test_media_line_shift") setup_test_line_databases( ) # add HITRAN-CO-TEST in ~/.radis if not there sf = SpectrumFactory( wavelength_min=4500, wavelength_max=4600, wstep=0.001, parallel=False, bplot=False, cutoff=1e-30, path_length=0.1, mole_fraction=400e-6, isotope=[1], db_use_cached=True, medium="vacuum", broadening_max_width=10, export_populations="rovib", verbose=verbose, ) sf.warnings["MissingSelfBroadeningWarning"] = "ignore" sf.load_databank("HITRAN-CO-TEST") # Populations cannot be calculated at equilibrium (no access to energy levels) s = sf.eq_spectrum(300) with pytest.raises(ValueError): # .. we expect this error here! pops = s.get_populations("CO", isotope=1, electronic_state="X") # Calculate populations using the non-equilibrium module: s = sf.non_eq_spectrum(300, 300) pops = s.get_populations("CO", isotope=1, electronic_state="X") if not "n" in list(pops["rovib"].keys()): raise ValueError("Populations not calculated") if plot: s.plot_populations() # Compare with factory # Plot populations: with pytest.raises(ValueError): sf.plot_populations() # no isotope given: error expected if plot: sf.plot_populations("rovib", isotope=1) plt.close() # no need to keep it open, we just tested the function # Test calculated quantities are there assert hasattr(sf.df1, "Qref") assert hasattr(sf.df1, "Qvib") assert hasattr(sf.df1, "Qrotu") assert hasattr(sf.df1, "Qrotl") # Test hardcoded populations assert np.isclose(pops["rovib"]["n"].iloc[0], 0.0091853446840826653) assert np.isclose(pops["rovib"]["n"].iloc[1], 0.027052543988733215) assert np.isclose(pops["rovib"]["n"].iloc[2], 0.04345502115897712) return True except DatabankNotFound as err: assert IgnoreMissingDatabase(err, __file__, warnings)
def test_optically_thick_limit_1iso(verbose=True, plot=True, *args, **kwargs): """ Test that we find Planck in the optically thick limit In particular, this test will fail if : - linestrength are not properly calculated - at noneq, linestrength and emission integrals are mixed up The test should be run for 1 and several isotopes, because different calculations paths are used internally, and this can lead to different errors. Also, this test is used to run with DEBUG_MODE = True, which will check that isotopes and molecule ids are what we expect in all the groupby() loops that make the production code very fast. Notes ----- switched from large band calculation with [HITRAN-2016]_ to a calculation with the embedded [HITEMP-2010]_ fragment (shorter range, but no need to download files) """ if plot: # Make sure matplotlib is interactive so that test are not stuck in pytest plt.ion() # Force DEBUG_MODE DEBUG_MODE = radis.DEBUG_MODE radis.DEBUG_MODE = True try: wavenum_min = 2284.2 wavenum_max = 2284.6 P = 0.017 # bar wstep = 0.001 # cm-1 Tgas = 1200 # %% Generate some CO2 emission spectra # -------------- sf = SpectrumFactory( wavenum_min=wavenum_min, wavenum_max=wavenum_max, molecule="CO2", mole_fraction=1, path_length=0.05, cutoff=1e-25, broadening_max_width=1, export_populations=False, #'vib', export_lines=False, isotope=1, use_cached=True, wstep=wstep, pseudo_continuum_threshold=0, pressure=P, verbose=False, ) # sf.fetch_databank('astroquery') sf.warnings["NegativeEnergiesWarning"] = "ignore" sf.load_databank("HITEMP-CO2-TEST") pb = ProgressBar(3, active=verbose) s_eq = sf.eq_spectrum(Tgas=Tgas, mole_fraction=1, name="Equilibrium") pb.update(1) s_2T = sf.non_eq_spectrum(Tvib=Tgas, Trot=Tgas, mole_fraction=1, name="Noneq (2T)") pb.update(2) s_4T = sf.non_eq_spectrum(Tvib=(Tgas, Tgas, Tgas), Trot=Tgas, mole_fraction=1, name="Noneq (4T)") pb.update(3) s_plck = sPlanck( wavelength_min=2000, # =wavelength_min, wavelength_max= 5000, # =wavelength_max - wstep, # there is a border effect on last point T=Tgas, ) pb.done() # %% Post process: # MAke optically thick, and compare with Planck for s in [s_eq, s_2T, s_4T]: s.rescale_path_length(1e6) if plot: nfig = "test_opt_thick_limit_1iso {0}".format(s.name) plt.figure(nfig).clear() s.plot(wunit="nm", nfig=nfig, lw=4) s_plck.plot(wunit="nm", nfig=nfig, Iunit="mW/cm2/sr/nm", lw=2) plt.legend() if verbose: printm( "Residual between opt. thick CO2 spectrum ({0}) and Planck: {1:.2g}" .format( s.name, get_residual(s, s_plck, "radiance_noslit", ignore_nan=True), )) # assert get_residual(s, s_plck, 'radiance_noslit', ignore_nan=True) < 1e-3 assert get_residual(s, s_plck, "radiance_noslit", ignore_nan=True) < 0.9e-4 if verbose: printm("Tested optically thick limit is Planck (1 isotope): OK") finally: # Reset DEBUG_MODE radis.DEBUG_MODE = DEBUG_MODE