def fetch_astroquery(molecule, isotope, wmin, wmax, verbose=True): ''' Wrapper to Astroquery [1]_ fetch function to download a line database Notes ----- Astroquery [1]_ is itself based on [HAPI]_ Parameters ---------- molecule: str, or int molecule name or identifier isotope: int isotope number wmin, wmax: float (cm-1) wavenumber min and max Other Parameters ---------------- verbose: boolean Default ``True`` References ---------- .. [1] `Astroquery <https://astroquery.readthedocs.io>`_ See Also -------- :func:`astroquery.hitran.reader.download_hitran`, :func:`astroquery.hitran.reader.read_hitran_file` ''' # Check input if not is_float(molecule): mol_id = get_molecule_identifier(molecule) else: mol_id = molecule molecule = get_molecule(mol_id) assert is_float(isotope) empty_range = False # tbl = Hitran.query_lines_async(molecule_number=mol_id, # isotopologue_number=isotope, # min_frequency=wmin / u.cm, # max_frequency=wmax / u.cm) # # Download using the astroquery library response = Hitran.query_lines_async(molecule_number=mol_id, isotopologue_number=isotope, min_frequency=wmin / u.cm, max_frequency=wmax / u.cm) if response.status_code == 404: # Maybe there are just no lines for this species in this range # In that case we usually end up with errors like: # (<class 'Exception'>, Exception('Query failed: 404 Client Error: # Not Found for url: http://hitran.org/lbl/api?numax=25000&numin=19000&iso_ids_list=69\n',), # <traceback object at 0x7f0967c91708>) if response.reason == 'Not Found': # Let's bet it's just that there are no lines in this range empty_range = True if verbose: print(( 'No lines for {0} (id={1}), iso={2} in range {3:.2f}-{4:.2f}cm-1. ' .format(molecule, mol_id, isotope, wmin, wmax))) else: raise ValueError( 'An error occured during the download of HITRAN files ' + 'for {0} (id={1}), iso={2} between {3:.2f}-{4:.2f}cm-1. '. format(molecule, mol_id, isotope, wmin, wmax) + 'Are you online?\n' + 'See details of the error below:\n\n {0}'.format( response.reason)) # Rename columns from Astroquery to RADIS format rename_columns = { 'molec_id': 'id', 'local_iso_id': 'iso', 'nu': 'wav', 'sw': 'int', 'a': 'A', 'gamma_air': 'airbrd', 'gamma_self': 'selbrd', 'elower': 'El', 'n_air': 'Tdpair', 'delta_air': 'Pshft', 'global_upper_quanta': 'globu', 'global_lower_quanta': 'globl', 'local_upper_quanta': 'locu', 'local_lower_quanta': 'locl', 'line_mixing_flag': 'lmix', 'gp': 'gp', 'gpp': 'gpp', } if not empty_range: # _fix_astroquery_file_format(filename) # Note: as of 0.9.16 we're not fixing astroquery_file_format anymore. # maybe we should. tbl = Hitran._parse_result(response) df = tbl.to_pandas() df = df.rename(columns=rename_columns) else: df = pd.DataFrame(columns=list(rename_columns.values())) # Cast type to float64 cast_type = { 'wav': np.float64, 'int': np.float64, 'A': np.float64, 'airbrd': np.float64, 'selbrd': np.float64, 'El': np.float64, 'Tdpair': np.float64, 'Pshft': np.float64, } for c, typ in cast_type.items(): df[c] = df[c].astype(typ) return df
def fetch_astroquery(molecule, isotope, wmin, wmax, verbose=True, cache=True, metadata={}): ''' Wrapper to Astroquery [1]_ fetch function to download a line database Notes ----- Astroquery [1]_ is itself based on [HAPI]_ Parameters ---------- molecule: str, or int molecule name or identifier isotope: int isotope number wmin, wmax: float (cm-1) wavenumber min and max Other Parameters ---------------- verbose: boolean Default ``True`` cache: boolean if ``True``, tries to find a ``.h5`` cache file in the Astroquery :py:attr:`~astroquery.query.BaseQuery.cache_location`, that would match the requirements. If not found, downloads it and saves the line dataframe as a ``.h5`` file in the Astroquery. metadata: dict if ``cache=True``, check that the metadata in the cache file correspond to these attributes. Arguments ``molecule``, ``isotope``, ``wmin``, ``wmax`` are already added by default. References ---------- .. [1] `Astroquery <https://astroquery.readthedocs.io>`_ See Also -------- :py:func:`astroquery.hitran.reader.download_hitran`, :py:func:`astroquery.hitran.reader.read_hitran_file`, :py:attr:`~astroquery.query.BaseQuery.cache_location` ''' # Check input if not is_float(molecule): mol_id = get_molecule_identifier(molecule) else: mol_id = molecule molecule = get_molecule(mol_id) assert is_float(isotope) empty_range = False # If cache, tries to find from Astroquery: if cache: # Update metadata with physical properties from the database. metadata.update({ 'molecule': molecule, 'isotope': isotope, 'wmin': wmin, 'wmax': wmax }) fcache = join( Hitran.cache_location, CACHE_FILE_NAME.format( **{ 'molecule': molecule, 'isotope': isotope, 'wmin': wmin, 'wmax': wmax })) check_cache_file(fcache=fcache, use_cached=cache, metadata=metadata, verbose=verbose) if exists(fcache): try: return get_cache_file(fcache, verbose=verbose) except Exception as err: if verbose: printr( 'Problem reading cache file {0}:\n{1}\nDeleting it!'. format(fcache, str(err))) os.remove(fcache) # tbl = Hitran.query_lines_async(molecule_number=mol_id, # isotopologue_number=isotope, # min_frequency=wmin / u.cm, # max_frequency=wmax / u.cm) # # Download using the astroquery library try: response = Hitran.query_lines_async(molecule_number=mol_id, isotopologue_number=isotope, min_frequency=wmin / u.cm, max_frequency=wmax / u.cm) except KeyError as err: raise KeyError(str(err)+' <<w this error occured in Astroquery. Maybe these molecule '+\ '({0}) and isotope ({1}) are not supported'.format(molecule, isotope)) from err # Deal with usual errors if response.status_code == 404: # Maybe there are just no lines for this species in this range # In that case we usually end up with errors like: # (<class 'Exception'>, Exception('Query failed: 404 Client Error: # Not Found for url: http://hitran.org/lbl/api?numax=25000&numin=19000&iso_ids_list=69\n',), # <traceback object at 0x7f0967c91708>) if response.reason == 'Not Found': # Let's bet it's just that there are no lines in this range empty_range = True if verbose: print(( 'No lines for {0} (id={1}), iso={2} in range {3:.2f}-{4:.2f}cm-1. ' .format(molecule, mol_id, isotope, wmin, wmax))) else: raise ValueError( 'An error occured during the download of HITRAN files ' + 'for {0} (id={1}), iso={2} between {3:.2f}-{4:.2f}cm-1. '. format(molecule, mol_id, isotope, wmin, wmax) + 'Are you online?\n' + 'See details of the error below:\n\n {0}'.format( response.reason)) elif response.status_code == 500: raise ValueError('{0} while querying the HITRAN server: '.format(response.status_code)+\ '\n\n{0}'.format(response.text)) # Process response # Rename columns from Astroquery to RADIS format rename_columns = { 'molec_id': 'id', 'local_iso_id': 'iso', 'nu': 'wav', 'sw': 'int', 'a': 'A', 'gamma_air': 'airbrd', 'gamma_self': 'selbrd', 'elower': 'El', 'n_air': 'Tdpair', 'delta_air': 'Pshft', 'global_upper_quanta': 'globu', 'global_lower_quanta': 'globl', 'local_upper_quanta': 'locu', 'local_lower_quanta': 'locl', 'line_mixing_flag': 'lmix', 'gp': 'gp', 'gpp': 'gpp', } if not empty_range: # _fix_astroquery_file_format(filename) # Note: as of 0.9.16 we're not fixing astroquery_file_format anymore. # maybe we should. tbl = Hitran._parse_result(response) df = tbl.to_pandas() df = df.rename(columns=rename_columns) else: df = pd.DataFrame(columns=list(rename_columns.values())) # Cast type to float64 cast_type = { 'wav': np.float64, 'int': np.float64, 'A': np.float64, 'airbrd': np.float64, 'selbrd': np.float64, 'El': np.float64, 'Tdpair': np.float64, 'Pshft': np.float64, } for c, typ in cast_type.items(): df[c] = df[c].astype(typ) # cached file mode but cached file doesn't exist yet (else we had returned) if cache: if verbose: print('Generating cached file: {0}'.format(fcache)) try: save_to_hdf(df, fcache, metadata=metadata, version=radis.__version__, key='df', overwrite=True, verbose=verbose) except: if verbose: print(sys.exc_info()) print( 'An error occured in cache file generation. Lookup access rights' ) pass return df
def fetch_astroquery(molecule, isotope, wmin, wmax, verbose=True): ''' Wrapper to Astroquery [1]_ fetch function to download a line database Notes ----- Astroquery [1]_ is itself based on HAPI [2]_ Parameters ---------- molecule: str, or int molecule name or identifier isotope: int isotope number wmin, wmax: float (cm-1) wavenumber min and max Other Parameters ---------------- verbose: boolean Default True References ---------- .. [1] `Astroquery <https://astroquery.readthedocs.io>`_ .. [2] `HAPI: The HITRAN Application Programming Interface <http://hitran.org/hapi>`_ ''' # Check input if not is_float(molecule): mol_id = get_molecule_identifier(molecule) else: mol_id = molecule molecule = get_molecule(mol_id) assert is_float(isotope) empty_range = False # Download using the astroquery library try: download_hitran(mol_id, isotope, wmin, wmax) except: # Maybe there are just no lines for this species in this range # In that case we usually end up with errors like: # (<class 'Exception'>, Exception('Query failed: 404 Client Error: # Not Found for url: http://hitran.org/lbl/api?numax=25000&numin=19000&iso_ids_list=69\n',), # <traceback object at 0x7f0967c91708>) import sys _err_class, _err_details, _err_obj = sys.exc_info() if 'Not Found for url:' in str(_err_details): # Let's bet it's just that there are no lines in this range empty_range = True if verbose: print(( 'Not lines for {0} (id={1}), iso={2} between {3:.2f}-{4:.2f}cm-1. ' .format(molecule, mol_id, isotope, wmin, wmax))) else: raise ValueError('An error occured during the download of HITRAN files '+\ 'for {0} (id={1}), iso={2} between {3:.2f}-{4:.2f}cm-1. '.format( molecule, mol_id, isotope, wmin, wmax)+\ 'See details of the error below: {0}'.format(_err_details)) # Rename columns from Astroquery to RADIS format rename_columns = { 'molec_id': 'id', 'local_iso_id': 'iso', 'nu': 'wav', 'sw': 'int', 'a': 'A', 'gamma_air': 'airbrd', 'gamma_self': 'selbrd', 'elower': 'El', 'n_air': 'Tdpair', 'delta_air': 'Pshft', 'global_upper_quanta': 'globu', 'global_lower_quanta': 'globl', 'local_upper_quanta': 'locu', 'local_lower_quanta': 'locl', 'line_mixing_flag': 'lmix', 'gp': 'gp', 'gpp': 'gpp', } if not empty_range: tbl = read_hitran_file(join(cache_location, molecule + '.data')) df = tbl.to_pandas() df = df.rename(columns=rename_columns) else: df = pd.DataFrame(columns=list(rename_columns.values())) # Cast type to float64 cast_type = { 'wav': np.float64, 'int': np.float64, 'A': np.float64, 'airbrd': np.float64, 'selbrd': np.float64, 'El': np.float64, 'Tdpair': np.float64, 'Pshft': np.float64, } for c, typ in cast_type.items(): df[c] = df[c].astype(typ) return df
def fetch_astroquery( molecule, isotope, wmin, wmax, verbose=True, cache=True, expected_metadata={} ): """Download a HITRAN line database to a Pandas DataFrame. Wrapper to Astroquery [1]_ fetch function Parameters ---------- molecule: str, or int molecule name or identifier isotope: int isotope number wmin, wmax: float (cm-1) wavenumber min and max Other Parameters ---------------- verbose: boolean Default ``True`` cache: boolean or ``'regen'`` if ``True``, tries to find a ``.h5`` cache file in the Astroquery :py:attr:`~astroquery.query.BaseQuery.cache_location`, that would match the requirements. If not found, downloads it and saves the line dataframe as a ``.h5`` file in the Astroquery. If ``'regen'``, delete existing cache file to regerenate it. expected_metadata: dict if ``cache=True``, check that the metadata in the cache file correspond to these attributes. Arguments ``molecule``, ``isotope``, ``wmin``, ``wmax`` are already added by default. Notes ----- The HITRAN module in Astroquery [1]_ is itself based on [HAPI]_ References ---------- .. [1] `Astroquery <https://astroquery.readthedocs.io>`_ See Also -------- :py:func:`astroquery.hitran.reader.download_hitran`, :py:func:`astroquery.hitran.reader.read_hitran_file`, :py:attr:`~astroquery.query.BaseQuery.cache_location` """ # Check input if not is_float(molecule): mol_id = get_molecule_identifier(molecule) else: mol_id = molecule molecule = get_molecule(mol_id) assert is_float(isotope) empty_range = False if cache: # Cache file location in Astroquery cache # TODO: move full HITRAN databases in ~/radisdb cache like io/hitemp/fetch_hitemp ? fcache = join( Hitran.cache_location, CACHE_FILE_NAME.format( **{"molecule": molecule, "isotope": isotope, "wmin": wmin, "wmax": wmax} ), ) # ... Update metadata with physical properties from the database. expected_metadata.update( {"molecule": molecule, "isotope": isotope, "wmin": wmin, "wmax": wmax} ) if cache == "regen": if exists(fcache): if verbose: print(f"Cache file {fcache} deleted to be regenerated") os.remove(fcache) else: # Load cache file if valid check_cache_file( fcache=fcache, use_cached=cache, expected_metadata=expected_metadata, verbose=verbose, ) if exists(fcache): try: return get_cache_file(fcache, verbose=verbose) except Exception as err: if verbose: printr( "Problem reading cache file {0}:\n{1}\nDeleting it!".format( fcache, str(err) ) ) os.remove(fcache) # Download using the astroquery library try: response = Hitran.query_lines_async( molecule_number=mol_id, isotopologue_number=isotope, min_frequency=wmin / u.cm, max_frequency=wmax / u.cm, ) except KeyError as err: raise KeyError( str(err) + " <<w this error occured in Astroquery. Maybe these molecule " + "({0}) and isotope ({1}) are not supported".format(molecule, isotope) ) from err # Deal with usual errors if response.status_code == 404: # Maybe there are just no lines for this species in this range # In that case we usually end up with errors like: # (<class 'Exception'>, Exception('Query failed: 404 Client Error: # Not Found for url: http://hitran.org/lbl/api?numax=25000&numin=19000&iso_ids_list=69\n',), # <traceback object at 0x7f0967c91708>) if response.reason == "Not Found": # Let's bet it's just that there are no lines in this range empty_range = True if verbose: print( ( "No lines for {0} (id={1}), iso={2} in range {3:.2f}-{4:.2f}cm-1. ".format( molecule, mol_id, isotope, wmin, wmax ) ) ) else: raise ValueError( "An error occured during the download of HITRAN files " + "for {0} (id={1}), iso={2} between {3:.2f}-{4:.2f}cm-1. ".format( molecule, mol_id, isotope, wmin, wmax ) + "Are you online?\n" + "See details of the error below:\n\n {0}".format(response.reason) ) elif response.status_code == 500: raise ValueError( "{0} while querying the HITRAN server: ".format(response.status_code) + "\n\n{0}".format(response.text) ) # Process response # Rename columns from Astroquery to RADIS format rename_columns = { "molec_id": "id", "local_iso_id": "iso", "nu": "wav", "sw": "int", "a": "A", "gamma_air": "airbrd", "gamma_self": "selbrd", "elower": "El", "n_air": "Tdpair", "delta_air": "Pshft", "global_upper_quanta": "globu", "global_lower_quanta": "globl", "local_upper_quanta": "locu", "local_lower_quanta": "locl", "line_mixing_flag": "lmix", "gp": "gp", "gpp": "gpp", } if not empty_range: tbl = Hitran._parse_result(response) df = tbl.to_pandas() df = df.rename(columns=rename_columns) else: df = pd.DataFrame(columns=list(rename_columns.values())) # Cast type to float64 cast_type = { "wav": np.float64, "int": np.float64, "A": np.float64, "airbrd": np.float64, "selbrd": np.float64, "El": np.float64, "Tdpair": np.float64, "Pshft": np.float64, } for c, typ in cast_type.items(): df[c] = df[c].astype(typ) # cached file mode but cached file doesn't exist yet (else we had returned) if cache: new_metadata = { "molecule": molecule, "isotope": isotope, "wmin": wmin, "wmax": wmax, } if verbose: print( "Generating cache file {0} with metadata :\n{1}".format( fcache, new_metadata ) ) try: save_to_hdf( df, fcache, metadata=new_metadata, version=radis.__version__, key="df", overwrite=True, verbose=verbose, ) except PermissionError: if verbose: print(sys.exc_info()) print("An error occured in cache file generation. Lookup access rights") pass return df