Source code for sndata.loss._ganeshalingam13

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

"""This module defines the LOSS Ganeshalingam13 API"""

from functools import lru_cache
from typing import List

import numpy as np
import pandas as pd
from astropy.table import Table

from ._load_meta_data import load_meta
from .. import utils
from ..base_classes import DefaultParser, PhotometricRelease


[docs]class Ganeshalingam13(PhotometricRelease, DefaultParser): """The ``Ganeshalingam13`` class provides access to BVRI light curves of 165 objects published by the first data release of the Lick Observatory Supernova Search (LOSS) conducted between 1998 and 2008. (Source: Ganeshalingam et al. 2013) Deviations from the standard UI: - None Cuts on returned data: - None """ survey_name = 'Lick Observatory Supernova Search' survey_abbrev = 'LOSS' release = 'Ganeshalingam13' survey_url = 'None' data_type = 'photometric' publications = ('Stahl et al. (2019)',) ads_url = 'https://ui.adsabs.harvard.edu/abs/2019MNRAS.490.3882S/abstract' _filter_file_names = [ 'B_kait1_shifted.txt', 'V_kait1_shifted.txt', 'R_kait1_shifted.txt', 'I_kait1_shifted.txt', 'B_kait2_shifted.txt', 'V_kait2_shifted.txt', 'R_kait2_shifted.txt', 'I_kait2_shifted.txt', 'B_kait3_shifted.txt', 'V_kait3_shifted.txt', 'R_kait3_shifted.txt', 'I_kait3_shifted.txt', 'B_kait4_shifted.txt', 'V_kait4_shifted.txt', 'R_kait4_shifted.txt', 'I_kait4_shifted.txt', 'B_nickel_shifted.txt', 'V_nickel_shifted.txt', 'R_nickel_shifted.txt', 'I_nickel_shifted.txt' ] band_names = ( 'loss_ganeshalingam13_B_kait1', 'loss_ganeshalingam13_V_kait1', 'loss_ganeshalingam13_R_kait1', 'loss_ganeshalingam13_I_kait1', 'loss_ganeshalingam13_B_kait2', 'loss_ganeshalingam13_V_kait2', 'loss_ganeshalingam13_R_kait2', 'loss_ganeshalingam13_I_kait2', 'loss_ganeshalingam13_B_kait3', 'loss_ganeshalingam13_V_kait3', 'loss_ganeshalingam13_R_kait3', 'loss_ganeshalingam13_I_kait3', 'loss_ganeshalingam13_B_kait4', 'loss_ganeshalingam13_V_kait4', 'loss_ganeshalingam13_R_kait4', 'loss_ganeshalingam13_I_kait4', 'loss_ganeshalingam13_B_nickle', 'loss_ganeshalingam13_V_nickle', 'loss_ganeshalingam13_R_nickle', 'loss_ganeshalingam13_I_nickle') # Taken from Table 1 zero_point = ( 15.304, # KAIT1 B 14.913, # KAIT1 V 15.357, # KAIT1 R 14.686, # KAIT1 I 15.361, # KAIT2 B 14.914, # KAIT2 V 14.975, # KAIT2 R 14.452, # KAIT2 I 15.332, # KAIT3 B 14.921, # KAIT3 V 15.008, # KAIT3 R 14.457, # KAIT3 I 15.249, # KAIT4 B 14.922, # KAIT4 V 14.973, # KAIT4 R 14.439, # KAIT4 I 15.224, # Nickel B 14.828, # Nickel V 14.930, # Nickel R 14.703, # Nickel I ) def __init__(self): """Define local and remote paths of data""" # Call to parent class defines the self._data_dir attribute # All data should be downloaded to / read from that directory super().__init__() # Define data urls self._table_3_url = 'http://heracles.astro.berkeley.edu/sndb/static/LOSS/table3_full.txt' self._photometry_url = 'http://heracles.astro.berkeley.edu/sndb/static/LOSS/loss.phot.natural.table.txt' self._filter_url = 'http://heracles.astro.berkeley.edu/sndb/static/LOSS/transmission_curves.tar' # Local data paths self._table_3_path = self._table_dir / 'table3.dat' self._photometry_path = self._data_dir / 'photometry.txt' self._filter_dir = self._data_dir / 'filters' def _load_table(self, table_id: int) -> Table: """Return a Vizier table published by this data release Args: table_id: The published table number or table name """ if table_id == 'meta_data': return load_meta() if table_id == 3: table_path = self._table_dir / f'table{table_id}.dat' df = pd.read_table( table_path, sep=r'\s{2,}', comment='#', names=['obj_id', 'z', 'm_{B}', 'm_{B} err', 'x_{1}', 'x_{1} err', 'c', 'c err', 'mu', 'mu_err', 'Sample Name', 'Reference']) table = Table.from_pandas(df) table = Table(table, masked=True) for col in table.columns.values(): col.mask = col == 99.999 return table raise NotImplementedError(f'Parsing is not implimented for table {table_id}') @lru_cache() def _load_photometry(self) -> Table: """Load photometry data Returns: An astropy table """ return Table.read( self._photometry_path, format='ascii', names=['SN', 'MJD', 'Filter', 'Mag', 'Mag err', 'Telescope System'] ) def _get_available_ids(self) -> List[str]: """Return a list of target object IDs for the current survey""" return sorted(np.unique(self._load_photometry()['SN'])) def _get_available_tables(self) -> List[str]: """Add the ``meta_data`` table to the list of available tables""" tables = super()._get_available_tables() tables.append('meta_data') return tables 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 """ photometry = self._load_photometry() object_data = photometry[photometry['SN'] == obj_id] if format_table: zp_dict = dict(zip(self.band_names, self.zero_point)) bands, zp = [], [] for row in object_data: band = f'loss_ganeshalingam13_{row["Filter"]}_{row["Telescope System"].lower()}' bands.append(band) zp.append(zp_dict[band]) object_data['time'] = utils.convert_to_jd(object_data['MJD'], 'mjd') object_data['band'] = bands object_data['zp'] = zp object_data['flux'] = 10 ** ((object_data['Mag'] - object_data['zp']) / -2.5) object_data['fluxerr'] = (np.log(10) / -2.5) * object_data['flux'] * object_data['Mag err'] object_data['zpsys'] = 'AB' object_data.remove_columns(['SN', 'MJD', 'Filter', 'Mag', 'Mag err']) meta = load_meta() obj_meta = meta[meta['obj_id'] == obj_id][0] object_data.meta = {k: (v if v != -99.99 else None) for k, v in zip(obj_meta.colnames, obj_meta)} return object_data 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 """ urls = (self._table_3_url, self._photometry_url) paths = (self._table_3_path, self._photometry_path) for file_url, file_path in zip(urls, paths): utils.download_file( url=file_url, destination=file_path, force=force, timeout=timeout ) utils.download_tar( url=self._filter_url, out_dir=self._filter_dir, skip_exists=self._filter_dir, mode='r', force=force, timeout=timeout )