Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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