@@ -972,6 +972,48 @@ def _intrinsic_coherence_uncertainties(
972972 return uncertainty
973973
974974
975+ @vectorize (
976+ ["UniTuple(float64[:, :], 2)(float64[:, :], float64[:, :], float64, float64, int64)" ],
977+ nopython = True ,
978+ )
979+ def check_powers_for_intrinsic_coherence (
980+ power1 , power2 , power1_noise , power2_noise , n_ave , threshold = 3
981+ ):
982+ """Check if the powers are above the threshold for the intrinsic coherence to be well defined.
983+
984+ Parameters
985+ ----------
986+ power1 : float `np.array`
987+ sub-band periodogram
988+ power2 : float `np.array`
989+ reference-band periodogram
990+ power1_noise : float
991+ Poisson noise level of the sub-band periodogram
992+ power2_noise : float
993+ Poisson noise level of the reference-band periodogram
994+ n_ave : int
995+ number of intervals that have been averaged to obtain the input spectra
996+
997+ Other Parameters
998+ ----------------
999+ threshold : float, default 3
1000+ The threshold in sigma above the noise level for the powers to be considered "high".
1001+
1002+ Returns
1003+ -------
1004+ low_power1 : bool `np.array`
1005+ Whether the powers of the first band are below the threshold.
1006+ low_power2 : bool `np.array`
1007+ Whether the powers of the second band are below the threshold.
1008+
1009+ """
1010+ # Consider low power when the power is less than 3 sigma above the noise level.
1011+ # This is somewhat arbitrary, better criteria suggestions are welcome.
1012+ low_power1 = (power1 - power1_noise ) <= 3 * power1_noise / np .sqrt (n_ave )
1013+ low_power2 = (power2 - power2_noise ) <= 3 * power2_noise / np .sqrt (n_ave )
1014+ return low_power1 or low_power2
1015+
1016+
9751017@vectorize (
9761018 ["UniTuple(float64[:, :], 2)(float64, float64, float64, float64, float64, int64, float64)" ],
9771019 nopython = True ,
@@ -1022,19 +1064,16 @@ def _intrinsic_coherence(
10221064 The intrinsic coherence values at all frequencies. If ``return_uncertainty`` is True,
10231065 also returns the uncertainty on the coherence.
10241066 """
1067+
1068+ if check_powers_for_intrinsic_coherence (power1 , power2 , power1_noise , power2_noise , n_ave ):
1069+ # If the powers are too close to the noise level, the coherence is not well defined.
1070+ return np .nan , np .nan
1071+
10251072 bsq = _bias_term (power1 , power2 , power1_noise , power2_noise , n_ave , 1 )
10261073 num = (cross_power * np .conj (cross_power )).real - bsq
10271074 if num < 0 :
10281075 num = 0
10291076
1030- # Consider low power when the power is less than 3 sigma above the noise level.
1031- # This is somewhat arbitrary, better criteria suggestions are welcome.
1032- low_power1 = power1 - power1_noise <= 3 * power1_noise / np .sqrt (n_ave )
1033- low_power2 = power2 - power2_noise <= 3 * power2_noise / np .sqrt (n_ave )
1034- if low_power1 or low_power2 :
1035- # If the powers are too close to the noise level, the coherence is not well defined.
1036- return np .nan , np .nan
1037-
10381077 power1_sub = power1 - power1_noise
10391078 power2_sub = power2 - power2_noise
10401079
@@ -1072,17 +1111,16 @@ def _intrinsic_coherence_with_adjusted_bias(
10721111 and the coherence will be set to NaN.
10731112
10741113 """
1114+
1115+ if check_powers_for_intrinsic_coherence (power1 , power2 , power1_noise , power2_noise , n_ave ):
1116+ # If the powers are too close to the noise level, the coherence is not well defined.
1117+ return np .nan , np .nan
1118+
10751119 # Consider low power when the power is less than 3 sigma above the noise level.
10761120 # This is somewhat arbitrary, better criteria suggestions are welcome.
10771121 power1_sub = power1 - power1_noise
10781122 power2_sub = power2 - power2_noise
10791123
1080- low_power1 = power1_sub <= 3 * power1_noise / np .sqrt (n_ave )
1081- low_power2 = power2_sub <= 3 * power2_noise / np .sqrt (n_ave )
1082- if low_power1 or low_power2 :
1083- # If the powers are too close to the noise level, the coherence is not well defined.
1084- return np .nan , np .nan
1085-
10861124 current_coherence = 1.0
10871125
10881126 for _ in range (40 ):
0 commit comments