Source code for sndata.snls._balland09

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

"""This module defines the SNLS Balland09 API"""

import os
from pathlib import Path

from astropy.table import Table, vstack

from ..base_classes import DefaultParser, SpectroscopicRelease
from ..exceptions import InvalidObjId
from ..utils import downloads, unit_conversion


def fix_balland09_cds_readme(readme_path):
    """Fix typos in the Balland 2009 CDS Readme so it is machine parsable

    Args:
        readme_path: Path of the README file to fix
    """

    # The downloaded files in this case are readonly, so we change permissions
    os.chmod(readme_path, 438)

    with open(readme_path, 'r+') as data_in:
        lines = data_in.readlines()
        lines[112] = lines[112].replace('? ', '?=- ')

        data_in.seek(0)
        data_in.writelines(lines)


[docs]class Balland09(DefaultParser, SpectroscopicRelease): """The ``Balland09`` class provides access to to the three year data release of the Supernova Legacy Survey (SNLS) performed by the Canada-France-Hawaii Telescope (CFHT). It includes 139 spectra of 124 Type Ia supernovae that range from z = 0.149 to z = 1.031 and have an average redshift of z = 0.63 +/- 0.02. (Source: Balland et al. 2009) Deviations from the standard UI: - Time values returned in units of phase and not observed Julian date. Cuts on returned data: - None """ # General metadata (Required) survey_name = 'Supernova Legacy Survey' survey_abbrev = 'SNLS' release = 'Balland09' survey_url = 'http://supernovae.in2p3.fr/~balland/VltRelease/' publications = ('Balland et al. 2009',) ads_url = 'https://ui.adsabs.harvard.edu/abs/2009A%26A...507...85B/abstract' def __init__(self): """Define local and remote paths of data""" super().__init__() # Local paths self._spectra_dir = self._data_dir / 'spectra' # DR1 spectra self._table_dir = self._data_dir / 'tables' # DR3 paper tables # Define urls for remote data self._phase_spectra_url = 'http://supernovae.in2p3.fr/~balland/VltRelease/PHASE_spec_Balland09.tar.gz' self._snonly_spectra_url = 'http://supernovae.in2p3.fr/~balland/VltRelease/snonly_spec_Balland09.tar.gz' self._table_url = 'http://cdsarc.u-strasbg.fr/viz-bin/nph-Cat/tar.gz?J/A+A/507/85' def _get_available_ids(self): """Return a list of target object IDs for the current survey""" # Use recursive glob since the data files are in sub directories files = self._spectra_dir.rglob('*.dat') ids = (Path(f).name.split('_')[1] for f in files) return sorted(set(ids)) # noinspection PyUnusedLocal def _get_data_for_id(self, obj_id: str, format_table: bool = True) -> Table: """Returns data for a given object ID Args: obj_id: The ID of the desired object format_table: Format for use with ``sncosmo`` (Default: True) Returns: An astropy table of data for the given ID """ if obj_id not in self.get_available_ids(): raise InvalidObjId() tables = [] for fpath in self._spectra_dir.rglob(f'*_{obj_id}_*_Balland_etal_09.dat'): data_table = Table.read( fpath, names=['pixel', 'wavelength', 'flux', 'fluxerr'], format='ascii.basic', comment='[#]|[@]' ) data_table['type'] = fpath.name.split('_')[0].lower() data_table['phase'] = float(data_table.meta['comments'][7].split()[-1]) tables.append(data_table) # Get object coordinates table1 = self.load_table(1) table1_object_data = table1[table1['SN'] == obj_id][0] ra, dec = unit_conversion.hourangle_to_degrees( rah=table1_object_data['RAh'], ram=table1_object_data['RAm'], ras=table1_object_data['RAs'], dec_sign=table1_object_data['DE-'], decd=table1_object_data['DEd'], decm=table1_object_data['DEm'], decs=table1_object_data['DEs'] ) # Get object redshift # Get redshift table2 = self.load_table(2) table2_object_data = table2[table2['SN'] == obj_id][0] z = table2_object_data['z'] z_err = table2_object_data['e_z'] out_table = vstack(tables) out_table.meta['obj_id'] = obj_id out_table.meta['ra'] = ra out_table.meta['dec'] = dec out_table.meta['z'] = z out_table.meta['z_err'] = z_err del out_table.meta['comments'] return out_table def _download_module_data(self, force: bool = False, timeout: float = 15): """Download data for the current survey / data release Args: force: Re-Download locally available data timeout: Seconds before timeout for individual files/archives """ downloads.download_tar( url=self._table_url, out_dir=self._table_dir, skip_exists=self._table_dir, mode='r:gz', force=force ) readme_path = self._table_dir / 'ReadMe' if readme_path.exists(): fix_balland09_cds_readme(readme_path) # Download both kinds of spectra spec_urls = self._phase_spectra_url, self._snonly_spectra_url names = 'combined', 'sn_only' for spectra_url, data_name in zip(spec_urls, names): downloads.download_tar( url=spectra_url, out_dir=self._spectra_dir / data_name, skip_exists=self._spectra_dir / data_name, mode='r:gz', force=force, timeout=timeout )