Detection Efficiency Filter Demo
This notebook demonstrates the detection efficiency/fading function filter. The equation for the fading function is taken from Veres & Chesley (2017):
where \(\epsilon(m)\) is the probability of detection, \(F\) is the peak detection efficiency, \(m\) and \(m_{5\sigma}\) are respectively the observed magnitude and \(5\sigma\) limiting magnitude of the pointing, and \(w\) is the width of the fading function.
[1]:
from sorcha.modules.PPFadingFunctionFilter import PPFadingFunctionFilter
from sorcha.utilities.sorchaModuleRNG import PerModuleRNG
[2]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
Create a dataframe of synthetic observations
Only the apparent magnitude and the five-sigma limiting depth are needed for this. For simplicity, we will set the five-sigma limiting depth to be constant for all observations.
[3]:
nobs_per_field = 1000000
[4]:
mags = np.random.uniform(23.0, 26.0, nobs_per_field)
five_sigma = np.zeros(nobs_per_field) + 24.5
random_obs = pd.DataFrame({"PSFMag":mags, "fiveSigmaDepth_mag":five_sigma})
[5]:
random_obs
[5]:
| PSFMag | fiveSigmaDepth_mag | |
|---|---|---|
| 0 | 23.714230 | 24.5 |
| 1 | 25.921639 | 24.5 |
| 2 | 24.809060 | 24.5 |
| 3 | 24.450894 | 24.5 |
| 4 | 24.829012 | 24.5 |
| ... | ... | ... |
| 999995 | 24.655972 | 24.5 |
| 999996 | 25.373721 | 24.5 |
| 999997 | 25.008599 | 24.5 |
| 999998 | 23.506419 | 24.5 |
| 999999 | 23.894184 | 24.5 |
1000000 rows × 2 columns
We can apply the fading function filter implementation in Sorcha to the randomised observations.
[6]:
peak_efficiency = 1.0
width = 0.1
rng=PerModuleRNG(2021)
reduced_obs = PPFadingFunctionFilter(random_obs, peak_efficiency, width, rng)
Now we calculate the probabilty of each observation to survive Sorcha’s fading function filter, binned by magnitude.
[7]:
bin_width = 0.04
magbins = np.arange(23.0, 26.0, bin_width)
magcounts, _ = np.histogram(random_obs['PSFMag'].values, bins=magbins)
redmagcounts, _ = np.histogram(reduced_obs['PSFMag'].values, bins=magbins)
sorcha_probability = redmagcounts/magcounts
And we can compare this to the calculated detection probability of each magnitude bin, using Equation One.
[8]:
calculated_probability = peak_efficiency / (1.0 + np.exp((magbins - 24.5) / width))
[9]:
fig, ax = plt.subplots(1, figsize=(8, 6))
ax.bar(magbins[:-1], sorcha_probability, align="edge", width=bin_width, color="mediumaquamarine", label="Sorcha detection probability")
ax.set_ylim((0, 1.1))
ax.set_xlim((23, 26))
ax.set_xlabel("PSF magnitude")
ax.set_ylabel("detection probability")
ax.plot(magbins, calculated_probability, color="darkslateblue", label="calculated detection probability")
ax.legend()
plt.show()
Sorcha’s detection probability clearly follows the expected curve.
We can also take a look at how the fading function/detection efficiency changes with parameters.
[10]:
def deteff(mags, fivesig, peak, width):
return peak / (1.0 + np.exp((mags - fivesig) / width))
[11]:
colors = plt.get_cmap('gnuplot', 3)
x = colors(np.arange(0,3,1))
[12]:
widths = [0.05, 0.1, 0.15]
colors = ["tomato", "darkslateblue", "mediumturquoise"]
styles = ["solid", "dotted", "dashed"]
[13]:
fig, ax = plt.subplots(1, figsize=(8, 6))
ax.axvline(24.5, 0, 1, linestyle="-", alpha=0.5, color="grey", linewidth=0.8)
ax.axhline(0.5, 0, 1, linestyle="-", alpha=0.5, color="grey", linewidth=0.8)
for i, width in enumerate(widths):
y = deteff(magbins, 24.5, 1., width)
ax.plot(magbins, y, color=colors[i], linestyle=styles[i], label=f"$F = $ 1.0, $w = {width}$")
y = deteff(magbins, 24.5, .9, 0.1)
ax.plot(magbins, y, color="mediumpurple", linestyle="dashdot", label=f"$F = $ 0.9, $w = {width}$")
ax.set_xlim((23, 26))
ax.legend()
ax.set_xlabel("PSF magnitude")
ax.set_ylabel("detection probability")
fig.tight_layout()
plt.show()