Looping over this loop

Dear Forum,

Maybe you guys can help me to troubleshoot this. I have written a For loop to creates a window that runs over a waveform to generate an FFT, and from that FFT obtain information over the first peak which in my data usually appears between 0.2 and 1 Hz. I want to track frequency changes overtime by monitoring the peak position and eventually dispersion as well by checking the width of the FFT peak. I also use an IF statement to run all values down to 0 in case no peak above a given threshold is not observed.

To avoid detecting other adjoining peaks that may be more intense, I have implemented the search method in the FFTs as a two step process: first using
FindLevels
followed by
FindPeak
.

My problem is the following: every time I run this code my first value is always 0, all the remaining values seem to be OK, but the very first one is always zero.

If you can detect something wrong in the code below, your input would be greatly appreciated.

Many thanks in advance,

R.

//walk over a time-series using a window of defined size to:
//	(1) make an FFT
//	(2) collect peak data from the FFT over the specified frequency range
//Window advances by sliding a fraction of the window size

	
	
	For (i=0; i<Numbsteps; i+=1) 
		
		wleft = StepSize_P*i //Left side pf the window starts ate 0 and is a function of the window step size
		Wright = WinSize_P+wleft-1 //Right side of the window is a function of the left side and of the windows size
		WinTime=pnt2x(TempWave, wright-WinSize_P/2) //window time is a middle value
		Temp_Time1[i]=WinTime

		Print "window borders: ", wleft, wright, "and the average is", WinTime
				
		//Do the FFTs and correct for the sampling number
		FFT /OUT=3 /WINF=Hanning /RP=[wleft,wright] /DEST=TempFFT TempWave;
		TempFFT/=WinSize_P
		
		
		//Use FindLevels to detect the occurance shoulder of a peak
		wave W_FindLevels
		FindLevels /R=(StartSearch, EndSearch) /N=1 /EDGE=1 TempFFT, PeakThreshold
		
		//if no levels are crossed
		if (V_Flag!=0)
		Temp_Amp[i] = 0
		Temp_Pos[i] = 0
		Temp_Width[i] = 0
		
		Else
				//should levels be crossed then do FindPeak
				Variable StartHz = W_FindLevels[0]-0.2
				Variable EndHz = W_FindLevels[0]+0.2
				Variable V_PeakLoc
				Variable V_PeakWidth
				Variable V_PeakVal
				FindPeak /R=(StartHz, EndHz) /M=(PeakThreshold) TempFFT
				Temp_Pos[i] = V_PeakLoc
				Temp_Width [i] = V_PeakWidth
				Temp_Amp[i] = V_PeakVal


		EndIf
		//Give FFT a name and store in own folder
		FinalFFTName="FFT_"+MaskName+"_"+num2str(i)
		print FinalFFTName
		Duplicate TempFFT $FinalFFTName
		Movewave $FinalFFTName, root:Dynamic_FFT:$(MaskName):FFTs:				
		
		
	EndFor	
StartSearch, EndSearch are defined?

I'd recommend to use the built-in debugger (right click on the code: Enable Debugger and set a break point (left click on the grey are left of the code, a red circle shows up, click again to undo) within

if (V_Flag!=0)
	Temp_Amp[i] = 0
	Temp_Pos[i] = 0
	Temp_Width[i] = 0
 Else...

If it stops here and i is zero, just no peaks are found for the first frame.

Alternatively, use 42 instead of 0 in this part of code and see if 'the answer' (42) shows up in the results.

HJ
Thank you for the input. This was great help - I never used the debugger until now.
It appears that W_FindLevels only appears to populate on the second turn of the cycle, when i =1 and above, for i = 0 the value of W_FindLevels is . This means that when i=0, StartHz and EndHz variables return NaN.

Any ideas of what could be going wrong here?

Many thanks.

R.
There seems to be a typo:

//if no levels are crossed
	if (V_Flag!=0)   //<----- Shouln't this be == 2

From the description of v_flag in Findlevels

V_flag 0: maxLevels level crossings were found.
1: At least one but less than maxLevels level crossings found.
2: No level crossings were found.

HJ
Are you trying to implement some form of STFT (short time Fourier transform)? If so, check out the Sonogram Demo under File Menu->Example Experiments->Movies and Audio.

A.G.
Many thanks! Indeed, you were correct regarding the value of V_Flag. This was corrected.
However, that did not resolve the problem. In fact, removing the IF statement all together, had no change in the process.
What appears to matter is where in the code W_FindLevels is declared.

Originally W_FindLevels was declared right before the FindLevels operation.
Declaring it outside the For loop, results in an empty wave throughout the several For loop cycles, not just when i=0
The problem was resolved by declaring the wave W_FindLevels after the Find_Levels operation.
This is interesting because I did not
MAKE
a wave that cannot be overwritten, I simply declared it.

And so, is it then the general rule that every time one needs to call a wave generated by an igor function - say, as part of an expression - one should declare it after its creation, not before?

Many thanks,
R.
rhjpires wrote: ...And so, is it then the general rule that every time one needs to call a wave generated by an igor function - say, as part of an expression - one should declare it after its creation, not before?

Many thanks,
R.


It is best to think of a WAVE w=something statement as a runtime assignment, not only a compile-time declaration.

So where the statement occurs matters, just like other assignments.

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
rhjpires wrote:
And so, is it then the general rule that every time one needs to call a wave generated by an igor function - say, as part of an expression - one should declare it after its creation, not before?

Yes- DisplayHelpTopic "Accessing Global Variables And Waves"
At runtime, a WAVE statement triggers the actual look-up of the wave, so it must happen only after the wave actually exists.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Many thanks to everyone. Until now, I thought of declarations more as a form of generating awareness, rather than actual value look up.

Cheers,

R.