Missing abort button (Ctrl-C didn't work either) when running a for loop
Hi,
I implemented a looping function includes some Igor function and some XOPs. The purpose is to digitize a signal for a given amount of time, repeat it for N times and average them. I was glad to finally have everything working together, but then I realized that the abort button (bottom right of Igor Pro 8 main window) didn't show up. I also tried Ctrl-C and it didn't stop the routine either.
It will be important to be able to stop it as sometimes with an error we could have made a loop too long. What could be the cause?
The code is rather long and includes lots of subroutines that uses XOP and hardware, I would like to post the useful parts if any of them may indicate something, please kindly let me know.
Thanks in advance.
Attached is the main routine for ref (some trimming applied):
STRUCT WMButtonAction &ba
switch( ba.eventCode )
case 2: // mouse up
string cfolder,path
cfolder = GetDataFolder(1) //store the current data folder
variable AVG_POW = 1 //Set this variable to 1 if you want to average the Power directly in addition to average the quadratures.
path = "root:panels:"
SetDataFolder $path
SVAR ActivePanel
if (!(stringmatch(ActivePanel,"MagPhaseVsTime")))
ActivateMPVT()
endif
path = "root:panels:MagPhaseVsTime:"
SetDataFolder $path
SVAR SGname,DIGname
NVAR SampPerSeg,NumSeg,NumTrig,NumSamples,Division,Smoothing,AutoSave,RepFreq
//S: no longer used, DIGid is a software id now.
NVAR SGid,DIGid,SampFreq
path = "root:panels:MagPhaseVsTime:"
SetDataFolder $path
variable check_freq,error
//make sure the sampling frequency is correct
//S: Now we simply abort the routine if this fails, as we should not arbitarily modify the SampFreq
SampFreq = RepFreq*SampPerSeg
check_freq = DigitizerGet(DIGid,DIG_IF_FS)
if (abs(SampFreq-check_freq) > 1)
abort "Measurement sampling frequency does not equal instrument's sampling frequency."
endif
Button/z UpdateButtonMPVT,title="Running",win = MagPhaseVsTime
//S: about waves handling, note that the raw data should anyway first go to the GageRM instrument folder;
//only the final I/Q data should be transferred to the measurement folder. These final IQ data should be the input wave
//for the GPU DDC function to avoid the need of copying them around.
Make/N=(NumSamples)/O Idata,Qdata // Create wave of the right length (filled with zeros)
Make/N=(SampPerSeg)/O Im,Qm,Iavg=0,Qavg=0,mag,phase
SetScale/p x 0,(1/SampFreq),"s", mag,phase // Set the scale to seconds
// arm trigger and capture first set of data
if (AVG_POW)
Make/N=(NumSamples)/O PowData
Make/N=(SampPerSeg)/O Powm,PowAvg=0
SetScale/p x 0,(1/SampFreq),"s", PowData,Powm,PowAvg
endif
//S: Now level correct is a constant given by what one wants. If one wants the voltage to appear in I/Q, applies only the VoltLevelCorrect;
//If one wants to follow the old convention of PXI, applies both (sum them in log scale)
variable LevelCorrect = 10*log(GageRM_DDC_VoltLevelCorrect)+GageRM_DDC_PowerLevelCorrect
// LevelCorrect = DigitizerGet(DIGid,DIG_LEVEL_CORRECT)
LevelCorrect = 10^(LevelCorrect/10) //convert level correct from dBm correction to Watts correction
//Due to the passivity of PXDAC, now it should be reset before any arming routine of the digitizers
if(stringmatch(whichInstrument(SGid),"PXDAC"))
PXDAC_Reset(whichInstrument(SGid))
endif
error = DigitizerTrigger(DIGid,DIG_TRIG_ARM,NumSamples)
// if (error)
// print "Digitizer Trigger arm failed"
// print DigitizerError(DIGid)
// endif
variable Time1,Time2
variable m,n,CaptComp
for (m=1;m<=NumTrig;m+=1) //This loop covers the number of triggers
Button/z UpdateButtonMPVT,title=num2str(m),win = MagPhaseVsTime
//This loop checks that the dig capture is complete before looping back to where the mu freq is changed.
do
CaptComp = DigitizerGet(DIGid,DIG_CAPT_COMPLETE)
if (!CaptComp)
WaitTicks(5)
endif
while (!CaptComp)
//Time1 = stopMStimer(-2)
//S: Here the deal, we need to split the old DigitizerCapture function into two parts, as now 1. the data transfer from digitizer to host is done as the capture finishes
//2. The anaylysis routine should include the data processing part by the GPU in order to better overlap the capture time and processing time
//I am keeping the DigitizerCapture as the function name for use with GPU-host transfer/analysis, and a new function called DigitizerTransfer is made.
//S: This function will now assume the capture has finished, and it will attempt to transfer the data located in the digitizer back to the host memory.
DigitizerTransfer(DIGid)
if (m<NumTrig) // arm trigger and start capture of next data while we process the last
//Due to the passivity of PXDAC, now it should be reset before any arming routine of the digitizers
if(stringmatch(whichInstrument(SGid),"PXDAC"))
PXDAC_Reset(whichInstrument(SGid))
endif
endif
//DIG_GPU_DDC means using GPU to perform the DDC
error = DigitizerCapture(DIGid,DIG_GPU_DDC,Idata,Qdata)
DigitizerFold(Im,Idata)
DigitizerFold(Qm,Qdata)
// Average different triggers and compute mag and phase
FastOp Iavg = ((m-1)/m)*Iavg+(1/m)*Im
FastOp Qavg = ((m-1)/m)*Qavg+(1/m)*Qm
mag = sqrt(Iavg^2+Qavg^2)
phase = atan2(Qavg,Iavg)*180/pi
Duplicate/O mag,mag_smth
Duplicate/O phase,phase_smth
if (Smoothing > 0)
Smooth (Smoothing), mag_smth,phase_smth
endif
if (AVG_POW)
//FastOP PowData = Idata*Idata + Qdata*Qdata
FastOP PowData = (LevelCorrect)*Idata*Idata + (LevelCorrect)*Qdata*Qdata
DigitizerFold(Powm,PowData)
FastOp PowAvg = ((m-1)/m)*PowAvg+(1/m)*Powm
Duplicate/O PowAvg,Pow_smth
if (Smoothing > 0)
Smooth (Smoothing), Pow_smth
endif
endif
//print SqeezingFigure(Idata,Qdata)
DoUpdate
endfor
Button/z UpdateButtonMPVT,title="Update",win = MagPhaseVsTime
SetDataFolder $cfolder //restore the data folder
break
endswitch
return 0
End
Strangely, it comes back after I have restarted Igor. The button still appear/disappears, but if I click there it works to stop the loop. A bit intermittent at the moment.
January 28, 2019 at 03:34 pm - Permalink
Igor has a delay between when you start the function and when the Abort button is displayed. Under some circumstances, that delay is set pretty long. I think one such circumstance is a button action procedure- that is because at the same time that the Abort button is shown, the beachball cursor is also shown, and that's usually annoying with a control action.
In Igor 8, I made it possible to abort using the keyboard even before the Abort button is displayed. But the keys for aborting are not Ctrl+C. You have a choice of Shift+Esc or Ctrl+Break. Break is also sometimes called Pause. Those key combinations should abort your function more or less immediately.
January 28, 2019 at 04:47 pm - Permalink
In reply to Igor has a delay between… by johnweeks
Thanks, it works now to abort with Shift+Esc, even when the abort button is not shown.
January 29, 2019 at 10:44 am - Permalink