09-13-2019 12:52 PM
Hello,
I am having an issue where a script is taking around 70x as long to run from a dialog box as it does when I run it directly from the script editor.
The way I have my initial function call setup is below (runs in 7 seconds):
Call ScriptInclude(CurrentScriptPath+"Sub-Routine Library.VBS") Call OrderCalcFast(Array(73.5,125.2,251.8),"[1]/Intermediate X","[1]/Speed",5,210,0.1,"Orders")
And when I call the same function through a dialog, below is the relevant function where the script is called (takes around 8 minutes to run):
Sub Run_OrderAnalysis_EventClick(ByRef This) 'Created Event Handler View.AutoRefresh=False Call UIAutoRefreshSet(False) If AccelChannel="" or SpeedChannel="" then Call MsgBoxDisp("Must select Y reference and FFT channels.") ElseIf StopTime<=StartTime then Call MsgBoxDisp("Stop time must be greater than start time.") ElseIf TimeStep<=0 then Call MsgBoxDisp("Time step must be greater than 0.") Else Call OrderCalcFast(Array(Order),AccelChannel,SpeedChannel,StartTime,StopTime,TimeStep,ResultName) End If View.AutoRefresh=True Call UIAutoRefreshSet(True) End Sub
All of the variables are just dims, and scriptinclude is called at the top of the script identically to the top version. The dialog is mainly there to simplify the use and help our users to avoid entering invalid info. But this script will eventually be running quite a few times consecutively as it will be set up to run on various portions of the data.
One thing I have noticed is that it will allows me to access and modify the information in the data portal when running it from the dialog, but nothing I do lets me lock the screen.
Any suggestions to fix this is appreciated..
Thanks
Solved! Go to Solution.
09-16-2019 05:18 PM
I have been doing a lot of work in dialogs lately, and other than an issue with workers/parallel processes, I haven't experienced this. It would be helpful to understand the DIAdem commands or especially any other that use CreateObject() in your OrderCalcFast() function. Anything you can share would be appreciated.
09-17-2019 06:10 AM
I can share the code without any issues, I mainly didn't post it as it is a pretty significant amount of code. Here is the OrderCalcFast() Function:
Sub OrderCalcFast(Orders,Acc_Ch_Nm,Sp_Ch_Nm,t_start,t_stop,t_step,ResName) Dim Z,f_order,Length,Max,Ord_Index,FFT_Results,OrderCh 'gets the selected accel channel Set FFTCh = data.GetChannel(Acc_Ch_Nm) 'checks whether the user wants to use time, or a different reference channel Set RefCh = data.GetChannel(Sp_Ch_Nm) 'stops the user inteface from updating while the script is running Call UIAutoRefreshSet(False) 'pulls the time channel from the accel waveform t = ChnFromWfXGen(FFTCh, t, "WfXRelative") 'gets the name of the reference channel RefChName=RefCh.Name tempStrArr=Split(Sp_Ch_Nm,"/") RefGrpNum=CDbl(Replace(Replace(tempStrArr(0),"[",""),"]","")) Call GroupDefaultSet(RefGrpNum) 'gets the accel channel name tempStrArr=Split(Acc_Ch_Nm,"/") GrpNum=CDbl(Replace(Replace(tempStrArr(0),"[",""),"]","")) 'creates the temporary analysis group Set Analysis = CreateGroup("Analysis",True) 'Creates seperate group for FFT results to be deleted Set FFT_Results = CreateGroup(ResName+"_Temp",True) 'creates the result group Set Results = CreateGroup(ResName,True) 'determines the time steps of the accel channel as well as the reference channel (if you are using a reference channel) dt_FFT=FFTCh.Properties("wf_increment").Value dt_sp=RefCh.Properties("wf_increment").Value 'determines the number of calculation steps steps=(t_stop-t_start)/t_step 'loops through the data and does each calculation for i = 1 to (steps) 'determines the number of data points in a given group IndexStep=Int(t_step/dt_FFT) 'determines the index of the start of the first data point to use strt=Int(t_step/dt_FFT)*Int(t_start/t_step) 'determines this loops start/stop indices istart=IndexStep*(i-1)+1+strt istop=IndexStep*i+strt 'creates the channels to use for the calculations, and gets the data to do the calculation on for the current step Set NewCh = CreateChannel("Analysis",Cstr(i), DataTypeChnFloat64,True) Call DataBlCopy(FFTCh,istart,istop-istart,NewCh,1) Set tCh = CreateChannel("Analysis","Time"&Cstr(i),DataTypeDate,True) Call DataBlCopy(t,istart,istop-istart,tCh,1) 'runs the FFT calculation on this steps data Call ChnFFT1(tCh,NewCh) 'deletes the newly created frequency channel after the first loop, as it will be a duplicate of every previous loop if i>1 then ChnDelete(Data.Root.ChannelGroups(GrpNum).Channels("Frequency"+cstr(1))) End If 'deletes the temporary Channel in analysis ChnDelete(NewCh) 'Create temporary analysis channel to hold speed data to get average speed in a given amount of time. Set NewCh = Analysis.Channels.Add(Cstr(i), DataTypeChnFloat64) Call DataBlCopy(RefCh,istart,istop-istart,NewCh,1) 'turns off all of the stat functions For S = 1 To 23 StatSel(S) = "No" Next 'S 'Turns on the necessary statistic calcs StatSel(6) = "Yes" ' Arith. mean 'completes statistical calculation Call StatBlockCalc("Channel","1-", NewCh) 'creates a channel in the results group to hold the reference channel, adds that data too it If CNo(GroupName(GroupIndexGet(FFT_Results.Name))+"/"+RefChName) = 0 Then Set RefrenceCh = CreateChannel(ResName+"_Temp",RefChName, DataTypeChnFloat64,True) RefrenceCh(RefrenceCh.Size+1)=Data.Root.ChannelGroups(RefGrpNum).Channels("ArithmeticMean").Values(1) Else RefrenceCh(RefrenceCh.Size+1)=Data.Root.ChannelGroups(RefGrpNum).Channels("ArithmeticMean").Values(1) End If 'deletes the temporary channel in the analysis group ChnDelete(NewCh) 'deletes the channel that help the arithmetic mean channel ChnDelete(Data.Root.ChannelGroups(RefGrpNum).Channels("ArithmeticMean")) 'moves the resulting FFT calculated channe into the results group Call data.Move(Data.Root.ChannelGroups(GrpNum).Channels("AmplitudePeak"),FFT_Results.Channels) 'deletes this loops temporary time channel ChnDelete(tCh) next 'i 'deletes the temporary time channel generated from the waveform channel ChnDelete(t) 'moves the FFT frequency channel into the results group Call data.Move(Data.Root.ChannelGroups(GrpNum).Channels("Frequency"),FFT_Results.Channels,1) 'deletes the temporary analysis group Call GroupDel(Data.Root.ChannelGroups("Analysis").Properties("index").Value) 'Gets the length of the frequency channel Length=Data.Root.ChannelGroups(ResName+"_Temp").Channels("Frequency").Properties("length").Value 'Gets the maximum Frequency Value from the frequency channel Max=Data.Root.ChannelGroups(ResName+"_Temp").Channels("Frequency").Maximum 'determines the step length that the frequency is taking f_step=Max/(Length-1) 'Moves the speed channel into the results group Call data.Move(RefrenceCh,Results.Channels,1) 'determines the values for each of the orders desired for each Z in Orders 'creates the channel for the given order in the results group Set OrderCh = CreateChannel(ResName,"Order: "+Cstr(Z),DataTypeChnFloat64,True) 'iterates through each of the time steps and determines the order magnitude for that step for i = 1 to (steps) 'determines the frequency of the desired order for every step f_order=(RefrenceCh(i)/60)*Z 'gets the closest index for that order Ord_Index=Round(f_order/f_step) 'if the index desired is greater than the highest calculated frequency, return magnitude 0 if Ord_Index<=Length Then 'pulls the specific magnitudes for the given order if i=1 then OrderCh(i) = FFT_Results.Channels("AmplitudePeak")(Ord_Index) Else OrderCh(i) = FFT_Results.Channels("AmplitudePeak"+CStr(i-1))(Ord_Index) End If Else OrderCh(i)=0 End If next 'i next 'Z 'Deletes the temporary group storing the FFT results Call GroupDel(Data.Root.ChannelGroups(ResName+"_Temp").Properties("index").Value) 'tells diadem to number the channels in the order they appear in the data portal Call ChnRenumber() 'begins refreshing the UI Call UIAutoRefreshSet(True) End Sub
Any and all help is appreciated.
Thanks
09-19-2019 02:07 PM
I spent a fair amount of time trying to make the OrderCalcFast() work with generic waveform data, but without success. The major obstacle is not knowing the value of the arguments for Orders,Acc_Ch_Nm,Sp_Ch_Nm,t_start,t_stop,t_step,ResName that are passed to OrderCalcFast(). Without those arguments, I can't figure out what the "for i = 1 to (steps)" is doing.
Nothing in your script stands out that I know would cause an issue when running within a dialog.
Sorry I could not be of more help.
09-19-2019 02:30 PM
So, a quick summary of what the script is doing is breaking the data into sections to determine the magnitude of the frequencies being excited by a shaft spinning at some speed (Reference Channel). In other words, if the shaft is spinning at 1Hz, and you have a 1:3 gear ratio, then a 10:1 gear ratio, you will see the dominant frequencies 1, 3, and 30 Hz. Because of this the reference channel will need to be relatively linear throughout the measurement.
Throughout a typical test that we would use this speed might go from 50 RPM to 16,000 RPM over 12 minutes and the Acc_Ch_Nm (accelerometer channel name) would be the measurement of the vibrational acceleration during that ramp time.
The last part is pulling the dominant frequencies out of the Fourier transform.
The data types for each of the variables are:
Acc_Ch_Nm - string ([1]/Vibration Channel name)
Sp_Ch_Nm - string ([1]/Speed Channel Name)
t_start - Float (start time for data analysis)
t_stop - Float (stop time for data analysis)
t_step - float (best to use a value where mod(t_stop-t_start,t_step)=0)
I would provide you with a working data set, but most of the data sets we work with are sampled at 204.8 kHz over about 30 minutes and 18-30 channels, so all of our data sets are immensely large.
Is there any settings in a dialog box that you are aware of that can cause the user interface to freeze similar to how it does during script operation? That would be ideal, because I believe the main issue is that the UI stays active, and because I am manipulating such large data sets, each UI update causes a significant amount of delay.
I do appreciate the effort that you put into helping me solve the issue.
Thanks
09-20-2019 10:09 AM
If you start it from dialog the DIAdem user interface is not switched off.
There is a method to witch it off.
You can use a class like the given one to automatically set the value back when your script finished.
class CAutoUIAutoRefresh Private Sub Class_Initialize() oldVal_ = UIAutoRefresh UIAutoRefreshSet false End Sub Private Sub Class_Terminate() UIAutoRefreshSet oldVal_ End Sub private oldVal_ end class dim doNotUpdate : set doNotUpdate = new CAutoUIAutoRefresh
09-20-2019 11:56 AM
Unfortunately this method did not work either, the user interface was still active. However, i was able to figure out a working solution.
I have a diadem view setup with all of our data analysis tools which was directly calling the method:
SUDDlgShow("NVH","Data Anaylsis.SUD")
Instead I created a separate script which only has the above method, and in the dialog I call:
Call ScriptStart(CurrentScriptPath+"Launch NVH Program.VBS")
This locks Diadems panels while the script is working, and drops the time back down to about 5 seconds for each order. It seems pretty roundabout to me, but since works I am not too worried about it.
Thanks for the help.
10-15-2019 08:29 AM
UIAutorefreshSet(false) will reduce the flickering of the data portal and you will get a little bit increasing of the performance. But if you have many code lines to be processed, it is better to place the code into an own script and execute the script by ScriptStart.