| Author |
Topic  |
|
|
kaiousama
Japan
Posts |
Posted - 09/08/2004 : 6:24:56 PM
|
Hi, i'm facing problems in performing FFT on a limited range of rows: I want to perform FFT only over the range the user selected on a plot via the "data selector" tool. So i've created the following script, setting fft.start and fft.size according with mks1 / mks2 values.
Running the script for a limited range of rows selected on the plot, the "fype" procedure reports the correct values for mks1 / mks2 in the script window but the FFT calculation lasts exacltly in the same time amount and produce exactly the sameal results as performing FFT over the whole dataset (tried with the pClamp sample file contained in the \pClamp\96322002.abf directory of my Origin 6.0 installation).
Doing the same selection in the plot with the "data selector" and performing FFT via origin's menu does take only a little amount of the time needed for an FFT over the whole data, indicating that performing FFT via origin's menu does correctly perform FFT over the selected range only, while performing FFT with my script does result in a FFT over the whole dataset no matter what.
Can you help me to understand what's wrong with my script?
Thanks.
[fft]
//------------------------------------------------------------------------------ // FFT COMPUTATION //------------------------------------------------------------------------------
%Z=%H; // Store active worksheet name in %Z variable
fft.reset( ); // Reset previous fft settings fft.forward=1; // 1= forward 0=backward fft.forward.timeData$=%Z_Time; // Time values dataset fft.forward.tdelta=%Z_Time[2]-%Z_Time[1]; // Sampling interval fft.forward.realData$=%Z_Avg; // Values dataset
if ((mks1!=-1)&&(mks2!=-1)) { fft.start=mks1; fft.size=mks2-mks1; type Performing FFT between $(mks1) and $(mks2); } else { type Performing FFT over the whole data; }
window -t W fft %ZFFT; // Output worksheet
fft.output.samplingdata$=%ZFFT_Freq; fft.output.realdata$=%ZFFT_Real; fft.output.imagdata$=%ZFFT_Imag; fft.output.ampdata$=%ZFFT_r; fft.output.phasedata$=%ZFFT_Phi; fft.output.powerdata$=%ZFFT_Power;
fft.spectrum=1; // 1=amplitude spectrum 2= Power spectrum fft.real=1; // 1=Real FFT 0=complex FFT fft.normalize=1; // 1= normalize magnitudes 0= leave unchanged fft.shifted=0; // 1= shift results 0=leave unshifted fft.windowing=1; // 1= rectangular fft.unwrap=0; // 1=unwrap 0=do not unwrap fft.convention=1; // 0=Engineering 1=science (this is the right property)
fft.forward( ); // Execute Forward FFT //------------------------------------------------------------------------------
Origin Version : 6.0 Operating System: windows XP |
|
|
Mike Buess
USA
3037 Posts |
Posted - 09/08/2004 : 7:49:39 PM
|
It's possible that fft.nextPowerOf2 remains set by the total dataset size so you might try something like this...
if ((mks1!=-1)&&(mks2!=-1)) { fft.start=mks1; fft.size=mks2-mks1; type Performing FFT between $(mks1) and $(mks2); zpt=1; for(i=1;i>0;i++) {zpt*=2; if(zpt>fft.size) break}; fft.nextPowerOf2=zpt; }
Mike Buess Origin WebRing Member |
 |
|
|
kaiousama
Japan
Posts |
Posted - 09/09/2004 : 04:14:23 AM
|
quote:
It's possible that fft.nextPowerOf2 remains set by the total dataset size so you might try something like this...
You are right, the fft.NextPowerOf2 remained setted to zero.
Unfortunately even this fix doen't solve the problem, probaly there is something else wrong.... i think now all the fft object's properties are set, is maybe the order I declared the properties not correct?
Regards. |
 |
|
|
Mike Buess
USA
3037 Posts |
Posted - 09/09/2004 : 07:46:14 AM
|
Now I remember also having problems using the fft object on a range of data. My solution was to copy that range to another worksheet, fft from there and copy results back (if needed).
Mike Buess Origin WebRing Member |
 |
|
|
kaiousama
Japan
Posts |
Posted - 09/09/2004 : 09:17:31 AM
|
Thanks Mike, these are those kind of problems i can spend days without finding a solution ^_^
In order to copy the selected range into temporary datasets i encountered another one problem, this is the situation:
The active window is the graph window where the user selected FFT range with Data selector tool, I need to access X and Y datasets plotted in the graph. Is there a way to retrieve X and Y axis datasets from plotted layer? Alternatively, is there a way to retrieve the name of the worksheet used to create a certain layer (%H variable cannot be used since it stores the graph window)?
pratically i'd like to add these lines:
create Hidden -wd (mks2-mks1) Time Value; copy -b mks1 X Hidden_Time -b 1 -e (mks2-mks1); copy -b mks1 Y Hidden_Value -b 1 -e (mks2-mks1);
but i don't know how to retrieve X and Y datasets from the graph or from the original dataset.
Sincerely.
Edited by - kaiousama on 09/09/2004 09:22:04 AM |
 |
