Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
t1 = t0
if len(df) == 0:
return # no lines in database, no need to go further
# partition function
# ... unlike the (tabulated) equilibrium case, here we recalculate it from
# scratch
dgb = df.groupby(by=['id', 'iso'])
# TODO: optimize with np.take trick (see equilibrium case)
for (id, iso), idx in dgb.indices.items():
molecule = get_molecule(id)
state = self.input.state
parsum = self.get_partition_function_calculator(
molecule, iso, state)
Q = parsum.at_noneq_3Tvib(Tvib, Trot,
vib_distribution=vib_distribution,
rot_distribution=rot_distribution,
overpopulation=overpopulation,
update_populations=self.misc.export_populations)
# df.loc[idx, 'Qvib'] = Qvib
df.loc[idx, 'Q'] = Q
# dg_list.append(dg)
if radis.DEBUG_MODE:
assert (df.loc[idx, 'id'] == id).all()
assert (df.loc[idx, 'iso'] == iso).all()
wavenum_min, wavenum_max)) +
' ({0:.2f}-{1:.2f}nm) Check your range !'.format(
cm2nm(wavenum_min), cm2nm(wavenum_max)))
raise ValueError(msg)
maxwavdb = df.wav.max()
minwavdb = df.wav.min()
# ... Explicitely write molecule if not given
if self.input.molecule in [None, '']:
id_set = df.id.unique()
if len(id_set) > 1:
raise NotImplementedError('RADIS expects one molecule per run for the '+\
"moment. Got {0}. Use different runs ".format(id_set)+\
"and use MergeSlabs(out='transparent' afterwards")
self.input.molecule = get_molecule(id_set[0])
# ... explicitely write all isotopes based on isotopes found in the database
if self.input.isotope == 'all':
self.input.isotope = ','.join([str(k) for k in self._get_isotope_list(df=df)])
# ... check all requested isotopes are present (only if not using 'all',
# in which case we assume the user didnt really care about a particular
# isotope and shouldnt be surprised if it's not there)
else:
isotope_list = self._get_isotope_list()
# check no isotope shows 0 line in this range. Raise an warning if it
# happens
for k in isotope_list:
if not (sum(df.iso == k) > 0):
msg = (("Reference databank ({0:.2f}-{1:.2f}cm-1)".format(
molecule = get_molecule(id_set[0])
state = self.input.state
parsum = self.get_partition_function_calculator(
molecule, iso_set[0], state) # partition function
df.Qref = parsum.at(Tref, update_populations=False) # stored as attribute, not column
assert 'Qref' not in df.columns
else:
# normal method
# still much faster than the groupby().apply() method (see radis<=0.9.19)
# (tested + see https://stackoverflow.com/questions/44954514/efficient-way-to-conditionally-populate-elements-in-a-pandas-groupby-object-pos)
dgb = df.groupby(by=['id', 'iso'])
for (id, iso), idx in dgb.indices.items():
molecule = get_molecule(id)
state = self.input.state
parsum = self.get_partition_function_calculator(
molecule, iso, state) # partition function
df.at[idx, 'Qref'] = parsum.at(Tref, update_populations=False)
# ... note: do not update the populations here, so populations in the
# ... energy level list correspond to the one calculated for T and not Tref
if radis.DEBUG_MODE:
assert (df.loc[idx, 'id'] == id).all()
assert (df.loc[idx, 'iso'] == iso).all()
# Get moment
gl = df.gl
El = df.El
nu = df.wav
Ia = df.Ia
dbformat, KNOWN_DBFORMAT))
if not lvlformat in KNOWN_LVLFORMAT:
raise ValueError('lvlformat ({0}) should be one of: {1}'.format(
lvlformat, KNOWN_LVLFORMAT))
if verbose:
t0 = time()
print('... sorting lines by vibrational bands')
# Calculate bands:
id = list(pd.unique(df['id']))
if len(id) > 1:
raise ValueError('Cant calculate vibrational bands for multiple ' +
'molecules yet') # although it's an easy fix. Just
# groupby id
molecule = get_molecule(id[0])
if molecule == 'CO2':
vib_lvl_name_hitran = vib_lvl_name_hitran_class5
if lvlformat in ['cdsd-pc', 'cdsd-pcN', 'cdsd-hamil']:
# ensures that vib_lvl_name functions wont crash
if dbformat not in ['cdsd-hitemp', 'cdsd-4000', 'hitran']:
raise NotImplementedError('lvlformat {0} not supported with dbformat {1}'.format(
lvlformat, dbformat))
# Use vibrational nomenclature of CDSD (p,c,j,n) or HITRAN (v1v2l2v3J)
# depending on the Level Database.
# In both cases, store the other one.
return None
equilibrium = _is_at_equilibrium(sload['conditions'])
if equilibrium is not None:
sload['conditions']['thermal_equilibrium'] = equilibrium
fixed = True
printr("File {0}".format(basename(file))+" has a deprecrated structure (" +
"thermal_equilibrium not defined). Fixed it this time (guessed {0})".format(
equilibrium)+", but regenerate file ASAP.") #, DeprecationWarning)
# Fix lines format HITRAN_CLASS_1 molecules
if 'lines' in sload and sload['lines'] is not None:
lines = sload['lines']
from radis.io.hitran import get_molecule, HITRAN_CLASS1
if 'v1u' in lines and get_molecule(lines.id.iloc[0]) in HITRAN_CLASS1:
printr("File {0}".format(basename(file))+" has a deprecrated structure " +\
"(v1u in lines is now called vu). Fixed this time, but regenerate " +\
"database ASAP.")
# Fix it:
lines.rename(columns={'v1u':'vu', 'v1l':'vl'}, inplace=True)
return sload, fixed
printg('... Fetching molecular parameters for all transitions')
t0 = time()
# prefill:
# Use the fact that isotopes are int, and thus can be considered as
# index in an array.
# ... in the following we exploit this to use the np.take function,
# ... which is amazingly fast
# ... Read https://stackoverflow.com/a/51388828/5622825 to understand more
# ... @dev: old versions: see radis <= 0.9.19
id_set = df.id.unique()
if len(id_set) == 1:
id = list(id_set)[0]
molecule = get_molecule(id)
iso_set = self._get_isotope_list(molecule) #df.iso.unique()
# Shortcut if only 1 molecule & 1 isotope. We attribute molar_mass & abundance
# as attributes of the line database, instead of columns. Much
# faster!
if len(iso_set) == 1:
params = molpar.df.loc[(id, iso_set[0])] # fetch all table directly
df.Ia = params.abundance # attribute, not column
df.molar_mass = params.mol_mass # attribute, not column
# # add in metadata so they follow when dataframe is copied/serialized
# for k in ['Ia', 'molar_mass']:
# assert k not in df.columns
# if k not in df._metadata:
# df._metadata.append(k)
wbroad_centered = _generate_broadening_range(
wstep, broadening_max_width)
# Get boolean array to switch from `wavenumber_calc` to `wavenumber`
woutrange = np.in1d(wavenumber_calc, wavenumber, assume_unique=True)
self.wbroad_centered = wbroad_centered
self.wavenumber = wavenumber
self.wavenumber_calc = wavenumber_calc
self.woutrange = woutrange
# Init variables
# --------------
# Get molecule name
if isinstance(molecule, int):
molecule == get_molecule(molecule)
# Store isotope identifier in str format (list wont work in database queries)
if not isinstance(isotope, string_types):
isotope = ','.join([str(k) for k in list_if_float(isotope)])
# Initialize input conditions
self.input.wavenum_min = wavenum_min
self.input.wavenum_max = wavenum_max
self.input.Tref = Tref
self.input.pressure_mbar = pressure*1e3
self.input.mole_fraction = mole_fraction
self.input.path_length = path_length
self.input.molecule = molecule # if None, will be overwritten after reading database
self.input.state = 'X' # for the moment only ground-state is used
# (but the code is electronic state aware)
self.verbose = verbose
# Get name and integer id
if isinstance(name, string_types):
self.name = name
# Get name without parenthesis (without state) for HITRAN identification
filtername = re.sub("[\(\[].*?[\)\]]", "", name)
try:
self.id = get_molecule_identifier(filtername)
except KeyError: # Not an HITRAN molecule
self.id = None
elif type(name) == int:
self.id = name
self.name = get_molecule(name)
else:
raise ValueError('Wrong name type:', name)