All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.slf.FFTRealOneSided Maven / Gradle / Ivy

The newest version!
/**
* Global Sensor Networks (GSN) Source Code
* Copyright (c) 2006-2016, Ecole Polytechnique Federale de Lausanne (EPFL)
* 
* This file is part of GSN.
* 
* GSN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* GSN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with GSN.  If not, see .
* 
* File: src/ch/slf/FFTRealOneSided.java
*
* @author Timotee Maret
*
*/

package ch.slf;

import java.io.Serializable;

import org.apache.commons.math.MathException;
import org.apache.commons.math.complex.Complex;
import org.apache.commons.math.transform.FastFourierTransformer;
import org.slf4j.LoggerFactory;

import ch.epfl.gsn.beans.DataField;
import ch.epfl.gsn.beans.DataTypes;
import ch.epfl.gsn.beans.StreamElement;

import org.slf4j.Logger;

/**
 * 

* This Virtual Sensor computes the FFT over an array of data. * The input array must contain a power of 2 elements. If any other number of elements is used, the array will be zero-padded to the next power of 2 elements. *

*

* The output format is a 1 sided real FFT normalised using 1/sqrt(N). * This algorithm uses the Cooley-Tukey FFT method. * The algorithm returns N/2 +1 points where the first point is the DC component. *

*

* This Virtual Sensor uses the free Apache Math Library for computation. * Have a look to Apache Math Library * for its documentation. *

*/ public class FFTRealOneSided extends WindowAwareVS { private static final String DF = "DF"; private static final String VALUES = "VALS"; private static final DataField [] outputStructure = new DataField[] { new DataField(DF, DataTypes.DOUBLE_NAME), new DataField(VALUES, "BINARY:text/plain") }; private static transient Logger logger = LoggerFactory.getLogger ( FFTRealOneSided.class ); private static FastFourierTransformer fft; private int fft_size; public boolean init() { try { fft_size = getPredicateValueAsIntWithException("window-size"); fft = new FastFourierTransformer () ; if (! FastFourierTransformer.isPowerOf2(fft_size)) { logger.error("The window size >" + fft_size + "< is not a power of 2."); return false; } }catch (Exception e) { logger.error(e.getMessage(),e); return false; } return true; } /** * @param values A two dimensional array that contains in first dimension (values[]) * the differents steps, and in the second dimension (value[step][]) the different * measures for this step. * @param timestamps An array that contains the timestamps in milli seconds at every * step. * @return */ public void process(double [] values , long[] timestampsInMSec) { if (logger.isDebugEnabled()) { logger.debug("INPUT FFT DATA"); for (int i = 0 ; i < values.length ; i++) { logger.debug(values[i] + "\n"); } } int windowSize = timestampsInMSec.length; logger.debug("Window Size: " + windowSize); long deltaTimeStampInSec = (timestampsInMSec[timestampsInMSec.length - 1] - timestampsInMSec[0]) / 1000; logger.debug("Delta Time Stamp in s: " + deltaTimeStampInSec); double sampling_rate = ((double)windowSize / (double)deltaTimeStampInSec); logger.debug("Sampling Rate: " + sampling_rate); double df = 1 / (double)deltaTimeStampInSec; logger.debug("df: " + df); int nbOfPointsToReturn = (windowSize / 2) + 1; logger.debug("Number of points to return: " + nbOfPointsToReturn); long middleTimeStamp = timestampsInMSec[0] + ((deltaTimeStampInSec / 2) * 1000); Complex[] fftResult = null; try { fftResult = fft.transform2(values); double[] realPartFftResult = new double [nbOfPointsToReturn] ; for (int i = 0 ; i < realPartFftResult.length ; i++) { realPartFftResult[i] = fftResult[i].getReal(); } // Serializable[] dataOut = new Serializable[2]; // df dataOut[0] = df; // data StringBuilder sb = new StringBuilder(); sb.append(realPartFftResult[0]); for (int i = 1 ; i < realPartFftResult.length ; i++) { sb.append("," + realPartFftResult[i]); } dataOut[1] = sb.toString().getBytes(); // StreamElement se = new StreamElement (outputStructure, dataOut, middleTimeStamp); logger.debug("FFT StreamElement produced: " + se); dataProduced( se ); } catch (IllegalArgumentException e) { logger.error("Unable to compute the FFT: " + e.getMessage()); } catch (Exception e) { logger.error("Unable to compute the FFT: " + e.getMessage()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy