Skip to content

Commit ca11e4f

Browse files
committed
offset source wave and cleanup
1 parent 3fc0309 commit ca11e4f

File tree

1 file changed

+67
-59
lines changed

1 file changed

+67
-59
lines changed

Packages/MIES/MIES_MiesUtilities_Algorithm.ipf

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -596,14 +596,14 @@ threadsafe Function/WAVE FindIndizes(WAVE numericOrTextWave, [variable col, stri
596596
return result
597597
End
598598

599-
//@brief Band‑pass filters a wave while automatically reducing IIR filter order until the output contains no NaNs/Infs and its SEM is not larger than the original (simple ringing detection).
599+
// @brief Band‑pass filters a wave while automatically reducing IIR filter order until the output contains no NaNs/Infs and its SEM is not larger than the original (simple ringing detection).
600600

601601
// -----------------------------------------------------------------------------
602602
// BandPassWithRingingDetection(src, fHigh, fLow, maxOrder)
603603
// -----------------------------------------------------------------------------
604-
// * src – input wave (is **not** modified; a filtered copy called <src>_BPF is produced)
605-
// * fHigh/fLow – pass‑band edge frequencies in Hz (Igor’s band‑pass requires fLow > fHigh; the routine swaps them if needed)
606-
// * maxOrder – starting (maximum) IIR filter order to try (>0)
604+
// @param src – input wave (is **not** modified; a filtered copy called <src>_BPF is produced)
605+
// @param fHigh/fLow – pass‑band edge frequencies in Hz (Igor’s band‑pass requires fLow > fHigh; the routine swaps them if needed)
606+
// @param maxOrder – starting (maximum) IIR filter order to try (>0)
607607
//
608608
// Logic: iteratively lowers the filter order until three conditions are met:
609609
// 1. FilterIIR executes without error.
@@ -612,61 +612,69 @@ End
612612
//
613613
// Return value: filter order that finally succeeded (0 if every order failed).
614614
// -----------------------------------------------------------------------------
615-
Function bandpass_with_RingingDetection(WAVE src, variable fHigh, variable fLow, variable maxOrder)
615+
Function [variable curOrder, WAVE filtered] bandpass_with_RingingDetection(WAVE src, variable fHigh, variable fLow, variable maxOrder)
616616

617617
// ---- parameter sanity ---------------------------------------------------
618-
ASSERT(maxOrder > 0, "maxOrder must be positive")
619-
if(fLow <= fHigh) // Igor band‑pass expects fLow > fHigh
620-
variable tmp = fLow
621-
fLow = fHigh
622-
fHigh = tmp
623-
endif
624-
625-
// Sampling rate (Hz) – assumes X scaling is in milliseconds
626-
variable samp = 1 / (DeltaX(src) * MILLI_TO_ONE)
627-
628-
// Pre‑compute SEM(original) once
629-
WaveStats/Q src
630-
variable semOrig = V_sem
631-
632-
// Prepare destination wave (same name every call → convenient overwrite)
633-
duplicate/O src, src_BPF
634-
WAVE filtered = src_BPF
635-
636-
variable curOrder = maxOrder, err
637-
do
638-
// -------- copy fresh data into filtered ------------------------------
639-
filtered = src // avoids repeated duplicate/O allocations
640-
641-
// -------- attempt current order --------------------------------------
642-
FilterIIR/LO=(fLow/samp)/HI=(fHigh/samp)/DIM=(ROWS)/ORD=(curOrder) filtered
643-
err = GetRTError(1)
644-
if(err)
645-
Print "FilterIIR failed (order="+num2str(curOrder)+"): "+GetErrMessage(err)
646-
curOrder -= 1
647-
continue
648-
endif
649-
650-
// -------- WaveStats: NaN/Inf + SEM in one call ------------------------
651-
WaveStats/Q filtered
652-
if(V_numNaNs > 0 || V_numInfs > 0)
653-
curOrder -= 1
654-
continue // bad numerical output → lower order
655-
endif
656-
657-
if(V_sem > semOrig) // noisier than original → ringing
658-
curOrder -= 1
659-
continue
660-
endif
661-
662-
// -------- success -----------------------------------------------------
663-
664-
break
665-
while(curOrder > 0)
666-
667-
if(curOrder <= 0)
668-
Print "bandpass_with_RingingDetection(): all orders down to 1 produced NaNs/Infs or increased SEM."
669-
endif
670-
671-
return curOrder
618+
ASSERT(maxOrder > 0, "maxOrder must be positive")
619+
if(fLow <= fHigh) // Igor band‑pass expects fLow > fHigh
620+
variable tmp = fLow
621+
fLow = fHigh
622+
fHigh = tmp
623+
endif
624+
625+
// Sampling rate (Hz) – assumes X scaling is in milliseconds
626+
variable samp = 1 / (DeltaX(src) * MILLI_TO_ONE)
627+
628+
// Pre‑compute SEM(original) once
629+
WaveStats/Q src
630+
variable semOrig = V_sem
631+
variable offset = v_avg
632+
633+
// Prepare destination wave (same name every call → convenient overwrite)
634+
duplicate/FREE src, src_BPF
635+
WAVE/z filtered = src_BPF
636+
637+
// remove offset from src copy
638+
filtered -= offset
639+
640+
curOrder = maxOrder
641+
variable err
642+
do
643+
// -------- copy fresh data into filtered ------------------------------
644+
filtered = src // avoids repeated duplicate/O allocations
645+
646+
// -------- attempt current order --------------------------------------
647+
FilterIIR/LO=(fLow/samp)/HI=(fHigh/samp)/DIM=(ROWS)/ORD=(curOrder) filtered
648+
err = GetRTError(1)
649+
if(err)
650+
Print "FilterIIR failed (order="+num2str(curOrder)+"): "+GetErrMessage(err)
651+
curOrder -= 1
652+
continue
653+
endif
654+
655+
// -------- WaveStats: NaN/Inf + SEM in one call ------------------------
656+
WaveStats/Q filtered
657+
if(V_numNaNs > 0 || V_numInfs > 0)
658+
curOrder -= 1
659+
continue // bad numerical output → lower order
660+
endif
661+
662+
if(V_sem > semOrig) // noisier than original → ringing
663+
curOrder -= 1
664+
continue
665+
endif
666+
667+
// -------- success -----------------------------------------------------
668+
669+
break
670+
while(curOrder > 0)
671+
672+
if(curOrder <= 0)
673+
Print "bandpass_with_RingingDetection(): all orders down to 1 produced NaNs/Infs or increased SEM."
674+
endif
675+
676+
// add offset back to filtered wave
677+
filtered += offset
678+
679+
return [curOrder, filtered]
672680
End

0 commit comments

Comments
 (0)