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')