@@ -596,14 +596,14 @@ threadsafe Function/WAVE FindIndizes(WAVE numericOrTextWave, [variable col, stri
596596 return result
597597End
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]
672680End
0 commit comments