Showing time or clock on the panel
Ann
Hi all,
How can I show the progressive time in a panel after a simulation/calculation has been started (say, I want to show the time in seconds after the launch of the simulation like 1, 2, 3,....4 s on a digital watch)?
I noticed several time function like date time, time; what I want is to display the elapsed time in seconds. I can calculate the total elapsed time at the end of the simulation but my target is to show the progressive simulation time in seconds after the beginning of it .
Thanks.
You can use a progress bar if you have an idea of how many steps you are into the simulation. If you want to simply display real or elapsed time you can have a panel with a SetVariable displaying a variable or a string that is updated from a background process. Here is an example:
// Add the following in your procedure window:
function backgroundTime()
SVAR sss=root:sss
sss=Secs2Time(DateTime,3)
return 0
End
Window Panel0() : Panel
PauseUpdate; Silent 1 // building window...
NewPanel /W=(55,45,475,190)
SetVariable setvar0,pos={61.00,66.00},size={249.00,25.00},bodyWidth=200
SetVariable setvar0,title="Time:",fSize=18,value=sss
EndMacro
// now execute on the command line:
ctrlBackground start, period=60
April 27, 2023 at 12:11 pm - Permalink
I thought that a lengthy calculation would normally run in the same thread as the background task, preventing it from running until the calculation is completed? So you'd have to start a new thread for this to work?
April 27, 2023 at 12:27 pm - Permalink
It was not clear to me if the OP was running the computation task in the main thread or otherwise. My response above was intended to illustrate a simple, uncomplicated way of displaying time in seconds.
If running everything in one thread, the computation task could call backgroundTime() periodically.
April 27, 2023 at 12:42 pm - Permalink
You can execute this on Igor's command line:
DisplayHelpTopic "Progress Windows"
The call to DoUpdate is key to having the updated progress value updated in the panel that displays it.
April 28, 2023 at 05:31 am - Permalink
Hi all,
Thanks for your comments and suggestions.
So basically below is a part of my whole code I am trying to use. My target is to run a lengthy simulation using start, stop and pause button on a control panel so that I have controls on the ongoing simulation at any time. Say I want to pause the simulation after 1.45 minutes (the real simulation may take 5 hours to get finished) and then resume it from exactly that point. Hence I am trying to keep a track of the elapsed time after the simulation had started. A few things I am noticing, even if I stop or pause the simulation, the code does not work according to the expectations, the for loop keeps running until it gets finished instead of getting paused or stopped. Also, the time is not updating on the display. I have another concern as well, when the time will keep updating (after getting everything ok), will it make the simulation slower? I am using two cntrlnamedbackground to avoid the potential problem, is this a right step for this work?
Your suggestions will be highly appreciated.
Thanks.
#pragma TextEncoding = "MacRoman"
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
static StrConstant kPanelName = "MyStartStopPanel"
static StrConstant kPanelTitle = "My Start Stop Panel"
Menu "Macros"
"Create the control panel", CreateMyPanel()
End
// Create the panel for me
Function CreateMyPanel()
Dowindow/K $kPanelName
NewPanel /N=$kPanelName /W=(145,86,603,217) /K=3 as kPanelTitle
String/g gsSimulationTime = ""
Variable/G running = 0
Variable/G paused = 0
Button myStartStopButton,pos={20,20},size={80,20},proc=myStartStopProc,title="Start"
Button myPauseResumeButton,pos={243,20},size={80,20},disable=1,proc=myPauseResumeProc,title="Pause"
SetVariable setvar0,pos={17,60},size={249.00,25.00},bodyWidth=120
SetVariable setvar0,title="Time:", fSize=16,value=gsSimulationTime
End
// ------------
Function myStartStopProc(ctrlName) : ButtonControl
String ctrlName
NVAR/Z running = root:running
if (running)
StopSimulation()
else
StartSimulation()
endif
End
Function myPauseResumeProc(ctrlName) : ButtonControl
String ctrlName
NVAR/Z paused = root:paused
if (paused)
ResumeSimulation()
else
PauseSimulation()
endif
End
//----------------
Function StartSimulation()
NVAR/Z running = root:running
running = 1
NVAR/Z paused = root:paused
paused = 0
SVAR/Z gsSimulationTime=root:gsSimulationTime
gsSimulationTime=Secs2Time(DateTime,3)
Button myStartStopButton, win=$kPanelName, title="Stop"
Button myPauseResumeButton, win=$kPanelName, title="Pause", disable=0 // Unhide button
myStartBackgroundTask()
myStartBackgroundTime()
End
Function StopSimulation()
NVAR/Z running = root:running
running = 0
NVAR/Z paused = root:paused
paused = 0
Button myStartStopButton, win=$kPanelName, title="Start"
Button myPauseResumeButton, win=$kPanelName, title="Pause", disable=1 // Hide button
myStopBackgroundTask()
End
Function PauseSimulation()
NVAR/Z paused = root:paused
paused = 1
Button myPauseResumeButton, win=$kPanelName, title="Resume"
myStopBackgroundTask()
End
Function ResumeSimulation()
NVAR/Z paused = root:paused
paused = 0
Button myPauseResumeButton, win=$kPanelName, title="Pause"
myStartBackgroundTask()
End
//------------------------------------
Function myStartBackgroundTask()
CtrlNamedBackground $kPanelName, proc=mySimulationTask, start
End
Function myStopBackgroundTask()
CtrlNamedBackground $kPanelName, stop
End
Function myStartBackgroundTime()
CtrlNamedBackground startTimeOfSimulation, period=60, start
End
Function mySimulationTask(s)
STRUCT WMBackgroundStruct &s
// Here will be my function that will do lengthy simulation
DoTheSimulation()
End
//------------------------------------
Function DoTheSimulation()
// Code that will do the lengthy simulation....Now I used just a for loop to check things
variable i
for (i=0; i<100000; i++)
print i
endfor
End
//---------------------------------------
April 28, 2023 at 10:56 am - Permalink
Your simulation is a tight loop that does not allow Igor to service the GUI events in the panel. You can update the display time by periodically calling doUpdate from inside the loop. For example, you can add in the loop:
doUpdate...
endif
This is still not going to service the Pause button in the way that you intend. If you intend to Pause and Resume you may want to use a global for the loop index. Pause could simply be implemented using Cmd+'.' on the Mac or Ctrl-break on windows and resume would simply start running the loop from the last index position.
April 28, 2023 at 02:09 pm - Permalink
In reply to Your simulation is a tight… by Igor
Let me explain a little bit more.
In my real simulation, there will be hundreds of lines of codes which will include different loops, conditions, functions etc in the Domysimulation() function (in the above code I showed just one for loop for an example). My target is to pause the simulation whenever I want and resume it when I will wish and keep track of the simulation time as it progresses.
I hope you get it now.
Thanks.
April 28, 2023 at 02:40 pm - Permalink
I'd start by adding to your CreateMyPanel() function:
Now change your simulation call to:
// Code that will do the lengthy simulation....Now I used just a for loop to check things
NVAR gIndex=root:gIndex
SVAR/Z gsSimulationTime=root:gsSimulationTime
do
gIndex+=1
print gIndex
if(mod(gIndex,100)==0)
gsSimulationTime=Secs2Time(DateTime,3)
doupdate/w=MyStartStopPanel
endif
while(gIndex<100000)
End
To pause the simulation use the CMD+'.' or CTRL-Break.
To continue the simulation from the paused point simply call DoTheSimulation().
April 28, 2023 at 02:45 pm - Permalink
Note that if your simulation contains multiple loops, you may not be able to exit the outer loop as in this example. I think that calls for using try/catch approach in all places where you may want to terminate the simulation.
April 28, 2023 at 02:49 pm - Permalink
Another solution to problems like this is to use PauseForUser/C. That way, you have a well-defined point in your code where you service the events for a control panel. That control panel can have things like a progress indicator and a Pause button. For demo of PauseForUser/C: DisplayHelpTopic "Progress Windows"
Our conception is that PauseForUser/C is for driving a progress bar or other progress indicator. But that same progress window can contain other controls as well. In fact, the demo code in that section includes a Stop button
May 1, 2023 at 10:14 am - Permalink
Thanks everybody for your suggestions!
I am using progress window now, anyways I was looking for something that will show the time of the simulation as it progresses on the panel just like a digital clock.
May 1, 2023 at 11:26 am - Permalink