/* * FFTUtil.java * * Created on December 1, 2004, 9:11 PM */ package org.das2.qds.util; import org.das2.datum.Datum; import org.das2.datum.Units; import org.das2.datum.UnitsConverter; import org.das2.datum.UnitsUtil; import org.das2.qds.AbstractDataSet; import org.das2.qds.DDataSet; import org.das2.qds.DataSetOps; import org.das2.qds.DataSetUtil; import org.das2.qds.IndexGenDataSet; import org.das2.qds.JoinDataSet; import org.das2.qds.MutablePropertyDataSet; import org.das2.qds.QDataSet; import org.das2.qds.SemanticOps; import org.das2.qds.ops.Ops; import org.das2.qds.math.fft.ComplexArray; import org.das2.qds.math.fft.GeneralFFT; /** * Utilities for FFT operations, such as getting the frequencies for each bin * and fftPower. * @author Jeremy */ public class FFTUtil { public static QDataSet fftPower( GeneralFFT fft, final QDataSet vds ) { return fftPower( fft, vds, getWindowUnity(vds.length()) ); } /** * returns a rank 2 dataset from the rank 1 dataset, where the * FFT would be run on each of the datasets. * @param ds rank 1 dataset of length N * @param size size of each FFT. * @return rank 2 dataset[N/size,size] */ public static QDataSet window( QDataSet ds, int size ) { JoinDataSet jds= new JoinDataSet(2); JoinDataSet dep1= new JoinDataSet(2); int idx=0; DDataSet ttags= DDataSet.createRank1( ds.length()/size ); QDataSet dep0= (QDataSet) ds.property(QDataSet.DEPEND_0); if ( dep0==null ) { dep0= Ops.dindgen(ds.length()); } ttags.putProperty( QDataSet.UNITS, SemanticOps.getUnits(dep0) ); DDataSet offsets=null; boolean qube= true; while ( idx+sizef[i]= i / n*T * where T= time[1] - time[0] and n= len(time). * for the first n/2 points and * f[i]= (n21-n+i) / ( n*T ) for the second half. * When units have a known inverse, this is returned. * @param timeDomainTags * @return the frequency domain tags. */ public static QDataSet getFrequencyDomainTags( QDataSet timeDomainTags ) { Units timeUnit= (Units) timeDomainTags.property( QDataSet.UNITS ); if ( timeUnit==null ) timeUnit= Units.dimensionless; QDataSet x= timeDomainTags; double[] result= new double[x.length()]; result[0]= 0.; int n= x.length(); double T,Tcheck; if ( n>120 ) { T= ( x.value(n-1)-x.value(0) ) / (n-1); Tcheck= ( x.value(60)-x.value(0) ) / 60 ; } else { T= ( x.value(n-1)-x.value(0) ) / (n-1); Tcheck= x.value(1)-x.value(0); } if ( Math.abs( ( T-Tcheck ) / ( T ) ) > 0.001 ) { if ( debugPrintCount>0 ) { debugPrintCount--; System.err.println("WARNING: timetags do not appear to be uniform: "+x ); System.err.println( String.format( "t[0]=%s t[1]=%s t[%d]=%s", Ops.subtract( timeDomainTags.slice(0), timeDomainTags.slice(0) ), Ops.subtract( timeDomainTags.slice(1), timeDomainTags.slice(0) ), timeDomainTags.length()-1, Ops.subtract( timeDomainTags.slice(timeDomainTags.length()-1), timeDomainTags.slice(0) ) ) ); } } int n21= n/2+1; Units frequencyUnit= UnitsUtil.getInverseUnit( timeUnit.getOffsetUnits() ); if ( T>0.5 ) { if ( frequencyUnit==Units.megaHertz ) { if ( T>1000 ) { frequencyUnit= Units.hertz; T= T/1000000; } else { frequencyUnit= Units.kiloHertz; T= T/1000; } } else if ( frequencyUnit==Units.gigaHertz ) { if ( T>1000000 ) { frequencyUnit= Units.hertz; T= T/1000000000; } else { frequencyUnit= Units.kiloHertz; T= T/1000000; } } } for ( int i=0; i