Merge pull request #10 from PAMGuard/main

Changes from main
This commit is contained in:
Douglas Gillespie 2022-08-19 08:18:21 +01:00 committed by GitHub
commit 5369df60df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 1876 additions and 466 deletions

View File

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/AdoptOpenJDK 16">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
@ -10,11 +17,5 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -26,6 +26,7 @@ import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamTextField;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.flipPane.FlipPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionParameters;
import Acquisition.ChannelListPanel;
@ -153,7 +154,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
//create the flip pane.
flipPane=new FlipPane();
flipPane.setFlipDirection(Orientation.HORIZONTAL);
flipPane.setFlipTime(250); //default is 700ms- way too high
flipPane.setFlipTime(PamFlipPane.FLIP_TIME); //default is 700ms- way too high
//flipPane.prefWidthProperty().bind(mainPane.widthProperty());
if (aquisitionControl.isViewer()){

View File

@ -0,0 +1,136 @@
package PamController;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.flipPane.FlipPane;
/**
* A pane which can flip to show another pane (referred to as the advanced settings pane).
* @author Jamie Macaulay
*
* @param <T>
*/
public abstract class FlipSettingsPane<T> extends SettingsPane<T> {
/**
* The holder pane.
*/
private FlipPane flipPane;
/**
* The label at the top of the advanced pane.
*/
private Label advLabel;
/**
* The advanced pane.
*/
private PamBorderPane advPane;
/**
* The button which flips back to the front pane.
*/
private PamButton backButton;
public FlipSettingsPane(Object ownerWindow) {
super(ownerWindow);
flipPane = new FlipPane();
flipPane.setFlipTime(200);
this.advPane = createAdvSettingsPane() ;
flipPane.getBack().getChildren().add(advPane);
}
@Override
public Node getContentNode() {
flipPane.getFront().getChildren().clear();
flipPane.getFront().getChildren().add(getFrontContentNode());
return flipPane;
}
/**
* Flip the pane to show the advanced settings pane.
*/
public void flipToBack() {
flipPane.flipToBack();
}
/**
* Flip the pane to show the primary pane.
*/
public void flipToFront() {
flipPane.flipToBack();
}
/**
* Set the contents of the advanced pane.
* @param contentNode - the content to set.
*/
public void setAdvPaneContents(Node contentNode) {
this.advPane.setCenter(contentNode);
}
/**
* Get the content node for the flip pane.
* @return
*/
public abstract Pane getFrontContentNode();
/**
* Create the advanced settings pane which can be accessed by DAQ panes if needed.
*/
private PamBorderPane createAdvSettingsPane() {
backButton = new PamButton();
backButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-chevron-left", Color.WHITE, PamGuiManagerFX.iconSize));
backButton.setOnAction((action)->{
flipPane.flipToFront();
});
PamBorderPane advPane = new PamBorderPane();
//advPane.setPadding(new Insets(5,5,5,5));
PamHBox buttonHolder = new PamHBox();
buttonHolder.setBackground(null);
//buttonHolder.setStyle("-fx-background-color: red;");
buttonHolder.setAlignment(Pos.CENTER_LEFT);
buttonHolder.getChildren().addAll(backButton, advLabel = new Label("Adv. Settings"));
advLabel.setAlignment(Pos.CENTER);
advLabel.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
PamGuiManagerFX.titleFont2style(advLabel);
advLabel.setAlignment(Pos.CENTER);
HBox.setHgrow(advLabel, Priority.ALWAYS);
advPane.setTop(buttonHolder);
return advPane;
}
public PamBorderPane getAdvPane() {
return advPane;
}
}

View File

@ -17,7 +17,7 @@ public abstract class PamControlledUnitGUI {
public abstract int getGUIFlag();
/**
* Allows the GUI to be notified of changes, e.g. in the PAMControlle.r
* Allows the GUI to be notified of changes, e.g. in the PAMController
* @param flag - the change flag.
*/
public void notifyGUIChange(int flag) {

View File

@ -40,7 +40,7 @@ public abstract class SettingsPane<T> {
public abstract String getName();
/**
* Get node for GUI chnage of settings.
* Get node for GUI change of settings.
*/
public abstract Node getContentNode();

View File

@ -6,6 +6,7 @@ import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
@ -62,7 +63,7 @@ public class TxtFileUtils {
boolean isNaN=false;
for (String line : lines) {
System.out.println(line);
//System.out.println(line);
String[] recordsOnLine = line.split(delimeter);
@ -82,11 +83,15 @@ public class TxtFileUtils {
// //This was causing isses with some numbers with e-06...dunno why so switched to parse double
// String input = new String(recordsOnLine[i].toCharArray());
// //System.out.println(input);
// System.out.println("|" + recordsOnLine[i] + "|");
// dat = nF.parse(input).doubleValue();
dat = Double.parseDouble(recordsOnLine[i]);
//5/08/2022 - there was a bug here where there is some sort of invisible character that does not appear on the
//print screen - the only way you can tell is the char array is greater than the number of digits - removed all non numeric
//characters.
String number = new String(recordsOnLine[i].strip().replaceAll("[^\\d.]", ""));
dat = Double.valueOf(number);
//dat = DecimalFormat.getNumberInstance().parse(new String(recordsOnLine[i].strip().toCharArray())).doubleValue();
}
catch (Exception e){
e.printStackTrace();

View File

@ -99,6 +99,7 @@ public class RawDataTransforms {
*/
private int shortestFFTLength;
private Object synchObject;
/**
@ -187,31 +188,29 @@ public class RawDataTransforms {
* @param fftLength
* @return Power spectrum
*/
public double[] getPowerSpectrum(int channel, int fftLength) {
synchronized (synchObject) {
if (powerSpectra == null) {
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
}
if (fftLength == 0) {
fftLength = getCurrentSpectrumLength();
}
if (powerSpectra[channel] == null
|| powerSpectra[channel].length != fftLength / 2) {
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
currentSpecLen = fftLength;
powerSpectra[channel] = cData.magsq();
if (powerSpectra==null){
System.err.println("DLDetection: could not calculate power spectra");
return null;
}
if (powerSpectra[channel].length != fftLength/2) {
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
}
}
return powerSpectra[channel];
public synchronized double[] getPowerSpectrum(int channel, int fftLength) {
if (powerSpectra == null) {
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
}
if (fftLength == 0) {
fftLength = getCurrentSpectrumLength();
}
if (powerSpectra[channel] == null
|| powerSpectra[channel].length != fftLength / 2) {
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
currentSpecLen = fftLength;
powerSpectra[channel] = cData.magsq();
if (powerSpectra==null){
System.err.println("DLDetection: could not calculate power spectra");
return null;
}
if (powerSpectra[channel].length != fftLength/2) {
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
}
}
return powerSpectra[channel];
}
@ -221,27 +220,25 @@ public class RawDataTransforms {
* @param fftLength
* @return Sum of power spectra
*/
public double[] getTotalPowerSpectrum(int fftLength) {
synchronized (synchObject) {
if (fftLength == 0) {
fftLength = getCurrentSpectrumLength();
}
if (fftLength == 0) {
fftLength = PamUtils.getMinFftLength(getSampleDuration());
}
double[] ps;
if (totalPowerSpectrum == null
|| totalPowerSpectrum.length != fftLength / 2) {
totalPowerSpectrum = new double[fftLength / 2];
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
ps = getPowerSpectrum(c, fftLength);
for (int i = 0; i < fftLength / 2; i++) {
totalPowerSpectrum[i] += ps[i];
}
public synchronized double[] getTotalPowerSpectrum(int fftLength) {
if (fftLength == 0) {
fftLength = getCurrentSpectrumLength();
}
if (fftLength == 0) {
fftLength = PamUtils.getMinFftLength(getSampleDuration());
}
double[] ps;
if (totalPowerSpectrum == null
|| totalPowerSpectrum.length != fftLength / 2) {
totalPowerSpectrum = new double[fftLength / 2];
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
ps = getPowerSpectrum(c, fftLength);
for (int i = 0; i < fftLength / 2; i++) {
totalPowerSpectrum[i] += ps[i];
}
}
return totalPowerSpectrum;
}
return totalPowerSpectrum;
}
@ -256,17 +253,15 @@ public class RawDataTransforms {
* @param fftLength - the FFT length to use.
* @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel.
*/
public ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
synchronized (synchObject) {
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
if (complexSpectrum[channel] == null
|| complexSpectrum.length != fftLength / 2) {
public synchronized ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
if (complexSpectrum[channel] == null
|| complexSpectrum.length != fftLength / 2) {
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
currentSpecLen = fftLength;
}
return complexSpectrum[channel];
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
currentSpecLen = fftLength;
}
return complexSpectrum[channel];
}
@ -394,31 +389,29 @@ public class RawDataTransforms {
* @param fftLength
* @return the complex spectrum
*/
public ComplexArray getComplexSpectrum(int channel, int fftLength) {
synchronized (synchObject) {
double[] paddedRawData;
double[] rawData;
int i, mn;
public synchronized ComplexArray getComplexSpectrum(int channel, int fftLength) {
double[] paddedRawData;
double[] rawData;
int i, mn;
if (complexSpectrum == null) {
complexSpectrum = new ComplexArray[getNChan()];
}
if (complexSpectrum[channel] == null
|| complexSpectrum.length != fftLength / 2) {
paddedRawData = new double[fftLength];
rawData = getWaveData(channel);
//double[] rotData = getRotationCorrection(channel);
mn = Math.min(fftLength, getSampleDuration().intValue());
for (i = 0; i < mn; i++) {
paddedRawData[i] = rawData[i];//-rotData[i];
}
for (i = mn; i < fftLength; i++) {
paddedRawData[i] = 0;
}
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
}
return complexSpectrum[channel];
if (complexSpectrum == null) {
complexSpectrum = new ComplexArray[getNChan()];
}
if (complexSpectrum[channel] == null
|| complexSpectrum.length != fftLength / 2) {
paddedRawData = new double[fftLength];
rawData = getWaveData(channel);
//double[] rotData = getRotationCorrection(channel);
mn = Math.min(fftLength, getSampleDuration().intValue());
for (i = 0; i < mn; i++) {
paddedRawData[i] = rawData[i];//-rotData[i];
}
for (i = mn; i < fftLength; i++) {
paddedRawData[i] = 0;
}
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
}
return complexSpectrum[channel];
}
@ -427,16 +420,14 @@ public class RawDataTransforms {
* @param iChan channel index
* @return analytic waveform
*/
public double[] getAnalyticWaveform(int iChan) {
synchronized (synchObject) {
if (analyticWaveform == null) {
analyticWaveform = new double[getNChan()][];
}
// if (analyticWaveform[iChan] == null) {
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
// }
return analyticWaveform[iChan];
public synchronized double[] getAnalyticWaveform(int iChan) {
if (analyticWaveform == null) {
analyticWaveform = new double[getNChan()][];
}
// if (analyticWaveform[iChan] == null) {
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
// }
return analyticWaveform[iChan];
}
/**
@ -448,14 +439,12 @@ public class RawDataTransforms {
* @param fftFilterParams fft filter parameters.
* @return analystic waveform.
*/
public double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
synchronized (synchObject) {
if (filtered == false || fftFilterParams == null) {
return getAnalyticWaveform(iChan);
}
else {
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
}
public synchronized double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
if (filtered == false || fftFilterParams == null) {
return getAnalyticWaveform(iChan);
}
else {
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
}
}
@ -466,6 +455,7 @@ public class RawDataTransforms {
* @param iChan channel number
* @return envelope of the filtered data.
*/
public double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
synchronized (synchObject) {
if (analyticWaveform == null) {
@ -509,6 +499,7 @@ public class RawDataTransforms {
* @param channelIndex channel index
* @return filtered waveform data
*/
public double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
synchronized (synchObject) {
filteredWaveData = getFilteredWaveData(filterParams);
@ -522,6 +513,7 @@ public class RawDataTransforms {
* @param filterParams filter parameters
* @return array of filtered data
*/
public double[][] getFilteredWaveData(FFTFilterParams filterParams) {
synchronized (synchObject) {
//System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams));

View File

@ -638,4 +638,24 @@
#module-pane .ikonli-font-icon {
-fx-icon-color: black;
}
/*******************************************************************************
* *
* Custom slider for volume controls *
* *
******************************************************************************/
#thickslider .track {
-fx-pref-height:14;
-fx-background-radius: 8;
}
#thickslider:vertical .track {
-fx-pref-width:12;
-fx-background-radius: 8;
}
#thickslider .thumb {
-fx-pref-height: 14;
-fx-pref-width: 14;
}

Binary file not shown.

Binary file not shown.

View File

@ -24,6 +24,7 @@ import clickDetector.ClickClassifiers.ClickIdentifier;
import clickDetector.ClickClassifiers.ClickTypeCommonParams;
import clickDetector.ClickClassifiers.basic.BasicClickIdentifier;
import clickDetector.layoutFX.clickClassifiers.ClassifyPaneFX;
import clickDetector.layoutFX.clickClassifiers.SweepClassifierPaneFX;
/**
* An improvements on the BasicClickIdentifier based on work by
@ -44,6 +45,9 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
private SweepClassifierPanel dialogPanel;
private SweepClassifierPaneFX fxPane;
private SweepClassifierWorker sweepClassifierWorker;
protected SweepClassifierParameters sweepClassifierParameters = new SweepClassifierParameters();
@ -408,8 +412,8 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
@Override
public ClassifyPaneFX getClassifierPane() {
// TODO Auto-generated method stub
return null;
if (fxPane==null) fxPane = new SweepClassifierPaneFX(this, clickControl);
return fxPane;
}
@Override

View File

@ -194,8 +194,8 @@ public class ClickDelayPane extends SettingsPane<ClickParameters> {
public ClickParameters getParams(ClickParameters clickParameters) {
if (clickParameters==null) return null;
if (delayParams[0] == null) {
return null;
if (delayParams==null || delayParams[0] == null) {
return clickParameters;
}
clickParameters.setDelayMeasurementParams(0, delayParams[0]);
for (int i = 1; i < typesList.length; i++) {

View File

@ -6,6 +6,7 @@ import java.text.ParseException;
import clickDetector.ClickControl;
import clickDetector.ClickParameters;
import clickDetector.layoutFX.clickClassifiers.ClickClassifyPaneFX;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
@ -13,6 +14,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
@ -41,6 +43,8 @@ import pamViewFX.fxNodes.utilityPanes.GroupedSourcePaneFX;
* @author Jamie Macaulay
*/
public class ClickSettingsPane extends SettingsPane<ClickParameters>{
public static double PREF_SPINNER_WIDTH = 100;
/**
* Group source pane for the click settings pane.
@ -158,7 +162,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
/**
* The default pane width
*/
public static double paneWidth=1050;
public static double paneWidth=500;
/**
* The default pane height.
@ -180,22 +184,17 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
pamTabbedPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
//create a combined detection and length pane
PamHBox detectionPane=new PamHBox();
PamVBox detectionPane=new PamVBox();
detectionPane.setSpacing(20);
detectionPane.getChildren().add(createClickDetectionPane());
//create a dividing line.
Line line=new Line(0,20,0,0);
line.startYProperty().bind(sourcePane.layoutYProperty().add(20));
line.endYProperty().bind(detectionPane.heightProperty().subtract(20));
line.setStroke(Color.WHITE);
line.setStrokeWidth(2);
PamHBox lineHolder=new PamHBox();
lineHolder.getChildren().add(line);
lineHolder.setAlignment(Pos.CENTER);
detectionPane.getChildren().add(lineHolder);
PamVBox holder=new PamVBox();
PamHBox holder=new PamHBox();
holder.setSpacing(20);
holder.getChildren().addAll(createClickLengthPane(), createClickTriggerPane());
detectionPane.getChildren().add(holder);
detectionPane.getChildren().add(createTriggerGraph());
//add everything to tabs.
pamTabbedPane.getTabs().add(new Tab("Click Detection", detectionPane));
@ -211,11 +210,11 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
//pre filter pane.
preFilter=new FilterPaneFX();
preFilter=new FilterPaneFX(Orientation.VERTICAL);
pamTabbedPane.getTabs().add(new Tab("Pre Filter", preFilter.getContentNode()));
//trigger pane
triggerFilter=new FilterPaneFX();
triggerFilter=new FilterPaneFX(Orientation.VERTICAL);
pamTabbedPane.getTabs().add(new Tab("Trigger Filter", triggerFilter.getContentNode()));
//echo detection pane.
@ -268,12 +267,16 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
//channels, groups and trigger are all in one pane to make it easy not to make mistakes
sourcePane=createClickSourcePane(); //create the source pane.
GridPane.setColumnSpan(sourcePane.getDataBlockBox(), 4);
//now create trigger pane. The trigger pane is added to the source pane.
Label triggerLabel = new Label("Trigger Channels");
PamGuiManagerFX.titleFont2style(triggerLabel);
sourcePane.getSourcePane().add(triggerLabel,1,2);
sourcePane.getSourcePane().add(triggerChannels=new Pane(),1,3);
triggerChannels=new Pane();
sourcePane.getSourcePane().add(triggerChannels,1,3);
createTriggerChannels();
//sourcePane.getSourcePane().add(createClickTriggerPane(), 2, 3);
@ -282,6 +285,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
// pamTabbedPane.getTabs().add(new Tab("Click Echoes", createEchoPane()));
// pamTabbedPane.getTabs().add(new Tab("Click Delays", createDelayPane()));
sourcePane.setPrefWidth(paneWidth);
return sourcePane;
}
@ -299,33 +303,41 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
lengthPane.setVgap(5);
lengthPane.setHgap(5);
lengthPane.add(new Label("Min click separation"),0,0);
lengthPane.add(new Label("Min separation"),0,0);
minClickSep=new PamSpinner<Integer>(0, 10000000, 100, 20);
minClickSep.setEditable(true);
minClickSep.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
minClickSep.setPrefWidth(PREF_SPINNER_WIDTH);
lengthPane.add(minClickSep,1,0);
lengthPane.add(new Label("samples"),2,0);
lengthPane.add(new Label("Max click length"),0,1);
lengthPane.add(new Label("Max length"),0,1);
maxClickLength=new PamSpinner<Integer>(0, 10000000, 100, 20);
maxClickLength.setEditable(true);
maxClickLength.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
maxClickLength.setPrefWidth(PREF_SPINNER_WIDTH);
lengthPane.add(maxClickLength,1,1);
lengthPane.add(new Label("samples"),2,1);
lengthPane.add(new Label("pre samples"),0,2);
lengthPane.add(new Label("Pre samples"),0,2);
preSampleSpinner=new PamSpinner<Integer>(0, 10000000, 100, 20);
preSampleSpinner.setEditable(true);
preSampleSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
preSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
lengthPane.add(preSampleSpinner,1,2);
lengthPane.add(new Label("samples"),2,2);
lengthPane.add(new Label("pre samples"),0,3);
lengthPane.add(new Label("Post samples"),0,3);
postSampleSpinner=new PamSpinner<Integer>(0, 10000000, 100, 20);
postSampleSpinner.setEditable(true);
postSampleSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
postSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
lengthPane.add(postSampleSpinner,1,3);
lengthPane.add(new Label("samples"),2,3);
@ -398,6 +410,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
});
triggerBox.add(threshold,1,0);
triggerBox.add(new Label("dB"),2,0);
threshold.setPrefWidth(PREF_SPINNER_WIDTH);
triggerBox.add(new Label("Long Filter"),0,1);
longFilter=new PamSpinner<Double>(0.0000001, 0.1, 0.000001, 0.000001);
@ -410,6 +423,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
clickTriggerGraph.updateWaveformGraph(this.clickParameters);
});
triggerBox.add(longFilter,1,1);
longFilter.setPrefWidth(PREF_SPINNER_WIDTH);
triggerBox.add(new Label("Long Filter 2"),0,2);
longFilter2=new PamSpinner<Double>(0.0000001, 0.1, 0.000001, 0.000001);
@ -419,6 +433,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
longFilter2.getValueFactory().valueProperty().addListener((obs, before, after)->{
clickParameters.longFilter2=after;
});
longFilter2.setPrefWidth(PREF_SPINNER_WIDTH);
triggerBox.add(longFilter2,1,2);
triggerBox.add(new Label("Short Filter"),0,3);
@ -431,25 +446,33 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
clickTriggerGraph.setShortFilter(clickParameters.shortFilter);
clickTriggerGraph.updateWaveformGraph(this.clickParameters);
});
shortFilter.setPrefWidth(PREF_SPINNER_WIDTH);
triggerBox.add(shortFilter,1,3);
triggerPane.add(triggerBox,0,1);
//trigger graph
Label graphLabel = new Label("Filter Graph");
PamGuiManagerFX.titleFont2style(graphLabel);
triggerPane.add(graphLabel,0,2);
clickTriggerGraph=new ClickTriggerGraph();
PamGridPane.setHgrow(clickTriggerGraph, Priority.ALWAYS);
PamGridPane.setVgrow(clickTriggerGraph, Priority.ALWAYS);
triggerPane.add(clickTriggerGraph,0,3);
//triggerPane.setGridLinesVisible(true);
return triggerPane;
}
private Pane createTriggerGraph() {
//trigger graph
Label graphLabel = new Label("Filter Graph");
PamGuiManagerFX.titleFont2style(graphLabel);
clickTriggerGraph=new ClickTriggerGraph();
PamGridPane.setHgrow(clickTriggerGraph, Priority.ALWAYS);
PamGridPane.setVgrow(clickTriggerGraph, Priority.ALWAYS);
PamVBox triggerGraph = new PamVBox();
triggerGraph.setSpacing(5);
triggerGraph.getChildren().addAll(graphLabel, clickTriggerGraph);
return triggerGraph;
}
/**
* Unselect all trigger channels

View File

@ -19,6 +19,9 @@ import simulatedAcquisition.sounds.SimSignal;
public class ClickTriggerGraph extends PamBorderPane {
public final static int PORPOISE_CLICK=0;
public final static int SPERM_WHALE=1;
private int currentClick=PORPOISE_CLICK;
@ -44,11 +47,15 @@ public class ClickTriggerGraph extends PamBorderPane {
private LineChart<Number, Number> plotChart;
private int freq2;
private double[] waveform;
public ClickTriggerGraph(){
this.setCenter(createWaveformGraph());
this.setPrefWidth(500);
this.setPrefWidth(400);
//FIXME - seems to a resize bug in high DPI displays. Seems fixed in 8u60.
this.waveform=generateClickWaveform(currentClick, noise);
}
/**
@ -67,7 +74,6 @@ public class ClickTriggerGraph extends PamBorderPane {
Series<Number, Number> noiseLevelSeries = new Series<Number, Number>();
double[] waveform=generateClickWaveform(currentClick, noise);
double[] signalLevel=calcFilter(waveform, shortFilter);
double[] noiseLevel=calcFilter(waveform, longFilter);
@ -111,6 +117,10 @@ public class ClickTriggerGraph extends PamBorderPane {
clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
sR=500000;
break;
case SPERM_WHALE:
clickSound=(new ClickSound("Beaked Whale", 30000, 60000, length = 0.3e-3, WINDOWTYPE.HANN));
sR=192000;
break;
default:
clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
sR=500000;

View File

@ -1,17 +1,15 @@
package clickDetector.layoutFX.clickClassifiers;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.hidingPane.HidingPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import pamViewFX.fxNodes.table.TableSettingsPane;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Dialog;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.paint.Color;
import clickDetector.BasicClickIdParameters;
import clickDetector.ClickControl;
import clickDetector.ClickTypeParams;
@ -40,10 +38,10 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
*/
private TableSettingsPane<ClickTypeProperty> settingsPane;
/**
* Hiding pane which slides out to allow users to change click type settings.
*/
protected HidingPane hidingPane;
// /**
// * Hiding pane which slides out to allow users to change click type settings.
// */
// protected HidingPane hidingPane;
/**
* Holds click classifier controls inside hiding pane.
@ -62,10 +60,10 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
*/
protected PamBorderPane mainHolderPane;
/**
* The width of the hiding pane
*/
private double hidingPaneWidth=900;
// /**
// * The width of the hiding pane
// */
// private double hidingPaneWidth=900;
/**
* Cloned copy of BasicClickIdParameters.
@ -73,10 +71,12 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
private BasicClickIdParameters basicClickIdParameters;
private PamBorderPane mainPane;
private PamFlipPane flipPane;
/**
* Create a BasicClickIdParameters pane which allows users to add multiple basic click identifiers to the PAMGuard click classifier.
* @param basicClickIdentifier - the ClickIdentifier.
* @param basicClickIdentifier - the ClickIdentifier. ob
* @param clickControl -a reference to the ClickControl the classifier is associated with.
*/
public BasicIdentifierPaneFX(ClickIdentifier basicClickIdentifier,
@ -84,9 +84,17 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
this.basicClickIdentifier= basicClickIdentifier;
this.clickControl=clickControl;
mainPane= new PamBorderPane();
mainPane.setCenter(createSettingsPane());
flipPane = new PamFlipPane();
flipPane.getFrontPane().setCenter(createSettingsPane());
flipPane.getBackPane().setCenter(clickTypeHolder);
mainPane.setCenter(flipPane);
}
/**
* Create the controls for the basic click identifier pane.
* @return node with all controls for basic click classifier.
@ -97,21 +105,23 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
mainHolderPane.setCenter(settingsPane=new ClickClassifierTable(clickClassifiers));
clickTypeHolder=new PamBorderPane();
clickTypeHolder.setPrefWidth(hidingPaneWidth);
//clickTypeHolder.setPrefWidth(hidingPaneWidth);
return mainHolderPane;
}
/**
* Added purely so can be override and hiding pane set in different location if required
*/
public void createHidingPane(){
hidingPane=new HidingPane(Side.RIGHT, clickTypeHolder, mainPane, false);
//hidingPane.showHidePane(false);
mainHolderPane.setRight(hidingPane);
hidingPane.showHidePane(false);
}
// /**
// * Added purely so can be override and hiding pane set in different location if required
// */
// public void createHidingPane(){
// hidingPane=new HidingPane(Side.RIGHT, clickTypeHolder, mainPane, false);
// //hidingPane.showHidePane(false);
// mainHolderPane.setRight(hidingPane);
// hidingPane.showHidePane(false);
// }
@Override
public Node getNode() {
@ -192,14 +202,14 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
public Dialog<ClickTypeProperty> createSettingsDialog(ClickTypeProperty data) {
//we do not use dialogs here- sliding pane instead.
setClassifierPane(data);
showHidingPane(true);
showFlipPane(true);
return null;
}
@Override
public void editData(ClickTypeProperty data){
setClassifierPane(data);
showHidingPane(true);
showFlipPane(true);
}
@Override
@ -210,16 +220,31 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
}
// /**
// * Show the hiding pane which contains classifier settings
// * NOTE: needed to add this to stop a stack overflow error in BasicClickIdentifier 06/09/2016
// * @param show - true to show pane.
// */
// public void showHidingPane(boolean show){
// if (hidingPane==null){
// this.createHidingPane();
// }
// hidingPane.showHidePane(true);
// }
/**
* Show the hiding pane which contains classifier settings
* Show the flip pane.
* NOTE: needed to add this to stop a stack overflow error in BasicClickIdentifier 06/09/2016
* @param show - true to show pane.
*/
public void showHidingPane(boolean show){
if (hidingPane==null){
this.createHidingPane();
public void showFlipPane(boolean show){
if (show) {
//System.out.println("Show flip pane: " + show);
flipPane.flipToBack();
}
else {
flipPane.flipToFront();
}
hidingPane.showHidePane(true);
}
/**
@ -243,7 +268,9 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
//now need to make sure on closing the pane that settings are saved. Need to
//remove the old click type from the list and add new one in the same position.
getHidingPaneCloseButton().setOnAction((action)->{
getFlipPaneCloseButton().setOnAction((action)->{
//System.out.println("CLOSE FLIP PANE");
showFlipPane(false);
//this should update the click type property in the observable list thus changing the table
clickTypePane.getParams(clickTypeProperty);
});
@ -253,20 +280,20 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
* Get the button which closes the hiding pane.
* @return button which closes the hiding pane.
*/
public Button getHidingPaneCloseButton() {
return getClickTypeHidingPane().getHideButton();
public Button getFlipPaneCloseButton() {
return flipPane.getBackButton();
}
/**
* Get the hiding pane which holds settings for different click types.
* @return the HidingPane for click classifiers.
*/
public HidingPane getClickTypeHidingPane() {
if (hidingPane==null) {
this.createHidingPane();
}
return hidingPane;
}
// /**
// * Get the hiding pane which holds settings for different click types.
// * @return the HidingPane for click classifiers.
// */
// public HidingPane getClickTypeHidingPane() {
// if (hidingPane==null) {
// this.createHidingPane();
// }
// return hidingPane;
// }
/**
* Get the pane which holds the ClickTypePaneFX.

View File

@ -4,6 +4,7 @@ import org.controlsfx.glyphfont.Glyph;
import clickDetector.ClickControl;
import clickDetector.ClickParameters;
import clickDetector.ClickClassifiers.ClickClassifierManager;
import clickDetector.ClickClassifiers.ClickIdentifier;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@ -41,6 +42,7 @@ public class ClickClassifyPaneFX extends PamStackPane {
*/
private ClickControl clickControl;
private CheckBox runOnlineCheckBox;
private CheckBox discardClicksCheckBox;
@ -160,7 +162,11 @@ public class ClickClassifyPaneFX extends PamStackPane {
//set parameters - listener will do everything else.
currentClickIdentifier=clickControl.getClassifierManager().
getClassifier(clickParameters.clickClassifierType);
System.out.println("ClickClassifyPaneFX:setParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
if (clickParameters.clickClassifierType == ClickClassifierManager.CLASSIFY_BASIC) {
}
//System.out.println("ClickClassifyPaneFX:setParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
classifierComboBox.getSelectionModel().select(clickParameters.clickClassifierType);
//set classifier parameters
if (currentClickIdentifier!=null && currentClickIdentifier.getClassifierPane()!=null) {
@ -171,7 +177,7 @@ public class ClickClassifyPaneFX extends PamStackPane {
public ClickParameters getParams(ClickParameters clickParameters){
//set all parameters in classifier.
System.out.println("ClickClassifyPaneFX:getParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
//System.out.println("ClickClassifyPaneFX:getParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
clickParameters.clickClassifierType=classifierComboBox.getSelectionModel().getSelectedIndex();
if (currentClickIdentifier != null && currentClickIdentifier.getClassifierPane() != null) {

View File

@ -1,7 +1,6 @@
package clickDetector.layoutFX.clickClassifiers;
import pamViewFX.fxNodes.PamScrollPane;
import clickDetector.ClickControl;
import clickDetector.ClickClassifiers.basicSweep.SweepClassifier;
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierParameters;
@ -9,17 +8,18 @@ import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
/**
* Slightly different pane for the sweep classifier.
*
* @author Jamie Macaulay
*/
public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
/**
* Reference to the sweep classifier
* Reference to the sweep classifier.
*/
SweepClassifier sweepClickClassifier;
/**
* Reference to the sweep classifier params
* Reference to the sweep classifier params.
*/
private SweepClassifierParameters sweepIdParameters;
@ -39,11 +39,12 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
public void setClassifierPane(ClickTypeProperty clickTypeProperty){
SweepClassifierSetPaneFX sweepPane=new SweepClassifierSetPaneFX(sweepClickClassifier);
sweepPane.setParams(clickTypeProperty);
super.getClickTypeHolder().setCenter(new PamScrollPane(sweepPane.getContentNode()));
super.getClickTypeHolder().setCenter(sweepPane.getContentNode());
//now need to make sure on closing the pane that settings are saved. Need to
//remove the old click type from the list and add new one in the same position.
getHidingPaneCloseButton().setOnAction((action)->{
getFlipPaneCloseButton().setOnAction((action)->{
showFlipPane(false);
sweepPane.getParams(clickTypeProperty);
});
}

View File

@ -15,21 +15,22 @@ import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Priority;
import javafx.scene.text.Font;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamTitledPane;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxNodes.picker.SymbolPicker;
import pamViewFX.fxNodes.utilityPanes.FreqBandPane;
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
import pamViewFX.fxNodes.utilityPanes.SimpleFilterPaneFX;
import pamViewFX.PamGuiManagerFX;
import PamController.SettingsPane;
import clickDetector.ClickClassifiers.basicSweep.CodeHost;
@ -38,6 +39,7 @@ import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
/**
* Pane which contains controls to change a SweepClassifierSet.
*
* @author Jamie Macaulay
*
*/
@ -110,14 +112,15 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
private Node createSweepPane(){
PamVBox holder=new PamVBox();
holder.setSpacing(10);
holder.setPadding(new Insets(10,5,5,40));
holder.setSpacing(15);
holder.setPadding(new Insets(10,0,0,0));
optionBox=new OptionsBox();
/*********Waveform Tab************/
Tab waveformTab=new Tab("Waveform");
PamVBox waveformHolder=new PamVBox(5);
waveformHolder.setPadding(new Insets(10,0,0,0));
clickLength=new ClickLengthBox();
filterBox=new FilterBox();
@ -134,11 +137,13 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
energyBox=new EnergyBandBox();
freqBox=new FrequencySearchBlock();
spectrumHolder.getChildren().addAll(energyBox, freqBox);
spectrumHolder.setPadding(new Insets(10,0,0,0));
spectrumTab.setContent(spectrumHolder);
/**********Main Layout**************/
TabPane tabPane= new TabPane();
tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
tabPane.getTabs().addAll(waveformTab, spectrumTab);
holder.getChildren().add(optionBox);
@ -153,12 +158,12 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
* @author Jamie Macaulay
*
*/
private abstract class SweepBox extends PamTitledPane {
private abstract class SweepBox extends PamBorderPane {
/**
* Check box to enable pane
*/
private CheckBox enableBox;
private PamToggleSwitch enableBox;
/**
* Border pane to hold content
@ -167,40 +172,52 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
private Font disableFont;
private Label label;
SweepBox(String borderTitle, Boolean enableButton) {
//create holder pnae
borderPane=new PamBorderPane();
this.setCenter(borderPane);
PamHBox hBox = new PamHBox();
hBox.setSpacing(5);
if (borderTitle != null) {
//Label label=new Label(borderTitle);
PamGuiManagerFX.titleFont2style(this);
//borderPane.setTop(label);
this.setText(borderTitle);
label=new Label(borderTitle);
PamGuiManagerFX.titleFont2style(label);
hBox.getChildren().add(label);
}
if (enableButton) {
enableBox = new CheckBox("Enable");
PamVBox vBox=new PamVBox();
vBox.setPadding(new Insets(0,20,0,0));
vBox.setAlignment(Pos.CENTER);
vBox.getChildren().add(enableBox);
if (enableButton.booleanValue() == true) {
enableBox = new PamToggleSwitch("");
//vBox.setPadding(new Insets(0,20,0,0));
enableBox.setTooltip(new Tooltip("Enable " + borderTitle + " measurements"));
enableBox.setOnAction((action)->{
enableBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
disbleControls(!enableBox.isSelected());
/**FIXME- this does not seem to work. If titlepane collapsed auto returns to white**/
// if (enableBox.isSelected()) this.setTextFill(Color.WHITE);
// else this.setTextFill(Color.GRAY);
});
borderPane.setLeft(vBox);
hBox.getChildren().add(0,enableBox);
// setOnAction((action)->{
// disbleControls(!enableBox.isSelected());
//
// /**FIXME- this does not seem to work. If titlepane collapsed auto returns to white**/
// if (enableBox.isSelected()) this.setTextFill(Color.WHITE);
// else this.setTextFill(Color.GRAY);
// });
//this.setDisable(!enableBox.isSelected());
}
this.setContent(borderPane);
this.setTop(hBox);
/**Don't like this in old swing version*/
//tP.setCenter( description = new Label("", JLabel.CENTER));
//this.setTop(tP);
@ -211,7 +228,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
* @param desc - a description of the control
*/
protected void setDescription(String desc) {
this.setTooltip(new Tooltip(desc));
label.setTooltip(new Tooltip(desc));
}
// private void showTopStrip() {
@ -326,7 +343,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
nameField=new TextField();
nameField.setPrefColumnCount(10);
pamGridPane.add(nameField, 1, 0);
pamGridPane.add(nameField, 0, 0);
PamGridPane.setColumnSpan(nameField, 2);
@ -334,17 +351,17 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
codeSpinner=new PamSpinner<Integer> (0, 500, 0, 1);
codeSpinner.setEditable(true);
codeSpinner.setPrefWidth(150);
//codeSpinner.setPrefWidth(150);
codeSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
pamGridPane.add(codeSpinner, 4, 0);
pamGridPane.add(codeSpinner, 1, 0);
// pamGridPane.add(new Label("Symbol"), 0,1);
//create colour picker to allow users to change symbol colour.
symbolPicker=new SymbolPicker();
pamGridPane.add(symbolPicker, 6, 0);
pamGridPane.add(symbolPicker, 2, 0);
pamGridPane.add(new Label("Symbol"), 5,0);
pamGridPane.add(new Label("Symbol"), 3,0);
// //create a button to allow users to change symbol shape.
// symbolColour=new ColorPicker();
@ -372,7 +389,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
clickLengthSpinner=new PamSpinner<Integer>(4,102400,128,32);
clickLengthSpinner.setEditable(true);
clickLengthSpinner.setPrefWidth(150);
//clickLengthSpinner.setPrefWidth(150);
clickLengthSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
clickCenterBox.getChildren().add(clickLengthSpinner);
@ -380,7 +397,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
clickCenterBox.getChildren().add(lengthMS=new Label("()"));
clickCenterBox.getChildren().add(new Label("around click center."));
clickCenterBox.setAlignment(Pos.CENTER_LEFT);
PamGridPane.setColumnSpan(clickCenterBox, 7);
PamGridPane.setColumnSpan(clickCenterBox, 4);
PamGridPane.setHgrow(clickCenterBox, Priority.ALWAYS);
pamGridPane.add(clickCenterBox, 0,2);
@ -494,7 +511,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
protected void setParams() {
//set sample rate.
simpleFilterPane.setSampleRate(sweepClassifier.getClickDetector().getSampleRate());
simpleFilterPane.setParams(sweepClassifierSet.fftFilterParams);
if (sweepClassifierSet.fftFilterParams!=null) simpleFilterPane.setParams(sweepClassifierSet.fftFilterParams);
}
@ -558,7 +575,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
// gridPane.add(new Label("Smoothing"),0,0);
smoothing=new PamSpinner<Integer>(3,101,5,2);
smoothing.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
smoothing.setPrefWidth(100);
//smoothing.setPrefWidth(100);
// gridPane.add(smoothing,1,0);
// gridPane.add(new Label("bins (must be odd)"),2,0);
@ -566,7 +583,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
// gridPane.add(new Label("Threshold"),3,0);
threshold=new PamSpinner<Double>(1., 300., 6.,1.);
threshold.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
threshold.setPrefWidth(100);
//threshold.setPrefWidth(100);
// gridPane.add(threshold,4,0);
// gridPane.add(new Label("dB"),5,0);
@ -583,12 +600,12 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
minLengthms=new PamSpinner<Double>(0.00, 1.00, 0.03,0.01);
minLengthms.setEditable(true);
minLengthms.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
minLengthms.setPrefWidth(130);
//minLengthms.setPrefWidth(130);
maxLengthms=new PamSpinner<Double>(0.00, 1.00, 0.22,0.01);
maxLengthms.setEditable(true);
maxLengthms.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
maxLengthms.setPrefWidth(130);
//maxLengthms.setPrefWidth(130);
PamHBox clickLengthHolder2=new PamHBox();
@ -752,9 +769,9 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
*/
private class FrequencySearchBlock extends SweepBox {
private CheckBox peakFreqCheckBox;
private CheckBox peakWidthCheckBox;
private CheckBox meanFreqCheckBox;
private PamToggleSwitch peakFreqCheckBox;
private PamToggleSwitch peakWidthCheckBox;
private PamToggleSwitch meanFreqCheckBox;
/**
@ -767,7 +784,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
private FreqBandPane meanFreq;
FrequencySearchBlock() {
super("Peak and Mean Frequency", false);
super("Peak and Mean Frequency", true);
this.getHolderPane().setCenter(createFreqSearchPane());
}
@ -796,8 +813,8 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
//peak frequency
peakFreqCheckBox=new CheckBox("Enable");
peakFreqCheckBox.setOnAction((action)->{
peakFreqCheckBox=new PamToggleSwitch("");
peakFreqCheckBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
peakFreqPane.setDisableFreqPane(!peakWidthCheckBox.isSelected());
});
@ -811,8 +828,8 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
//peak width
peakWidthCheckBox=new CheckBox("Enable");
peakWidthCheckBox.setOnAction((action)->{
peakWidthCheckBox=new PamToggleSwitch("");
peakWidthCheckBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
//peakWidthPane.setDisable(!peakWidthCheckBox.isSelected());
peakWidthPane.setDisableFreqPane(!peakWidthCheckBox.isSelected());
threshold.setDisable(!peakWidthCheckBox.isSelected());
@ -838,8 +855,8 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
//mean frequency
meanFreqCheckBox=new CheckBox("Enable");
meanFreqCheckBox.setOnAction((action)->{
meanFreqCheckBox=new PamToggleSwitch("");
meanFreqCheckBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
meanFreq.setDisableFreqPane(!peakWidthCheckBox.isSelected());
});

View File

@ -5,6 +5,7 @@ import java.util.List;
import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
/**
* Holds some basic IDI info on the click train.
@ -47,7 +48,7 @@ public class IDIInfo {
lastNumber = dataUnits.size();
if (dataUnits.size()<3) {
System.out.println("CTDataUnit: Cannot calculate IDIInfo for less than three data units");
Debug.out.println("CTDataUnit: Cannot calculate IDIInfo for less than three data units");
return;
}

View File

@ -31,7 +31,6 @@ public class SimpleCTClassification implements CTClassification {
@Override
public String getSummaryString() {
// TODO Auto-generated method stub
return "SimpleClssf: SpeciesID: " + speciesID + " ClassifierType: " + classifierType;
}

View File

@ -1,8 +1,8 @@
package clickTrainDetector.classification.bearingClassifier;
import org.renjin.gcc.runtime.Debug;
import PamUtils.PamArrayUtils;
import PamguardMVC.debug.Debug;
import clickTrainDetector.CTDataUnit;
import clickTrainDetector.ClickTrainControl;
import clickTrainDetector.classification.CTClassification;
@ -95,7 +95,7 @@ public class BearingClassifier implements CTClassifier {
if (nullcount>clickTrain.getSubDetectionsCount()-4) {
//less than three data units with loc results
Debug.println("The bearing classifier has a null count: ");
Debug.out.println("The bearing classifier has a null count: ");
return new BearingClassification(CTClassifier.NOSPECIES, Double.NaN, Double.NaN, Double.NaN);
}
@ -111,7 +111,7 @@ public class BearingClassifier implements CTClassifier {
double medianBearingD = PamArrayUtils.median(bearingDiff);
double stdBearingD = PamArrayUtils.std(bearingDiff);
Debug.println("Bearing classifier: No. Detections: " + clickTrain.getSubDetectionsCount() + " medianBearing: " + medianBearingD);
Debug.out.println("Bearing classifier: No. Detections: " + clickTrain.getSubDetectionsCount() + " medianBearing: " + medianBearingD);
int speciesID = CTClassifier.NOSPECIES;
boolean passed= true;
@ -120,31 +120,31 @@ public class BearingClassifier implements CTClassifier {
//is the minimum and maximum bearing in range...
if ((min>=bearingClssfrParams.bearingLimMin && min<=bearingClssfrParams.bearingLimMax) ||
(max>=bearingClssfrParams.bearingLimMin && max<=bearingClssfrParams.bearingLimMax)) {
Debug.println("Passed on min max bearing");
Debug.out.println("Passed on min max bearing");
}
else passed =false;
//mean bearing derivative
if (bearingClssfrParams.useMean && meanBearingD>=bearingClssfrParams.minMeanBearingD
&& meanBearingD<=bearingClssfrParams.maxMeanBearingD) {
Debug.println("Passed on mean bearing");
Debug.out.println("Passed on mean bearing");
}
else if (bearingClssfrParams.useMean) passed=false;
//median bearing derivative
Debug.println("Median Bearing: " + Math.toDegrees(medianBearingD) +
Debug.out.println("Median Bearing: " + Math.toDegrees(medianBearingD) +
" minlim: " + Math.toDegrees(bearingClssfrParams.minMedianBearingD)+
" maxlim: " + Math.toDegrees(bearingClssfrParams.maxMedianBearingD));
if (bearingClssfrParams.useMedian && medianBearingD>=bearingClssfrParams.minMedianBearingD
&& medianBearingD<=bearingClssfrParams.maxMedianBearingD) {
Debug.println("Passed on median bearing");
Debug.out.println("Passed on median bearing");
}
else if (bearingClssfrParams.useMedian) passed = false;
//standard deviation derivative
if (bearingClssfrParams.useStD && stdBearingD>=bearingClssfrParams.minStdBearingD
&& stdBearingD<=bearingClssfrParams.maxStdBearingD) {
Debug.println("Passed on std bearing");
Debug.out.println("Passed on std bearing");
}
else if (bearingClssfrParams.useStD) passed= false;
@ -152,7 +152,7 @@ public class BearingClassifier implements CTClassifier {
speciesID = this.bearingClssfrParams.speciesFlag;
}
Debug.println("SPECIESID!! " + speciesID);
Debug.out.println("SPECIESID!! " + speciesID);
return new BearingClassification(speciesID, meanBearingD, medianBearingD, stdBearingD);

View File

@ -70,11 +70,13 @@ public class MHTGarbageBot {
double maxICI = mhtKernel.getMHTParams().maxCoast * mhtKernel.getMHTChi2Provider().getChi2Params().maxICI;
//check the current set of click train possible ICI's
//Debug.out.println("MHTGARBAGEBOT: maxICI " + maxICI + " " + iciPrev);
//we have reached the hard limit. Save click trains, wipe the detector and start again.
if (mhtKernel.getKCount()>mhtKernel.getMHTParams().nPruneBackStart && (iciPrev>maxICI || mhtKernel.getKCount()>DETECTION_HARD_LIMIT)) {
// Debug.out.println("MHTGarbageBot: KERNEL HARD LIMIT");
//Debug.out.println("MHTGARBAGEBOT: KERNEL HARD LIMIT");
//check whether the next click has a gap so big that all click trains should be restarted
//grab tracks
mhtKernel.confirmRemainingTracks();

View File

@ -158,10 +158,10 @@ public class MHTKernel<T> {
if (verbosity>0) {
Debug.out.println("Possiblity matrix size is " + possibleTracks.size() + " x " + kcount );
}
// for (int i=0; i<possibleTracks.size(); i++) {
// System.out.println("Pos " + i + " chi^2 "+ possibleTracks.get(i).chi2Track +
// " " + printBitSet(possibleTracks.get(i).trackBitSet) );
// }
// for (int i=0; i<possibleTracks.size(); i++) {
// System.out.println("Pos " + i + " chi^2 "+ possibleTracks.get(i).chi2Track.getChi2() +
// " " + MHTKernel.bitSetString(possibleTracks.get(i).trackBitSet,kcount));
// }
//prune the probability matrix.
pruneProbMatrix(false);
@ -412,6 +412,7 @@ public class MHTKernel<T> {
testBranch = newPossibleTracks.get(j);
testBitSet=testBranch.trackBitSet.get(0, kcount-(pruneback));
//now test whether the current and test branch are the same.
if (testBitSet.equals(currentBitSet)) {
indexConfirm[j]=true;
@ -423,6 +424,7 @@ public class MHTKernel<T> {
indexRemove[j]=true;
}
}
}
//long time2a=System.currentTimeMillis();
@ -437,9 +439,11 @@ public class MHTKernel<T> {
if (nCoasts>=this.mHTParams.maxCoast || confirmAll || currentBranch.flag==TrackBitSet.JUNK_TRACK) {
//the branch needs to be confirmed.
// System.out.println(i + " DONE: "+ String.format("%.3f ", possibleTracks.get(i).chi2Track.getChi2())+
// " " + String.format("%d ", possibleTracks.get(i).chi2Track.getNCoasts())
// + MHTKernel.bitSetString(possibleTracks.get(i).trackBitSet, kcount));
// System.out.println(i + " DONE: " + (nCoasts >= this.mHTParams.maxCoast) + " " + confirmAll + " "
// + (currentBranch.flag == TrackBitSet.JUNK_TRACK) + " "
// + String.format("%.3f ", currentBranch.chi2Track.getChi2()) + " "
// + String.format("%d ", currentBranch.chi2Track.getNCoasts())
// + MHTKernel.bitSetString(currentBranch.trackBitSet, kcount));
/**
* 27/02/2020
@ -460,7 +464,7 @@ public class MHTKernel<T> {
//add confirmed track
confirmedTracks.add(currentBranch);
//// //if a branch is confirmed then all the tracks which include it's clicks must also be removed.
//// //test the testBranch against all other branches. TODO - Is this the most efficient code -could add if statements to above loop?
for (int j=0; j<newPossibleTracks.size(); j++) {
@ -471,6 +475,7 @@ public class MHTKernel<T> {
indexRemove[j]=true;
}
}
}
else {
//save as an active track.
@ -678,7 +683,7 @@ public class MHTKernel<T> {
/**
*
* Set a new reference index and junk all data before that index. This can be
* useful for long data sets to save memory once all click trains in preceeding
* useful for long data sets to save memory once all click trains in preceding
* data units have been detecteded. Note that the function deletes the currently
* confirmed tracks. These should be extracted beforehand;
*

View File

@ -5,6 +5,7 @@ import java.util.BitSet;
import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
import clickTrainDetector.clickTrainAlgorithms.CTAlgorithmInfo;
import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.ElectricalNoiseFilter;
import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.SimpleElectricalNoiseFilter;
@ -225,16 +226,17 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
getIDIManager().setForceCalc(true);
this.lastIDIData = getIDIManager().getIDIStruct(bitSet);
//System.out.println("Time diff: " + lastIDIData.timeDiff + " " + lastIDIData.medianIDI);
nCoasts=(int) Math.floor(lastIDIData.timeDiff/Math.abs(lastIDIData.medianIDI));
}
else if (bitcount==1) {
//this stops a single units being stuck in the back of the probability matrix.
nCoasts = (int) Math.floor((newdataUnit.getTimeMilliseconds()/1000.
-getIDIManager().getLastTime(bitSet)/this.getChi2Params().maxICI));
nCoasts = (int) Math.floor(((newdataUnit.getTimeMilliseconds()-getIDIManager().getFirstDataUnit().getTimeMilliseconds())/1000.
-getIDIManager().getLastTime(bitSet))/this.getChi2Params().maxICI);
}
//System.out.println("nCoasts: " + nCoasts);
return nCoasts;
}
@ -332,6 +334,8 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
double totalTracktime = PamArrayUtils.sum(lastIDIData.idiSeries);
//System.out.println("Total track time: " + totalTracktime);
/**
* Add a nudge towards longer tracks (remember to cast to double when dividing). Note that
* kcount coefficient is meaningless because all tracks are multiplied by it and x^2 is only used
@ -341,7 +345,7 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
//19/03/2020 - fixed a bug; Was multiplying instead of dividing - as such long tracks were being
//discriminated against causing fragmentation...ooops
chi2=chi2/Math.pow(totalTracktime/getIDIManager().getTotalTime(),getChi2Params().longTrackExponent);
//chi2=chi2/Math.pow(bitSet.cardinality(),getChi2Params().longTrackExponent);
}
@ -374,6 +378,8 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
//All done. Set the values.
//set the chi2 values.
//long time3=System.nanoTime();
//Debug.out.println("Track chi2: " + chi2 + " " + bitcount );
return chi2;
}

View File

@ -2,6 +2,9 @@ package clickTrainDetector.clickTrainAlgorithms.mht.mhtvar;
import PamguardMVC.PamDataUnit;
import clickTrainDetector.clickTrainAlgorithms.mht.StandardMHTChi2Params;
import clickTrainDetector.layout.mht.AmplitudeMHTVarPane;
import clickTrainDetector.layout.mht.MHTVarSettingsPane;
/**
* Chi^2 value for dB amplitude of tracks. Measures the chnage in track delta between
@ -13,9 +16,14 @@ import PamguardMVC.PamDataUnit;
@SuppressWarnings("rawtypes")
public class AmplitudeChi2 extends SimpleChi2VarDelta {
private double lastDiff;
private AmplitudeChi2Params amplitudeParams;
public AmplitudeChi2() {
super();
super.setSimpleChiVarParams(defaultSettings());
super.setSimpleChiVarParams(amplitudeParams = (AmplitudeChi2Params) defaultSettings());
}
/**
@ -23,7 +31,7 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
* @return
*/
private SimpleChi2VarParams defaultSettings() {
SimpleChi2VarParams simpleChiVarParams = new SimpleChi2VarParams(getName(), getUnits());
AmplitudeChi2Params simpleChiVarParams = new AmplitudeChi2Params(getName(), getUnits());
//simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100};
simpleChiVarParams.error=30;
simpleChiVarParams.minError=1;
@ -36,13 +44,15 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
return "Amplitude";
}
@Override
public double getDiffValue(PamDataUnit pamDataUnit0, PamDataUnit pamDataUnit1) {
//System.out.println("DB: " + pamDataUnit0.getAmplitudeDB());
//made this abs so it can deal with increasing then decreasing click trains. i.e.
//the click trian is not penalised if it gradually increasing then starts to gradually decrease
//in amplitude.
return Math.abs(pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB());
this.lastDiff = Math.abs(pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB());
return lastDiff;
}
@Override
@ -50,6 +60,28 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
//just a simple static error coefficient.
return super.getError();
}
@Override
public double calcDeltaChi2(double lastDelta, double newDelta, double timeDiff) {
double chi2 = super.calcDeltaChi2(lastDelta, newDelta, timeDiff);
/**
* There was a problem here with using the delta instead of the absolute difference between amplitudes.
* When using the delta there could be a slow change of amplitude gradient which could lead to giant
* changes in absolute amplitude. By ensuring this is the absolute
* value between bearings (lastdiff) then the bearingJump threshold works as it should.
*/
//System.out.println("Amplitude: " + amplitudeParams.ampJumpEnable + " " + lastDiff + " " + amplitudeParams.maxAmpJump);
if (lastDiff>amplitudeParams.maxAmpJump && amplitudeParams.ampJumpEnable ) {
chi2=chi2+StandardMHTChi2Params.JUNK_TRACK_PENALTY;
}
return chi2;
}
@Override
@ -57,6 +89,27 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
return "dB";
}
@Override
public void setSimpleChiVarParams(SimpleChi2VarParams params) {
if (params==null) amplitudeParams = new AmplitudeChi2Params(getName(), getUnits()); //backwards compatibility
else this.amplitudeParams = (AmplitudeChi2Params) params; ;
super.setSimpleChiVarParams(params);
//save a reference to params so we don;t have to keep casting.
}
@Override
public void setSettingsObject(Object object) {
this.setSimpleChiVarParams((AmplitudeChi2Params) object);
}
@Override
public MHTVarSettingsPane<SimpleChi2VarParams> getSettingsPane() {
if (this.settingsPane==null) this.settingsPane= new AmplitudeMHTVarPane(getSimpleChiVarParams(), new ResultConverter());
settingsPane.setParams(getSimpleChiVarParams());
return settingsPane;
}
}

View File

@ -0,0 +1,46 @@
package clickTrainDetector.clickTrainAlgorithms.mht.mhtvar;
import PamModel.parametermanager.ManagedParameters;
public class AmplitudeChi2Params extends SimpleChi2VarParams implements ManagedParameters {
public AmplitudeChi2Params(String name, String unitString, double error, double minError, double errorScaleValue) {
super(name, unitString, error, minError, errorScaleValue);
// TODO Auto-generated constructor stub
}
public AmplitudeChi2Params(String name, String unitString, double error, double minError) {
super(name, unitString, error, minError);
// TODO Auto-generated constructor stub
}
public AmplitudeChi2Params(String name, String unitString) {
super(name, unitString);
// TODO Auto-generated constructor stub
}
public AmplitudeChi2Params(String name) {
super(name);
}
public AmplitudeChi2Params(SimpleChi2VarParams params) {
this(params.name, params.getUnits(), params.error, params.minError, params.errorScaleValue);
}
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Whether the bearing jump is used.
*/
public boolean ampJumpEnable = true;
/**
* The maximum allowed bearing bearing jump in a click train in RADIANS
*/
public double maxAmpJump = 10; //dB
}

View File

@ -141,7 +141,7 @@ public class BearingChi2Delta extends SimpleChi2VarDelta {
if (delta>bearingParams.maxBearingJump) {
//System.out.println("Hello!!!! Reverse Bearing");
chi2=chi2*StandardMHTChi2Params.JUNK_TRACK_PENALTY;
chi2=chi2+StandardMHTChi2Params.JUNK_TRACK_PENALTY;
}
}

View File

@ -536,6 +536,10 @@ public class IDIManager {
return (this.lastDetection.getTimeMilliseconds()- this.firstDetection.getTimeMilliseconds())/1000.;
}
public PamDataUnit getFirstDataUnit() {
return this.firstDetection;
}

View File

@ -16,7 +16,6 @@ public class LengthChi2 extends SimpleChi2Var {
@Override
public String getName() {
// TODO Auto-generated method stub
return "Click Length";
}
@ -44,7 +43,7 @@ public class LengthChi2 extends SimpleChi2Var {
//simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100};
simpleChiVarParams.error=0.2;
simpleChiVarParams.minError=0.002;
simpleChiVarParams.errorScaleValue = SimpleChi2VarParams.SCALE_FACTOR_ICI;
simpleChiVarParams.errorScaleValue = SimpleChi2VarParams.SCALE_FACTOR_ICI*10;
return simpleChiVarParams;
}

View File

@ -288,7 +288,7 @@ public class CTDataSelectPanel implements PamDialogPanel {
}
// System.out.println("No. count: " + count);
currentParams.classifier = new int[count];
currentParams.classifier = new int[count];
ArrayList<CTClassifier> classifiers = ctDataSelector.getClickControl().getClassifierManager().getCurrentClassifiers();
int used = 0;
for (int i=0; i<classifierCheckBoxes.length; i++) {

View File

@ -28,7 +28,7 @@ public class AdvMHTVarPane extends DynamicSettingsPane<SimpleChi2VarParams> {
/**
* Default divisor of error for min error.
*/
private static final Double ERROR_DIVISOR = 10000.0;
private static final Double ERROR_DIVISOR = 100.0;
/**
* The main pane.

View File

@ -0,0 +1,97 @@
package clickTrainDetector.layout.mht;
import org.controlsfx.control.ToggleSwitch;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.AmplitudeChi2Params;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.IDIChi2Params;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.ResultConverter;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.SimpleChi2VarParams;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import pamViewFX.fxNodes.PamSpinner;
public class AmplitudeChi2AdvPane extends AdvMHTVarPane {
private PamSpinner<Double> ampJumpSpinner;
private ToggleSwitch ampEnaleSwitch;
public AmplitudeChi2AdvPane(SimpleChi2VarParams simpleChi2Var2, ResultConverter resultConverter) {
super(simpleChi2Var2, resultConverter);
}
@Override
protected GridPane createAdvPane() {
GridPane gridPane = (GridPane) super.createAdvPane();
int gridY=3;
gridPane.add(ampEnaleSwitch = new ToggleSwitch("Max jump"), 0, gridY);
ampEnaleSwitch.selectedProperty().addListener((obsVal, newVal, oldVal)->{
ampJumpSpinner.setDisable(!ampEnaleSwitch.isSelected());
});
ampJumpSpinner = new PamSpinner<Double>(0.,Double.MAX_VALUE,0.,1.0);
ampJumpSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
ampJumpSpinner.setPrefWidth(90);
ampJumpSpinner.valueProperty().addListener((obs,oldVal,newVal)->{
notifySettingsListeners();
});
gridPane.add(ampJumpSpinner, 1, gridY);
gridPane.add(new Label("dB"), 2, gridY);
ampJumpSpinner.setEditable(true);
//create tool tip
Tooltip errorCoeffTip = new Tooltip(
"The minimum Amplitude defines the maximum decibel jump between two detection allowed in a click train"
+ "If an IDI below this minimum occurs in a click train it will incur"
+ "a large chi^2 penalty and so the click train is unlikely to be kept"
+ "in the hypothesis mix.");
errorCoeffTip.setWrapText(true);
errorCoeffTip.setPrefWidth(200);
ampEnaleSwitch.setTooltip(errorCoeffTip);
ampJumpSpinner.setTooltip(errorCoeffTip);
ampJumpSpinner.setDisable(!ampEnaleSwitch.isSelected());
return gridPane;
}
@Override
public AmplitudeChi2Params getParams(SimpleChi2VarParams currParams) {
System.out.println("Get params: AMPLITUDE");
AmplitudeChi2Params newParams = new AmplitudeChi2Params(super.getParams(currParams));
newParams.maxAmpJump = ampJumpSpinner.getValue();
newParams.ampJumpEnable = ampEnaleSwitch.isSelected();
return newParams;
}
@Override
public void setParams(SimpleChi2VarParams currParams) {
AmplitudeChi2Params newParams;
if (currParams instanceof AmplitudeChi2Params) {
newParams = (AmplitudeChi2Params) currParams;
}
else {
newParams = new AmplitudeChi2Params(currParams);
}
super.setParams(newParams);
ampJumpSpinner.setDisable(!ampEnaleSwitch.isSelected());
ampJumpSpinner.getValueFactory().setValue(newParams.maxAmpJump);
ampEnaleSwitch.setSelected(newParams.ampJumpEnable);
}
}

View File

@ -0,0 +1,22 @@
package clickTrainDetector.layout.mht;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.ResultConverter;
import clickTrainDetector.clickTrainAlgorithms.mht.mhtvar.SimpleChi2VarParams;
public class AmplitudeMHTVarPane extends SimpleMHTVarPane {
public AmplitudeMHTVarPane(SimpleChi2VarParams simpleChi2Var, ResultConverter resultsConverter) {
super(simpleChi2Var, resultsConverter);
// TODO Auto-generated constructor stub
}
/**
* Create the advanced settings pane.
* @return the advanced settings pane.
*/
@Override
public AdvMHTVarPane createAdvMHTVarPane(SimpleChi2VarParams simpleChi2VarParams, ResultConverter resultConverter) {
return new AmplitudeChi2AdvPane(simpleChi2VarParams, resultConverter);
}
}

View File

@ -8,7 +8,6 @@ public class BearingMHTVarPane extends SimpleMHTVarPane {
public BearingMHTVarPane(SimpleChi2VarParams simpleChi2Var, ResultConverter resultsConverter) {
super(simpleChi2Var, resultsConverter);
// TODO Auto-generated constructor stub
}
/**

View File

@ -86,11 +86,11 @@ public class CorrelationAdvMHTPane extends AdvMHTVarPane {
CorrelationChi2Params newParams = new CorrelationChi2Params(super.getParams(currParams));
System.out.println("GETPARAMS:fftFilterParams_OLD HIGHPASS: " + newParams.fftFilterParams.highPassFreq);
//System.out.println("GETPARAMS:fftFilterParams_OLD HIGHPASS: " + newParams.fftFilterParams.highPassFreq);
newParams.fftFilterParams=filterPane.getParams(newParams.fftFilterParams);
System.out.println("GETPARAMS:fftFilterParams_NEW HIGHPASS: " + newParams.fftFilterParams.highPassFreq);
//System.out.println("GETPARAMS:fftFilterParams_NEW HIGHPASS: " + newParams.fftFilterParams.highPassFreq);
newParams.useFilter=this.useFilterBox.isSelected();

View File

@ -42,7 +42,8 @@ public class ICIChi2AdvPane extends AdvMHTVarPane {
});
gridPane.add(minICISpinner, 1, gridY);
gridPane.add(new Label("ms"), 2, gridY);
minICISpinner.setEditable(true);
//create tool tip
Tooltip errorCoeffTip = new Tooltip( "The minimum IDI defines a minimum IDI allowed in a click train \n"
+ "If an IDI below this minimum occurs in a click train it will incur\n"

View File

@ -98,7 +98,7 @@ public class ClickTrainDetLogging extends SuperDetLogging {
//average spectrum
tableDef.addTableItem(avrg_Spectrum_max = new PamTableItem("avrg_spectrum_max", Types.DOUBLE));
tableDef.addTableItem(avrg_Spectrum = new PamTableItem("avrg_spectrum", Types.CHAR, 8*DEFAULT_SPECTRUM_LEN));
tableDef.addTableItem(classifiers = new PamTableItem("classifiers", Types.CHAR, 4096));
tableDef.addTableItem(classifiers = new PamTableItem("classifiers", Types.CHAR, 8128));
//a species flag, this is entirely for user convenience and is NOT read back - the species flag
//is read from the JSON strings when reloading the data unit. If they end being different something has gone
@ -133,12 +133,15 @@ public class ClickTrainDetLogging extends SuperDetLogging {
String classificationData = getClassifierData(ctDataUnit);
// Debug.out.println("Classifier Save: " + classificationData);
System.out.println("Classifier Save: " + classificationData);
if (classificationData.length()>0) {
classifiers.setLength(classificationData.length());
//classifiers.setLength(classificationData.length());
classifiers.setValue(classificationData);
}
else {
classifiers.setValue(null);
}
if (ctDataUnit.getClassificationIndex()>=0) {
speciesFlag.setValue(ctDataUnit.getCtClassifications().
@ -279,7 +282,9 @@ public class ClickTrainDetLogging extends SuperDetLogging {
//set the classifications.
String classifiersData = classifiers.getStringValue();
//FIXME
//System.out.println(classifiersData);
if (classifiersData!=null && classifiersData.length()>0) {
String[] classifiersDatas = classifiersData.split(JSON_DELIMITER);
@ -299,8 +304,8 @@ public class ClickTrainDetLogging extends SuperDetLogging {
}
}
catch (Exception e) {
Debug.err.println("ClickTrainDetLogging: BAD JSON CLASSIFIER STRING: " + classifiersDatas[i]);
Debug.err.println(classifiersData);
System.err.println("ClickTrainDetLogging: BAD JSON CLASSIFIER STRING: " + classifiersDatas[i]);
System.err.println(classifiersData);
e.printStackTrace();
}
}

View File

@ -44,7 +44,7 @@ public class CTProcessDialog extends OLProcessDialog {
getTaskCheckBoxs()[i].setEnabled(aTask.canRun() && nr);
//added extra but here so that only one tasks can be run at a time- may change
System.out.println("A task can run: !!" + aTask.canRun() + " " + aTask.getDataBlock());
//System.out.println("A task can run: !!" + aTask.canRun() + " " + aTask.getDataBlock());
//if more tasks are added to the click train detector.
if (aTask.canRun() == false || (aTask!=task && task!=null)) {
getTaskCheckBoxs()[i].setSelected(false);

View File

@ -14,7 +14,8 @@ import pamViewFX.fxNodes.connectionPane.StandardConnectionNode;
import pamViewFX.fxNodes.connectionPane.structures.ExtensionSocketStructure;
/**
* PAM extension structure
* PAM extension structure. The extension structure allows one parent to be split into multiple
* children primarily a way to neaten up a data model display.
*
* @author Jamie Macaulay
*
@ -22,10 +23,11 @@ import pamViewFX.fxNodes.connectionPane.structures.ExtensionSocketStructure;
public class PamExtensionStructure extends ExtensionSocketStructure implements PAMConnectionNode {
private PamStructureParams groupStructureParams;
public PamExtensionStructure(ConnectionPane connectionPane) {
super(connectionPane);
groupStructureParams = new PamStructureParams(this);
final ContextMenu contextMenu = new ContextMenu();
@ -34,13 +36,18 @@ public class PamExtensionStructure extends ExtensionSocketStructure implements P
paste.setOnAction((action)->{
removeStructure();
});
this.getConnectionNodeBody().setOnMousePressed((event)->{
//this is a bit of a hack. We can't add this to the main connection body because
//it is already used for dragging. So instead at to the circle within the connection group. The event is registered
//by both the group and the circle.
circle.setOnMousePressed((event)->{
if (event.isSecondaryButtonDown()) {
contextMenu.show(this.getConnectionNodeBody(), event.getScreenX(), event.getScreenY());
}
});
}

View File

@ -41,6 +41,7 @@ public class ImportTemplateCSV implements TemplateImport {
//the first row is the waveform
double[] waveform = new double[data.get(0).size()];
for (int i=0; i<waveform.length; i++) {
//System.out.println("i: " + i + " : " + data.get(0).get(i));
waveform[i]=data.get(0).get(i);
}

View File

@ -71,7 +71,7 @@ public abstract class OfflineTask<T extends PamDataUnit> {
*/
PamControlledUnit parentControl = getTaskControlledUnit();
if (parentControl == null) {
System.out.printf("Offline task %d with datablock %s is not associated with a PAMGuard module\n", getName(), parentDataBlock);
System.out.printf("Offline task %s with datablock %s is not associated with a PAMGuard module\n", getName(), parentDataBlock==null ? "null": parentDataBlock.getDataName());
}
else {
OfflineTaskManager.getManager().registerTask(this);

View File

@ -187,11 +187,16 @@ public class TaskLogging {
String modType = moduleType.getDeblankedStringValue();
String modName = moduleName.getDeblankedStringValue();
String tskName = taskName.getDeblankedStringValue();
long dStart = SQLTypes.millisFromTimeStamp(dataStart.getValue());
long dEnd = SQLTypes.millisFromTimeStamp(dataEnd.getValue());
long procEnd = SQLTypes.millisFromTimeStamp(runEnd.getValue());
Long dEnd = null, dStart = null, procEnd = null;
dStart = SQLTypes.millisFromTimeStamp(dataStart.getValue());
dEnd = SQLTypes.millisFromTimeStamp(dataEnd.getValue());
procEnd = SQLTypes.millisFromTimeStamp(runEnd.getValue());
if (dStart==null && dEnd==null && procEnd==null) return null;
String compStatus = completionCode.getDeblankedStringValue();
TaskStatus status = null;
if (compStatus==null) return null;
try {
status = TaskStatus.valueOf(TaskStatus.class, compStatus);
}
@ -199,8 +204,13 @@ public class TaskLogging {
System.out.printf("Uknown completion code \"%s\" for task %s ended at %s\n", compStatus, tskName, PamCalendar.formatDateTime(dEnd));
}
String taskNote = note.getDeblankedStringValue();
OldTaskData monData = new OldTaskData(status, dStart, dEnd, utc, procEnd, taskNote);
return monData;
if (dStart!=null && dEnd!=null && procEnd!=null) {
OldTaskData monData = new OldTaskData(status, dStart, dEnd, utc, procEnd, taskNote);
return monData;
}
else {
return null;
}
}
/**

View File

@ -48,6 +48,11 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
*/
private PamTabPane mainTabPane;
/**
* The preferred width of the side pane.
*/
public static final double SIDE_PANE_PREF_WIDTH = 250;
// /**
// * Icon for menu
// */
@ -157,7 +162,9 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
/**create right hiding pane**/
sidePaneContent=new PamVBox();
sidePaneContent.setPrefWidth(250);
sidePaneContent.setPrefWidth(SIDE_PANE_PREF_WIDTH);
sidePaneContent.setPadding(new Insets(25,5,5,5)); //give quite abit of spacing at the top so that there is room for close button
sidePaneContent.setMinWidth(0);
hidingSidePane=new HidingPane(Side.RIGHT, sidePaneContent, this, false);
hidingSidePane.showHidePane(false);
@ -176,7 +183,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
// showButton.prefWidthProperty().addListener((listener)->{
// mainTabPane.layout(); //Don't need this
// });
hidingSidePane.getTimeLineShow().setOnFinished((value)->{
showButtonRight.setPrefWidth(1);
showButtonRight.setVisible(false);
@ -187,6 +194,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
showButtonRight.setPrefWidth(40);
showButtonRight.setVisible(true);
hidingSidePane.getHideButton().setVisible(false);
//sidePaneContent.setVisible(false);
layout.layout();
});

View File

@ -24,4 +24,5 @@ public class PamHBox extends HBox {
// TODO Auto-generated constructor stub
}
}

View File

@ -13,41 +13,55 @@ import javafx.util.StringConverter;
*/
public class PamSpinner<T> extends Spinner<T>{
/**
* Default widths are way off in JavaFX for spinners.
*/
// private static final double PAMSPINNER_PREF_WIDTH = USE_COMPUTED_SIZE;
private static final double PAMSPINNER_PREF_WIDTH = 100;
public PamSpinner() {
super();
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
// TODO Auto-generated constructor stub
}
public PamSpinner(double min, double max, double initialValue, double amountToStepBy) {
super(min, max, initialValue, amountToStepBy);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter();
}
public PamSpinner(double min, double max, double initialValue) {
super(min, max, initialValue);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter();
}
public PamSpinner(int min, int max, int initialValue, int amountToStepBy) {
super(min, max, initialValue, amountToStepBy);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter();
}
public PamSpinner(int min, int max, int initialValue) {
super(min, max, initialValue);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter();
}
public PamSpinner(ObservableList<T> arg0) {
super(arg0);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter();
}
public PamSpinner(SpinnerValueFactory<T> arg0) {
super(arg0);
addDefocusConverter();
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
}
/**

View File

@ -34,6 +34,8 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
* The colour of the extension socket body
*/
private static Color bodyColour = Color.DODGERBLUE;
protected Shape circle;
/**
* Extension structure construction.
@ -69,7 +71,7 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
@Override
public ConnectionNodeBody createNodeBody() {
Circle circle = new Circle(DEFAULT_BODY_WIDTH/2,DEFAULT_BODY_WIDTH/2, DEFAULT_BODY_WIDTH/2);
circle = new Circle(DEFAULT_BODY_WIDTH/2,DEFAULT_BODY_WIDTH/2, DEFAULT_BODY_WIDTH/2);
circle.setFill(bodyColour);
ConnectionNodeBody connectionNodeBody = new ConnectionNodeBody(this);
@ -79,7 +81,6 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
connectionNodeBody.getChildren().add(circle);
connectionNodeBody.setPrefHeight(DEFAULT_BODY_WIDTH);
connectionNodeBody.setPrefWidth(DEFAULT_BODY_WIDTH);

View File

@ -0,0 +1,132 @@
package pamViewFX.fxNodes.flipPane;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
/**
* Flip pane which has is supposed to be used for advanced settings. The front
* of the pane is to be used for standard settings and the pane can then flip to
* the back to show advanced settings. A back button is included in the back
* pane which can be used to flip the pane back to the standard settings. The
* front pane needs a control that calls flipPane.toBack() to show the advanced
* pane.
*
* @author Jamie Macaulay
*
*/
public class PamFlipPane extends FlipPane {
public static final double FLIP_TIME =250; //milliseconds - the default is 700ms whihc is way too long.
private PamBorderPane advPane;
private PamBorderPane frontPane;
private Label advLabel;
private PamButton backButton;
public PamFlipPane() {
super();
this.advPane = createAdvSettingsPane();
this.getFront().getChildren().add(frontPane = new PamBorderPane());
this.getBack().getChildren().add(advPane);
this.setFlipTime(FLIP_TIME);
}
public PamFlipPane(Orientation FLIP_DIRECTION) {
super(FLIP_DIRECTION);
this.advPane = createAdvSettingsPane();
this.getFront().getChildren().add(frontPane = new PamBorderPane());
this.getBack().getChildren().add(advPane);
this.setFlipTime(FLIP_TIME);
}
/**
* Get the front pane.
* @return the front pane.
*/
public PamBorderPane getFrontPane() {
return frontPane;
}
/**
* Get the back pane.
* @return the back pane.
*/
public PamBorderPane getBackPane() {
return advPane;
}
/**
* Convenience duplicate of getBackPane().
* @return the back pane.
*/
public PamBorderPane getAdvPane() {
return advPane;
}
/**
* Create the advanced settings pane which can be accessed by DAQ panes if needed.
*/
private PamBorderPane createAdvSettingsPane() {
backButton = new PamButton();
backButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-chevron-left", Color.WHITE, PamGuiManagerFX.iconSize));
backButton.setOnAction((action)->{
// System.out.println("FLIP BACK TO FRONT");
this.flipToFront();
});
//backButton.setPrefWidth(150);
PamBorderPane advPane = new PamBorderPane();
advPane.setPadding(new Insets(5,5,5,5));
PamHBox buttonHolder = new PamHBox();
buttonHolder.setBackground(null);
//buttonHolder.setStyle("-fx-background-color: red;");
buttonHolder.setAlignment(Pos.CENTER_LEFT);
buttonHolder.getChildren().addAll(backButton, advLabel = new Label("Adv. Settings"));
advLabel.setAlignment(Pos.CENTER);
advLabel.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
PamGuiManagerFX.titleFont2style(advLabel);
advLabel.setAlignment(Pos.CENTER);
HBox.setHgrow(advLabel, Priority.ALWAYS);
advPane.setTop(buttonHolder);
return advPane;
}
public Label getAdvLabel() {
return advLabel;
}
public void setAdvLabel(Label advLabel) {
this.advLabel = advLabel;
}
public PamButton getBackButton() {
return backButton;
}
}

View File

@ -1,46 +1,93 @@
package pamViewFX.fxNodes.sliders.skin;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.Slider;
import javafx.scene.control.skin.SliderSkin;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
//import com.sun.javafx.scene.control.skin.SliderSkin;
public class PamSliderSkin extends SliderSkin {
/**
* Reference to the slider track.
*/
private Node track;
private Slider slider;
private Pane track;
private Slider slider;
private StackPane topBar;
private Pane thumb;
public PamSliderSkin(Slider slider) {
super(slider);
this.slider=slider;
track = slider.lookup(".track");
setTrackColor(Color.RED);
track = (Pane) slider.lookup(".track");
thumb = (Pane) slider.lookup(".thumb");
initTopBar();
setTrackColor(Color.RED);
}
/**
* Create the top bar.
*/
public void initTopBar(){
topBar=new StackPane();
//TODO-need to sort for horizontal
if (slider.getOrientation()==Orientation.VERTICAL){
topBar.layoutXProperty().bind(track.layoutXProperty());
}
else {
topBar.layoutYProperty().bind(track.layoutYProperty());
}
// topBar.setStyle("-fx-background-color: red;");
//topBar.setSty
getChildren().add(topBar);
thumb.toFront();
}
@Override
protected void layoutChildren(final double x, final double y,
final double w, final double h) {
super.layoutChildren(x, y, w, h);
double rangeStart;
if (track==null) return;
//now resize the top bar.
if (slider.getOrientation()==Orientation.VERTICAL){
rangeStart=thumb.getLayoutY()+thumb.getHeight();
topBar.layoutYProperty().setValue(0);
topBar.resize(track.getWidth(), rangeStart+1);
}
else {
rangeStart=thumb.getLayoutX()+thumb.getWidth();
topBar.layoutXProperty().setValue(0);
topBar.resize(rangeStart+1, track.getHeight());
}
};
public void setTrackColor(Color trackCol){
track = slider.lookup(".track");
// int r = (int) (trackCol.getRed() * 255);
// int g = (int) (trackCol.getGreen() * 255);
// int b = (int) (trackCol.getBlue() * 255);
// String str = String.format("#%02X%02X%02X;", r, g, b);
//28/03/2017 - had to change to css as adding to a scroll pane seemed ot override background.
track.setStyle("-fx-background-color: " + PamUtilsFX.color2Hex(trackCol));
track = (Pane) slider.lookup(".track");
thumb = (Pane) slider.lookup(".thumb");
// int r = (int) (trackCol.getRed() * 255);
// int g = (int) (trackCol.getGreen() * 255);
// int b = (int) (trackCol.getBlue() * 255);
// String str = String.format("#%02X%02X%02X;", r, g, b);
//28/03/2017 - had to change to css as adding to a scroll pane seemed ot override background.
if (topBar!=null) topBar.setStyle("-fx-background-color: " + PamUtilsFX.color2Hex(trackCol) + "; -fx-background-radius: " + 6 + "; -fx-border-radius: "
+ 6 + " ; -fx-border-color: none;");
//((Region) track).setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(2), Insets.EMPTY)));
}

View File

@ -15,6 +15,7 @@ import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.chart.NumberAxis;
@ -35,10 +36,10 @@ import PamController.SettingsPane;
public class FilterPaneFX extends SettingsPane<FilterParams> {
private String[] filterNames = { "None", "IIR Butterworth", "IIR Chebyshev",
"FIR Filter (Window Method)", "Arbitrary FIR Filter"};
/**
* Combo box for selecting filter types.
*/
@ -53,12 +54,12 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
* Text field for lower frequency
*/
private PamSpinner<Double> lowPass;
/**
* Spinner to allow user to change filter order.
*/
private PamSpinner<Integer> filterOrder;
/**
* Spinner to allow user to change filter order.
*/
@ -81,7 +82,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
private PamRadioButton logScale;
private PamRadioButton linScale;
/**
* Some default frequency values for the high and low pass frequency spinner.
*/
@ -106,12 +107,12 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
* Plot pane for the graph axis.
*/
private PamLineChart<Number, Number> plotLogChart;
/**
* Line chart without logarithmic frequency axis.
*/
private PamLineChart<Number, Number> plotLinChart;
/**
* Log axis for log chart
*/
@ -126,15 +127,28 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
* Ripple label
*/
private Label rippleLabel;
private PamBorderPane mainPane = new PamBorderPane();
public FilterPaneFX () {
super(null);
mainPane.setLeft(createFilterPane());
mainPane.setCenter(createBodeGraph());
}
private PamBorderPane mainPane = new PamBorderPane();
public FilterPaneFX () {
this(Orientation.HORIZONTAL);
}
public FilterPaneFX (Orientation orientaiton) {
super(null);
if (orientaiton == Orientation.HORIZONTAL) {
mainPane.setLeft(createFilterPane());
mainPane.setCenter(createBodeGraph());
}
else {
mainPane.setTop(createFilterPane());
mainPane.setBottom(createBodeGraph());
}
}
/**
* Create the filter pane. This contains controls to change filter types and shows a graph of the current filter.
* @return pane with controls to change filter params.
@ -142,14 +156,14 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
public Node createFilterPane(){
controlPane=new PamVBox();
controlPane.setSpacing(5);
//label title
Label title=new Label("Filter type");
PamGuiManagerFX.titleFont2style(title);
// title.setFont(PamGuiManagerFX.titleFontSize2);
// title.setFont(PamGuiManagerFX.titleFontSize2);
controlPane.getChildren().add(title);
//create combo box
filterTypes=new PamComboBox<String>();
for (int i=0; i<filterNames.length; i++){
@ -160,24 +174,24 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
updateBodeGraph();
enableControls();
});
filterTypes.setMaxWidth(Double.MAX_VALUE);
filterTypes.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(filterTypes, Priority.ALWAYS);
controlPane.getChildren().add(filterTypes);
//Radio buttons and frequency response
Label freqResponse=new Label("Frequency Response");
// freqResponse.setFont(PamGuiManagerFX.titleFontSize2);
// freqResponse.setFont(PamGuiManagerFX.titleFontSize2);
PamGuiManagerFX.titleFont2style(freqResponse);
controlPane.getChildren().add(freqResponse);
//radio buttons
final ToggleGroup group = new ToggleGroup();
// group.selectedToggleProperty().addListener((obs, old_val, new_val)-> {
// if (group.getSelectedToggle() != null) {
//
// }
// });
// group.selectedToggleProperty().addListener((obs, old_val, new_val)-> {
// if (group.getSelectedToggle() != null) {
//
// }
// });
PamVBox radioButtonBox=new PamVBox();
radioButtonBox.setSpacing(3);
@ -198,7 +212,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
updateBodeGraph();
});
radioButtonBox.getChildren().add(bandPassrb);
bandStoprb = new PamRadioButton("Band Stop");
bandStoprb.setToggleGroup(group);
bandStoprb.setOnAction((action)->{
@ -207,7 +221,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
updateBodeGraph();
});
radioButtonBox.getChildren().add(bandStoprb);
lowPassrb = new PamRadioButton("Low Pass");
lowPassrb.setToggleGroup(group);
lowPassrb.setOnAction((action)->{
@ -216,17 +230,17 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
updateBodeGraph();
});
radioButtonBox.getChildren().add(lowPassrb);
//create frequency text boxes
PamGridPane gridPaneFreq=new PamGridPane();
gridPaneFreq.setHgap(5);
gridPaneFreq.setVgap(5);
//lost of filter order sizes- anyone using >500 will be crazy anyway
// ObservableList<Double> freqList=FXCollections.observableArrayList();
// for (int i=0; i<defaultFrequencyVals.length; i++){
// freqList.add(defaultFrequencyVals[i]);
// }
// ObservableList<Double> freqList=FXCollections.observableArrayList();
// for (int i=0; i<defaultFrequencyVals.length; i++){
// freqList.add(defaultFrequencyVals[i]);
// }
highCut=new PamSpinner<Double>(10.,500000.,2000.,2000.);
highCut.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
@ -256,21 +270,21 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
gridPaneFreq.add(new Label("Low Pass"), 0, 1);
gridPaneFreq.add(lowPass, 1, 1);
gridPaneFreq.add(new Label("Hz"), 2, 1);
PamHBox filterSettings=new PamHBox(); //holds radio buttons and frquency text fields.
filterSettings.getChildren().addAll(radioButtonBox, gridPaneFreq);
filterSettings.setSpacing(15);
controlPane.getChildren().add(filterSettings);
//next create filter order settings
Label filterOrderLabel=new Label("Filter Order");
PamGuiManagerFX.titleFont2style(filterOrderLabel);
// filterOrderLabel.setFont(PamGuiManagerFX.titleFontSize2);
// filterOrderLabel.setFont(PamGuiManagerFX.titleFontSize2);
controlPane.getChildren().add(filterOrderLabel);
PamGridPane gridPaneOrder=new PamGridPane();
gridPaneOrder.setHgap(5);
gridPaneOrder.setVgap(5);
@ -296,14 +310,14 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
});
gridPaneOrder.add(rippleLabel=new Label("Pass Band Ripple"), 0,1);
gridPaneOrder.add( ripple, 1,1);
controlPane.getChildren().add(gridPaneOrder);
// TODO Auto-generated method stub
return controlPane;
}
/**
* Set correct filter type from filter type combo box selection.
*/
@ -363,17 +377,17 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
filterParams.filterBand == FilterBand.BANDSTOP ||
filterParams.filterBand == FilterBand.LOWPASS) {
if (filterParams.lowPassFreq > niquist) {
PamController.getInstance();
PamController.getInstance();
PamDialogFX.showWarning(PamController.getMainStage(), "Filter Settings", "The low pass cut off frequency is too high");
return null;
return null;
}
}
if (filterParams.filterBand == FilterBand.BANDPASS ||
filterParams.filterBand == FilterBand.BANDSTOP ||
filterParams.filterBand == FilterBand.HIGHPASS) {
if (filterParams.highPassFreq > niquist) {
PamDialogFX.showWarning(PamController.getMainStage(),"Filter Settings", "The high pass cut off frequency is too high");
return null;
PamDialogFX.showWarning(PamController.getMainStage(),"Filter Settings", "The high pass cut off frequency is too high");
return null;
}
}
@ -385,19 +399,19 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
return filterParams;
}
public void setSampleRate(float sampleRate) {
this.sampleRate = sampleRate;
filterMethod = FilterMethod.createFilterMethod(sampleRate, filterParams);
}
public Node createBodeGraph(){
pamBorderPane=new PamBorderPane();
//pamBorderPane.setPadding(new Insets(0, 0, 0, 10));
pamBorderPane.setPrefWidth(500);
final ToggleGroup group = new ToggleGroup();
logScale = new PamRadioButton("Log Scale");
logScale.setOnAction((action)->{
@ -409,22 +423,22 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
linScale.setOnAction((action)->{
setGraphLogAxis(!linScale.isSelected());
});
final PamHBox scalePane=new PamHBox();
scalePane.setPadding(new Insets(5));
scalePane.setSpacing(5);
scalePane.getChildren().addAll(linScale, logScale);
plotLogChart=createBodeChart(logarithmAxis=new LogarithmicAxis(10,50000));
plotLinChart=createBodeChart(new NumberAxis(0, 50000, 10000));
pamBorderPane.setTop(scalePane);
pamBorderPane.setCenter(plotLogChart);
return pamBorderPane;
}
/**
* Convenience function to stop code repitition. Creates a line chart fro pane with specified x axis.
* @param xAxis - x axis
@ -434,13 +448,13 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
PamLineChart<Number, Number> plotChart=new PamLineChart<Number, Number>(xAxis, new NumberAxis());
plotChart.setLegendVisible(false);
plotChart.setCreateSymbols(false);
plotChart.getXAxis().setLabel("Frequency (Hz)");
plotChart.getYAxis().setLabel("dB");
plotChart.getYAxis().setAutoRanging(false);
plotChart.getXAxis().setSide(Side.TOP);
/**
* HACK. Make sure the graph updates once the axis has a width.
*/
@ -459,7 +473,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
});
return plotChart;
}
@Override
public Node getContentNode() {
return mainPane;
@ -471,7 +485,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
setSettings();
}
/**
* Set controls to input params.
*/
@ -516,19 +530,19 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
}
// highCut.setText(String.format("%1.1f", filterParams.highPassFreq));
// highCut.setText(String.format("%1.1f", filterParams.highPassFreq));
highCut.getValueFactory().setValue(Double.valueOf(Float.valueOf(filterParams.highPassFreq).doubleValue()));
// lowCut.setText(String.format("%1.1f", filterParams.lowPassFreq));
// lowCut.setText(String.format("%1.1f", filterParams.lowPassFreq));
lowPass.getValueFactory().setValue(Double.valueOf(Float.valueOf(filterParams.lowPassFreq).doubleValue()));
filterOrder.getValueFactory().setValue(filterParams.filterOrder);
setRippleParam();
logScale.setSelected(filterParams.scaleType == FilterParams.SCALE_LOG);
linScale.setSelected(filterParams.scaleType == FilterParams.SCALE_LIN);
filterMethod = FilterMethod.createFilterMethod(sampleRate, filterParams);
//update control disable status
enableControls();
//update graph
@ -536,7 +550,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
setXAxisRange(10, sampleRate/2.);
}
void setRippleParam() {
int filtType = filterTypes.getSelectionModel().getSelectedIndex();
switch(filtType) {
@ -549,7 +563,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
break;
}
}
private void enableControls() {
int filterType = filterTypes.getSelectionModel().getSelectedIndex();
boolean haveFilter = filterType > 0;
@ -573,15 +587,15 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
break;
}
boolean isArb = filterType == 4;
// normalPanel.setVisible(isArb == false);
// arbPanel.setVisible(isArb);
// normalPanel.setVisible(isArb == false);
// arbPanel.setVisible(isArb);
}
@Override
public String getName() {
return "Filter Pane";
}
/**
* A VBox which holds all the main controls for the pane but not the graph. Can be used to add in custom controls such
* as a source level pane.
@ -590,15 +604,15 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
public PamVBox getControlPane() {
return controlPane;
}
/************Bode Graph************/
private int yScaleIndex = 0;
private double[] yScales = {-90, -60, -30};
/**
* Set the graph axis to a log or linear scale.
* @param log - true to set chart with frequency log scale.
@ -614,7 +628,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
//setYAxisRange(yScales[0],10);
updateBodeGraph();
}
/**
* Update the bode graph
*/
@ -629,7 +643,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
plotLinChart.getData().add(createFilterPoints((ValueAxis<Number>) plotLinChart.getXAxis()));
}
}
/**
* Set y axis of graphs
*/
@ -639,7 +653,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
((NumberAxis) plotLinChart.getXAxis()).setLowerBound(0);
((NumberAxis) plotLinChart.getXAxis()).setUpperBound(max);
}
//Set x axis of graphs.
private void setYAxisRange(double min, double max){
//System.out.println("Set y axis range: min "+min+" max "+max);
@ -647,13 +661,13 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
((NumberAxis) plotLinChart.getYAxis()).setUpperBound(max);
plotLinChart.getYAxis().requestLayout();
plotLinChart.getYAxis().requestAxisLayout();
((NumberAxis) plotLogChart.getYAxis()).setLowerBound(min);
((NumberAxis) plotLogChart.getYAxis()).setUpperBound(max);
plotLogChart.getYAxis().requestLayout();
plotLogChart.getYAxis().requestAxisLayout();
}
/**
* Get the scale type from the graph.
* @return
@ -666,7 +680,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
return FilterParams.SCALE_LIN;
}
}
/**
* Create a data series for a filter. The function bases the data points on the pixel length of the chart frequency axis. This
* is important because a log scale is used which would mess up if a data point was created at regular frequency, rather than pixel
@ -675,17 +689,17 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
* @return a data series to add to the line chart
*/
private Series<Number, Number> createFilterPoints(ValueAxis<Number> axis){
Series<Number, Number> series = new Series<Number, Number>();
/*
* It's on a log scale, so set up enough points to fill the plot on
* a log scale
*/
//total number of pixels on axis
// double pixels=Math.abs(axis.getDisplayPosition(axis.getLowerBound())-axis.getDisplayPosition(axis.getUpperBound()));
// double pixels=Math.abs(axis.getDisplayPosition(axis.getLowerBound())-axis.getDisplayPosition(axis.getUpperBound()));
double pixels=axis.getWidth();
int nPoints = (int) Math.max(pixels, 1024);
//System.out.println("Update bode graph WIDTH: "+ pixels+ " height: " +this.plotLogChart.getYAxis().getHeight()+ this.plotLogChart.getWidth());
double xScale = pixels / (double) nPoints;
@ -693,7 +707,7 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
double[] freqPoints = new double[nPoints];
double[] gainPoints = new double[nPoints];
double[] phasePoints = new double[nPoints];
int i=0;
while (i < freqPoints.length) {
freqPoints[i] = axis.getValueForDisplay(i*xScale).doubleValue();
@ -702,17 +716,17 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
/ filterMethod.getFilterGainConstant();
phasePoints[i] = filterMethod.getFilterPhase(
freqPoints[i] / sampleRate * 2 * Math.PI);
// System.out.println("freqPoints[i]: "+freqPoints[i] +" gainPoints[i] "+gainPoints[i]+
// " nPoints: "+nPoints+" xScale "+xScale+ " sampleRate: "+sampleRate + " pixels "+pixels);
// System.out.println("freqPoints[i]: "+freqPoints[i] +" gainPoints[i] "+gainPoints[i]+
// " nPoints: "+nPoints+" xScale "+xScale+ " sampleRate: "+sampleRate + " pixels "+pixels);
series.getData().add(new Data<Number, Number>(freqPoints[i], 20. * Math.log10(gainPoints[i])));
i++;
}
return series;
}
private void checkYScale() {
double yScale = 0;
if (plotLogChart.getYAxis() == null) return;

View File

@ -72,7 +72,7 @@ public class FreqBandPane extends PamGridPane {
if (after>sampleRate/2.) highPassFreq.getValueFactory().setValue(sampleRate/2.);
});
highPassFreq.setEditable(true);
highPassFreq.setPrefWidth(140);
//highPassFreq.setPrefWidth(140);
//highCut.setPrefColumnCount(6);
if (orientation==Orientation.VERTICAL){
@ -94,7 +94,7 @@ public class FreqBandPane extends PamGridPane {
});
lowPassFreq.setEditable(true);
lowPassFreq.setPrefWidth(140);
//lowPassFreq.setPrefWidth(140);
if (orientation==Orientation.VERTICAL){

View File

@ -183,6 +183,7 @@ public class SimpleFilterPaneFX extends DynamicSettingsPane<FFTFilterParams>{
@Override
public FFTFilterParams getParams(FFTFilterParams fftFilterParams) {
if (fftFilterParams==null) fftFilterParams=new FFTFilterParams();
fftFilterParams.filterBand = getBand();
try {
//if (fftFilterParams.filterBand != FilterBand.HIGHPASS) {

View File

@ -110,6 +110,9 @@ public class DLPredictionPane extends PamBorderPane implements TDSettingsPane {
private void layoutColourPanes(DLClassName[] classNames){
if (classNames==null) return;
//System.out.println("Class name map: " + dlPredictionPlotInfoFX.getDlControl().getDLParams().classNameMap);
ArrayList<PredictionColourPane> colourPanes = new ArrayList<PredictionColourPane>();

View File

@ -307,7 +307,13 @@ public class DLPredictionPlotInfoFX extends GenericLinePlotInfo {
@Override
public double[][] getDetData(PamDataUnit pamDataUnit) {
double[] data = PamArrayUtils.float2Double(((DLDataUnit) pamDataUnit).getPredicitionResult().getPrediction());
return new double[][] {data};
double[][] dataD = new double[data.length][];
for (int i=0; i<data.length; i++) {
dataD[i] = new double[] {data[i]};
}
return dataD;
}
}

View File

@ -72,7 +72,8 @@ public class StandardAdvModelPane extends SettingsPane<StandardModelParams> {
defaultTogglePane = createTogglePane();
transfromPane = new DLImageTransformPane();
mainPane.setPadding(new Insets(5,5,5,5));
mainPane.setPadding(new Insets(2,2,2,2));
mainPane.setPrefWidth(400);
}

View File

@ -18,10 +18,14 @@ import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tooltip;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
@ -34,6 +38,7 @@ import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.flipPane.FlipPane;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
/**
@ -111,12 +116,14 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
protected PamHBox defaultSegBox;
private ProgressIndicator modelLoadIndicator;
private ProgressIndicator modelLoadIndicator;
public StandardModelPane(DLClassiferModel soundSpotClassifier) {
super(null);
this.dlClassifierModel=soundSpotClassifier;
mainPane = createPane();
//the directory chooser.
fileChooser = new FileChooser();
@ -283,7 +290,7 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
vBoxHolder = new PamVBox();
vBoxHolder.setSpacing(5);
vBoxHolder.getChildren().addAll(classiferInfoLabel, hBox, advSettings, classiferInfoLabel2, gridPane);
mainPane.setCenter(vBoxHolder);
return mainPane;
@ -336,6 +343,11 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
* @param advSettingsButton - the advanced settings.
*/
public void showAdvPane(PamButton advSettingsButton) {
// dlClassifierModel.getDLControl().getSettingsPane().setAdvPaneContents(getAdvSettingsPane().getContentNode());
// dlClassifierModel.getDLControl().getSettingsPane().flipToBack();
if (popOver==null) {
popOver = new PopOver();
@ -352,6 +364,9 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
popOver.show(advSettingsButton);
}
/**
* Update the path label and tool tip text;
@ -424,6 +439,15 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
//instead of a using changing a control.
currParams.classNames = paramsClone.classNames;
currParams.numClasses = paramsClone.numClasses;
if (paramsClone.classNames == null && speciesIDBox.getItems()!=null) {
String[] classNames = new String[speciesIDBox.getItems().size()];
for (int i=0; i<speciesIDBox.getItems().size(); i++) {
classNames[i] = speciesIDBox.getItems().get(i);
}
currParams.classNames = this.dlClassifierModel.getDLControl().getClassNameManager().makeClassNames(classNames);
}
currParams.useDefaultSegLen = usedefaultSeg.isSelected();
@ -495,8 +519,6 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
}
}
}
@Override

View File

@ -206,6 +206,7 @@ public class KetosClassifier implements DLClassiferModel, PamSettings {
@Override
public DLClassName[] getClassNames() {
//System.out.println("Ketos Model: " + ketosDLParams.numClasses);
return ketosDLParams.classNames;
}

View File

@ -35,20 +35,29 @@ public class KetosModelPane extends StandardModelPane {
@Override
public void newModelSelected(File file) {
//A ketos model contains information on the transforms, duration and the class names.
this.setCurrentSelectedFile(file);
this.setParamsClone(new KetosDLParams());
//prep the model with current parameters;
ketosClassifier.getKetosWorker().prepModel(getParams(getParamsClone()), ketosClassifier.getDLControl());
//get the model transforms calculated from the model by SoundSpoyWorker and apply them to our temporary params clone.
// System.out.println("Ketos transforms 1: " + this.ketosClassifier.getKetosWorker().getModelTransforms());
getParamsClone().dlTransfroms = this.ketosClassifier.getKetosWorker().getModelTransforms();
if (getParamsClone().defaultSegmentLen!=null) {
usedefaultSeg.setSelected(true);
}
//System.out.println("Ketos: " + getParamsClone().dlTransfroms.size());
///set the advanced pane parameters.
getAdvSettingsPane().setParams(getParamsClone());
}
}

View File

@ -113,7 +113,10 @@ public class KetosWorker extends DLModelWorker<KetosResult> {
ketosDLParams.binaryClassification[i] = true; //set default to true.
}
}
if (ketosParams.classNames!=null) {
ketosDLParams.classNames = dlControl.getClassNameManager().makeClassNames(ketosParams.classNames);
}
// if (dlParams.classNames!=null) {
// for (int i = 0; i<dlParams.classNames.length; i++) {

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import org.controlsfx.control.PopOver;
import PamController.FlipSettingsPane;
import PamController.SettingsPane;
import PamDetection.RawDataUnit;
import PamView.dialog.warn.WarnOnce;
@ -14,10 +15,10 @@ import clipgenerator.ClipDataUnit;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.PopupControl;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tooltip;
import javafx.scene.control.Alert.AlertType;
@ -49,6 +50,8 @@ import warnings.PamWarning;
public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
public static double MAX_WIDTH = 250;
/**
* The source for the FFT data source.
*/
@ -111,6 +114,10 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
private Label infoLabel;
private Object flipPane;
private PopupControl advLabel;
public RawDLSettingsPane(DLControl dlControl){
super(null);
this.dlControl=dlControl;
@ -128,8 +135,10 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
mainPane.setCenter(createDLPane());
mainPane.setPadding(new Insets(5,5,5,5));
mainPane.setMinHeight(400);
mainPane.setMaxWidth(250);
mainPane.setPrefWidth(250);
mainPane.setMaxWidth(MAX_WIDTH);
mainPane.setPrefWidth(MAX_WIDTH);
//this.getAdvPane().setMaxWidth(MAX_WIDTH);
//mainPane.getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
@ -253,7 +262,7 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
return vBox;
}
/**
* Create the data selector.
@ -483,7 +492,7 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
@Override
public Node getContentNode() {
public Pane getContentNode() {
return mainPane;
}
@ -501,4 +510,6 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
return sourcePane.getSource();
}
}

View File

@ -39,7 +39,6 @@ import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.Exam
*/
public abstract class DLTransformImage extends PamBorderPane{
/**
* Plot pane.
*/
@ -70,7 +69,6 @@ public abstract class DLTransformImage extends PamBorderPane{
*/
private SpectrogramImage specImage = null;
/**
* The current 1D transform data.
*/
@ -97,7 +95,7 @@ public abstract class DLTransformImage extends PamBorderPane{
private RangeSlider timeSlider;
/**
* tIME BINS.
* Time bins.
*/
private int[] timeBins = new int[2];
@ -139,6 +137,7 @@ public abstract class DLTransformImage extends PamBorderPane{
plotPane.repaint();
});
transformschoiceBox.setConverter(new DLTransformConverter());
transformschoiceBox.setPrefWidth(170);
plotPane.getPlotCanvas().widthProperty().addListener((obsval, oldval, newval)->{
plotPane.repaint();
@ -174,6 +173,7 @@ public abstract class DLTransformImage extends PamBorderPane{
updateExampleSound(newval);
});
speciesChoiceBox.getSelectionModel().select(0);
speciesChoiceBox.setPrefWidth(170);
PamHBox hBox = new PamHBox();
hBox.setAlignment(Pos.CENTER_RIGHT);

View File

@ -77,7 +77,7 @@ public class DataTransformPaneFactory {
((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(1, -1000.0, 1000.0, 0.1);
break;
case SPECCROPINTERP:
settingsPane = new SimpleTransformPane((SimpleTransform) dlTransfrom, new String[]{"Min. Freq. ", "Max. Freq. ", " No. bins "}, new String[]{"Hz", "Hz", ""}, 2);
settingsPane = new SimpleTransformPane((SimpleTransform) dlTransfrom, new String[]{"Min. Freq. ", "Max. Freq. ", "No. bins "}, new String[]{"Hz", "Hz", ""}, 2);
((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(0, 0.0, 500000.0, 100.); //hmmmm would be nice to have the sample rate here...
((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(1, 0.0, 500000.0, 100.);
((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(2, 0, Integer.MAX_VALUE, 10);

View File

@ -25,6 +25,7 @@ public class FFTTransformPane extends SimpleTransformPane {
//System.out.println("Create step list: " + createStepList().size());
PamSpinner<Number> spinner = new PamSpinner<Number>(createStepList());
spinner.getValueFactory().setConverter(new NumberConverter());
spinner.setPrefWidth(PREF_SPINNER_WIDITH);
return spinner;
}
else return super.createSpinner(i);

View File

@ -29,7 +29,7 @@ public class SimpleTransformPane extends DLTransformPane {
/**
* The default spinner width.
*/
protected static int prefSpinnerWidth = 80;
protected static int PREF_SPINNER_WIDITH = 70;
int nParamCol=10;
@ -80,7 +80,7 @@ public class SimpleTransformPane extends DLTransformPane {
gridPane.setHgap(5);
gridPane.setVgap(5);
gridPane.setPadding(new Insets(5,5.,5.,15));
gridPane.setPadding(new Insets(2,2,2,2));
PamSpinner<Number> spinner;
@ -139,7 +139,9 @@ public class SimpleTransformPane extends DLTransformPane {
* @return a new spinner
*/
protected PamSpinner<Number> createSpinner(int i) {
return new PamSpinner<Number>(0.0, Double.MAX_VALUE, 2, 0.01);
PamSpinner spnner = new PamSpinner<Number>(0.0, Double.MAX_VALUE, 2, 0.01);
spnner.setPrefWidth(PREF_SPINNER_WIDITH);
return spnner;
}
/**

View File

@ -15,9 +15,14 @@ public class ExampleSoundFactory {
*
*/
public enum ExampleSoundType {
BAT_CALL("Bat Call (Myotis daubentonii)"),
RIGHT_WHALE("Southern Right Whale (Eubalaena australis)");
RIGHT_WHALE("Southern Right Whale (Eubalaena australis)"),
MINKE_WHALE("Minke Whale (Balaenoptera spp.)"),
HUMPBACK_WHALE("Humpback whale (Megaptera novaeangliae) ");
private final String text;
@ -56,6 +61,16 @@ public class ExampleSoundFactory {
path = getClass().getResource("/Resources/exampleSounds/southern_right_whale_clip2.wav");
exampleSound = new SimpleExampleSound(path);
break;
case MINKE_WHALE:
//file = new File("src/rawDeepLearningClassifier/layoutFX/exampleSounds/southern_right_whale_clip2.wav");
path = getClass().getResource("/Resources/exampleSounds/Minke_whale.wav");
exampleSound = new SimpleExampleSound(path);
break;
case HUMPBACK_WHALE:
//file = new File("src/rawDeepLearningClassifier/layoutFX/exampleSounds/southern_right_whale_clip2.wav");
path = getClass().getResource("/Resources/exampleSounds/Humpback_whale.wav");
exampleSound = new SimpleExampleSound(path);
break;
default:
break;
}

View File

@ -144,6 +144,7 @@ public class PlaybackControl extends PamControlledUnit implements PamSettings {
playbackSystem = findPlaybackSystem(sourceDataBlock);
playbackProcess.noteNewSettings();
playbackSidePanel.newSettings();
if (playBackGUI!=null) playBackGUI.notifyGUIChange(PamController.CHANGED_PROCESS_SETTINGS);
// if (this.getSidePanel() != null){
// this.getSidePanel().getPanel().setVisible(!isRealTimePlayback());
// }

View File

@ -0,0 +1,110 @@
package soundPlayback.fx;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
import soundPlayback.preprocess.PlaybackFilter;
import soundPlayback.preprocess.PreProcessFXPane;
public class FilterSidePane implements PreProcessFXPane {
private Label label;
private FilterSlider filterSlider;
private PlaybackFilter playBackFilter;
private PamBorderPane mainPane;
private PamButton defaultGainButton;
public FilterSidePane(PlaybackFilter playBackFilter) {
this.playBackFilter = playBackFilter;
filterSlider = new FilterSlider();
filterSlider.getSlider().setTooltip(new Tooltip("High pass filter the data before playback"));
filterSlider.addChangeListener((oldval, newVal, obsVal)->{
filterChanged();
});
defaultGainButton = new PamButton("off");
defaultGainButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-refresh", PamGuiManagerFX.iconSize-3));
defaultGainButton.setPrefWidth(70);
defaultGainButton.setOnAction((action)->{
filterSlider.setDataValue(filterSlider.getMinValue());
});
label = new Label("Filter");
//label.setGraphic(PamGlyphDude.createPamIcon("mdi2f-filter", PamGuiManagerFX.iconSize));
PamHBox hBox = new PamHBox();
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setSpacing(5);
hBox.getChildren().addAll(PamGlyphDude.createPamIcon("mdi2f-filter", PamGuiManagerFX.iconSize), filterSlider);
filterSlider.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(filterSlider, Priority.ALWAYS);
this.mainPane = new PamBorderPane();
this.mainPane.setCenter(hBox);
}
protected void filterChanged() {
playBackFilter.setValue(filterSlider.getDataValue());
sayFilter();
}
@Override
public void update() {
filterSlider.setDataValue(playBackFilter.getValue());
sayFilter();
}
private void sayFilter() {
//playGainSlider.setTextLabel(playbackGain.getTextValue());
label.setText(playBackFilter.getTextValue());
defaultGainButton.setDisable(false);
if (playBackFilter.getValue()==filterSlider.getMinValue()) {
defaultGainButton.setDisable(true);
}
}
@Override
public Pane getPane() {
return mainPane;
}
@Override
public Label getLabel() {
return label;
}
@Override
public Node getDefaultButton() {
return defaultGainButton;
}
}

View File

@ -0,0 +1,60 @@
package soundPlayback.fx;
/**
* Slider for the high pass filter sound out process.
* @author Jamie Macaulay
*
*/
public class FilterSlider extends PlaySliderPane {
private static final double MIN = 0.5e-3;
private static final double MAX = 0.5;
private static final double NSTEP = 100;
public FilterSlider() {
super();
}
@Override
public double valueToPos(double filter) {
if (filter <= MIN) {
return 0;
}
else {
double grad = (Math.log(MAX)-Math.log(MIN))/NSTEP;
int pos = (int) Math.round((Math.log(filter/MIN))/grad);
return pos;
}
}
@Override
public double posToValue(double pos) {
if (pos == 0) {
return 0;
}
else if (pos >= NSTEP) {
return MAX;
}
else {
double grad = (Math.log(MAX)-Math.log(MIN))/NSTEP;
return Math.exp(pos*grad)*MIN;
}
}
@Override
public double getMinValue() {
return 0;
}
@Override
public double getMaxValue() {
return 100;
}
}

View File

@ -67,6 +67,17 @@ public class PlayBackGUI extends PamControlledGUIFX {
}
/**
* Allows the GUI to be notified of changes, e.g. in the PAMController
* @param flag - the change flag.
*/
public void notifyGUIChange(int flag) {
for (Pane sidePane: sidePanes) {
((PlayBackSidePane) sidePane).newSettings();
}
}
}

View File

@ -1,11 +1,16 @@
package soundPlayback.fx;
import java.util.ArrayList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import pamViewFX.PamGuiFX;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox;
@ -13,6 +18,7 @@ import pamViewFX.fxNodes.sliders.PamSlider;
import soundPlayback.PlaybackControl;
import soundPlayback.preprocess.PlaybackPreprocess;
import soundPlayback.preprocess.PreProcessFXPane;
import soundPlayback.preprocess.PreprocessSwingComponent;
/**
* Th eplay back side pane.
@ -26,6 +32,11 @@ public class PlayBackSidePane extends BorderPane {
*/
private PlaybackControl playBackControl;
/**
* Label which shows which sound ouptut device is being used.
*/
private Label deviceLabel;
public PlayBackSidePane(PlaybackControl playBackControl) {
this.playBackControl=playBackControl;
this.setCenter(createSidePane());
@ -39,29 +50,97 @@ public class PlayBackSidePane extends BorderPane {
PamBorderPane borderPane = new PamBorderPane();
borderPane.setPrefWidth(PamGuiFX.SIDE_PANE_PREF_WIDTH-10);
borderPane.setMaxWidth(Double.MAX_VALUE);
Label titlelabel = new Label("Playback");
PamGuiManagerFX.titleFont2style(titlelabel);
// titlelabel.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play", PamGuiManagerFX.iconSize));
borderPane.setTop(titlelabel);
PamHBox hBox = new PamHBox();
hBox.setSpacing(5);
PamVBox vBox = new PamVBox();
vBox.setSpacing(5);
hBox.getChildren().add(deviceLabel= new Label(""));
borderPane.setCenter(hBox);
borderPane.setBottom(vBox);
PamVBox vBox = new PamVBox();
vBox.setSpacing(0);
vBox.setPadding(new Insets(5,0,0,0));
ArrayList<PlaybackPreprocess> preProcesses = playBackControl.getPlaybackProcess().getPreProcesses();
PreProcessFXPane preProcessFXPane;
for (int i=0; i<preProcesses.size() ; i++) {
//System.out.println("PLAYBACKSIDEPANE: ADDING : " + preProcesses.get(i).toString());
preProcessFXPane = preProcesses.get(i).getSideParPane();
if (preProcessFXPane!=null) {
hBox.getChildren().add(preProcessFXPane.getPane());
PamBorderPane labelHBox = new PamBorderPane();
// labelHBox.setAlignment(Pos.CENTER_LEFT);
// labelHBox.setSpacing(5);
labelHBox.setLeft(preProcessFXPane.getLabel());
labelHBox.setRight(preProcessFXPane.getDefaultButton() == null ? new Label() : preProcessFXPane.getDefaultButton());
vBox.getChildren().add(labelHBox);
vBox.getChildren().add(preProcessFXPane.getPane());
vBox.getChildren().add(new Label(""));
// if (preProcessFXPane.getDefaultButton()!=null) {
//
// //only show the default button when the user is inside the slider to reduce clutter.
// final Node defaultButton = preProcessFXPane.getDefaultButton();
// labelHBox.setOnMouseEntered((e)->{
// defaultButton.setVisible(true);
// });
//
// labelHBox.setOnMouseExited((e)->{
// defaultButton.setVisible(false);
// });
//
// preProcessFXPane.getPane().setOnMouseEntered((e)->{
// defaultButton.setVisible(true);
// });
//
// preProcessFXPane.getPane().setOnMouseExited((e)->{
// defaultButton.setVisible(false);
// });
//
// }
}
}
borderPane.setBottom(vBox);
return borderPane;
}
public void newSettings() {
boolean isRT = playBackControl.isRealTimePlayback();
ArrayList<PlaybackPreprocess> preProcesses = playBackControl.getPlaybackProcess().getPreProcesses();
for (PlaybackPreprocess pp : preProcesses) {
PreProcessFXPane comp = pp.getSideParPane();
if (comp != null) {
comp.update();
}
}
this.setVisible(playBackControl.getPlaybackParameters().getSidebarShow() > 0);
// speedLabel.setVisible(!isRT);
// speedSlider.getSlider().setVisible(!isRT);
// PlaybackParameters params = playbackControl.getPlaybackParameters();
// gainLabel.setText(String.format("Gain %d dB", params.playbackGain));
// gainSlider.setGain(params.playbackGain);
// sayPlaySpeed(speedSlider.getSpeed());
// speedSlider.setSpeed(params.getPlaybackSpeed());
}
}

View File

@ -0,0 +1,106 @@
package soundPlayback.fx;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
import soundPlayback.preprocess.PlaybackDecimator;
import soundPlayback.preprocess.PlaybackGain;
import soundPlayback.preprocess.PreProcessFXPane;
public class PlayDecimatorSidePane implements PreProcessFXPane {
private static final double DEFAULT_PLAY_SPEED = 1;
private PlaybackDecimator playbackDecimator;
private PlaySpeedSlider playSpeedSlider;
private PamBorderPane mainPane;
private Label label;
private PamButton defaultSpeedButton;
public PlayDecimatorSidePane(PlaybackDecimator playbackDecimator) {
this.playbackDecimator = playbackDecimator;
playSpeedSlider = new PlaySpeedSlider();
playSpeedSlider.getSlider().setTooltip(new Tooltip("<html>Adjust the output volume.<br>"+
"N.B. You should also consider turning up the volume in the computers volume controls."));
playSpeedSlider.addChangeListener((oldval, newVal, obsVal)->{
speedChanged();
});
playSpeedSlider.getChildren().add(defaultSpeedButton = new PamButton("x 1"));
defaultSpeedButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-refresh", PamGuiManagerFX.iconSize-3));
defaultSpeedButton.setPrefWidth(70);
defaultSpeedButton.setOnAction((action)->{
playSpeedSlider.setDataValue(DEFAULT_PLAY_SPEED);
});
label = new Label("Speed");
PamHBox hBox = new PamHBox();
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setSpacing(5);
hBox.getChildren().addAll(PamGlyphDude.createPamIcon("mdi2p-play", PamGuiManagerFX.iconSize), playSpeedSlider);
playSpeedSlider.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(playSpeedSlider, Priority.ALWAYS);
this.mainPane = new PamBorderPane();
this.mainPane.setCenter(hBox);
}
@Override
public void update() {
playSpeedSlider.setVisible(playbackDecimator.makeVisible());
playSpeedSlider.setDataValue(playbackDecimator.getPlaySpeed());
saySpeed();
}
private void saySpeed() {
//playSpeedSlider.setTextLabel("Speed " + playSpeedSlider.getRatioString());
label.setText("Speed " + playSpeedSlider.getRatioString());
}
protected void speedChanged() {
defaultSpeedButton.setDisable(false);
playbackDecimator.setPlaySpeed(playSpeedSlider.getDataValue());
if (playSpeedSlider.getDataValue()== DEFAULT_PLAY_SPEED) {
defaultSpeedButton.setDisable(true);
}
saySpeed();
}
@Override
public Pane getPane() {
return mainPane;
}
@Override
public Label getLabel() {
return label;
}
@Override
public Node getDefaultButton() {
return defaultSpeedButton;
}
}

View File

@ -1,51 +1,153 @@
package soundPlayback.fx;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.text.Text;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
import soundPlayback.preprocess.PlaybackGain;
import soundPlayback.preprocess.PreProcessFXPane;
import soundPlayback.swing.BasicSidebarLayout;
import soundPlayback.fx.PlayGainSlider;
public class PlayGainSidePane implements PreProcessFXPane {
private PlaybackGain playbackGain;
private BasicSidebarLayout basicSidebarLayout;
private PlayGainSlider playGainSlider;
private PamBorderPane mainPane;
private Label label;
private Text medVol;
private Text lowVol;
private Text highVol;
private PamButton defaultGainButton;
private Label iconLabel;
private static final double DEFAULT_GAIN = 0;
// private PamHBox labelHBox;
public PlayGainSidePane(PlaybackGain playbackGain) {
this.playbackGain = playbackGain;
playGainSlider = new PlayGainSlider();
basicSidebarLayout.setToolTipText("<html>Adjust the output volume.<br>"+
"N.B. You should also consider turning up the volume in the computers volume controls.");
playGainSlider.getSlider().setTooltip(new Tooltip("<html>Adjust the output volume.<br>"+
"N.B. You should also consider turning up the volume in the computers volume controls."));
playGainSlider.addChangeListener((oldval, newVal, obsVal)->{
gainChanged();
});
gainChanged();
});
//create the label which also has a default button
defaultGainButton = new PamButton("0 dB");
defaultGainButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-refresh", PamGuiManagerFX.iconSize-3));
defaultGainButton.setPrefWidth(70);
defaultGainButton.setOnAction((action)->{
playGainSlider.setDataValue(0);
});
label = new Label("Gain");
// labelHBox = new PamHBox();
// labelHBox.setAlignment(Pos.CENTER_LEFT);
// labelHBox.setSpacing(5);
// labelHBox.getChildren().addAll(label, defaultGainButton);
lowVol = PamGlyphDude.createPamIcon("mdi2v-volume-low", PamGuiManagerFX.iconSize);
medVol = PamGlyphDude.createPamIcon("mdi2v-volume-medium", PamGuiManagerFX.iconSize);
highVol = PamGlyphDude.createPamIcon("mdi2v-volume-high", PamGuiManagerFX.iconSize);
iconLabel = new Label();
this.mainPane = new PamBorderPane();
PamHBox hBox = new PamHBox();
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setSpacing(5);
hBox.getChildren().addAll(iconLabel, playGainSlider);
playGainSlider.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(playGainSlider, Priority.ALWAYS);
this.mainPane.setCenter(hBox);
setLabelVolGrpahic();
}
private void setLabelVolGrpahic() {
//System.out.println("Playback gain: " + playbackGain.getGaindB());
if (playbackGain.getGaindB()<PlayGainSlider.MINGAIN+20 && iconLabel.getGraphic()!=lowVol)
iconLabel.setGraphic(lowVol);
else if (playbackGain.getGaindB()>=PlayGainSlider.MINGAIN+20 && playbackGain.getGaindB()<PlayGainSlider.MAXGAIN-20
&& iconLabel.getGraphic()!=medVol) {
iconLabel.setGraphic(medVol);
}
else if ( playbackGain.getGaindB()>=PlayGainSlider.MAXGAIN-20 && iconLabel.getGraphic()!=highVol) {
iconLabel.setGraphic(highVol);
}
}
@Override
public void update() {
playGainSlider.setDataValue(playbackGain.getGaindB());
setLabelVolGrpahic();
sayGain();
}
private void sayGain() {
basicSidebarLayout.setTextLabel(playbackGain.getTextValue());
//playGainSlider.setTextLabel(playbackGain.getTextValue());
label.setText(playbackGain.getTextValue());
}
private void gainChanged() {
defaultGainButton.setDisable(false);
playbackGain.setGaindB(playGainSlider.getDataValue());
setLabelVolGrpahic();
sayGain();
if (playbackGain.getGaindB()==DEFAULT_GAIN) {
defaultGainButton.setDisable(true);
}
}
@Override
public Pane getPane() {
return null;
return mainPane;
}
@Override
public Node getLabel() {
return label;
}
@Override
public Node getDefaultButton() {
return defaultGainButton;
}
}

View File

@ -7,9 +7,9 @@ package soundPlayback.fx;
*/
public class PlayGainSlider extends PlaySliderPane {
private static final int MINGAIN = -20;
static final int MINGAIN = -20;
private static final int MAXGAIN = 60;
static final int MAXGAIN = 60;
public PlayGainSlider() {
@ -26,4 +26,5 @@ public class PlayGainSlider extends PlaySliderPane {
return MAXGAIN;
}
}

View File

@ -1,31 +1,72 @@
package soundPlayback.fx;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.sliders.PamSlider;
/**
* Default slider pane.
* Default slider pane for the sound output sliders.
*
* @author Jamie Macaulay
*
*/
public abstract class PlaySliderPane {
public abstract class PlaySliderPane extends PamHBox {
/**
* The slider to chnage the value of something.
*/
private PamSlider slider;
/**
* The label which shows a slider value
*/
private Label sliderLabel;
public PlaySliderPane() {
slider = new PamSlider(getMinValue(), getMaxValue(), getMinValue());
//slider.setShowTickMarks(true);
slider.setMaxWidth(Double.POSITIVE_INFINITY);
//slider.setShowTickLabels(true);
//setSliderSize();
sliderLabel = new Label();
slider.setId("thickslider");
HBox.setHgrow(slider, Priority.ALWAYS);
this.setAlignment(Pos.CENTER_LEFT);
this.setSpacing(5);
slider.setTrackColor(Color.rgb(0,204,204));
slider.setTrackColor(Color.DODGERBLUE);
//slider.setTrackColor(Color.GRAY);
this.getChildren().addAll(slider,sliderLabel);
}
/**
* get the minimum value of the slider
* @return the minimum value fo the slider.
*/
public abstract double getMinValue();
/**
* Get the maximum value of the slider.
* @return the maximum value of the slider.
*/
public abstract double getMaxValue();
/**
* @return the slider
*/
public PamSlider getSlider() {
public Slider getSlider() {
return slider;
}
@ -34,7 +75,7 @@ public abstract class PlaySliderPane {
* @return the real scaled value
*/
public double getDataValue() {
return slider.getValue();
return posToValue(slider.getValue());
}
/**
@ -42,7 +83,7 @@ public abstract class PlaySliderPane {
* @param value the scaled value.
*/
public void setDataValue(double value) {
slider.setValue(value);
slider.setValue(valueToPos(value));
}
/**
@ -53,4 +94,28 @@ public abstract class PlaySliderPane {
slider.valueProperty().addListener(changeListener);
}
public void setTextLabel(String textValue) {
this.sliderLabel.setText(textValue);
}
/**
* Get the slider position from a value (usually value = out).
* @param value
* @return
*/
public double valueToPos(double value) {
return value;
}
/**
* Get the value from a slider position (usually pos = out).
* @param pos - the position of the slider.
* @return - the corresponding value.
*/
public double posToValue(double pos) {
return pos;
}
}

View File

@ -0,0 +1,59 @@
package soundPlayback.fx;
import java.text.DecimalFormat;
public class PlaySpeedSlider extends PlaySliderPane {
private static final double MINSPEED = -6;
private static final double MAXSPEED = 6;
public PlaySpeedSlider() {
this.getSlider().setBlockIncrement(1);
}
public String getRatioString() {
return getRatioString(getDataValue());
}
public static String getRatioString(double speed) {
if (speed >= 1) {
DecimalFormat df = new DecimalFormat(" x #.##");
return df.format(speed);
}
else if (speed <= 0) {
return "Err 0";
}
else {
DecimalFormat df = new DecimalFormat(" \u00F7 #.##");
return df.format(1./speed);
}
}
@Override
public double getMinValue() {
return MINSPEED;
}
@Override
public double getMaxValue() {
return MAXSPEED;
}
@Override
public double valueToPos(double value) {
return super.valueToPos(Math.log(value)/Math.log(2.));
}
@Override
public double posToValue(double pos) {
return Math.pow(2,super.posToValue(pos));
}
}

View File

@ -11,6 +11,7 @@ import soundPlayback.PBSampleRateData;
import soundPlayback.PlaybackControl;
import soundPlayback.PlaybackParameters;
import soundPlayback.PlaybackProcess;
import soundPlayback.fx.PlayDecimatorSidePane;
import soundPlayback.swing.DecimatorSideBar;
public class PlaybackDecimator implements PlaybackPreprocess {
@ -22,6 +23,8 @@ public class PlaybackDecimator implements PlaybackPreprocess {
private PlaybackControl playbackControl;
private DecimatorSideBar decimatorSideBar;
private PlayDecimatorSidePane playDecimatorSidePane;
public PlaybackDecimator(PlaybackControl playbackControl) {
this.playbackControl = playbackControl;
@ -72,7 +75,9 @@ public class PlaybackDecimator implements PlaybackPreprocess {
@Override
public PreProcessFXPane getSideParPane() {
// TODO Auto-generated method stub
return null;
if (playDecimatorSidePane==null) {
playDecimatorSidePane = new PlayDecimatorSidePane(this);
}
return playDecimatorSidePane;
}
}

View File

@ -12,6 +12,8 @@ import PamUtils.FrequencyFormat;
import PamUtils.PamUtils;
import soundPlayback.PlaybackControl;
import soundPlayback.PlaybackParameters;
import soundPlayback.fx.FilterSidePane;
import soundPlayback.fx.PlayDecimatorSidePane;
import soundPlayback.swing.PlayFilterSideBar;
/**
@ -31,6 +33,8 @@ public class PlaybackFilter implements PlaybackPreprocess {
private PlayFilterSideBar playFilterSideBar;
private FilterSidePane filterSidePane;
public PlaybackFilter(PlaybackControl playbackControl) {
this.playbackControl = playbackControl;
playFilterSideBar = new PlayFilterSideBar(this);
@ -70,6 +74,7 @@ public class PlaybackFilter implements PlaybackPreprocess {
}
public String getTextValue() {
//System.out.println("Playback control Sample rate: " + playbackControl.getSourceSampleRate() + " val: " + getValue());
double f = getValue() * playbackControl.getSourceSampleRate();
if (f == 0) {
return "High pass filter off";
@ -114,8 +119,10 @@ public class PlaybackFilter implements PlaybackPreprocess {
@Override
public PreProcessFXPane getSideParPane() {
// TODO Auto-generated method stub
return null;
if (filterSidePane==null) {
filterSidePane = new FilterSidePane(this);
}
return filterSidePane;
}
}

View File

@ -1,5 +1,7 @@
package soundPlayback.preprocess;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
/**
@ -21,4 +23,14 @@ public interface PreProcessFXPane {
*/
public void update();
/**
* Pane which shows the name of the pre-process.
*/
public Node getLabel();
/**
* Pane which allows the user to switch to a default.
*/
public Node getDefaultButton();
}