def test_vibrational_levels_labelling(verbose=True, *args, **kwargs): # If verbose: print some if verbose: printm("Some vibrational level formats:") printm("... CO, HITRAN format (v):\t\t", vib_lvl_name_hitran_class1(10)) printm( "... CO2, HITRAN format (v1,v2,l2,v3):\t\t", vib_lvl_name_hitran_class5(2, 1, 1, 3), ) printm( "... CO2, HITRAN format, short (v1v2l2v3):\t", vib_lvl_name_hitran_class5_short(2, 1, 1, 3), ) printm("... CO2, CDSD format (p,c):\t\t", vib_lvl_name_cdsd_pc(14, 1)) printm("... CO2, CDSD format (p,c,N):\t\t", vib_lvl_name_cdsd_pcN(14, 1, 1)) # Do the tests assert vib_lvl_name_hitran_class1(10) == "(10)" assert vib_lvl_name_hitran_class5(2, 1, 1, 3) == "(2,1,1,3)" assert vib_lvl_name_hitran_class5_short(2, 1, 1, 3) == "21`1`3" assert vib_lvl_name_cdsd_pc(14, 1) == "(14,1)" assert vib_lvl_name_cdsd_pcN(14, 1, 1) == "(14,1,1)" return
def _add_levels(self, df): viblvl_label = self.viblvl_label if viblvl_label == "p": df["viblvl"] = vib_lvl_name_cdsd_p(df.p,) elif viblvl_label == "pc": df["viblvl"] = vib_lvl_name_cdsd_pc(df.p, df.c) elif viblvl_label == "pcN": df["viblvl"] = vib_lvl_name_cdsd_pcN(df.p, df.c, df.N) elif viblvl_label == "pcJN": df["viblvl"] = vib_lvl_name_cdsd_pcJN(df.p, df.c, df.j, df.N) elif viblvl_label is None: # dont label the levels. Wont be able to use the EnergyDatabase to fetch # vibrational energies for lines, however it can still be used to # calculate Partition functions independently from a Spectrum calculation pass else: raise ValueError("Unexpected viblvl_label value: {0}".format(viblvl_label)) return df
def vib_lvl_name_cdsd(p, c, N): return vib_lvl_name_cdsd_pc(p, c)
def add_bands(df, dbformat, lvlformat, verbose=True): ''' Assign all transitions to a vibrational band: Add 'band', 'viblvl_l' and 'viblvl_u' attributes for each line to allow parsing the lines by band with:: df0.groupby('band') Parameters ---------- df: pandas Dataframe Line (transitions) database dbformat: one of :data:`~radis.lbl.loader.KNOWN_DBFORMAT` : ``'cdsd```, ``'hitemp'`` format of Line database lvlformat: 'cdsd`, 'hitemp' format of Returns ------- None input df is changed Examples -------- Add transitions in a Dataframe based on CDSD (p, c, j, n) format:: add_bands(df, 'cdsd') Notes ----- Performance with test case (CDSD CO2 2380-2400 cm-1): - Initial: with .apply() 8.08 s ± 95.2 ms - with groupby(): 9s worse!! - using simple (and more readable) astype(str) statements: 523 ms ± 19.6 ms ''' # Check inputs if not dbformat in KNOWN_DBFORMAT: raise ValueError('dbformat ({0}) should be one of: {1}'.format( 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', 'cdsd4000', '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. # ... note: vib level in a CDSD (p,c,j,n) database is ambiguous. # ... a vibrational energy Evib can have been defined for every (p, c) group: if lvlformat in ['cdsd-pc']: viblvl_l_cdsd = vib_lvl_name_cdsd_pc(df.polyl, df.wangl) viblvl_u_cdsd = vib_lvl_name_cdsd_pc(df.polyu, df.wangu) # ... or for every (p, c, N) group: elif lvlformat in ['cdsd-pcN']: viblvl_l_cdsd = vib_lvl_name_cdsd_pcN(df.polyl, df.wangl, df.rankl) viblvl_u_cdsd = vib_lvl_name_cdsd_pcN(df.polyu, df.wangu, df.ranku) # ... or for every level (p, c, J ,N) (that's the case if coupling terms # are used taken into account... it also takes a much longer time # to look up vibrational energies in the LineDatabase, warning!): elif lvlformat in ['cdsd-hamil']: viblvl_l_cdsd = vib_lvl_name_cdsd_pcJN(df.polyl, df.wangl, df.jl, df.rankl) viblvl_u_cdsd = vib_lvl_name_cdsd_pcJN(df.polyu, df.wangu, df.ju, df.ranku) else: raise ValueError( 'Unexpected level format: {0}'.format(lvlformat)) band_cdsd = viblvl_l_cdsd + '->' + viblvl_u_cdsd df.loc[:, 'viblvl_l'] = viblvl_l_cdsd df.loc[:, 'viblvl_u'] = viblvl_u_cdsd df.loc[:, 'band'] = band_cdsd # Calculate HITRAN format too (to store them)) if all_in(['v1l', 'v2l', 'l2l', 'v3l'], df): viblvl_l_hitran = vib_lvl_name_hitran(df.v1l, df.v2l, df.l2l, df.v3l) viblvl_u_hitran = vib_lvl_name_hitran(df.v1u, df.v2u, df.l2u, df.v3u) band_hitran = viblvl_l_hitran + '->' + viblvl_u_hitran df.loc[:, 'viblvl_htrn_l'] = viblvl_l_hitran df.loc[:, 'viblvl_htrn_u'] = viblvl_u_hitran df.loc[:, 'band_htrn'] = band_hitran # 'radis' uses Dunham development based on v1v2l2v3 HITRAN convention elif lvlformat in ['radis']: if dbformat not in ['hitran', 'cdsd']: raise NotImplementedError( 'lvlformat `{0}` not supported with dbformat `{1}`'.format( lvlformat, dbformat)) # Calculate bands with HITRAN convention viblvl_l_hitran = vib_lvl_name_hitran(df.v1l, df.v2l, df.l2l, df.v3l) viblvl_u_hitran = vib_lvl_name_hitran(df.v1u, df.v2u, df.l2u, df.v3u) band_hitran = viblvl_l_hitran + '->' + viblvl_u_hitran df.loc[:, 'viblvl_l'] = viblvl_l_hitran df.loc[:, 'viblvl_u'] = viblvl_u_hitran df.loc[:, 'band'] = band_hitran else: raise NotImplementedError( 'Cant deal with lvlformat={0} for {1}'.format( lvlformat, molecule)) elif molecule in HITRAN_CLASS1: # includes 'CO' # Note. TODO. Move that in loader.py (or somewhere consistent with # classes defined in cdsd.py / hitran.py) if lvlformat in ['radis']: # ensures that vib_lvl_name functions wont crash if dbformat not in ['hitran']: raise NotImplementedError( 'lvlformat {0} not supported with dbformat {1}'.format( lvlformat, dbformat)) vib_lvl_name = vib_lvl_name_hitran_class1 df.loc[:, 'viblvl_l'] = vib_lvl_name(df['vl']) df.loc[:, 'viblvl_u'] = vib_lvl_name(df['vu']) df.loc[:, 'band'] = df['viblvl_l'] + '->' + df['viblvl_u'] else: raise NotImplementedError( 'Lvlformat not defined for {0}: {1}'.format( molecule, lvlformat)) else: raise NotImplementedError( 'Vibrational bands not yet defined for molecule: ' + '{0} with database format: {1}. '.format(molecule, dbformat) + 'Update add_bands()') if verbose: print(('... lines sorted in {0:.1f}s'.format(time() - t0))) return