DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

smoothing piecewise

Solved!
Go to solution

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.

0 Kudos
Message 1 of 8
(4,704 Views)
Solution
Accepted by Normann

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

0 Kudos
Message 2 of 8
(4,699 Views)

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.

0 Kudos
Message 3 of 8
(4,696 Views)

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.

0 Kudos
Message 4 of 8
(4,685 Views)

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

0 Kudos
Message 5 of 8
(4,674 Views)

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.

Zwischenablage02.jpg

 

 

Regards Normann

0 Kudos
Message 6 of 8
(4,666 Views)

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

0 Kudos
Message 7 of 8
(4,646 Views)

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

0 Kudos
Message 8 of 8
(4,624 Views)