Showing time or clock on the panel

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:

String/g sss   // execute on the command line

// 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

 

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?

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.

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.

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 IgorVersion = 7.08
#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
//---------------------------------------

 

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:

if(mod(i,200)==0)
    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.

In reply to 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.

I'd start by adding to your CreateMyPanel() function:

    Variable/G gIndex=0

Now change your simulation call to:

Function DoTheSimulation()
   
    // 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().

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.

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

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.