Implementation of Lupton et al. (1999) by Jan Luca van den Busch.
Hyperbolic magnitudes aim to overcome limitations of classical magnitudes, which are logarithmic in flux. Hyperbolic magnitudues are implemented using the inverse hyperbolic sine and therefore have a linear behaviour in flux at low signal to noise, which gradually transitions to the classical logarithmic scaling at high signal to noise (i.e. equivalent to classical magnitudes in this limit).
This notebooks provides an example of how to convert classical to hyperbolical magnitudes using the pipeline stages HyperbolicSmoothing and HyperbolicMagnitudes in the rail.core module.
import os
import numpy as np
import matplotlib.pyplot as plt
import rail
from rail.core.data import TableHandle
from rail.core.stage import RailStage
from rail.core.utilPhotometry import HyperbolicSmoothing, HyperbolicMagnitudes
We first set up a data store for interactive usage of RAIL (see the rail/examples/goldenspike/goldenspike.ipynb for further examples).
DS = RailStage.data_store
DS.__class__.allow_overwrite = True
Next we load some DC2 sample data that provides LSST ugrizy magnitudes and magnitude errors, which we want to convert to hyperbolic magnitudes.
from rail.core.utils import RAILDIR
testFile = os.path.join(RAILDIR, 'rail', 'examples', 'testdata', 'test_dc2_training_9816.pq')
test_mags = DS.read_file("test_data", TableHandle, testFile)
First we run the rail.core.HyperbolicSmoothing stage. This stage computes the smoothing parameter (called $b$ in Lupton et al. 1999), which determines the transition between the linear and logarithmic behaviour of the hyperbolic magnitudes.
The input for this stage is a table containing magnitudes and magnitude errors per object (fluxes are also supported as input data by setting is_flux=True in the configuration). In this example, we assume that the magnitude zeropoint is 0.0 and that we want to convert all 6 LSST bands. This can be specified with the value_columns and error_columns parameters, which list the names of the magnitude columns and their corresponding magnitude errors.
lsst_bands = 'ugrizy'
configuration = dict(
value_columns=[f"mag_{band}_lsst" for band in lsst_bands],
error_columns=[f"mag_err_{band}_lsst" for band in lsst_bands],
zeropoints=[0.0] * len(lsst_bands),
is_flux=False)
smooth = HyperbolicSmoothing.make_stage(name='hyperbolic_smoothing', **configuration)
smooth.compute(test_mags)
Inserting handle into data store. parameters_hyperbolic_smoothing: inprogress_parameters_hyperbolic_smoothing.pq, hyperbolic_smoothing
<rail.core.data.PqHandle at 0x7f2248ef3970>
The output of this stage is a table of relevant statistics required to compute the hyperbolic magnitudes per filter:
hyperbolic code)The field ID column is currently not used by the RAIL module and can be ignored.
smooth_params = smooth.get_handle("parameters").data
smooth_params
| flux error | zeropoint | ref. flux | b relative | b absolute | ||
|---|---|---|---|---|---|---|
| filter | field ID | |||||
| mag_u_lsst | 0 | 1.559839e-11 | 0.0 | 1.0 | 1.625332e-11 | 1.625332e-11 |
| mag_g_lsst | 0 | 3.286980e-12 | 0.0 | 1.0 | 3.424989e-12 | 3.424989e-12 |
| mag_r_lsst | 0 | 3.052049e-12 | 0.0 | 1.0 | 3.180194e-12 | 3.180194e-12 |
| mag_i_lsst | 0 | 4.441195e-12 | 0.0 | 1.0 | 4.627666e-12 | 4.627666e-12 |
| mag_z_lsst | 0 | 7.823318e-12 | 0.0 | 1.0 | 8.151793e-12 | 8.151793e-12 |
| mag_y_lsst | 0 | 1.785106e-11 | 0.0 | 1.0 | 1.860057e-11 | 1.860057e-11 |
Based on the smoothing parameters, the hyperbolic magnitudes are computed with be computed by rail.core.HyperbolicMagnitudes.
The input for this module is, again, the table with magnitudes and magnitude errors and the output table of rail.core.HyperbolicSmoothing.
hypmag = HyperbolicMagnitudes.make_stage(name='hyperbolic_magnitudes', **configuration)
hypmag.compute(test_mags, smooth_params)
Inserting handle into data store. parameters: None, hyperbolic_magnitudes Inserting handle into data store. output_hyperbolic_magnitudes: inprogress_output_hyperbolic_magnitudes.pq, hyperbolic_magnitudes
<rail.core.data.PqHandle at 0x7f2290e9ce20>
The output of this module is a table with hyperbolic magnitudes and their corresponding error.
Note: The current default is to relabel the columns names by substituting mag_ by mag_hyp_. If this substitution is not possible, the column names are identical to the input table with classical magnitudes.
test_hypmags = hypmag.get_handle("output").data
test_hypmags
| mag_hyp_u_lsst | mag_hyp_err_u_lsst | mag_hyp_g_lsst | mag_hyp_err_g_lsst | mag_hyp_r_lsst | mag_hyp_err_r_lsst | mag_hyp_i_lsst | mag_hyp_err_i_lsst | mag_hyp_z_lsst | mag_hyp_err_z_lsst | mag_hyp_y_lsst | mag_hyp_err_y_lsst | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 18.040370 | 0.005046 | 16.960892 | 0.005001 | 16.653413 | 0.005001 | 16.506310 | 0.005001 | 16.466378 | 0.005001 | 16.423906 | 0.005003 |
| 1 | 21.615533 | 0.009551 | 20.709402 | 0.005084 | 20.533851 | 0.005048 | 20.437566 | 0.005075 | 20.408885 | 0.005193 | 20.388203 | 0.005804 |
| 2 | 21.851866 | 0.011146 | 20.437067 | 0.005057 | 19.709715 | 0.005015 | 19.312630 | 0.005016 | 18.953412 | 0.005023 | 18.770441 | 0.005063 |
| 3 | 19.976499 | 0.005477 | 19.128676 | 0.005011 | 18.803485 | 0.005005 | 18.619996 | 0.005007 | 18.546590 | 0.005014 | 18.479452 | 0.005041 |
| 4 | 22.294717 | 0.015481 | 21.242782 | 0.005182 | 20.911803 | 0.005084 | 20.731707 | 0.005118 | 20.700288 | 0.005308 | 20.644994 | 0.006211 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 10220 | 25.732646 | 0.301680 | 25.301790 | 0.047027 | 25.099622 | 0.036055 | 25.180361 | 0.055825 | 25.295404 | 0.108750 | 25.229366 | 0.226270 |
| 10221 | 25.251545 | 0.205102 | 24.512358 | 0.023323 | 24.345662 | 0.018623 | 24.434138 | 0.028559 | 24.547622 | 0.055349 | 24.678486 | 0.140864 |
| 10222 | 25.147493 | 0.187751 | 24.113802 | 0.016640 | 23.828346 | 0.012276 | 23.711119 | 0.015380 | 23.755514 | 0.027202 | 23.830545 | 0.065739 |
| 10223 | 26.305978 | 0.435503 | 25.067304 | 0.038089 | 24.770026 | 0.026890 | 24.586800 | 0.032711 | 24.781555 | 0.068406 | 24.653411 | 0.137773 |
| 10224 | 26.429216 | 0.461142 | 25.548904 | 0.058784 | 24.983338 | 0.032494 | 24.889564 | 0.042924 | 24.836702 | 0.071907 | 24.752944 | 0.150422 |
10225 rows × 12 columns
This plot shows the difference between the classical and hyperbolic magnitude as function of the classical $r$-band magnitude. The turn-off point is determined by the value for $b$ estimated above.
filt = "r"
mag_class = test_mags.data[f"mag_{filt}_lsst"]
magerr_class = test_mags.data[f"mag_err_{filt}_lsst"]
mag_hyp = test_hypmags[f"mag_hyp_{filt}_lsst"]
magerr_hyp = test_hypmags[f"mag_hyp_err_{filt}_lsst"]
fig = plt.figure(dpi=100)
plt.axhline(y=0.0, color="k", lw=0.55)
plt.scatter(mag_class, mag_class - mag_hyp, s=1)
plt.xlabel("Classical magnitudue")
plt.ylabel("Classical $-$ hyperbolic magnitude")
plt.title("$r$-band magnitude")
Text(0.5, 1.0, '$r$-band magnitude')