/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* All rights reserved. This program and the accompanying materials are made available under
* the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html.
*/
package gov.redhawk.ui.port.nxmblocks;
import gov.redhawk.internal.ui.preferences.FftBlockPreferencePage;
import gov.redhawk.ui.port.nxmblocks.FftNxmBlockSettings.OutputType;
import gov.redhawk.ui.port.nxmblocks.FftNxmBlockSettings.WindowType;
import gov.redhawk.ui.port.nxmplot.AbstractNxmPlotWidget;
import gov.redhawk.ui.port.nxmplot.preferences.FftPreferences;
import gov.redhawk.ui.port.nxmplot.preferences.Preference;
import java.text.MessageFormat;
import nxm.sys.prim.fft;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.PropertyChangeEvent;
/**
* @noreference This class is provisional/beta and is subject to API changes
* @since 4.4
*/
public class FftNxmBlock extends AbstractNxmBlock<fft> {
public FftNxmBlock(@NonNull AbstractNxmPlotWidget plotWidget, @NonNull FftNxmBlockSettings settings) {
super(fft.class, plotWidget, FftNxmBlock.initStore());
if (settings != null) {
applySettings(settings);
}
}
private static IPreferenceStore initStore() {
return Preference.initStoreFromWorkbench(FftPreferences.getAllPreferences());
}
@Override
public int getMaxInputs() {
return 2;
}
@Override
public int getMaxOutputs() {
return 3; // SUPPRESS CHECKSTYLE MAGIC NUMBER
}
@Override
@NonNull
protected String formCmdLine(@NonNull AbstractNxmPlotWidget plotWidget, String streamID) {
final int numInputs = getNumberInputs();
if (numInputs < 1) {
throw new IllegalArgumentException("Input(s) has not been specified");
}
BlockIndexPair inBlockIndexPair1 = getInputBlockInfo(0);
if (inBlockIndexPair1 == null) {
throw new IllegalArgumentException("Input 1 has not been specified");
}
String inputName1 = inBlockIndexPair1.getBlock().getOutputName(inBlockIndexPair1.getIndex(), streamID);
String outputName1 = AbstractNxmPlotWidget.createUniqueName(true);
putOutputNameMapping(0, streamID, outputName1); // save output 1 name mapping
String inputName2;
String outputName2;
String outputNameCross;
BlockIndexPair inBlockInfo2 = getInputBlockInfo(1);
if (inBlockInfo2 != null) {
inputName2 = inBlockInfo2.getBlock().getOutputName(inBlockInfo2.getIndex(), streamID);
outputName2 = AbstractNxmPlotWidget.createUniqueName(true);
putOutputNameMapping(1, streamID, outputName2); // save output 2 name mapping
if (hasOutputBlockAt(2)) {
outputNameCross = AbstractNxmPlotWidget.createUniqueName(true);
putOutputNameMapping(2, streamID, outputNameCross); // save cross output 3 name mapping
} else {
outputNameCross = ""; // no cross output 3 specified
}
} else {
inputName2 = ""; // no input 2
outputName2 = ""; // hence no output 2
outputNameCross = ""; // and no cross output 3
}
String fftSwitches;
final OutputType fftOutputType = getOutputType();
if (fftOutputType != null) {
fftSwitches = fftOutputType.toSwitchString();
} else {
fftSwitches = "";
}
double overlap = getOverlap() / 100.0; // fraction of <transform size> to overlap blocks // SUPPRESS CHECKSTYLE MAGIC NUMBER
String pattern = "FFT{0}/NEXP={1,number,#} IN1={2} OUT1={3} NFFT={4,number,#} WIN={5} OVER={6,number,#.###} NAVG={7,number,#} IN2={8} OUT2={9} CROSS={10}";
String cmdLine = MessageFormat.format(pattern, fftSwitches, getNumExpAverages(), inputName1, outputName1, getTransformSize(),
getWindowType().toWindowString(), overlap, getNumAverages(), inputName2, outputName2, outputNameCross);
return cmdLine;
}
public int getNumAverages() {
return FftPreferences.NUM_AVERAGES.getValue(getPreferences());
}
public WindowType getWindowType() {
try {
return WindowType.valueOf(FftPreferences.WINDOW_TYPE.getValue(getPreferences()));
} catch (IllegalArgumentException e) {
return WindowType.HAMMING;
}
}
public int getTransformSize() {
return FftPreferences.TRANSFORM_SIZE.getValue(getPreferences());
}
public int getNumExpAverages() {
return FftPreferences.SLIDING_NUM_AVERAGES.getValue(getPreferences());
}
public int getOverlap() {
return FftPreferences.OVERLAP.getValue(getPreferences());
}
public OutputType getOutputType() {
String retVal = FftPreferences.OUTPUT_TYPE.getValue(getPreferences());
try {
return OutputType.valueOf(retVal);
} catch (IllegalArgumentException e) {
return null;
}
}
@NonNull
public FftNxmBlockSettings getSettings() {
return new FftNxmBlockSettings(getPreferences());
}
public void applySettings(FftNxmBlockSettings newSettings) {
// update block's settings (model - so that getSettings() returns latest value)
setNumAverages(newSettings.getNumAverages());
setNumExpAverages(newSettings.getNumExpAverages());
setOverlap(newSettings.getOverlap());
setWindow(newSettings.getWindow());
setTransformSize(newSettings.getTransformSize());
setOutputType(newSettings.getOutputType());
setPipeSize(newSettings.getPipeSize());
}
protected void setOutputType(OutputType outputType) {
FftPreferences.OUTPUT_TYPE.setValue(getPreferences(), outputType.toString());
}
public void setTransformSize(int transformSize) {
FftPreferences.TRANSFORM_SIZE.setValue(getPreferences(), transformSize);
}
public void setWindow(WindowType window) {
FftPreferences.WINDOW_TYPE.setValue(getPreferences(), window.toString());
}
public void setOverlap(int overlap) {
FftPreferences.OVERLAP.setValue(getPreferences(), overlap);
}
public void setNumExpAverages(int numExpAverages) {
FftPreferences.SLIDING_NUM_AVERAGES.setValue(getPreferences(), numExpAverages);
}
public void setNumAverages(int numAverages) {
FftPreferences.NUM_AVERAGES.setValue(getPreferences(), numAverages);
}
public void setPipeSize(int pipeSize) {
FftPreferences.PIPE_SIZE.setValue(getPreferences(), pipeSize);
FftPreferences.PIPE_SIZE_OVERRIDE.setValue(getPreferences(), true);
}
public int getPipeSize() {
return FftPreferences.PIPE_SIZE.getValue(getPreferences());
}
public boolean isSetPipeSize() {
return FftPreferences.PIPE_SIZE_OVERRIDE.getValue(getPreferences());
}
public void unsetPipeSize() {
FftPreferences.PIPE_SIZE.setToDefault(getPreferences());
FftPreferences.PIPE_SIZE_OVERRIDE.setValue(getPreferences(), false);
}
@Override
public void propertyChange(PropertyChangeEvent event) {
Integer numAvg = null;
if (FftPreferences.NUM_AVERAGES.isEvent(event)) {
numAvg = getNumAverages();
}
Integer nexp = null;
if (FftPreferences.SLIDING_NUM_AVERAGES.isEvent(event)) {
nexp = getNumExpAverages();
}
Integer overlap = null;
if (FftPreferences.OVERLAP.isEvent(event)) {
overlap = getOverlap();
}
String window = null;
if (FftPreferences.WINDOW_TYPE.isEvent(event)) {
WindowType windowType = getWindowType();
window = windowType.toWindowString();
}
OutputType outputType = null;
if (FftPreferences.OUTPUT_TYPE.isEvent(event)) {
outputType = getOutputType();
}
Integer nfft = null;
if (FftPreferences.TRANSFORM_SIZE.isEvent(event)) {
nfft = getTransformSize();
}
Integer pipeSize = null;
if (FftPreferences.PIPE_SIZE.isEvent(event) || FftPreferences.PIPE_SIZE_OVERRIDE.isEvent(event)) {
if (isSetPipeSize()) {
pipeSize = getPipeSize();
} else {
pipeSize = FftPreferences.PIPE_SIZE.getDefaultValue();
}
if (pipeSize <= 0) { // PANIC!!
pipeSize = 131072;
}
}
// update actual FFT Command's settings for each stream
for (fft cmd : getNxmCommands()) {
if (numAvg != null) {
cmd.setNAvg(numAvg);
}
if (nexp != null) {
cmd.setNExp(nexp);
}
if (overlap != null) {
cmd.setOverlap(overlap / 100.0); // SUPPRESS CHECKSTYLE MagicNumber
}
if (window != null) {
cmd.setWindow(window);
}
// TODO: change PIPE_SIZE for input1? output1? output2?, etc.
// if (pipeSize != null) {
// }
if (outputType != null) {
// PASS TODO: cannot change: output type (NORMAL, PSD, MAG, MAG & LOG, PSD & LOG) on FFT at this time
// 1. this could cause a restart (when switching from NORMAL to any of the other output types
// 2. could always force the FFT command to restart with new launch switches
}
if (nfft != null) {
cmd.setNFft(nfft); // do this last as it can cause FFT to restart
}
}
}
@Override
public IPreferencePage createPreferencePage() {
FftBlockPreferencePage retVal = new FftBlockPreferencePage();
retVal.setPreferenceStore(getPreferences());
return retVal;
}
public int getOutFramesize(int sriMode) {
int size = getTransformSize();
if (sriMode == 0) { // for scalar data
size = size / 2; // framesize is half fft size
}
return size;
}
}