Skip to content

Commit

Permalink
Added option to convert SNR to significance directly based on the num…
Browse files Browse the repository at this point in the history
…ber of independent apertures for noise estimates, instead of assuming all possible non-overlapping apertures at the same radius as the candidate (which may not be relevant for some coronagraph designs)
  • Loading branch information
VChristiaens committed Oct 23, 2024
1 parent 7014d55 commit d18a1d1
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions vip_hci/metrics/snr_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ def snr(array, source_xy, fwhm, full_output=False, array2=None, use2alone=False,
return snr_vale


def significance(snr, rad, fwhm, student_to_gauss=True, verbose=True):
def significance(snr, rad, fwhm, n_ap=None, student_to_gauss=True,
verbose=True):
"""Convert a S/N ratio (measured as in [MAW14]_) into a Gaussian\
significance (n-sigma) with equivalent false alarm probability for a\
point-source detection measured at a given separation, or the opposite.
Expand All @@ -467,6 +468,11 @@ def significance(snr, rad, fwhm, student_to_gauss=True, verbose=True):
to each snr measurement.
fwhm : float
Full Width Half Maximum of the PSF.
n_ap : int, optional
Number of independent samples available. If provided, will take
precedence over using input rad and FWHM. This can be useful when the
limited azimuthal coverage is available (e.g. when using APP or 4QPM
coronagraphs).
student_to_gauss : bool, optional
Whether the conversion is from Student SNR to Gaussian significance
(True), or the opposite (False).
Expand All @@ -477,9 +483,12 @@ def significance(snr, rad, fwhm, student_to_gauss=True, verbose=True):
Equivalent Gaussian significance [student_to_gauss=True] or equivalent
Student S/N ratio [student_to_gauss=False].
"""
if n_ap is None:
n_ap = (rad/fwhm)*2*np.pi-2

if student_to_gauss:
sig = norm.ppf(t.cdf(snr, (rad/fwhm)*2*np.pi-2))
if t.cdf(snr, (rad/fwhm)*2*np.pi-2) == 1.0:
sig = norm.ppf(t.cdf(snr, n_ap))
if t.cdf(snr, n_ap) == 1.0:
print("Warning high S/N! cdf>0.9999999999999999 is rounded to 1")
msg = "Returning 8.2 sigma, but quote significance > 8.2 sigma."
print(msg)
Expand All @@ -490,7 +499,7 @@ def significance(snr, rad, fwhm, student_to_gauss=True, verbose=True):
msg += r"Gaussian false alarm probability."
print(msg.format(rad, rad/fwhm, snr, sig))
else:
sig = t.ppf(norm.cdf(snr), (rad/fwhm)*2*np.pi-2)
sig = t.ppf(norm.cdf(snr), n_ap)
if verbose:
msg = r"At a separation of {:.1f} px ({:.1f} FWHM), a {:.1f}-sigma "
msg += r"detection in terms of Gaussian false alarm probability "
Expand Down

0 comments on commit d18a1d1

Please sign in to comment.