5858
5959function calc_mean_snr ( flux:: AV1 , var:: AV2 ) where { T1<: Real , T2<: Real , AV1<: AbstractVector{T1} , AV2<: AbstractVector{T2} }
6060 idx_bad = isnan .(flux) .| isnan .(var) .| (var .<= 0.0 )
61- return mean (flux[.! idx_bad]. / sqrt .(var[.! idx_bad]))
61+ return mean (view (flux,.! idx_bad)./ sqrt .(view (var,.! idx_bad)))
62+ # return mean(flux[.!idx_bad]./sqrt.(var[.!idx_bad]))
6263end
6364
64- function smooth (f:: AV2 ; half_width:: Integer = 6 ) where { T2<: Real , AV2<: AbstractVector{T2} }
65+ function smooth_no_nans (f:: AV2 ; half_width:: Integer = 6 ) where { T2<: Real , AV2<: AbstractVector{T2} }
6566 # println("# size(f) to smooth: ", size(f))
6667 w= DSP. hanning (1 + 2 * half_width)
6768 if 1 + 2 * half_width< 3
@@ -73,6 +74,35 @@ function smooth(f::AV2; half_width::Integer = 6 ) where { T2<:Real, AV2<:Abstra
7374 end
7475end
7576
77+ function smooth_over_nans (f:: AV2 ; half_width:: Integer = 6 ) where { T2<: Real , AV2<: AbstractVector{T2} }
78+ output = zeros (eltype (f),size (f))
79+ weights = zeros (eltype (f),1 + 2 * half_width)
80+ one_over_half_width = one (eltype (f))/ half_width
81+ for (k,j) in enumerate (- half_width: half_width)
82+ twox = j* one_over_half_width
83+ weights[k] = 0.5 * (1 + cos (pi * twox))
84+ end
85+ for i in 1 : length (f)
86+ sum = zero (eltype (f))
87+ norm = zero (eltype (f))
88+ for (k,j) in enumerate (max (1 ,i- half_width): min (i+ half_width,length (f)))
89+ if isnan (f[j]) continue end
90+ sum += f[j]* weights[k]
91+ norm += weights[k]
92+ end
93+ output[i] = norm> 0 ? sum/ norm : NaN
94+ end
95+ return output
96+ end
97+
98+ function smooth (f:: AV2 ; half_width:: Integer = 6 ) where { T2<: Real , AV2<: AbstractVector{T2} }
99+ if (half_width >= 256 ) && (sum (isnan .(f)) == 0 ) # just a guess where FFT based smoothing might be faster
100+ smooth_no_nans (f,half_width= half_width)
101+ else
102+ smooth_over_nans (f,half_width= half_width)
103+ end
104+ end
105+
76106function calc_rolling_max (f:: AV2 ; width:: Integer = 13 ) where { T2<: Real , AV2<: AbstractVector{T2} }
77107 # shift = max(1,floor(Int64,width//2))
78108 @assert width% 2 == 1
@@ -298,6 +328,9 @@ function calc_continuum_anchors(λ::AV1, f::AV2; radius::AV3,
298328 if verbose println (" # passed radius = " , extrema (radius)) end
299329 # radius = min_radius .* λ./min_λ
300330 keep = Vector {Int64} ()
331+ if any (isnan .(extrema (radius)))
332+ return keep
333+ end
301334 sizehint! (keep,max (32 ,min (256 ,2 ^ floor (Int64,log2 (length (λ))- 2 ))))
302335 push! (keep,1 )
303336 j = 1
368401function calc_continuum_from_anchors ( λ:: AV1 , f:: AV2 , anchors:: AV3 ; λout:: AV4 = λ,
369402 verbose:: Bool = false ) where {
370403 T1<: Real , T2<: Real , T3<: Integer , T4<: Real , AV1<: AbstractVector{T1} , AV2<: AbstractVector{T2} , AV3<: AbstractVector{T3} , AV4<: AbstractVector{T4} }
371- calc_continuum_from_anchors_hybrid ( λ, f, anchors, λout= λout,verbose= verbose)
404+
405+ anchors_mask = (.! isnan .(λ[anchors])) .& (.! isnan .(f[anchors]))
406+ if sum (anchors_mask) < length (anchors)
407+ @warn " NaN found at anchor location" num_anchors_removed= length (anchors)- sum (anchors_mask)
408+ end
409+ calc_continuum_from_anchors_hybrid ( λ, f, view (anchors,anchors_mask), λout= λout,verbose= verbose)
372410end
373411
374412function calc_continuum_from_anchors_linear ( λ:: AV1 , f:: AV2 , anchors:: AV3 ; λout:: AV4 = λ,
0 commit comments