|
|
Mike Buess
USA
3037 Posts |
Posted - 09/09/2004 : 10:12:14 AM
|
%C is the name of the active dataset. %(%W, @Xn) is the name of the X column in wks %W...
%W=%[%C,'_']; // name of wks containing %C %A=%(%W, @Xn); // name of X dataset copy -b mks1 %A Hidden_Time -b 1 -e (mks2-mks1); copy -b mks1 %C Hidden_Value -b 1 -e (mks2-mks1);
Mike Buess Origin WebRing Member |
 |
|
|
kaiousama
Japan
Posts |
Posted - 09/09/2004 : 12:18:57 PM
|
I was able to retrieve the correct X & Y datasets but still something didn't work. try to plot a line graph and select some range with data selector, then call this script:
//----------------------------------------------------------- [copyrange]
%Z=%[%C,'_']; // name of wks containing %C %A=%Z_%(%Z, @Xn); // name of X dataset %B=%C;
ty %A; ty %B; ty $(mks1); ty $(mks2);
create tmp -w (mks2-mks1) Time Value; // create a temporary worksheet copy -b mks1 %A tmp_Time -b 1 -e (mks2-mks1); // copy X dataset copy -b mks1 %B tmp_Value -b 1 -e (mks2-mks1); // copy Y dataset
//----------------------------------------------------------
It reports the correct values of mks1, mk2, %A, %B, but it isn't able to copy the range from %A to tmp_Time and from %B to tmp_Value. It apparently seems that copy() function doesn't like variables mks1 and mks2 because if you directly put numbers instead of mks1/2 the dataset are copied:
copy -b 1 %A tmp_Time -b 1 -e 10; // copy X dataset copy -b 1 %B tmp_Value -b 1 -e 10; // copy Y dataset
Any idea of what's wrong? are there other ways to copy a part of a dataset into another one?
Edited by - kaiousama on 09/09/2004 12:21:10 PM |
 |
|
|
Mike Buess
USA
3037 Posts |
Posted - 09/09/2004 : 12:48:02 PM
|
I've used variable indices many times with the copy command. Sometimes it doesn't like expressions so you might try this...
npt=mks2-mks1; create tmp -w npt Time Value; // create a temporary worksheet copy -b mks1 %A tmp_Time -b 1 -e npt; // copy X dataset copy -b mks1 %B tmp_Value -b 1 -e npt; // copy Y dataset
Mike Buess Origin WebRing Member |
 |
