Source code for redrock.results

"""
redrock.results
===============

Functions for reading and writing full redrock results to HDF5.
"""

from __future__ import absolute_import, division, print_function

import os
import os.path
import numpy as np
from astropy.table import Table

from .utils import encode_column
from .templates import parse_fulltype

[docs]def write_zscan(filename, zscan, zfit, clobber=False): """Writes redrock.zfind results to a file. The nested dictionary structure of results is mapped into a nested group structure of the HDF5 file: /targetids[nt] /zscan/{spectype}/redshifts[nz] /zscan/{spectype}/zchi2[nt, nz] /zscan/{spectype}/penalty[nt, nz] /zscan/{spectype}/zcoeff[nt, nz, nc] or zcoeff[nt, nc, nz] ? /zfit/{targetid}/zfit table... Args: filename (str): the output file path. zscan (dict): the full set of fit results. zfit (Table): the best fit redshift results. clobber (bool): if True, delete the file if it exists. """ import h5py filename = os.path.expandvars(filename) if clobber and os.path.exists(filename): os.remove(filename) outdir = os.path.dirname(os.path.abspath(filename)) if not os.path.exists(outdir): os.makedirs(outdir) zfit = zfit.copy() #- convert unicode to byte strings for colname in ('spectype', 'subtype', 'fitmethod'): if colname in zfit.columns: zfit.replace_column(colname, np.char.encode(zfit[colname], 'ascii')) zbest = zfit[zfit['znum'] == 0] zbest.remove_column('znum') zbest.write(filename, path='zbest', format='hdf5') targetids = np.asarray(zbest['targetid']) spectypes = list(zscan[targetids[0]].keys()) tempfile = filename + '.tmp' fx = h5py.File(tempfile, mode='w') fx['targetids'] = targetids for spectype in spectypes: zchi2 = np.vstack([zscan[t][spectype]['zchi2'] for t in targetids]) penalty = np.vstack([zscan[t][spectype]['penalty'] for t in targetids]) zcoeff = list() for t in targetids: tmp = zscan[t][spectype]['zcoeff'] tmp = tmp.reshape((1,)+tmp.shape) zcoeff.append(tmp) zcoeff = np.vstack(zcoeff) fx['zscan/{}/zchi2'.format(spectype)] = zchi2 fx['zscan/{}/penalty'.format(spectype)] = penalty fx['zscan/{}/zcoeff'.format(spectype)] = zcoeff fx['zscan/{}/redshifts'.format(spectype)] = \ zscan[targetids[0]][spectype]['redshifts'] for targetid in targetids: ii = np.where(zfit['targetid'] == targetid)[0] fx['zfit/{}/zfit'.format(targetid)] = zfit[ii].as_array() #- TODO: fx['zfit/{}/model'] fx.close() os.rename(tempfile, filename)
[docs]def read_zscan(filename, select_targetids=None): """Read redrock.zfind results from a file. Args: filename (str): redrock details (.h5) filename select_targetids (list): array of TARGETIDs to read Returns: tuple: ``(zscan, zfit)`` where ``zfit`` is a Table with the N best fits for each target per spectype and subtype; and ``zscan`` is a nested dictionary ``zscan[targetid][templatetype]`` with keys: - redshifts: array of redshifts scanned - zchi2: array of chi2 of fit vs. redshifts - penalty: array of chi2 penalties for unphysical fits at each z - zcoeff: array of coefficients fit per redshifts - zfit: table of N best-fit redshifts for just this target and templatetype """ import h5py # zbest = Table.read(filename, format='hdf5', path='zbest') with h5py.File(os.path.expandvars(filename), mode='r') as fx: targetids = fx['targetids'][()] # .value fulltypes = list(fx['zscan'].keys()) if select_targetids is not None: indx = np.where(np.isin(targetids, select_targetids))[0] else: indx = np.arange(len(targetids)) zscan = dict() for targetid in targetids[indx]: zscan[targetid] = dict() for fulltype in fulltypes: zscan[targetid][fulltype] = dict() for fulltype in fulltypes: spectype, subtype = parse_fulltype(fulltype) # blat[()] is obtuse syntax for what used to be clear blat.value zchi2 = fx['/zscan/{}/zchi2'.format(fulltype)][()] penalty = fx['/zscan/{}/penalty'.format(fulltype)][()] zcoeff = fx['/zscan/{}/zcoeff'.format(fulltype)][()] redshifts = fx['/zscan/{}/redshifts'.format(fulltype)][()] for i, targetid in zip(indx, targetids[indx]): zscan[targetid][fulltype]['redshifts'] = redshifts zscan[targetid][fulltype]['zchi2'] = zchi2[i] zscan[targetid][fulltype]['penalty'] = penalty[i] zscan[targetid][fulltype]['zcoeff'] = zcoeff[i] thiszfit = fx['/zfit/{}/zfit'.format(targetid)][()] ii = (thiszfit['spectype'].astype('U') == spectype) ii &= (thiszfit['subtype'].astype('U') == subtype) thiszfit = Table(thiszfit[ii]) thiszfit.remove_columns(['targetid', 'znum', 'deltachi2']) thiszfit.replace_column('spectype', encode_column(thiszfit['spectype'])) thiszfit.replace_column('subtype', encode_column(thiszfit['subtype'])) zscan[targetid][fulltype]['zfit'] = thiszfit zfit = [fx['zfit/{}/zfit'.format(tid)][()] for tid in targetids[indx]] zfit = Table(np.hstack(zfit)) zfit.replace_column('spectype', encode_column(zfit['spectype'])) zfit.replace_column('subtype', encode_column(zfit['subtype'])) return zscan, zfit
[docs]def read_zscan_redrock(filename): """Read redrock.zfind results from a file to be reused by redrock itself. Returns: dict: dictionary of results for each local target ID. dic.keys() are TARGETID dic[tg].keys() are TEMPLATE dic[tg][ft].keys() are ['penalty', 'zcoeff', 'zchi2', 'redshifts'] """ import h5py with h5py.File(os.path.expandvars(filename), mode='r') as fx: targetids = fx['targetids'][()] spectypes = list(fx['zscan'].keys()) tmp_results = { ft: {'redshifts':fx[f'/zscan/{ft}/redshifts'][()], 'zchi2':fx[f'/zscan/{ft}/zchi2'][()], 'penalty':fx[f'/zscan/{ft}/penalty'][()], 'zcoeff':fx[f'/zscan/{ft}/zcoeff'][()]} for ft in spectypes} results = { tg:{ ft: {'redshifts':tmp_results[ft]['redshifts'], 'zchi2':tmp_results[ft]['zchi2'][i], 'penalty':tmp_results[ft]['penalty'][i], 'zcoeff':tmp_results[ft]['zcoeff'][i]} for ft in spectypes } for i, tg in enumerate(targetids) } return results