fix Swift type-checker errors in LsvAnalysis chained closures
This commit is contained in:
parent
91a361732d
commit
399ee4229b
|
|
@ -41,22 +41,22 @@ func findExtrema(_ v: [Float], _ iSmooth: [Float], minProminence: Float) -> [(In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidates.filter { (idx, isMax) in
|
var result: [(Int, Bool)] = []
|
||||||
|
for (idx, isMax) in candidates {
|
||||||
let val = iSmooth[idx]
|
let val = iSmooth[idx]
|
||||||
let leftSlice = iSmooth[..<idx]
|
let leftSlice = iSmooth[..<idx]
|
||||||
let rightSlice = iSmooth[(idx + 1)...]
|
let rightSlice = iSmooth[(idx + 1)...]
|
||||||
let leftBound: Float
|
|
||||||
let rightBound: Float
|
|
||||||
if isMax {
|
if isMax {
|
||||||
leftBound = leftSlice.min() ?? val
|
let lb = leftSlice.min() ?? val
|
||||||
rightBound = rightSlice.min() ?? val
|
let rb = rightSlice.min() ?? val
|
||||||
return val - max(leftBound, rightBound) >= minProminence
|
if val - max(lb, rb) >= minProminence { result.append((idx, isMax)) }
|
||||||
} else {
|
} else {
|
||||||
leftBound = leftSlice.max() ?? val
|
let lb = leftSlice.max() ?? val
|
||||||
rightBound = rightSlice.max() ?? val
|
let rb = rightSlice.max() ?? val
|
||||||
return min(leftBound, rightBound) - val >= minProminence
|
if min(lb, rb) - val >= minProminence { result.append((idx, isMax)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detect Q/HQ redox peak in the -100 to +600 mV window.
|
/// Detect Q/HQ redox peak in the -100 to +600 mV window.
|
||||||
|
|
@ -75,13 +75,16 @@ func detectQhqPeak(_ points: [LsvPoint]) -> Float? {
|
||||||
|
|
||||||
let extrema = findExtrema(vVals, smoothed, minProminence: prominence)
|
let extrema = findExtrema(vVals, smoothed, minProminence: prominence)
|
||||||
|
|
||||||
let candidates = extrema
|
var bestIdx: Int? = nil
|
||||||
.filter { $0.1 && vVals[$0.0] >= -100 && vVals[$0.0] <= 600 }
|
var bestVal: Float = -.infinity
|
||||||
.max(by: { smoothed[$0.0] < smoothed[$1.0] })
|
for (idx, isMax) in extrema {
|
||||||
|
guard isMax, vVals[idx] >= -100, vVals[idx] <= 600 else { continue }
|
||||||
if let (idx, _) = candidates {
|
if smoothed[idx] > bestVal {
|
||||||
return vVals[idx]
|
bestVal = smoothed[idx]
|
||||||
|
bestIdx = idx
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if let idx = bestIdx { return vVals[idx] }
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,38 +111,33 @@ func deriveClPotentials(_ points: [LsvPoint]) -> ClPotentials {
|
||||||
let extrema = findExtrema(vVals, smoothed, minProminence: prominence)
|
let extrema = findExtrema(vVals, smoothed, minProminence: prominence)
|
||||||
|
|
||||||
// v_free: most prominent cathodic peak (isMax==false) in +300 to -300 mV
|
// v_free: most prominent cathodic peak (isMax==false) in +300 to -300 mV
|
||||||
let freePeak = extrema
|
var vFree: Float = 100
|
||||||
.filter { !$0.1 && vVals[$0.0] >= -300 && vVals[$0.0] <= 300 }
|
var vFreeDetected = false
|
||||||
.min(by: { smoothed[$0.0] < smoothed[$1.0] })
|
var freeIdx: Int? = nil
|
||||||
|
var freeBest: Float = .infinity
|
||||||
let vFree: Float
|
for (idx, isMax) in extrema {
|
||||||
let vFreeDetected: Bool
|
guard !isMax, vVals[idx] >= -300, vVals[idx] <= 300 else { continue }
|
||||||
let freeIdx: Int?
|
if smoothed[idx] < freeBest {
|
||||||
if let (idx, _) = freePeak {
|
freeBest = smoothed[idx]
|
||||||
vFree = vVals[idx]
|
vFree = vVals[idx]
|
||||||
vFreeDetected = true
|
vFreeDetected = true
|
||||||
freeIdx = idx
|
freeIdx = idx
|
||||||
} else {
|
}
|
||||||
vFree = 100
|
|
||||||
vFreeDetected = false
|
|
||||||
freeIdx = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// v_total: secondary cathodic peak between (vFree-100) and -500, excluding free peak
|
// v_total: secondary cathodic peak between (vFree-100) and -500, excluding free peak
|
||||||
let totalHi = vFree - 100
|
let totalHi = vFree - 100
|
||||||
let totalLo: Float = -500
|
let totalLo: Float = -500
|
||||||
let totalPeak = extrema
|
var vTotal: Float = vFree - 300
|
||||||
.filter { !$0.1 && vVals[$0.0] >= totalLo && vVals[$0.0] <= totalHi && $0.0 != freeIdx }
|
var vTotalDetected = false
|
||||||
.min(by: { smoothed[$0.0] < smoothed[$1.0] })
|
var totalBest: Float = .infinity
|
||||||
|
for (idx, isMax) in extrema {
|
||||||
var vTotal: Float
|
guard !isMax, vVals[idx] >= totalLo, vVals[idx] <= totalHi, idx != freeIdx else { continue }
|
||||||
let vTotalDetected: Bool
|
if smoothed[idx] < totalBest {
|
||||||
if let (idx, _) = totalPeak {
|
totalBest = smoothed[idx]
|
||||||
vTotal = vVals[idx]
|
vTotal = vVals[idx]
|
||||||
vTotalDetected = true
|
vTotalDetected = true
|
||||||
} else {
|
}
|
||||||
vTotal = vFree - 300
|
|
||||||
vTotalDetected = false
|
|
||||||
}
|
}
|
||||||
vTotal = max(vTotal, -400)
|
vTotal = max(vTotal, -400)
|
||||||
|
|
||||||
|
|
@ -179,18 +177,30 @@ func detectLsvPeaks(_ points: [LsvPoint]) -> [LsvPeak] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// largest peak in positive voltage region -> freeCl
|
// largest peak in positive voltage region -> freeCl
|
||||||
let freeCl = extrema
|
var freeClIdx: Int? = nil
|
||||||
.filter { $0.1 && vVals[$0.0] >= 0 }
|
var freeClVal: Float = -.infinity
|
||||||
.max(by: { smoothed[$0.0] < smoothed[$1.0] })
|
for (idx, isMax) in extrema {
|
||||||
if let (idx, _) = freeCl {
|
guard isMax, vVals[idx] >= 0 else { continue }
|
||||||
|
if smoothed[idx] > freeClVal {
|
||||||
|
freeClVal = smoothed[idx]
|
||||||
|
freeClIdx = idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let idx = freeClIdx {
|
||||||
peaks.append(LsvPeak(vMv: vVals[idx], iUa: smoothed[idx], kind: .freeCl))
|
peaks.append(LsvPeak(vMv: vVals[idx], iUa: smoothed[idx], kind: .freeCl))
|
||||||
}
|
}
|
||||||
|
|
||||||
// largest peak in negative voltage region -> totalCl
|
// largest peak in negative voltage region -> totalCl
|
||||||
let totalCl = extrema
|
var totalClIdx: Int? = nil
|
||||||
.filter { $0.1 && vVals[$0.0] < 0 }
|
var totalClVal: Float = -.infinity
|
||||||
.max(by: { smoothed[$0.0] < smoothed[$1.0] })
|
for (idx, isMax) in extrema {
|
||||||
if let (idx, _) = totalCl {
|
guard isMax, vVals[idx] < 0 else { continue }
|
||||||
|
if smoothed[idx] > totalClVal {
|
||||||
|
totalClVal = smoothed[idx]
|
||||||
|
totalClIdx = idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let idx = totalClIdx {
|
||||||
peaks.append(LsvPeak(vMv: vVals[idx], iUa: smoothed[idx], kind: .totalCl))
|
peaks.append(LsvPeak(vMv: vVals[idx], iUa: smoothed[idx], kind: .totalCl))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue