
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):
Function UpdateButtonMPVTProc(ba) : ButtonControl 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