def test_calc_hitemp_spectrum(*args, **kwargs): """ Test direct loading of HDF5 files """ from astropy import units as u from radis import calc_spectrum calc_spectrum( wavenum_min=2500 / u.cm, wavenum_max=4500 / u.cm, molecule="OH", Tgas=600, databank="hitemp", # test by fetching directly verbose=False, ) calc_spectrum( wavenum_min=2500 / u.cm, wavenum_max=4500 / u.cm, molecule="OH", Tgas=600, databank="HITEMP-OH", # test by loading the downloaded database verbose=False, ) return
def simulate(self, molec_name, min_wavelength=0, max_wavelength=None, isotopologues=None, wavelengths=None, **kwargs): self.molec_name = molec_name self.isotopologues = isotopologues if wavelengths is not None: minWavelengthStep = abs(wavelengths.diff().min()) * 0.25 else: minWavelengthStep = 0.01 if self.isotopologues is not None: isotopes = ','.join([str(k) for k in self.isotopologues.keys()]) else: isotopes = getAllIsotopes(self.molec_name) spec = radis.calc_spectrum(wavenum_min=min_wavelength, wavenum_max=max_wavelength, molecule=molec_name, isotope=isotopes, wstep=minWavelengthStep, databank='fetch', name=f'{self.name} (simulated)', **kwargs) spec.apply_slit(minWavelengthStep * 4, 'cm-1') nu, coeff = spec.get('abscoeff', wunit='cm-1') self.simulated = pd.DataFrame(data={ 'wavenumber': nu, 'intensity': coeff })
def test_plot_compare_with_nan( plot=True, verbose=True, close_plots=True, *args, **kwargs ): if plot and close_plots: import matplotlib.pyplot as plt plt.close("all") s = calc_spectrum( 1900, 2300, # cm-1 molecule="CO", isotope="1,2,3", pressure=1.01325, # bar Tgas=700, # K mole_fraction=0.1, path_length=1, # cm ) s = Radiance_noslit(s) s._q["radiance_noslit"][0] = np.nan # Test Plot function when there are Nans in the spectrum: if plot: s.plot(normalize=True) s.plot(normalize=(2200, 2250)) # Test plot_diff function when there are Nans in the spectra: if plot: plot_diff(s, s * 1.2, normalize=True) plot_diff(s, s * 1.2, "radiance_noslit", normalize=(2000, 2100))
def call_calc_spectrum(): # If too many requests happen at once, RADIS will segfault! try: spectrum = radis.calc_spectrum( wavenum_min=request.body_params.min_wavenumber_range, wavenum_max=request.body_params.max_wavenumber_range, molecule=[species.molecule for species in request.body_params.species], mole_fraction={ species.molecule: species.mole_fraction for species in request.body_params.species }, # TODO: Hard-coding "1" as the isotopologue for the time-being isotope={species.molecule: "1" for species in request.body_params.species}, pressure=request.body_params.pressure, Tgas=request.body_params.tgas, Tvib=request.body_params.tvib, Trot=request.body_params.trot, path_length=request.body_params.path_length, export_lines=False, warnings={ "AccuracyError": "warn", # do not raise error if grid too coarse. Discard once we have wstep='auto'. https://github.com/radis/radis/issues/184 }, ) except radis.misc.warning.EmptyDatabaseError: return ResponseModel(error="No line in the specified wavenumber range") except Exception as exc: return ResponseModel(error=str(exc)) else: if request.body_params.simulate_slit: spectrum.apply_slit(0.5, "nm") return plot_spectrum(spectrum)
async def calculate_spectrum(payload: Payload): print(payload) try: spectrum = radis.calc_spectrum( payload.min_wavenumber_range, payload.max_wavenumber_range, molecule=[species.molecule for species in payload.species], mole_fraction={ species.molecule: species.mole_fraction for species in payload.species }, # TODO: Hard-coding "1,2,3" as the isotopologue for the time-being isotope={species.molecule: "1,2,3" for species in payload.species}, pressure=payload.pressure, Tgas=payload.tgas, Tvib=payload.tvib, Trot=payload.trot, path_length=payload.path_length, export_lines=False, wstep="auto", databank=payload.database, use_cached=True, ) except radis.misc.warning.EmptyDatabaseError: return {"error": "No line in the specified wavenumber range"} except Exception as exc: return {"error": str(exc)} else: if payload.simulate_slit: spectrum.apply_slit(5, "nm") wunit = spectrum.get_waveunit() iunit = "default" x, y = spectrum.get(payload.mode, wunit=wunit, Iunit=iunit) # Reduce payload size threshold = 5e7 if len(spectrum) * 8 * 2 > threshold: print("Reducing the payload size") # Setting return payload size limit of 50 MB # one float is about 8 bytes # we return 2 arrays (w, I) # (note: we could avoid returning the full w-range, and recompute it on the client # from the x min, max and step --> less data transfer. TODO ) resample = int(len(spectrum) * 8 * 2 // threshold) x, y = x[::resample], y[::resample] return { "data": { "x": list(x), "y": list(y), "units": spectrum.units[payload.mode], }, }
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_calc_hitemp_CO_noneq(verbose=True, *args, **kwargs): """Test proper download of HITEMP CO database. Good to test noneq calculations with direct-download of HITEMP. ``05_HITEMP2020.par.bz2`` is about 14 Mb. We still download it (once per machine) because it allows to compute & test noneq spectra, which failed with direct HITEMP download in RADIS 0.9.28. Approximate cost for the planet 🌳 : ~ 14 gr CO2 (hard to evaluate !). """ from astropy import units as u from radis import calc_spectrum calc_spectrum( wavenum_min=2000 / u.cm, wavenum_max=2300 / u.cm, molecule="CO", isotope="1,2", Tvib=1500, Trot=300, databank="hitemp", # test by fetching directly ) # Recompute with (now) locally downloaded database [note : this failed on 0.9.28] calc_spectrum( wavenum_min=2000 / u.cm, wavenum_max=2300 / u.cm, molecule="CO", isotope="1,2", Tvib=1500, Trot=300, databank="HITEMP-CO", # registered in ~/.radis )
def call_calc_spectrum(): # If too many requests happen at once, RADIS will segfault! try: spectrum = radis.calc_spectrum( wavenum_min=request.query_params.min_wavenumber_range, wavenum_max=request.query_params.max_wavenumber_range, molecule=request.query_params.molecule, mole_fraction=request.query_params.mole_fraction, isotope="1", pressure=request.query_params.pressure, Tgas=request.query_params.tgas, Tvib=request.query_params.tvib, path_length=request.query_params.path_length, ) except radis.misc.warning.EmptyDatabaseError: return ResponseModel(error="No line in the specified wavenumber range") else: if request.query_params.simulate_slit: spectrum.apply_slit(0.5, "nm") return plot_spectrum(spectrum)
def test_lazy_loading(verbose=True, *args, **kwargs): """ Test lazy loading """ import numpy as np from radis import calc_spectrum DBNAME = "test_CO_OH_database" db = SpecDatabase(DBNAME, lazy_loading=False) # create the database #%% Simulate a fake database # Compute spectra of CO and OH and add them to the database T_db = np.linspace(300, 1200, 5) # Temperature array for T in T_db: s1 = ( calc_spectrum( wavenum_min=3000, wavenum_max=4500, molecule="CO", Tgas=T, databank="hitemp", # test by fetching directly verbose=False, ).apply_slit(2, "nm").take("radiance") # TODO : use https://github.com/radis/radis/issues/135 once implemented ) db.add(s1, store_name=f"CO_{T}K.spec", if_exists_then="ignore") s2 = ( calc_spectrum( wavenum_min=3000, wavenum_max=4500, molecule="OH", Tgas=T, databank="hitemp", # test by fetching directly verbose=False, ).apply_slit(2, "nm").take("radiance") # TODO : use https://github.com/radis/radis/issues/135 once implemented ) db.add(s2, store_name=f"OH_{T}K.spec", if_exists_then="ignore") #%% Access the spectra in the database via the get functions. # Check what species are in the database at a given temperature (300) s300 = db.get(Tgas=300) # simple use of get if verbose: print([s.conditions["molecule"] for s in s300]) # Check what species are in the database at a given species sCO = db.get(molecule="CO") if verbose: print([s.conditions["Tgas"] for s in sCO]) # Advanced use of the get function sdb = db.get('Tgas>=600 & Tgas<900 & molecule=="CO"') if verbose: print("Number of spectra found for the given conditions: ", len(sdb)) #%% Do the same in lazy-loading mode, and compare : db2 = SpecDatabase(DBNAME, lazy_loading=True) # create the database #%% Access the spectra in the database via the get functions. # Check what species are in the database at a given temperature (300) s300_2 = db2.get(Tgas=300) # simple use of get print([s.conditions["molecule"] for s in s300_2]) assert s300 == s300_2 # Check what species are in the database at a given species sCO_2 = db2.get(molecule="CO") if verbose: print([s.conditions["Tgas"] for s in sCO_2]) assert sCO == sCO_2 # Advanced use of the get function sdb_2 = db2.get('Tgas>=600 & Tgas<900 & molecule=="CO"') if verbose: print("Number of spectra found for the given conditions: ", len(sdb)) assert sdb == sdb_2
for i, M in enumerate(MOLECULES_LIST_EQUILIBRIUM): pb.update(i) filename = 'out/{0} - {1} infrared spectrum.png'.format(i, M) # To skip the existing ones from os.path import exists if exists(filename): continue try: # Calculate RADIS spectrum s = calc_spectrum(wavelength_min=1000, wavelength_max=20000, Tgas=300, pressure=1, molecule=M, lineshape_optimization=None, cutoff=1e-23, isotope='1', verbose=0) # Plot and save it s.name = M.replace('2', '$_{2}$').replace('3', '$_{3}$').replace('4', '$_{4}$') s.name += ' ({0:.1f}s)'.format(s.conditions['calculation_time']) s.plot('abscoeff', wunit='nm') # TODO: switch to µm after it's possible plt.yscale('log') plt.legend(loc='upper right') plt.savefig(filename)
def test_get_residual(): from radis import calc_spectrum, experimental_spectrum s1 = calc_spectrum( 1900, 2300, molecule="CO", isotope="1,2,3", pressure=1.01325, Tgas=1000, mole_fraction=0.1, ) s1.apply_slit(1, "nm") w1, I1 = s1.get("radiance", copy=False, wunit=s1.get_waveunit()) # Fake experimental spectrum (identical) s_expe_1 = experimental_spectrum(w1, I1, Iunit="mW/cm2/sr/nm", wunit="cm-1") residual1 = get_residual( s1, s_expe_1, "radiance", # ignore_nan=False, normalize=True, ) assert residual1 == 0 # Fake experimental spectrum with a new unit (but identical) I2 = I1 * 1e-3 s_expe_2 = experimental_spectrum(w1, I2, Iunit="W/cm2/sr/nm", wunit="cm-1") residual2 = get_residual( s1, s_expe_2, "radiance", normalize=False, ) assert residual2 < 1e-10 for bool_how in ["max", "area", "mean"]: residual2_bis = get_residual( s1, s_expe_2, "radiance", ignore_nan=False, normalize=True, normalize_how=bool_how, ) # print('residu2 ={}'.format(residual2)) assert residual2_bis < 1e-13 # Fake experimental spectrum with a nan I3 = I1.copy() I3[0] = np.nan s_expe_3 = experimental_spectrum(w1, I3, Iunit="W/cm2/sr/nm", wunit="cm-1") # Intrestingly, the "mean" method seams to be not adapted for spectra with nans criterion = [1e-10, 2e-6, 2e-2] for index, bool_how in enumerate(["max", "area", "mean"]): residual3 = get_residual( s1, s_expe_3, "radiance", ignore_nan=True, normalize=True, normalize_how=bool_how, ) # print('residu3 ={}'.format(residual3)) assert residual3 < criterion[index]
def peakmem_noneq_spectrum(self): calc_spectrum(**self.test_options)
def time_noneq_spectrum(self): calc_spectrum(**self.test_options)
mode different from the temperature of the rotational mode. This example uses the :py:func:`~radis.lbl.calc.calc_spectrum` function, the [HITRAN-2016]_ line database to derive the line positions and intensities, and the default RADIS spectroscopic constants to compute nonequilibrium energies and populations, but it can be extended to other line databases and other sets of spectroscopic constants. """ from astropy import units as u from radis import calc_spectrum s2 = calc_spectrum( 1900 / u.cm, 2300 / u.cm, molecule="CO", isotope="1,2,3", pressure=1.01325 * u.bar, Tvib=700 * u.K, Trot=300 * u.K, mole_fraction=0.1, path_length=1 * u.cm, databank="hitran", # or use 'hitemp' ) s2.apply_slit(0.5, "nm") s2.plot("radiance", nfig="same") # compare with previous
# -*- coding: utf-8 -*- """ =========== Line Survey =========== Plot details of every single line in a spectrum. Uses the :py:meth:`~radis.spectrum.spectrum.Spectrum.line_survey` function. """ from radis import calc_spectrum s = calc_spectrum( wavenum_min=2380, wavenum_max=2400, mole_fraction=400e-6, path_length=100, # cm Tgas=1500, molecule="CO2", isotope=[1], databank="hitran", export_lines=True, ) s.apply_slit(2, "nm") s.line_survey(overlay="radiance", barwidth=0.01)