/* TimeDomainSampleFilter.java created 2010-09-29
*
*/
package org.signalml.domain.montage.filter;
import java.util.Arrays;
import org.signalml.math.iirdesigner.ApproximationFunctionType;
import org.signalml.math.iirdesigner.FilterType;
import org.signalml.util.ResolvableString;
import org.springframework.context.MessageSourceResolvable;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import java.text.DecimalFormat;
import org.signalml.app.config.preset.Preset;
/**
* This class holds a time domain representation of a
* {@link SampleFilterDefinition sample filter}.
*
* @author Piotr Szachewicz
*/
@XStreamAlias("timeDomainSampleFilter")
public class TimeDomainSampleFilter extends SampleFilterDefinition implements Preset {
private static final long serialVersionUID = 1L;
/**
* codes describing the effect the filter has on the signal
*/
private static final String[] EFFECT_CODES = new String[] {"timeDomainFilter.effect"};
/**
* the name of the filter for the use of the {@link Preset} interface
*/
private String name;
/**
* the type of the filter (LOWPASS/HIGHPASS/BANDPASS/BANDSTOP)
*/
private FilterType filterType;
/**
* the type of approximation function which will be used to fulfill
* the requirements specified by the edge freuencies, passband ripple,
* stopband attenuation etc.
*/
private ApproximationFunctionType approximationFunctionType;
/**
* The edge frequencies at which the passband begins and/or ends.
* If the filter is a low-pass or a high-pass filter, then only one
* passband edge frequency is needed. In that case, the value of the
* passbandEdgeFrequencies[1] is ignored.
*/
private double[] passbandEdgeFrequencies = new double[2];
/**
* The edge frequencies at which the stopband begins and/or ends.
* If the filter is a low-pass or a high-pass filter, then only one
* stopband edge frequency is needed. In that case, the value of the
* stopbandEdgeFrequencies[1] is ignored.
*/
private double[] stopbandEdgeFrequencies = new double[2];
/**
* The maximum value (in decibels) of variations in the frequency
* magnitude response within the passband of a filter.
*/
private double passbandRipple;
/**
* The minimum value (in decibels) of attenuation for the stopband
* within the filter's frequency response.
*/
private double stopbandAttenuation;
/**
* The sampling frequency for which the filter's coefficients
* will be calculated.
*/
private transient double samplingFrequency;
/**
* Constructor. Creates an empty instance of a TimeDomainSampleFilter.
* For internal use only.
*/
protected TimeDomainSampleFilter() {
}
/**
* Creates a new filter which is a copy of the filter given as an
* argument.
* @param filter filter to be copied
*/
public TimeDomainSampleFilter(TimeDomainSampleFilter filter) {
this.copyFrom(filter);
}
/**
* Creates a new filter characterized by the given parameters.
* @param filterType the type of the filter (low-pass/high-pass etc.)
* @param approximationFunctionType the type of approximation function
* which will be used to calculate the filter coefficients (Butterworth,
* ChebyshevI, etc.)
* @param passbandEdgeFrequencies an array containing two (or one - if
* the filter is low-pass or high-pass) edge frequencies at which the
* passband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only one passbandband edge frequency
* is needed. In that case, the value of the passbandEdgeFrequencies[1]
* is never read.
* @param stopbandEdgeFrequencies an array containing two (or one - if
* the filter is low-pass or high-pass) edge frequencies at which the
* stopband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only one stopbandband edge frequency
* is needed. In that case, the value of the stopbandEdgeFrequencies[1]
* is never read.
* @param passbandRipple the maximum value (in decibels) of variations
* in the frequency magnitude response within the passband of a filter.
* @param stopbandAttenuation the minimum value (in decibels) of
* attenuation for the stopband within the filter's frequency response.
*/
public TimeDomainSampleFilter(FilterType filterType, ApproximationFunctionType approximationFunctionType, double[] passbandEdgeFrequencies, double[] stopbandEdgeFrequencies, double passbandRipple, double stopbandAttenuation) {
this.filterType = filterType;
this.approximationFunctionType = approximationFunctionType;
this.passbandEdgeFrequencies = passbandEdgeFrequencies.clone();
this.stopbandEdgeFrequencies = stopbandEdgeFrequencies.clone();
this.passbandRipple = passbandRipple;
this.stopbandAttenuation = stopbandAttenuation;
}
/**
* Returns the type of the filter (low-pass/high-pass/band-pass/band-stop).
* @return the type of the filter
*/
public FilterType getFilterType() {
return filterType;
}
/**
* Sets type of the filter (low-pass/high-pass/band-pass/band-stop).
* @param filterType the new type of the filter.
*/
public void setFilterType(FilterType filterType) {
this.filterType = filterType;
}
/**
* Returns the type of approximation function which will be used to
* calculate filter coeffients which should fulfill the requirements
* specified by this filter's parameters (passband/stopband edge frequencies,
* passband ripple etc.).
* @return the type of approximation function which will be used
* (Butterworth, Chebyshev, Elliptic)
*/
public ApproximationFunctionType getApproximationFunctionType() {
return approximationFunctionType;
}
/**
* Sets the type of approximation function which will be used to
* calculate filter coeffients which should fulfill the requirements
* specified by this filter's parameters (passband/stopband edge frequencies,
* passband ripple etc.).
* @param approximationFunctionType the type of approximation function
* which will be used (Butterworth, Chebyshev, Elliptic)
*/
public void setApproximationFunctionType(ApproximationFunctionType approximationFunctionType) {
this.approximationFunctionType = approximationFunctionType;
}
/**
* Returns an array containing two edge frequencies at which the
* passband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only the first passbandband edge frequency
* is valid.
* @return an array containing passband edge frequencies (in Hz)
*/
public double[] getPassbandEdgeFrequencies() {
return passbandEdgeFrequencies;
}
/**
* Sets the values of edge frequencies at which the
* passband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only the first passbandband edge frequency
* is valid.
* @param passbandEdgeFrequencies an array containing passband edge
* frequencies (in Hz)
*/
public void setPassbandEdgeFrequencies(double[] passbandEdgeFrequencies) {
this.passbandEdgeFrequencies = passbandEdgeFrequencies.clone();
}
/**
* Returns an array containing two edge frequencies at which the
* stopband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only one stopbandband edge frequency
* is valid.
* @return an array containing stopband edge frequencies
*/
public double[] getStopbandEdgeFrequencies() {
return stopbandEdgeFrequencies;
}
/**
* Sets the values of edge frequencies at which the
* stopband should begin and/or end. If the filter is a low-pass or a
* high-pass filter, then only one stopbandband edge frequency
* is valid.
* @param stopbandEdgeFrequencies an array containing new values
* of stopband edge frequencies
*/
public void setStopbandEdgeFrequencies(double[] stopbandEdgeFrequencies) {
this.stopbandEdgeFrequencies = stopbandEdgeFrequencies.clone();
}
/**
* Returns the maximum value (in decibels) of variations
* in the frequency magnitude response within the passband of a filter.
* @return the maximum ripple in the passband for this filter
*/
public double getPassbandRipple() {
return passbandRipple;
}
/**
* Sets the maximum value (in decibels) of variations which can occur
* in the frequency magnitude response within the passband of a filter.
* @param passbandRipple the maximum ripple which can occur in the
* passband for this filter
*/
public void setPassbandRipple(double passbandRipple) {
this.passbandRipple = passbandRipple;
}
/**
* Returns the minimum value (in decibels) of attenuation
* for the stopband within the filter's frequency response
* @return the minimum stopband attenuation for this filter
*/
public double getStopbandAttenuation() {
return stopbandAttenuation;
}
/**
* Sets the minimum value (in decibels) of attenuation
* for the stopband within the filter's frequency response
* @param stopbandAttenuation the minimum stopband attenuation
* this filter must ensure.
*/
public void setStopbandAttenuation(double stopbandAttenuation) {
this.stopbandAttenuation = stopbandAttenuation;
}
/**
* Returns the sampling frequency for which the coefficients of this filter
* will be calculated.
* @return the sampling frequency for which this filter will operate
*/
public double getSamplingFrequency() {
return samplingFrequency;
}
/**
* Sets the sampling frequency for which the coefficients of this filter
* will be calculated.
* @param samplingFrequency the sampling frequency for which this filter
* will operate
*/
public void setSamplingFrequency(double samplingFrequency) {
this.samplingFrequency = samplingFrequency;
}
/**
* Returns a string specifying the filter's passband frequencies.
* @return a string describing the filter's passband frequencies
*/
public String getEffect() {
String passbandEdgeFrequency0 = convertDoubleToString(passbandEdgeFrequencies[0]);
String passbandEdgeFrequency1 = convertDoubleToString(passbandEdgeFrequencies[1]);
String stopbandEdgeFrequency0 = convertDoubleToString(stopbandEdgeFrequencies[0]);
String stopbandEdgeFrequency1 = convertDoubleToString(stopbandEdgeFrequencies[1]);
String effectString = "";
effectString += filterType + " (";
if (filterType.isLowpass())
effectString += "0 - " + passbandEdgeFrequency0;
else if (filterType.isHighpass())
effectString += passbandEdgeFrequency0 + " - inf";
else if (filterType.isBandpass())
effectString += passbandEdgeFrequency0 + " - " + passbandEdgeFrequency1;
else if (filterType.isBandstop())
effectString += stopbandEdgeFrequency0 + " - " + stopbandEdgeFrequency1;
effectString += " Hz";
effectString += ")";
return effectString;
}
/**
* Converts a given double value to a string.
* @param value a double value to be converted
* @return the result of the conversion
*/
protected String convertDoubleToString(double value) {
DecimalFormat decimalFormat = new DecimalFormat("######.##");
return decimalFormat.format(value);
}
@Override
public SampleFilterType getType() {
return SampleFilterType.TIME_DOMAIN;
}
/**
* Duplicates (@link TimeDomainSampleFilter the definition of the filter).
* @return the copy of the filter
*/
@Override
public TimeDomainSampleFilter duplicate() {
TimeDomainSampleFilter duplicate = new TimeDomainSampleFilter();
duplicate.copyFrom(this);
return duplicate;
}
/**
* Sets all parameters of this filter to mathch the values of the
* parameters of the given filter.
* @param filter a filter which parameters are to be copied
* to this filter
*/
public void copyFrom(TimeDomainSampleFilter filter) {
filterType = filter.filterType;
approximationFunctionType = filter.approximationFunctionType;
passbandEdgeFrequencies = filter.passbandEdgeFrequencies.clone();
stopbandEdgeFrequencies = filter.stopbandEdgeFrequencies.clone();
passbandRipple = filter.passbandRipple;
stopbandAttenuation = filter.stopbandAttenuation;
samplingFrequency = filter.samplingFrequency;
description = filter.description;
}
/**
* Checks if the filter is equal to another filter o.
* (to be equal o must be an instance of (@link TimeDomainSampleFilter TimeDomainSampleFilter)
* and feedback and feedforward coefficients of each filters must be equal.
* (Strings describing the filters are not taken into account while comparing).
* @param o an Object to be compared with the filter
* @return true if the the filter is equal to the Object o, otherwise - false
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof TimeDomainSampleFilter))
return false;
TimeDomainSampleFilter tdf = (TimeDomainSampleFilter)o;
if (tdf.filterType.equals(filterType) && tdf.approximationFunctionType.equals(approximationFunctionType) &&
Arrays.equals(passbandEdgeFrequencies, tdf.passbandEdgeFrequencies) &&
Arrays.equals(stopbandEdgeFrequencies, tdf.stopbandEdgeFrequencies) &&
passbandRipple == tdf.passbandRipple && stopbandAttenuation == tdf.stopbandAttenuation)
return true;
return false;
}
@Override
public String toString() {
return getEffect();
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}