01-20-2014 02:30 AM - edited 01-20-2014 02:34 AM
Hi,
I am using the following function on a measured "step"-function (values rise to a peak, then fall exponentially down to a certain level, then again rise to a peak and to a higher level and so on...):
Call ChnPeakDetect(Data.Root.ChannelGroups(1).Channels("Noname"),Data.Root.ChannelGroups(1).Channels("Noname_1"),"ChnY/Pos","ChnX/Ampl", "Peaks", 0, 3500)
I got 60000 values in the channel, with the peaks after each 5000 to 10000 values.
But even with a threshold, Diadem gives me the wrong peaks, the number is correct, but the peaks are to low. Does the function give me some average-values? When I decrease the number of values (from 3500 to 3000) I get a little bit higher values.
What do I have to change or what did I wrong? Is it possible to get the max. local peaks in this way? I also tried "ChnPeakFind" but it didn't work out for me so far.
Thank you for you help!
01-20-2014 12:44 PM
Hi budist,
Peak finding is something that humans do better than computers, especially when you're talking about teaching the computer how to find the peaks you're LOOKING at, based on your definition of what constitutes a peak.
The easiest way to answer your question would be to see your data set, and ideally to be able to play with it a bit. Can you post it here or email it to me at brad.turpin@ni.com?
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-21-2014 01:38 AM - edited 01-21-2014 01:39 AM
Hi,
I've sent you the data. Peaks (column 2) in my case are the local maximum values. The peaks are "easy to look at"
Best Regards
01-21-2014 12:39 PM
Hi budist,
Here's the code I came up with to find your "step peaks". Feel free to send me other "similar" data sets that the script doesn't work right on, and perhaps we can make it more robust, but it works great with the one data set you sent.
OPTION EXPLICIT Dim n, P1, P2, Pn, Pmax, Group, Channels, XpeakChannel, YpeakChannel, RiseFormula, FallFormula Const LowPassFiltFreq = 0.05 Const PeakAmplDivider = 5 Set Group = Data.Root.ActiveChannelGroup Set Channels = Group.Channels Call LowPassFilter(Channels(1), Channels(2), "Filtered", LowPassFiltFreq) Call ChnDeltaCalc(Channels(3), "Delta") Call ChnLinScale(Channels(4), Channels(4), CMax(Channels(2))/CMax(Channels(4)), 0) Set XpeakChannel = Group.Channels.Add("Peak X", DataTypeFloat64) Set YpeakChannel = Group.Channels.Add("Peak Y", DataTypeFloat64) Pmax = Channels(4).Size R1 = CMax(Channels(2))/PeakAmplDivider RiseFormula = "Ch(Delta) > R1" RiseFormula = Replace(RiseFormula, "Delta", """" & Channels(4).GetReference(eRefTypeIndexName) & """") FallFormula = "Ch(Delta) < 0" FallFormula = Replace(FallFormula, "Delta", """" & Channels(4).GetReference(eRefTypeIndexName) & """") Call WndShow("VIEW") Do P1 = ChnFind(RiseFormula, P2+1) ' rising edge IF P1 = 0 THEN P2 = Pmax ELSE P2 = ChnFind(FallFormula, P1+1) ' falling edge IF P2 = 0 THEN P2 = Pmax END IF IF P1 > 0 THEN n = n + 1 Pn = 1 + FindLocalMaxRow(Channels(2), P1, P2) XpeakChannel.Values(n) = Channels(1).Values(Pn) YpeakChannel.Values(n) = Channels(2).Values(Pn) END IF Loop Until P2 = Pmax Sub LowPassFilter(ChnX, ChnY, ChnFilt, FiltFreq) IF FiltFreq > 0 THEN FiltLimit = FiltFreq FiltWndFct = "Rectangle" FiltType = "Low pass" FiltStruc = "IIR" FiltStyle = "Bessel" FiltZeroPhase = 1 FiltCorrection = 1 FiltDegree = 1 Call ChnFiltCalc(ChnX, ChnY, ChnFilt) END IF End Sub ' LowPassFilter() Function FindLocalMaxRow(Channel, P1, P2) Dim k, Pn, PeakFormula FOR k = 1 TO 22 StatSel(k) = "No" NEXT ' i StatSel(5) = "Yes" ' Maximum value StatClipCopy = 0 StatClipValue = 0 StatResChn = 0 Call StatBlockCalc("Channel", P1 & "-" & P2, Channel) PeakFormula = "ValEqual(Ch(Peak), StatMax)" PeakFormula = Replace(PeakFormula, "Peak", """" & Channel.GetReference(eRefTypeIndexName) & """") Pn = ChnFind(PeakFormula, P1) FindLocalMaxRow = Pn End Function ' FindLocalMaxRow()
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-23-2014 05:51 AM - edited 01-23-2014 05:55 AM
Hey Brad,
Thanks a lot for the code! It worked well on the example! I wanted to try it on multiple other data sets, but before that I got another problem and yet no solution:
I added a loop, but the subroutine wont save channel 4 in group 2 at the second iteration.
Do you know why? I cant put the subroutine definition into the loop. But thats how the code is defined, I guess.
Can I work around this problem? The reason I create 3 groups, is that I get data files consisting of three data sets, which I gave you. So I want to split them up and get the results for each single data set in one group. Seems to be the easiest way in comparison to copying the channels and handling the channel numbers with an index (if that is possible...)).
Thanks again!
.....
Dim loop for loop = 1 to Groupcount 'activates groups one after another ("if then", cause I couln't use index "loop" in Data.Root.ChannelGroups(loop).Activate()) if schleif=1 then Call Data.Root.ChannelGroups(1).Activate() else if schleif = 2 then Call Data.Root.ChannelGroups(2).Activate() 'activate group with index 2 in second loop iteration else if schleif = 3 then Call Data.Root.ChannelGroups(3).Activate() end if end if end if Set Group = Data.Root.ActiveChannelGroup 'select group "loop" at each iteration "loop" Set Channels = Group.Channels .... ... your code up to beginning of subroutine definition ... ... END IF Loop Until P2 = Pmax next 'Loop end Sub LowPassFilter(ChnX, ChnY, ChnFilt, FiltFreq) IF FiltFreq > 0 THEN FiltLimit = FiltFreq FiltWndFct = "Rectangle" FiltType = "Low pass" FiltStruc = "IIR" FiltStyle = "Bessel" FiltZeroPhase = 1 FiltCorrection = 1 FiltDegree = 1 Call ChnFiltCalc(ChnX, ChnY, ChnFilt) 'doesn't save the channel ChnFilt in activated group, seems only in the group with index 1 , why? Didn't found an option for ChnFiltCalc to chose a group for saving the results in END IF End Sub ' LowPassFilter() Function FindLocalMaxRow(Channel, P1, P2) Dim k, Pn, PeakFormula FOR k = 1 TO 22 StatSel(k) = "No" NEXT ' i StatSel(5) = "Yes" ' Maximum value StatClipCopy = 0 StatClipValue = 0 StatResChn = 0 Call StatBlockCalc("Channel", P1 & "-" & P2, Channel) PeakFormula = "ValEqual(Ch(Peak), StatMax)" PeakFormula = Replace(PeakFormula, "Peak", """" & Channel.GetReference(eRefTypeIndexName) & """") Pn = ChnFind(PeakFormula, P1) FindLocalMaxRow = Pn End Function ' FindLocalMaxRow()
01-23-2014 11:33 AM
Hi budist,
I'm not sure why you were getting an error, but I refactored my code a bit to support operating on all Groups in the Data Portal separately-- give this a try:
OPTION EXPLICIT Dim Group Const LowPassFiltFreq = 0.05 Const PeakAmplDivider = 5 FOR Each Group In Data.Root.ChannelGroups Call GroupStepPeaks(Group, LowPassFiltFreq, PeakAmplDivider) NEXT ' Group Sub GroupStepPeaks(Group, LowPassFiltFreq, PeakAmplDivider) Dim n, P1, P2, Pn, Pmax, Channels, XpeakChannel, YpeakChannel, RiseFormula, FallFormula Call Group.Activate Set Channels = Group.Channels Call LowPassFilter(Channels(1), Channels(2), "/Filtered", LowPassFiltFreq) Call ChnDeltaCalc(Channels(3), "/Delta") Call ChnLinScale(Channels(4), Channels(4), CMax(Channels(2))/CMax(Channels(4)), 0) Set XpeakChannel = Group.Channels.Add("Peak X", DataTypeFloat64) Set YpeakChannel = Group.Channels.Add("Peak Y", DataTypeFloat64) Pmax = Channels(4).Size R1 = CMax(Channels(2))/PeakAmplDivider RiseFormula = "Ch(Delta) > R1" RiseFormula = Replace(RiseFormula, "Delta", """" & Channels(4).GetReference(eRefTypeIndexName) & """") FallFormula = "Ch(Delta) < 0" FallFormula = Replace(FallFormula, "Delta", """" & Channels(4).GetReference(eRefTypeIndexName) & """") Call WndShow("VIEW") Do P1 = ChnFind(RiseFormula, P2+1) ' rising edge IF P1 = 0 THEN P2 = Pmax ELSE P2 = ChnFind(FallFormula, P1+1) ' falling edge IF P2 = 0 THEN P2 = Pmax END IF IF P1 > 0 THEN n = n + 1 Pn = 1 + FindLocalMaxRow(Channels(2), P1, P2) XpeakChannel.Values(n) = Channels(1).Values(Pn) YpeakChannel.Values(n) = Channels(2).Values(Pn) END IF Loop Until P2 = Pmax End Sub ' GroupStepPeaks() Sub LowPassFilter(ChnX, ChnY, ChnFilt, FiltFreq) IF FiltFreq > 0 THEN FiltLimit = FiltFreq FiltWndFct = "Rectangle" FiltType = "Low pass" FiltStruc = "IIR" FiltStyle = "Bessel" FiltZeroPhase = 1 FiltCorrection = 1 FiltDegree = 1 Call ChnFiltCalc(ChnX, ChnY, ChnFilt) END IF End Sub ' LowPassFilter() Function FindLocalMaxRow(Channel, P1, P2) Dim k, Pn, PeakFormula FOR k = 1 TO 22 StatSel(k) = "No" NEXT ' i StatSel(5) = "Yes" ' Maximum value StatClipCopy = 0 StatClipValue = 0 StatResChn = 0 Call StatBlockCalc("Channel", P1 & "-" & P2, Channel) PeakFormula = "ValEqual(Ch(Peak), StatMax)" PeakFormula = Replace(PeakFormula, "Peak", """" & Channel.GetReference(eRefTypeIndexName) & """") Pn = ChnFind(PeakFormula, P1) FindLocalMaxRow = Pn End Function ' FindLocalMaxRow()
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-26-2016 05:15 AM
Hi Brad,
Sorry for bumping an old thread but I have a 'similar' problem. I already posted my problem on the DIAdem forum, but today I found this thread and thought you might be able to help. I have a time trace of pressure from a sensor installed on a high-speed craft that was driven at high speeds in rough seas. The time trace consists of a large number of single impact events. I am using the Find Peaks tool to find the first 100 highest peaks. However the alogirthim is also picking up secondary peaks within the same impact event. Can you help me?
Regards,
Josef
02-01-2016 12:56 PM
Hi Josef,
It looks from your screenshot like the secondary peaks always occur AFTER the primary peak chronologically-- is that always true? Would you be able to assign a certain "dead window" time after each primary peak, so that any subsequent peaks in that time window could be categorically ignored? Or might there be another, different primary peak that occurs before all the secondary peaks from the last primary are done?
Brad Turpin
DIAdem Product Support Engineer
National Instruments
02-02-2016 03:09 AM
Hi Brad,
Thank you for your reply. I managed to sort out this problem with the help of Andreas (also a product support engineer) by first identifying all the 'impact events' and then searching for the peak within those events.
Regards,
Josef