01-11-2011 03:57 AM
Hi, I need to smooth a curve but the problem is, there are peaks that shouldn't be smoothed.
in the moment I select the area which should be smoothed and then I remove the data points and interpolate the values.
the problem here is that it's not accurate enough or it will cost too much time.
is there another way to smooth only parts of a curve or to lay a filter on parts of a curve?
Thanks.
Solved! Go to Solution.
01-11-2011 08:09 AM
Hi Normann,
If you have DIAdem 2010 (11.2) or later, then you should try the "Savitzky-Golay" filter in the "Curve Fitting" ANALYSIS palette-- this inherently smooths the curve while retaining peak information.
Another option would be to try the "Digital FIlters" in the "Signal Analysis" ANALYSIS palette-- if your noise is a higher frequency than your peaks a low pass filter works quite well (check the "Force zero phase" checkbox on the "IIR Parameters" tab).
If none of that works, then the only way to apply smoothing piecewise is to cut out the sections you want to smooth into new channels, smooth the new channels, then put the sections back together with the unsmoothed sections. There is no ANALYSIS dialog to do this, but it can be automated with a VBScript.
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-11-2011 09:11 AM
i have a student version of 2010 at home, i will try the savitzky filter. this evening.
i also had the idea with cutting out the channels and then smooth/filter the parts and putting back the sections.
thx for your answer. i think the cutting out option will be the better one.
01-11-2011 10:42 AM
i just tested the savitzky filter and the results weren't very good. i'll stay with the cut out of the parts.
is it possible to mark points with the band cursor and than the script chooses this points at my beginning and my end?
i tried to record this but it doesn't work. so i have to manually type the start and the end value of my cutoff in the script.
01-12-2011 12:46 AM
Hi Normann,
Try this code to automate the smoothing of N curves in the Active VIEW area. You'll need to use the Band cursor to select the X-axis region you want to smooth, and you may need to run the smoothing on the same region multiple times to get the effect you want. If you want to speed up the smoothing, just increase the SmoothWidth variable near the top of the VBScript. You might also want to assign this VBScript to one of the VBScript shortcut keys (F1, F2, etc.) so that you can just hit <Shift-F1> or <Shift-F2> to run the script directly from VIEW.
OPTION EXPLICIT Dim Sheet, Cursor, Area, Curve, Xch, Ych, Xmin, Xmax, Pmin, Pmax, Xstart, Xdelta, GrpIdx1, GrpIdx2 SmoothWidth = 5 SmoothType = "symmetric" Set Sheet = View.ActiveSheet Set Cursor = Sheet.Cursor Set Area = Sheet.ActiveArea IF Area.DisplayObjType <> "CurveChart2D" THEN Call AutoQuit("Smoothing Window only works on 2D graph VIEW Areas") IF Cursor.Type <> "Band" THEN Call AutoQuit("Smoothing Window only works with the VIEW Band Cursor") IF NOT Area.DisplayObj.Curves.Count > 0 THEN Call AutoQuit("Your 2D graph in VIEW has no curves configured") Xmin = MinV(Cursor.X1, Cursor.X2) Xmax = MaxV(Cursor.X1, Cursor.X2) Call WndShow("VIEW") FOR Each Curve In Area.DisplayObj.Curves Xch = Curve.XChannelNumber Ych = Curve.YChannelNumber IF NOT Xch > 0 AND ChnWfKey(Ych) = TRUE THEN Xstart = ChnPropValGet(Ych, "wf_start_offset") Xdelta = ChnPropValGet(Ych, "wf_increment") Pmin = 1 + CLng((Xmin - Xstart)/Xdelta) Pmax = 1 + CLng((Xmax - Xstart)/Xdelta) ELSE Pmin = PNo(Xch, Xmin) Pmax = PNo(Xch, Xmax) END IF GrpIdx1 = GroupIndexGet("Smoothing Window 1") IF GrpIdx1 > 0 THEN Call GroupDel(GrpIdx1) GrpIdx2 = GroupIndexGet("Smoothing Window 2") IF GrpIdx2 > 0 THEN Call GroupDel(GrpIdx2) Call GroupCreate("Smoothing Window 1") GrpIdx1 = CLng(GroupCount) Call GroupCreate("Smoothing Window 2") GrpIdx2 = CLng(GroupCount) Call ChnCopyExt(Ych, GrpIdx1, 1) L1 = CNoXGet(GrpIdx1, 1) Call ChnCopyExt(Ych, GrpIdx2, 1) L2 = CNoXGet(GrpIdx2, 1) IF Pmax < ChnLength(L1) THEN Call ChnAreaDel(L1, Pmax+1, ChnLength(L1)-Pmax) IF Pmin > 1 THEN Call ChnAreaDel(L1, 1, Pmin-1) Call ChnAreaDel(L2, 1, Pmax) Call ChnSmooth(L1, L1, SmoothWidth, SmoothType) ChnLength(Ych) = Pmin-1 Call ChnConcat(L1, Ych) Call ChnConcat(L2, Ych) Call GroupDel(GrpIdx2) Call GroupDel(GrpIdx1) NEXT ' Curve
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-12-2011 03:25 AM - edited 01-12-2011 03:28 AM
thx, i tried your script but it didn't work.it shows an error, PNO(0,510.2323)(0,510.2323)channel is outside the current data matrix.
510 is the start of the band cursor. 0 isn't in the view window, but it doesn't matter where my visible area is. the error is allways there.
i wrote my own script with the recording function and a bit testing. but i have two problems.
Option Explicit 'Forces the explicit declaration of all the variables in a script. Dim Anfang Dim Ende Dim Dauer Anfang = 585 'hier den Anfang des zu korrigierenden Abschnitts wählen Ende = 920 'hier das Ende des zu korrigierenden Abschnitts wählen Dauer = Ende-Anfang 'Anlegen der Dummygruppe und kopieren des Ausschnitts in einen Dummykanal Call Data.Root.ChannelGroups.Add("Dummy", 3) Call Data.Root.ChannelGroups(3).Channels.Add("DummyVerbrauch",DataTypeFloat64) Call DataBlClpCopy("[2]/Mom. Krst. Verbr._glatt",Anfang,Dauer) '... ChnNoStr,ChnRow,ValNo Call DataBlClpPaste("[3]/DummyVerbrauch",1,0) '... ChnNoStr,ChnRow,ValNo Call Data.Root.ChannelGroups(3).Channels.Add("Zeitkanal",DataTypeFloat64) Call ChnGenVal("[3]/Zeitkanal",1,Dauer,1,1,0) '... ChnArg1,ChnRow,ValNo,ChnBegin,ChnStep,ValueOverwrite 'Filtereinstellungen entweder Filter oder Glättung verwenden Call ChnFiltCalc("[3]/Zeitkanal","[3]/Mom. Krst. Verbr._glatt","[3]/Mom. Krst. Verbr.1","IIR","Butterworth","Low pass",2,0.008,0,0,1.2,25,"Hamming",1,1) '... XW,Y,E,FiltStruc,FiltStyle,FiltType,FiltDegree,FiltLimit,FiltLowLimit,FiltUppLimit,FiltWave,FiltSamples,FiltWndFct,FiltZeroPhase,FiltCorrection 'Call ChnSmooth("[3]/Mom. Krst. Verbr._glatt","[3]/Mom. Krst. Verbr.1",40,"symmetric") '... Y,E,SmoothWidth,SmoothType 'zurückkopieren des geglätteten Stücks Call Data.Root.ChannelGroups(2).Channels.Add("Mom. Krst. Verbr._glatt_neu",DataTypeFloat64) Call ChnClpCopy("[2]/Mom. Krst. Verbr._glatt") '... ClpSource Call DataBlClpPaste("[2]/Mom. Krst. Verbr._glatt_neu",1,0) '... ChnNoStr,ChnRow,ValNo 'Call DataBlDel("[2]/Mom. Krst. Verbr._glatt1",Anfang,Dauer,1) '... ChnNoStr,ChnRow,ValNo,ValDelOnly 'Call DataBlDel("[2]/Mom. Krst. Verbr._glatt",Anfang,Dauer,1) '... ChnNoStr,ChnRow,ValNo,ValDelOnly Call DataBlCopy("[3]/Mom. Krst. Verbr.1",1,Dauer,"[2]/Mom. Krst. Verbr._glatt1",Anfang) '... ChnNoStr,ChnRow,ValNo,ChnNoStr1,TargetLine 'löschen der Dummygruppe Call Data.Root.ChannelGroups.Remove(3)
i have to write the start and the beginning in the script. it would be cool if i can mark the area which should be smoothed and then start the script like your script should work. can you help me with this.
in the moment the smoothed part is copied to a new channel, i change that later.
another problem with my script is, when i use the filter i get a leap from the old curve to the filtered part. with the smoothing function there is no leap as shown on the picture. the red curve is the original, green is smoothed, the others are filtered. is there a way that i get no leap with a filter? if not, i have to use the smoothing function.
Regards Normann
01-12-2011 01:22 PM
Hi Normann,
I believe you're getting that "leap" with the digital filter because you didn't take my earlier advice to check the "Force zero phase" checkbox.
I'd be happy to debug my VBScript with your data set if you will post one or more of your data sets or email it/them to me at brad.turpin@ni.com, but I can't debug it without you data, because it works with all the data I've tried it with so far.
Brad Turpin
DIAdem Product Support Engineer
National Instruments
01-13-2011 11:19 AM
Hi All,
Normann and I figured things out via email, but I'm posting an updated "Smoothing Window" script that will take either a waveform curve, an XY curve, or a curve where the channel is plotted vs. its array index (which was the case it couldn't handle before).
OPTION EXPLICIT Dim Sheet, Cursor, Area, Curve, Xch, Ych, Xmin, Xmax, Pmin, Pmax, Xstart, Xdelta, GrpIdx1, GrpIdx2 SmoothWidth = 5 SmoothType = "symmetric" Set Sheet = View.ActiveSheet Set Cursor = Sheet.Cursor Set Area = Sheet.ActiveArea IF Area.DisplayObjType <> "CurveChart2D" THEN Call AutoQuit("Smoothing Window only works on 2D graph VIEW Areas") IF Cursor.Type <> "Band" THEN Call AutoQuit("Smoothing Window only works with the VIEW Band Cursor") IF NOT Area.DisplayObj.Curves.Count > 0 THEN Call AutoQuit("Your 2D graph in VIEW has no curves configured") Xmin = MinV(Cursor.X1, Cursor.X2) Xmax = MaxV(Cursor.X1, Cursor.X2) Call WndShow("VIEW") FOR Each Curve In Area.DisplayObj.Curves Xch = Curve.XChannelName Ych = Curve.YChannelName IF Xch = "" THEN IF ChnWfKey(Ych) = TRUE THEN Xstart = ChnPropValGet(Ych, "wf_start_offset") Xdelta = ChnPropValGet(Ych, "wf_increment") ELSE Xstart = 1 Xdelta = 1 END IF Pmin = 1 + CLng((Xmin - Xstart)/Xdelta) Pmax = 1 + CLng((Xmax - Xstart)/Xdelta) ELSE Pmin = PNo(Xch, Xmin) Pmax = PNo(Xch, Xmax) END IF GrpIdx1 = GroupIndexGet("Smoothing Window 1") IF GrpIdx1 > 0 THEN Call GroupDel(GrpIdx1) GrpIdx2 = GroupIndexGet("Smoothing Window 2") IF GrpIdx2 > 0 THEN Call GroupDel(GrpIdx2) Call GroupCreate("Smoothing Window 1") GrpIdx1 = CLng(GroupCount) Call GroupCreate("Smoothing Window 2") GrpIdx2 = CLng(GroupCount) Call ChnCopyExt(Ych, GrpIdx1, 1) L1 = CNoXGet(GrpIdx1, 1) Call ChnCopyExt(Ych, GrpIdx2, 1) L2 = CNoXGet(GrpIdx2, 1) IF Pmax < ChnLength(L1) THEN Call ChnAreaDel(L1, Pmax+1, ChnLength(L1)-Pmax) IF Pmin > 1 THEN Call ChnAreaDel(L1, 1, Pmin-1) Call ChnAreaDel(L2, 1, Pmax) Call ChnSmooth(L1, L1, SmoothWidth, SmoothType) ChnLength(Ych) = Pmin-1 Call ChnConcat(L1, Ych) Call ChnConcat(L2, Ych) Call GroupDel(GrpIdx2) Call GroupDel(GrpIdx1) NEXT ' Curve
Brad Turpin
DIAdem Product Support Engineer
National Instruments