|
|
kaiousama
Japan
Posts |
Posted - 09/09/2004 : 4:36:28 PM
|
Interesting developements are on the way:
I've tested your last suggestion and did copy ntp amount of rows, but unfortunately first row was blank and rows are copyed from the very first one ant not from mks1, so i supposed that something's wrong with mks1, and effectively the following script completely fix the problem:
npt=mks2-mks1; start=mks1 create tmp -w npt Time Value; // create a temporary worksheet copy -b start %A tmp_Time -b 1 -e npt; // copy X dataset copy -b start %B tmp_Value -b 1 -e npt; // copy Y dataset
Something's probably wrong in mks definition or in the copy() routine implementation that makes them uncompatible.
Solved even this matter i thought i'd reached the happy end, but i noticed another interesting thing:
I've now created the FFT script fully functional (you find the script at the end of the reply) that performs an FFT over the selection range of a plotted graph (or over the whole graph if no selection is avaible). This function exactly reproduces the origin's fft menu command except that you don't have to select fft preferences. So I tested my scripts result against origin's menu command expecting to obtain the sameal result.... but i was wrong:
Performing FFT over the whole graph (no selection) provides the same results as origin fft menu command.
Performing fft over a selected range in the graph provides different FFT results.
So i checked better leaving the temporary worksheet visible after FFT changing this line in my script (create tmp -wd delta Time Value;) and disabling tmp worksheet closing statement.
Analysing tmp worksheet, the selection range is correctly copied, and as final test i performed origin fft menu command over tmp worksheet data and the results are exactly equal to my Script results.
Maybe there is a bug in origin's fft menu command when performed on a selection range, please can you check/test the script in order to confirm/trash my hypotesis?
Sincerely.
[fft]
//------------------------------------------------------------------------------ // FFT COMPUTATION //------------------------------------------------------------------------------
%Z=%[%C,'_']; // name of wks containing Active dataset %C %A=%Z_%(%Z, @Xn); // name of X dataset (wks_dataset) %B=%C; // name of Y dataset (wks_daset)
ty [-----] F F T [-----]; // debug info ty [Times dataset = %A]; // debug info ty [Values dataset= %B]; // debug info
if ((mks1!=-1)&&(mks2!=-1)) { start=mks1; // start from selection delta=mks2-mks1; // selection range dimension type Performing FFT between $(mks1) and $(mks2);// debug info } else { start=1; // start from first row delta=%Z!wks.nrows; // process all rows type Performing FFT over the whole data; // debug info }
fft.reset( ); // Reset previous fft settings fft.start=1; // These poperties doesn't work for fft object but i set them anyway fft.size=delta; // These poperties doesn't work for fft object but i set them anyway
zpt=1; // next power of 2 after selected range rows amount for(i=1;i>0;i++){zpt*=2; if(zpt>delta) break}; fft.nextPowerOf2=zpt; // set the proper power of 2 accoring to fft.size type next power of 2 is $(zpt); // debug info
create tmp -wd delta Time Value; // create a temporary worksheet --> Replace -wd with -w for debug <-- copy -b start %A tmp_Time -b 1 -e delta; // copy X dataset copy -b start %B tmp_Value -b 1 -e delta; // copy Y dataset
fft.forward=1; // 1= forward 0=backward fft.forward.timeData$=tmp_Time; // Time values dataset fft.forward.tdelta=tmp_Time[2]-tmp_Time[1]; // Sampling interval fft.forward.realData$=tmp_Value; // Values dataset fft.forward.imagData$=""; // Set imaginary to Null
window -t W fft %ZFFT; // Output worksheet
fft.output.samplingdata$=%ZFFT_Freq; fft.output.realdata$=%ZFFT_Real; fft.output.imagdata$=%ZFFT_Imag; fft.output.ampdata$=%ZFFT_r; fft.output.phasedata$=%ZFFT_Phi; fft.output.powerdata$=%ZFFT_Power;
fft.real=1; // 1=Real FFT 0=complex FFT fft.spectrum=1; // 1=amplitude spectrum 2= Power spectrum fft.normalize=1; // 1=normalize magnitudes 0=leave unchanged fft.shifted=0; // 1=shift results 0=leave unshifted fft.windowing=1; // 1=rectangular fft.unwrap=0; // 1=unwrap 0=do not unwrap fft.convention=1; // 0=Engineering 1=science (this is the right property)
fft.forward( ); // Execute Forward FFT window -c tmp; // Close tmp worksheet --> disable this line to debug <--
|
 |
|
|
Mike Buess
USA
3037 Posts |
Posted - 09/09/2004 : 5:21:57 PM
|
A couple of comments...
First, my original suggestion about fft.nextPowerOf2 might have been a red herring. It's not clear from the fft documentation whether that value should be an exponent or a total number of points (n or 2^n). You might check it's value in the script window after running the FFT menu command. (I usually zero-fill prior to FFT and haven't paid much attention to this property.)
Second, and probably of no importance, is the fact the range mks1 to mks2 contains one more point than you are using. In other words, the number of points in the selection range is npt=mks2-mks1+1. If the difference between Origin's and your script's results are minor you might look at that.
Mike Buess Origin WebRing Member |
 |
|
|
kaiousama
Japan
Posts |
Posted - 09/14/2004 : 10:25:04 AM
|
Soved! the problem was nor my script nor origins' fft menu command. It was the sample data i used wrong, the dataset contained some empty values that results in fft errors. I've re-checked my function's results against Origin's fft command's ones on good datasets and all's gone right the obtained results are identical.
quote: It's not clear from the fft documentation whether that value should be an exponent or a total number of points (n or 2^n). You might check it's value in the script window after running the FFT menu command. (I usually zero-fill prior to FFT and haven't paid much attention to this property.)
Checked, fft.nextpowerof2 value is the total number of point, so the code you suggested before is right, from this point of view.
Maybe fft.nextpowerof2 wants the power of 2 closest to sample amount , not always the next. I've noticed it because sometimes, after fft, samples number in frequency domain do not correspond to the specified nextpowerof2 but to the previous one.
Edited by - kaiousama on 09/14/2004 10:34:01 AM |
 |
|
| |
Topic  |
|