Click trian detector fixes (#48)

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Create click_train_help.md

* Update click_train_help.md

* Screenshots

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* More screenshots

* Add screenshots

* Update click_train_help.md

* Add classifier screenshot

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Updates and bug fixes to click train detector and CPOD importer

* Update click_train_help.md

* Update POM with latest jdl4pam

* Add screenshots for click train detector help

* Screenshots

* Update click_train_help.md

* Defult option for CPOD and porpoise to click train detector.

Also a minor

* Update pom.xml

* Bug fix for raw spectrogram in TDDisplayFX

* Update KetosClassifier.java

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Create click_train_help.md

* Update click_train_help.md

* Screenshots

* Update click_train_help.md

* More screenshots

* Update click_train_help.md

* Update click_train_help.md

* Add screenshots

* Add classifier screenshot

* Update click_train_help.md

* Updates and bug fixes to click train detector and CPOD importer

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Add screenshots for click train detector help

* Screenshots

* Update click_train_help.md

* Defult option for CPOD and porpoise to click train detector.

Also a minor

* Bug fix for raw spectrogram in TDDisplayFX

* Update KetosClassifier.java

* Fix standard classifier JSON logging

* Update click_train_help.md

* Fixed bug in sweep classifier when using SoundTrap click detections

* Added some colour averaging in the TFDisplayFX spectrgoram

* Bug fix for rainbow click bearings

Bug fix when rainbow clicks are imported mean bearings cannot be calculated - was an array size issue in DelayGroup

* Google humpback whale deep learning classifier

Google's humpback whale deep learning classifier can now be imported.
Updated TDisplayFX to make the data selection panes cleaner and clearer.
Updated the TDisplayFX so that predicitons from deep learning models now have some display options e.g. changing colour.

* Updated the prediction plots on time display

Deep learning prediciton plots on the time display have now been updated to have some colour options and also act as a legend.

* Updates to TDisplayFX

yFIshmael now owrks with TDisplayFX
TDisplayFX UI changes to make simpler.
Some abstraction for drawing lines on TDisplayFX

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Create click_train_help.md

* Update click_train_help.md

* Screenshots

* Update click_train_help.md

* More screenshots

* Update click_train_help.md

* Update click_train_help.md

* Add screenshots

* Add classifier screenshot

* Update click_train_help.md

* Updates and bug fixes to click train detector and CPOD importer

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Add screenshots for click train detector help

* Screenshots

* Update click_train_help.md

* Defult option for CPOD and porpoise to click train detector.

Also a minor

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Create click_train_help.md

* Update click_train_help.md

* Update click_train_help.md

* Updates and bug fixes to click train detector and CPOD importer

* Bug fix for raw spectrogram in TDDisplayFX

* Update KetosClassifier.java

* Fix standard classifier JSON logging

* Fixed bug in sweep classifier when using SoundTrap click detections

* Added some colour averaging in the TFDisplayFX spectrgoram

* Bug fix for rainbow click bearings

Bug fix when rainbow clicks are imported mean bearings cannot be calculated - was an array size issue in DelayGroup

* Google humpback whale deep learning classifier

Google's humpback whale deep learning classifier can now be imported.
Updated TDisplayFX to make the data selection panes cleaner and clearer.
Updated the TDisplayFX so that predicitons from deep learning models now have some display options e.g. changing colour.

* Updated the prediction plots on time display

Deep learning prediciton plots on the time display have now been updated to have some colour options and also act as a legend.

* Updates to TDisplayFX

yFIshmael now owrks with TDisplayFX
TDisplayFX UI changes to make simpler.
Some abstraction for drawing lines on TDisplayFX

* Merge fixes to click train detector

* Bug fix to UI

* Updates to FX GUI

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Screenshots

* Updates and bug fixes to click train detector and CPOD importer

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Updates and bug fixes to click train detector and CPOD importer

* Fix standard classifier JSON logging

* Merge fixes to click train detector

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Screenshots

* Updates and bug fixes to click train detector and CPOD importer

* Updates to click train detector

New GUI for click train classification - more intuitive and allows users to build more powerful classifiers.
CPOD data can now build average waveforms.
CPOD click trains can be viewed in TDisplayFX pop up menu displays
Fixed Peak Frequency symbol chooser so it saves the colour box settings

* Screenshots

* Updates and bug fixes to click train detector and CPOD importer

* Fix standard classifier JSON logging

* Google humpback whale deep learning classifier

Google's humpback whale deep learning classifier can now be imported.
Updated TDisplayFX to make the data selection panes cleaner and clearer.
Updated the TDisplayFX so that predicitons from deep learning models now have some display options e.g. changing colour.

* Bug fix to UI

* Bug fixes to FX GUI

* Updates to click train detector

* Squashed commit of the following:

commit 9f998165ee
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon May 2 19:40:24 2022 +0100

    Updates to support ContactCollator plugin (#33)

    * Change synchronization on RawDataTransforms soit uses the owner data
    holder, not itself for synchronization. Otherwise you get thread locks.

    * fix problem in SummaryComand

    * Update command line options

    * Change synchronization on RawDataTransforms soit uses the owner data
    holder, not itself for synchronization. Otherwise you get thread locks.

    * Update command line options

    * Update DecimatorParams.java

    * couple of updates to support new contact collator plugin

    * Sorting out sample rate info in clip display to support Contact Collator
    plugin

    * FLAC Speed

    Improve flac speed

    * Update .gitignore

    * Update .gitignore

    * Updates to support new features in Contact Collator

    * Small update to RawDatautils to handle null data

* Updates to click train detector

* Squashed commit of the following:

commit 62b020b320
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Sat May 14 06:52:20 2022 +0100

    Add a new offlinefileslist function

commit 3a9a5311aa
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Wed Apr 27 09:43:31 2022 +0100

    Update .gitignore

commit 9f998165ee
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon May 2 19:40:24 2022 +0100

    Updates to support ContactCollator plugin (#33)

    * Change synchronization on RawDataTransforms soit uses the owner data
    holder, not itself for synchronization. Otherwise you get thread locks.

    * fix problem in SummaryComand

    * Update command line options

    * Change synchronization on RawDataTransforms soit uses the owner data
    holder, not itself for synchronization. Otherwise you get thread locks.

    * Update command line options

    * Update DecimatorParams.java

    * couple of updates to support new contact collator plugin

    * Sorting out sample rate info in clip display to support Contact Collator
    plugin

    * FLAC Speed

    Improve flac speed

    * Update .gitignore

    * Update .gitignore

    * Updates to support new features in Contact Collator

    * Small update to RawDatautils to handle null data

* Updated data selector for click train detector

* Click train detector updates and bug fixes

Fixed very annoying bug which meant templates did not show properly when the dialog was first opened in swing.

Added feature to simple classifier were % of clicks of one click classification (or other data selector paramter) can be used to classify.

* Bug fix and improvements for Ketos

Ketos models now automatically set the correct sample length when loaded.

Bug fix for the TDisplayFX - null pointer exception if no class names loaded and sorted recently introduced bug in drawing predictions.

* Updates to deep learning and FX GUI

Added some more example sounds to deep learning UI.

Updated click detector in the FX GUI.

* PAMGuard FX sound output update

* Updates to FX GUI

* Updates to FX GUI

* Update RawDataTransforms.java

* Fixes to FX UI

* Squashed commit of the following:

commit 11ba8bf91e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:45:47 2022 +0100

    MErge from DG Branch (#47)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 9a9f542d95
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:42:45 2022 +0100

    Merge DG to Main (#46)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 49cd547aee
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:40:29 2022 +0100

    Merge DG branch (#45)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 016cfd0da5
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:35:06 2022 +0100

    Dialog positioning

    New functions to better positions dialogs on screen

commit c9f2ab3e97
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 1 11:13:24 2022 +0100

    puch to main (#44)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

commit 55f5a3fcf1
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 1 10:59:36 2022 +0100

    Group detections menu

    Small changes to limit the number of menu items in "Add to existing
    group" to a maximum of 25 entries.

commit b3f6c0e665
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 29 10:50:45 2022 +0100

    Handle -nogui option in PamWorker

    PamWorker used to catalog files at startup (if a file folder input
    system is used). This creates a progress dialog. Stop it appearing in
    -nogui operations.

commit 8569b6b579
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 22 08:30:47 2022 +0100

    Click display fixes (#41)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

commit 128a512ff6
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 19 16:37:57 2022 +0100

    Another attempt at stopping it crashing on a headless system

    Dealing with displays that get created for clickangle vetos and a call
    to the gui in the click train detector.

commit 6eaa6e4978
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 19 08:20:07 2022 +0100

    nogoi fix for headless systems. (#40)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

commit 9fdd30556b
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 12 15:53:07 2022 +0100

    Variable sound output level (#39)

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

* Bug fixes to click train detector

Fixed bug with number of coasts in the MHT Kernel
Added an option for amplitude to have a maximum
Removed print statements.

Co-authored-by: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
This commit is contained in:
Jamie Mac 2022-08-08 10:32:19 +01:00 committed by GitHub
parent b4bdae94ca
commit ef0330173b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
77 changed files with 1869 additions and 462 deletions

View File

@ -1,7 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <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> <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"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
@ -10,11 +17,5 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </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"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

View File

@ -26,6 +26,7 @@ import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamTextField; import pamViewFX.fxNodes.PamTextField;
import pamViewFX.fxNodes.PamVBox; import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.flipPane.FlipPane; import pamViewFX.fxNodes.flipPane.FlipPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import Acquisition.AcquisitionControl; import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionParameters; import Acquisition.AcquisitionParameters;
import Acquisition.ChannelListPanel; import Acquisition.ChannelListPanel;
@ -153,7 +154,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
//create the flip pane. //create the flip pane.
flipPane=new FlipPane(); flipPane=new FlipPane();
flipPane.setFlipDirection(Orientation.HORIZONTAL); 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()); //flipPane.prefWidthProperty().bind(mainPane.widthProperty());
if (aquisitionControl.isViewer()){ 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(); 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. * @param flag - the change flag.
*/ */
public void notifyGUIChange(int flag) { public void notifyGUIChange(int flag) {

View File

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

View File

@ -6,6 +6,7 @@ import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -62,7 +63,7 @@ public class TxtFileUtils {
boolean isNaN=false; boolean isNaN=false;
for (String line : lines) { for (String line : lines) {
System.out.println(line); //System.out.println(line);
String[] recordsOnLine = line.split(delimeter); 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 // //This was causing isses with some numbers with e-06...dunno why so switched to parse double
// String input = new String(recordsOnLine[i].toCharArray()); // String input = new String(recordsOnLine[i].toCharArray());
// //System.out.println(input); // System.out.println("|" + recordsOnLine[i] + "|");
// dat = nF.parse(input).doubleValue(); // dat = nF.parse(input).doubleValue();
//5/08/2022 - there was a bug here where there is some sort of invisible character that does not appear on the
dat = Double.parseDouble(recordsOnLine[i]); //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){ catch (Exception e){
e.printStackTrace(); e.printStackTrace();

View File

@ -99,6 +99,7 @@ public class RawDataTransforms {
*/ */
private int shortestFFTLength; private int shortestFFTLength;
private Object synchObject; private Object synchObject;
/** /**
@ -187,8 +188,7 @@ public class RawDataTransforms {
* @param fftLength * @param fftLength
* @return Power spectrum * @return Power spectrum
*/ */
public double[] getPowerSpectrum(int channel, int fftLength) { public synchronized double[] getPowerSpectrum(int channel, int fftLength) {
synchronized (synchObject) {
if (powerSpectra == null) { if (powerSpectra == null) {
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][]; powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
} }
@ -212,7 +212,6 @@ public class RawDataTransforms {
} }
return powerSpectra[channel]; return powerSpectra[channel];
} }
}
/** /**
@ -221,8 +220,7 @@ public class RawDataTransforms {
* @param fftLength * @param fftLength
* @return Sum of power spectra * @return Sum of power spectra
*/ */
public double[] getTotalPowerSpectrum(int fftLength) { public synchronized double[] getTotalPowerSpectrum(int fftLength) {
synchronized (synchObject) {
if (fftLength == 0) { if (fftLength == 0) {
fftLength = getCurrentSpectrumLength(); fftLength = getCurrentSpectrumLength();
} }
@ -242,7 +240,6 @@ public class RawDataTransforms {
} }
return totalPowerSpectrum; return totalPowerSpectrum;
} }
}
@ -256,8 +253,7 @@ public class RawDataTransforms {
* @param fftLength - the FFT length to use. * @param fftLength - the FFT length to use.
* @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel. * @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel.
*/ */
public ComplexArray getComplexSpectrumHann(int channel, int fftLength) { public synchronized ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
synchronized (synchObject) {
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())]; complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
if (complexSpectrum[channel] == null if (complexSpectrum[channel] == null
|| complexSpectrum.length != fftLength / 2) { || complexSpectrum.length != fftLength / 2) {
@ -267,7 +263,6 @@ public class RawDataTransforms {
} }
return complexSpectrum[channel]; return complexSpectrum[channel];
} }
}
@ -394,8 +389,7 @@ public class RawDataTransforms {
* @param fftLength * @param fftLength
* @return the complex spectrum * @return the complex spectrum
*/ */
public ComplexArray getComplexSpectrum(int channel, int fftLength) { public synchronized ComplexArray getComplexSpectrum(int channel, int fftLength) {
synchronized (synchObject) {
double[] paddedRawData; double[] paddedRawData;
double[] rawData; double[] rawData;
int i, mn; int i, mn;
@ -419,7 +413,6 @@ public class RawDataTransforms {
} }
return complexSpectrum[channel]; return complexSpectrum[channel];
} }
}
/** /**
@ -427,8 +420,7 @@ public class RawDataTransforms {
* @param iChan channel index * @param iChan channel index
* @return analytic waveform * @return analytic waveform
*/ */
public double[] getAnalyticWaveform(int iChan) { public synchronized double[] getAnalyticWaveform(int iChan) {
synchronized (synchObject) {
if (analyticWaveform == null) { if (analyticWaveform == null) {
analyticWaveform = new double[getNChan()][]; analyticWaveform = new double[getNChan()][];
} }
@ -437,7 +429,6 @@ public class RawDataTransforms {
// } // }
return analyticWaveform[iChan]; return analyticWaveform[iChan];
} }
}
/** /**
* Get filtered or unfiltered analytic waveform. Easy access method for click * Get filtered or unfiltered analytic waveform. Easy access method for click
@ -448,8 +439,7 @@ public class RawDataTransforms {
* @param fftFilterParams fft filter parameters. * @param fftFilterParams fft filter parameters.
* @return analystic waveform. * @return analystic waveform.
*/ */
public double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) { public synchronized double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
synchronized (synchObject) {
if (filtered == false || fftFilterParams == null) { if (filtered == false || fftFilterParams == null) {
return getAnalyticWaveform(iChan); return getAnalyticWaveform(iChan);
} }
@ -457,7 +447,6 @@ public class RawDataTransforms {
return getFilteredAnalyticWaveform(fftFilterParams, iChan); return getFilteredAnalyticWaveform(fftFilterParams, iChan);
} }
} }
}
/** /**
* Get a filtered version of the analytic waveform. In principle, this could be made more efficient * Get a filtered version of the analytic waveform. In principle, this could be made more efficient
@ -466,6 +455,7 @@ public class RawDataTransforms {
* @param iChan channel number * @param iChan channel number
* @return envelope of the filtered data. * @return envelope of the filtered data.
*/ */
public double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) { public double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
synchronized (synchObject) { synchronized (synchObject) {
if (analyticWaveform == null) { if (analyticWaveform == null) {
@ -509,6 +499,7 @@ public class RawDataTransforms {
* @param channelIndex channel index * @param channelIndex channel index
* @return filtered waveform data * @return filtered waveform data
*/ */
public double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) { public double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
synchronized (synchObject) { synchronized (synchObject) {
filteredWaveData = getFilteredWaveData(filterParams); filteredWaveData = getFilteredWaveData(filterParams);
@ -522,6 +513,7 @@ public class RawDataTransforms {
* @param filterParams filter parameters * @param filterParams filter parameters
* @return array of filtered data * @return array of filtered data
*/ */
public double[][] getFilteredWaveData(FFTFilterParams filterParams) { public double[][] getFilteredWaveData(FFTFilterParams filterParams) {
synchronized (synchObject) { synchronized (synchObject) {
//System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams)); //System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams));

View File

@ -639,3 +639,23 @@
#module-pane .ikonli-font-icon { #module-pane .ikonli-font-icon {
-fx-icon-color: black; -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.ClickTypeCommonParams;
import clickDetector.ClickClassifiers.basic.BasicClickIdentifier; import clickDetector.ClickClassifiers.basic.BasicClickIdentifier;
import clickDetector.layoutFX.clickClassifiers.ClassifyPaneFX; import clickDetector.layoutFX.clickClassifiers.ClassifyPaneFX;
import clickDetector.layoutFX.clickClassifiers.SweepClassifierPaneFX;
/** /**
* An improvements on the BasicClickIdentifier based on work by * An improvements on the BasicClickIdentifier based on work by
@ -44,6 +45,9 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
private SweepClassifierPanel dialogPanel; private SweepClassifierPanel dialogPanel;
private SweepClassifierPaneFX fxPane;
private SweepClassifierWorker sweepClassifierWorker; private SweepClassifierWorker sweepClassifierWorker;
protected SweepClassifierParameters sweepClassifierParameters = new SweepClassifierParameters(); protected SweepClassifierParameters sweepClassifierParameters = new SweepClassifierParameters();
@ -408,8 +412,8 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
@Override @Override
public ClassifyPaneFX getClassifierPane() { public ClassifyPaneFX getClassifierPane() {
// TODO Auto-generated method stub if (fxPane==null) fxPane = new SweepClassifierPaneFX(this, clickControl);
return null; return fxPane;
} }
@Override @Override

View File

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

View File

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

View File

@ -20,6 +20,9 @@ public class ClickTriggerGraph extends PamBorderPane {
public final static int PORPOISE_CLICK=0; public final static int PORPOISE_CLICK=0;
public final static int SPERM_WHALE=1;
private int currentClick=PORPOISE_CLICK; private int currentClick=PORPOISE_CLICK;
private NumberAxis xAxis; private NumberAxis xAxis;
@ -45,10 +48,14 @@ public class ClickTriggerGraph extends PamBorderPane {
private int freq2; private int freq2;
private double[] waveform;
public ClickTriggerGraph(){ public ClickTriggerGraph(){
this.setCenter(createWaveformGraph()); this.setCenter(createWaveformGraph());
this.setPrefWidth(500); this.setPrefWidth(400);
//FIXME - seems to a resize bug in high DPI displays. Seems fixed in 8u60. //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>(); Series<Number, Number> noiseLevelSeries = new Series<Number, Number>();
double[] waveform=generateClickWaveform(currentClick, noise);
double[] signalLevel=calcFilter(waveform, shortFilter); double[] signalLevel=calcFilter(waveform, shortFilter);
double[] noiseLevel=calcFilter(waveform, longFilter); 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); clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
sR=500000; sR=500000;
break; break;
case SPERM_WHALE:
clickSound=(new ClickSound("Beaked Whale", 30000, 60000, length = 0.3e-3, WINDOWTYPE.HANN));
sR=192000;
break;
default: default:
clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN); clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
sR=500000; sR=500000;

View File

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

View File

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

View File

@ -1,7 +1,6 @@
package clickDetector.layoutFX.clickClassifiers; package clickDetector.layoutFX.clickClassifiers;
import pamViewFX.fxNodes.PamScrollPane;
import clickDetector.ClickControl; import clickDetector.ClickControl;
import clickDetector.ClickClassifiers.basicSweep.SweepClassifier; import clickDetector.ClickClassifiers.basicSweep.SweepClassifier;
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierParameters; import clickDetector.ClickClassifiers.basicSweep.SweepClassifierParameters;
@ -9,17 +8,18 @@ import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
/** /**
* Slightly different pane for the sweep classifier. * Slightly different pane for the sweep classifier.
*
* @author Jamie Macaulay * @author Jamie Macaulay
*/ */
public class SweepClassifierPaneFX extends BasicIdentifierPaneFX { public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
/** /**
* Reference to the sweep classifier * Reference to the sweep classifier.
*/ */
SweepClassifier sweepClickClassifier; SweepClassifier sweepClickClassifier;
/** /**
* Reference to the sweep classifier params * Reference to the sweep classifier params.
*/ */
private SweepClassifierParameters sweepIdParameters; private SweepClassifierParameters sweepIdParameters;
@ -39,11 +39,12 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
public void setClassifierPane(ClickTypeProperty clickTypeProperty){ public void setClassifierPane(ClickTypeProperty clickTypeProperty){
SweepClassifierSetPaneFX sweepPane=new SweepClassifierSetPaneFX(sweepClickClassifier); SweepClassifierSetPaneFX sweepPane=new SweepClassifierSetPaneFX(sweepClickClassifier);
sweepPane.setParams(clickTypeProperty); 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 //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. //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); sweepPane.getParams(clickTypeProperty);
}); });
} }

View File

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

View File

@ -5,6 +5,7 @@ import java.util.List;
import PamUtils.PamArrayUtils; import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
/** /**
* Holds some basic IDI info on the click train. * Holds some basic IDI info on the click train.
@ -47,7 +48,7 @@ public class IDIInfo {
lastNumber = dataUnits.size(); lastNumber = dataUnits.size();
if (dataUnits.size()<3) { 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; return;
} }

View File

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

View File

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

View File

@ -71,10 +71,12 @@ public class MHTGarbageBot {
//check the current set of click train possible ICI's //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. //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)) { 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 //check whether the next click has a gap so big that all click trains should be restarted
//grab tracks //grab tracks
mhtKernel.confirmRemainingTracks(); mhtKernel.confirmRemainingTracks();

View File

@ -159,8 +159,8 @@ public class MHTKernel<T> {
Debug.out.println("Possiblity matrix size is " + possibleTracks.size() + " x " + kcount ); Debug.out.println("Possiblity matrix size is " + possibleTracks.size() + " x " + kcount );
} }
// for (int i=0; i<possibleTracks.size(); i++) { // for (int i=0; i<possibleTracks.size(); i++) {
// System.out.println("Pos " + i + " chi^2 "+ possibleTracks.get(i).chi2Track + // System.out.println("Pos " + i + " chi^2 "+ possibleTracks.get(i).chi2Track.getChi2() +
// " " + printBitSet(possibleTracks.get(i).trackBitSet) ); // " " + MHTKernel.bitSetString(possibleTracks.get(i).trackBitSet,kcount));
// } // }
//prune the probability matrix. //prune the probability matrix.
@ -412,6 +412,7 @@ public class MHTKernel<T> {
testBranch = newPossibleTracks.get(j); testBranch = newPossibleTracks.get(j);
testBitSet=testBranch.trackBitSet.get(0, kcount-(pruneback)); testBitSet=testBranch.trackBitSet.get(0, kcount-(pruneback));
//now test whether the current and test branch are the same. //now test whether the current and test branch are the same.
if (testBitSet.equals(currentBitSet)) { if (testBitSet.equals(currentBitSet)) {
indexConfirm[j]=true; indexConfirm[j]=true;
@ -423,6 +424,7 @@ public class MHTKernel<T> {
indexRemove[j]=true; indexRemove[j]=true;
} }
} }
} }
//long time2a=System.currentTimeMillis(); //long time2a=System.currentTimeMillis();
@ -437,9 +439,11 @@ public class MHTKernel<T> {
if (nCoasts>=this.mHTParams.maxCoast || confirmAll || currentBranch.flag==TrackBitSet.JUNK_TRACK) { if (nCoasts>=this.mHTParams.maxCoast || confirmAll || currentBranch.flag==TrackBitSet.JUNK_TRACK) {
//the branch needs to be confirmed. //the branch needs to be confirmed.
// System.out.println(i + " DONE: "+ String.format("%.3f ", possibleTracks.get(i).chi2Track.getChi2())+ // System.out.println(i + " DONE: " + (nCoasts >= this.mHTParams.maxCoast) + " " + confirmAll + " "
// " " + String.format("%d ", possibleTracks.get(i).chi2Track.getNCoasts()) // + (currentBranch.flag == TrackBitSet.JUNK_TRACK) + " "
// + MHTKernel.bitSetString(possibleTracks.get(i).trackBitSet, kcount)); // + String.format("%.3f ", currentBranch.chi2Track.getChi2()) + " "
// + String.format("%d ", currentBranch.chi2Track.getNCoasts())
// + MHTKernel.bitSetString(currentBranch.trackBitSet, kcount));
/** /**
* 27/02/2020 * 27/02/2020
@ -471,6 +475,7 @@ public class MHTKernel<T> {
indexRemove[j]=true; indexRemove[j]=true;
} }
} }
} }
else { else {
//save as an active track. //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 * 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 * data units have been detecteded. Note that the function deletes the currently
* confirmed tracks. These should be extracted beforehand; * confirmed tracks. These should be extracted beforehand;
* *

View File

@ -5,6 +5,7 @@ import java.util.BitSet;
import PamUtils.PamArrayUtils; import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
import clickTrainDetector.clickTrainAlgorithms.CTAlgorithmInfo; import clickTrainDetector.clickTrainAlgorithms.CTAlgorithmInfo;
import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.ElectricalNoiseFilter; import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.ElectricalNoiseFilter;
import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.SimpleElectricalNoiseFilter; import clickTrainDetector.clickTrainAlgorithms.mht.electricalNoiseFilter.SimpleElectricalNoiseFilter;
@ -225,17 +226,18 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
getIDIManager().setForceCalc(true); getIDIManager().setForceCalc(true);
this.lastIDIData = getIDIManager().getIDIStruct(bitSet); this.lastIDIData = getIDIManager().getIDIStruct(bitSet);
//System.out.println("Time diff: " + lastIDIData.timeDiff + " " + lastIDIData.medianIDI); //System.out.println("Time diff: " + lastIDIData.timeDiff + " " + lastIDIData.medianIDI);
nCoasts=(int) Math.floor(lastIDIData.timeDiff/Math.abs(lastIDIData.medianIDI)); nCoasts=(int) Math.floor(lastIDIData.timeDiff/Math.abs(lastIDIData.medianIDI));
} }
else if (bitcount==1) { else if (bitcount==1) {
//this stops a single units being stuck in the back of the probability matrix. //this stops a single units being stuck in the back of the probability matrix.
nCoasts = (int) Math.floor((newdataUnit.getTimeMilliseconds()/1000. nCoasts = (int) Math.floor(((newdataUnit.getTimeMilliseconds()-getIDIManager().getFirstDataUnit().getTimeMilliseconds())/1000.
-getIDIManager().getLastTime(bitSet)/this.getChi2Params().maxICI)); -getIDIManager().getLastTime(bitSet))/this.getChi2Params().maxICI);
} }
//System.out.println("nCoasts: " + nCoasts);
return nCoasts; return nCoasts;
} }
@ -332,6 +334,8 @@ public class StandardMHTChi2 implements MHTChi2<PamDataUnit>, Cloneable {
double totalTracktime = PamArrayUtils.sum(lastIDIData.idiSeries); 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 * 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 * 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 //19/03/2020 - fixed a bug; Was multiplying instead of dividing - as such long tracks were being
//discriminated against causing fragmentation...ooops //discriminated against causing fragmentation...ooops
chi2=chi2/Math.pow(totalTracktime/getIDIManager().getTotalTime(),getChi2Params().longTrackExponent); 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. //All done. Set the values.
//set the chi2 values. //set the chi2 values.
//long time3=System.nanoTime(); //long time3=System.nanoTime();
//Debug.out.println("Track chi2: " + chi2 + " " + bitcount );
return chi2; return chi2;
} }

View File

@ -2,6 +2,9 @@ package clickTrainDetector.clickTrainAlgorithms.mht.mhtvar;
import PamguardMVC.PamDataUnit; 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 * Chi^2 value for dB amplitude of tracks. Measures the chnage in track delta between
@ -13,9 +16,14 @@ import PamguardMVC.PamDataUnit;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class AmplitudeChi2 extends SimpleChi2VarDelta { public class AmplitudeChi2 extends SimpleChi2VarDelta {
private double lastDiff;
private AmplitudeChi2Params amplitudeParams;
public AmplitudeChi2() { public AmplitudeChi2() {
super(); super();
super.setSimpleChiVarParams(defaultSettings()); super.setSimpleChiVarParams(amplitudeParams = (AmplitudeChi2Params) defaultSettings());
} }
/** /**
@ -23,7 +31,7 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
* @return * @return
*/ */
private SimpleChi2VarParams defaultSettings() { private SimpleChi2VarParams defaultSettings() {
SimpleChi2VarParams simpleChiVarParams = new SimpleChi2VarParams(getName(), getUnits()); AmplitudeChi2Params simpleChiVarParams = new AmplitudeChi2Params(getName(), getUnits());
//simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100}; //simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100};
simpleChiVarParams.error=30; simpleChiVarParams.error=30;
simpleChiVarParams.minError=1; simpleChiVarParams.minError=1;
@ -36,13 +44,15 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
return "Amplitude"; return "Amplitude";
} }
@Override @Override
public double getDiffValue(PamDataUnit pamDataUnit0, PamDataUnit pamDataUnit1) { public double getDiffValue(PamDataUnit pamDataUnit0, PamDataUnit pamDataUnit1) {
//System.out.println("DB: " + pamDataUnit0.getAmplitudeDB()); //System.out.println("DB: " + pamDataUnit0.getAmplitudeDB());
//made this abs so it can deal with increasing then decreasing click trains. i.e. //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 //the click trian is not penalised if it gradually increasing then starts to gradually decrease
//in amplitude. //in amplitude.
return Math.abs(pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB()); this.lastDiff = Math.abs(pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB());
return lastDiff;
} }
@Override @Override
@ -51,12 +61,55 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
return super.getError(); 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 @Override
public String getUnits() { public String getUnits() {
return "dB"; 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) { if (delta>bearingParams.maxBearingJump) {
//System.out.println("Hello!!!! Reverse Bearing"); //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.; 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 @Override
public String getName() { public String getName() {
// TODO Auto-generated method stub
return "Click Length"; return "Click Length";
} }
@ -44,7 +43,7 @@ public class LengthChi2 extends SimpleChi2Var {
//simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100}; //simpleChiVarParams.errLimits=new double[] {Double.MIN_VALUE, 100};
simpleChiVarParams.error=0.2; simpleChiVarParams.error=0.2;
simpleChiVarParams.minError=0.002; simpleChiVarParams.minError=0.002;
simpleChiVarParams.errorScaleValue = SimpleChi2VarParams.SCALE_FACTOR_ICI; simpleChiVarParams.errorScaleValue = SimpleChi2VarParams.SCALE_FACTOR_ICI*10;
return simpleChiVarParams; return simpleChiVarParams;
} }

View File

@ -28,7 +28,7 @@ public class AdvMHTVarPane extends DynamicSettingsPane<SimpleChi2VarParams> {
/** /**
* Default divisor of error for min error. * 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. * 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) { public BearingMHTVarPane(SimpleChi2VarParams simpleChi2Var, ResultConverter resultsConverter) {
super(simpleChi2Var, 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)); 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); 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(); newParams.useFilter=this.useFilterBox.isSelected();

View File

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

View File

@ -98,7 +98,7 @@ public class ClickTrainDetLogging extends SuperDetLogging {
//average spectrum //average spectrum
tableDef.addTableItem(avrg_Spectrum_max = new PamTableItem("avrg_spectrum_max", Types.DOUBLE)); 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(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 //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 //is read from the JSON strings when reloading the data unit. If they end being different something has gone
@ -280,6 +280,8 @@ public class ClickTrainDetLogging extends SuperDetLogging {
//set the classifications. //set the classifications.
String classifiersData = classifiers.getStringValue(); String classifiersData = classifiers.getStringValue();
//FIXME
//System.out.println(classifiersData);
if (classifiersData!=null && classifiersData.length()>0) { if (classifiersData!=null && classifiersData.length()>0) {
String[] classifiersDatas = classifiersData.split(JSON_DELIMITER); String[] classifiersDatas = classifiersData.split(JSON_DELIMITER);

View File

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

View File

@ -14,7 +14,8 @@ import pamViewFX.fxNodes.connectionPane.StandardConnectionNode;
import pamViewFX.fxNodes.connectionPane.structures.ExtensionSocketStructure; 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 * @author Jamie Macaulay
* *
@ -26,6 +27,7 @@ public class PamExtensionStructure extends ExtensionSocketStructure implements P
public PamExtensionStructure(ConnectionPane connectionPane) { public PamExtensionStructure(ConnectionPane connectionPane) {
super(connectionPane); super(connectionPane);
groupStructureParams = new PamStructureParams(this); groupStructureParams = new PamStructureParams(this);
final ContextMenu contextMenu = new ContextMenu(); final ContextMenu contextMenu = new ContextMenu();
@ -35,12 +37,17 @@ public class PamExtensionStructure extends ExtensionSocketStructure implements P
removeStructure(); 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()) { if (event.isSecondaryButtonDown()) {
contextMenu.show(this.getConnectionNodeBody(), event.getScreenX(), event.getScreenY()); 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 //the first row is the waveform
double[] waveform = new double[data.get(0).size()]; double[] waveform = new double[data.get(0).size()];
for (int i=0; i<waveform.length; i++) { 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); waveform[i]=data.get(0).get(i);
} }

View File

@ -71,7 +71,7 @@ public abstract class OfflineTask<T extends PamDataUnit> {
*/ */
PamControlledUnit parentControl = getTaskControlledUnit(); PamControlledUnit parentControl = getTaskControlledUnit();
if (parentControl == null) { 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 { else {
OfflineTaskManager.getManager().registerTask(this); OfflineTaskManager.getManager().registerTask(this);

View File

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

View File

@ -48,6 +48,11 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
*/ */
private PamTabPane mainTabPane; private PamTabPane mainTabPane;
/**
* The preferred width of the side pane.
*/
public static final double SIDE_PANE_PREF_WIDTH = 250;
// /** // /**
// * Icon for menu // * Icon for menu
// */ // */
@ -157,7 +162,9 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
/**create right hiding pane**/ /**create right hiding pane**/
sidePaneContent=new PamVBox(); 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=new HidingPane(Side.RIGHT, sidePaneContent, this, false);
hidingSidePane.showHidePane(false); hidingSidePane.showHidePane(false);
@ -187,6 +194,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
showButtonRight.setPrefWidth(40); showButtonRight.setPrefWidth(40);
showButtonRight.setVisible(true); showButtonRight.setVisible(true);
hidingSidePane.getHideButton().setVisible(false); hidingSidePane.getHideButton().setVisible(false);
//sidePaneContent.setVisible(false);
layout.layout(); layout.layout();
}); });

View File

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

View File

@ -13,41 +13,55 @@ import javafx.util.StringConverter;
*/ */
public class PamSpinner<T> extends Spinner<T>{ 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() { public PamSpinner() {
super(); super();
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
public PamSpinner(double min, double max, double initialValue, double amountToStepBy) { public PamSpinner(double min, double max, double initialValue, double amountToStepBy) {
super(min, max, initialValue, amountToStepBy); super(min, max, initialValue, amountToStepBy);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter(); addDefocusConverter();
} }
public PamSpinner(double min, double max, double initialValue) { public PamSpinner(double min, double max, double initialValue) {
super(min, max, initialValue); super(min, max, initialValue);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter(); addDefocusConverter();
} }
public PamSpinner(int min, int max, int initialValue, int amountToStepBy) { public PamSpinner(int min, int max, int initialValue, int amountToStepBy) {
super(min, max, initialValue, amountToStepBy); super(min, max, initialValue, amountToStepBy);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter(); addDefocusConverter();
} }
public PamSpinner(int min, int max, int initialValue) { public PamSpinner(int min, int max, int initialValue) {
super(min, max, initialValue); super(min, max, initialValue);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter(); addDefocusConverter();
} }
public PamSpinner(ObservableList<T> arg0) { public PamSpinner(ObservableList<T> arg0) {
super(arg0); super(arg0);
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
addDefocusConverter(); addDefocusConverter();
} }
public PamSpinner(SpinnerValueFactory<T> arg0) { public PamSpinner(SpinnerValueFactory<T> arg0) {
super(arg0); super(arg0);
addDefocusConverter(); addDefocusConverter();
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
} }
/** /**

View File

@ -35,6 +35,8 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
*/ */
private static Color bodyColour = Color.DODGERBLUE; private static Color bodyColour = Color.DODGERBLUE;
protected Shape circle;
/** /**
* Extension structure construction. * Extension structure construction.
*/ */
@ -69,7 +71,7 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
@Override @Override
public ConnectionNodeBody createNodeBody() { 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); circle.setFill(bodyColour);
ConnectionNodeBody connectionNodeBody = new ConnectionNodeBody(this); ConnectionNodeBody connectionNodeBody = new ConnectionNodeBody(this);
@ -79,7 +81,6 @@ public class ExtensionSocketStructure extends StandardConnectionNode implements
connectionNodeBody.getChildren().add(circle); connectionNodeBody.getChildren().add(circle);
connectionNodeBody.setPrefHeight(DEFAULT_BODY_WIDTH); connectionNodeBody.setPrefHeight(DEFAULT_BODY_WIDTH);
connectionNodeBody.setPrefWidth(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,9 +1,12 @@
package pamViewFX.fxNodes.sliders.skin; package pamViewFX.fxNodes.sliders.skin;
import javafx.geometry.Orientation;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Slider; import javafx.scene.control.Slider;
import javafx.scene.control.skin.SliderSkin; import javafx.scene.control.skin.SliderSkin;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX; import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
@ -14,33 +17,77 @@ public class PamSliderSkin extends SliderSkin {
/** /**
* Reference to the slider track. * Reference to the slider track.
*/ */
private Node track; private Pane track;
private Slider slider; private Slider slider;
private StackPane topBar;
private Pane thumb;
public PamSliderSkin(Slider slider) { public PamSliderSkin(Slider slider) {
super(slider); super(slider);
this.slider=slider; this.slider=slider;
track = slider.lookup(".track"); track = (Pane) slider.lookup(".track");
thumb = (Pane) slider.lookup(".thumb");
initTopBar();
setTrackColor(Color.RED); 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 @Override
protected void layoutChildren(final double x, final double y, protected void layoutChildren(final double x, final double y,
final double w, final double h) { final double w, final double h) {
super.layoutChildren(x, y, w, 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){ public void setTrackColor(Color trackCol){
track = slider.lookup(".track"); track = (Pane) slider.lookup(".track");
thumb = (Pane) slider.lookup(".thumb");
// int r = (int) (trackCol.getRed() * 255); // int r = (int) (trackCol.getRed() * 255);
// int g = (int) (trackCol.getGreen() * 255); // int g = (int) (trackCol.getGreen() * 255);
// int b = (int) (trackCol.getBlue() * 255); // int b = (int) (trackCol.getBlue() * 255);
// String str = String.format("#%02X%02X%02X;", r, g, b); // 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. //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));
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))); //((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.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Side; import javafx.geometry.Side;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.chart.NumberAxis; import javafx.scene.chart.NumberAxis;
@ -130,10 +131,23 @@ public class FilterPaneFX extends SettingsPane<FilterParams> {
private PamBorderPane mainPane = new PamBorderPane(); private PamBorderPane mainPane = new PamBorderPane();
public FilterPaneFX () { public FilterPaneFX () {
this(Orientation.HORIZONTAL);
}
public FilterPaneFX (Orientation orientaiton) {
super(null); super(null);
if (orientaiton == Orientation.HORIZONTAL) {
mainPane.setLeft(createFilterPane()); mainPane.setLeft(createFilterPane());
mainPane.setCenter(createBodeGraph()); 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. * Create the filter pane. This contains controls to change filter types and shows a graph of the current filter.

View File

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

View File

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

View File

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

View File

@ -307,7 +307,13 @@ public class DLPredictionPlotInfoFX extends GenericLinePlotInfo {
@Override @Override
public double[][] getDetData(PamDataUnit pamDataUnit) { public double[][] getDetData(PamDataUnit pamDataUnit) {
double[] data = PamArrayUtils.float2Double(((DLDataUnit) pamDataUnit).getPredicitionResult().getPrediction()); 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(); defaultTogglePane = createTogglePane();
transfromPane = new DLImageTransformPane(); 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.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Labeled;
import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.Spinner; import javafx.scene.control.Spinner;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.control.Alert.AlertType; 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.Font;
import javafx.scene.text.FontWeight; import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
@ -34,6 +38,7 @@ import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox; import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner; import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamVBox; import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.flipPane.FlipPane;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel; import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
/** /**
@ -114,9 +119,11 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
private ProgressIndicator modelLoadIndicator; private ProgressIndicator modelLoadIndicator;
public StandardModelPane(DLClassiferModel soundSpotClassifier) { public StandardModelPane(DLClassiferModel soundSpotClassifier) {
super(null); super(null);
this.dlClassifierModel=soundSpotClassifier; this.dlClassifierModel=soundSpotClassifier;
mainPane = createPane(); mainPane = createPane();
//the directory chooser. //the directory chooser.
fileChooser = new FileChooser(); fileChooser = new FileChooser();
@ -337,6 +344,11 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
*/ */
public void showAdvPane(PamButton advSettingsButton) { public void showAdvPane(PamButton advSettingsButton) {
// dlClassifierModel.getDLControl().getSettingsPane().setAdvPaneContents(getAdvSettingsPane().getContentNode());
// dlClassifierModel.getDLControl().getSettingsPane().flipToBack();
if (popOver==null) { if (popOver==null) {
popOver = new PopOver(); popOver = new PopOver();
popOver.setContentNode(getAdvSettingsPane().getContentNode()); popOver.setContentNode(getAdvSettingsPane().getContentNode());
@ -353,6 +365,9 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
popOver.show(advSettingsButton); popOver.show(advSettingsButton);
} }
/** /**
* Update the path label and tool tip text; * Update the path label and tool tip text;
*/ */
@ -425,6 +440,15 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
currParams.classNames = paramsClone.classNames; currParams.classNames = paramsClone.classNames;
currParams.numClasses = paramsClone.numClasses; 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(); currParams.useDefaultSegLen = usedefaultSeg.isSelected();
@ -495,8 +519,6 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
} }
} }
} }
@Override @Override

View File

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

View File

@ -35,20 +35,29 @@ public class KetosModelPane extends StandardModelPane {
@Override @Override
public void newModelSelected(File file) { public void newModelSelected(File file) {
//A ketos model contains information on the transforms, duration and the class names.
this.setCurrentSelectedFile(file); this.setCurrentSelectedFile(file);
this.setParamsClone(new KetosDLParams()); this.setParamsClone(new KetosDLParams());
//prep the model with current parameters; //prep the model with current parameters;
ketosClassifier.getKetosWorker().prepModel(getParams(getParamsClone()), ketosClassifier.getDLControl()); 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. //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()); // System.out.println("Ketos transforms 1: " + this.ketosClassifier.getKetosWorker().getModelTransforms());
getParamsClone().dlTransfroms = this.ketosClassifier.getKetosWorker().getModelTransforms(); getParamsClone().dlTransfroms = this.ketosClassifier.getKetosWorker().getModelTransforms();
if (getParamsClone().defaultSegmentLen!=null) {
usedefaultSeg.setSelected(true);
}
//System.out.println("Ketos: " + getParamsClone().dlTransfroms.size()); //System.out.println("Ketos: " + getParamsClone().dlTransfroms.size());
///set the advanced pane parameters. ///set the advanced pane parameters.
getAdvSettingsPane().setParams(getParamsClone()); getAdvSettingsPane().setParams(getParamsClone());
} }
} }

View File

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

View File

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

View File

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

View File

@ -29,7 +29,7 @@ public class SimpleTransformPane extends DLTransformPane {
/** /**
* The default spinner width. * The default spinner width.
*/ */
protected static int prefSpinnerWidth = 80; protected static int PREF_SPINNER_WIDITH = 70;
int nParamCol=10; int nParamCol=10;
@ -80,7 +80,7 @@ public class SimpleTransformPane extends DLTransformPane {
gridPane.setHgap(5); gridPane.setHgap(5);
gridPane.setVgap(5); gridPane.setVgap(5);
gridPane.setPadding(new Insets(5,5.,5.,15)); gridPane.setPadding(new Insets(2,2,2,2));
PamSpinner<Number> spinner; PamSpinner<Number> spinner;
@ -139,7 +139,9 @@ public class SimpleTransformPane extends DLTransformPane {
* @return a new spinner * @return a new spinner
*/ */
protected PamSpinner<Number> createSpinner(int i) { 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 { public enum ExampleSoundType {
BAT_CALL("Bat Call (Myotis daubentonii)"), 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; private final String text;
@ -56,6 +61,16 @@ public class ExampleSoundFactory {
path = getClass().getResource("/Resources/exampleSounds/southern_right_whale_clip2.wav"); path = getClass().getResource("/Resources/exampleSounds/southern_right_whale_clip2.wav");
exampleSound = new SimpleExampleSound(path); exampleSound = new SimpleExampleSound(path);
break; 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: default:
break; break;
} }

View File

@ -144,6 +144,7 @@ public class PlaybackControl extends PamControlledUnit implements PamSettings {
playbackSystem = findPlaybackSystem(sourceDataBlock); playbackSystem = findPlaybackSystem(sourceDataBlock);
playbackProcess.noteNewSettings(); playbackProcess.noteNewSettings();
playbackSidePanel.newSettings(); playbackSidePanel.newSettings();
if (playBackGUI!=null) playBackGUI.notifyGUIChange(PamController.CHANGED_PROCESS_SETTINGS);
// if (this.getSidePanel() != null){ // if (this.getSidePanel() != null){
// this.getSidePanel().getPanel().setVisible(!isRealTimePlayback()); // 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; package soundPlayback.fx;
import java.util.ArrayList; import java.util.ArrayList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import pamViewFX.PamGuiFX;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane; import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamHBox; import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox; import pamViewFX.fxNodes.PamVBox;
@ -13,6 +18,7 @@ import pamViewFX.fxNodes.sliders.PamSlider;
import soundPlayback.PlaybackControl; import soundPlayback.PlaybackControl;
import soundPlayback.preprocess.PlaybackPreprocess; import soundPlayback.preprocess.PlaybackPreprocess;
import soundPlayback.preprocess.PreProcessFXPane; import soundPlayback.preprocess.PreProcessFXPane;
import soundPlayback.preprocess.PreprocessSwingComponent;
/** /**
* Th eplay back side pane. * Th eplay back side pane.
@ -26,6 +32,11 @@ public class PlayBackSidePane extends BorderPane {
*/ */
private PlaybackControl playBackControl; private PlaybackControl playBackControl;
/**
* Label which shows which sound ouptut device is being used.
*/
private Label deviceLabel;
public PlayBackSidePane(PlaybackControl playBackControl) { public PlayBackSidePane(PlaybackControl playBackControl) {
this.playBackControl=playBackControl; this.playBackControl=playBackControl;
this.setCenter(createSidePane()); this.setCenter(createSidePane());
@ -39,29 +50,97 @@ public class PlayBackSidePane extends BorderPane {
PamBorderPane borderPane = new PamBorderPane(); 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(); PamHBox hBox = new PamHBox();
hBox.setSpacing(5); hBox.setSpacing(5);
hBox.getChildren().add(deviceLabel= new Label(""));
PamVBox vBox = new PamVBox();
vBox.setSpacing(5);
borderPane.setCenter(hBox); 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(); ArrayList<PlaybackPreprocess> preProcesses = playBackControl.getPlaybackProcess().getPreProcesses();
PreProcessFXPane preProcessFXPane; PreProcessFXPane preProcessFXPane;
for (int i=0; i<preProcesses.size() ; i++) { for (int i=0; i<preProcesses.size() ; i++) {
//System.out.println("PLAYBACKSIDEPANE: ADDING : " + preProcesses.get(i).toString());
preProcessFXPane = preProcesses.get(i).getSideParPane(); preProcessFXPane = preProcesses.get(i).getSideParPane();
if (preProcessFXPane!=null) { 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; 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; package soundPlayback.fx;
import javax.swing.event.ChangeEvent; import javafx.geometry.Pos;
import javax.swing.event.ChangeListener; 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.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.PlaybackGain;
import soundPlayback.preprocess.PreProcessFXPane; import soundPlayback.preprocess.PreProcessFXPane;
import soundPlayback.swing.BasicSidebarLayout;
import soundPlayback.fx.PlayGainSlider;
public class PlayGainSidePane implements PreProcessFXPane { public class PlayGainSidePane implements PreProcessFXPane {
private PlaybackGain playbackGain; private PlaybackGain playbackGain;
private BasicSidebarLayout basicSidebarLayout;
private PlayGainSlider playGainSlider; 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) { public PlayGainSidePane(PlaybackGain playbackGain) {
this.playbackGain = playbackGain; this.playbackGain = playbackGain;
playGainSlider = new PlayGainSlider(); playGainSlider = new PlayGainSlider();
basicSidebarLayout.setToolTipText("<html>Adjust the output volume.<br>"+ 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."); "N.B. You should also consider turning up the volume in the computers volume controls."));
playGainSlider.addChangeListener((oldval, newVal, obsVal)->{ 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 @Override
public void update() { public void update() {
playGainSlider.setDataValue(playbackGain.getGaindB()); playGainSlider.setDataValue(playbackGain.getGaindB());
setLabelVolGrpahic();
sayGain(); sayGain();
} }
private void sayGain() { private void sayGain() {
basicSidebarLayout.setTextLabel(playbackGain.getTextValue()); //playGainSlider.setTextLabel(playbackGain.getTextValue());
label.setText(playbackGain.getTextValue());
} }
private void gainChanged() { private void gainChanged() {
defaultGainButton.setDisable(false);
playbackGain.setGaindB(playGainSlider.getDataValue()); playbackGain.setGaindB(playGainSlider.getDataValue());
setLabelVolGrpahic();
sayGain(); sayGain();
if (playbackGain.getGaindB()==DEFAULT_GAIN) {
defaultGainButton.setDisable(true);
}
} }
@Override @Override
public Pane getPane() { 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 { 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() { public PlayGainSlider() {
@ -26,4 +26,5 @@ public class PlayGainSlider extends PlaySliderPane {
return MAXGAIN; return MAXGAIN;
} }
} }

View File

@ -1,31 +1,72 @@
package soundPlayback.fx; package soundPlayback.fx;
import javafx.beans.value.ChangeListener; 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; import pamViewFX.fxNodes.sliders.PamSlider;
/** /**
* Default slider pane. * Default slider pane for the sound output sliders.
*
* @author Jamie Macaulay * @author Jamie Macaulay
* *
*/ */
public abstract class PlaySliderPane { public abstract class PlaySliderPane extends PamHBox {
/**
* The slider to chnage the value of something.
*/
private PamSlider slider; private PamSlider slider;
/**
* The label which shows a slider value
*/
private Label sliderLabel;
public PlaySliderPane() { public PlaySliderPane() {
slider = new PamSlider(getMinValue(), getMaxValue(), getMinValue()); slider = new PamSlider(getMinValue(), getMaxValue(), getMinValue());
//slider.setShowTickMarks(true);
slider.setMaxWidth(Double.POSITIVE_INFINITY);
//slider.setShowTickLabels(true);
//setSliderSize(); //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(); public abstract double getMinValue();
/**
* Get the maximum value of the slider.
* @return the maximum value of the slider.
*/
public abstract double getMaxValue(); public abstract double getMaxValue();
/** /**
* @return the slider * @return the slider
*/ */
public PamSlider getSlider() { public Slider getSlider() {
return slider; return slider;
} }
@ -34,7 +75,7 @@ public abstract class PlaySliderPane {
* @return the real scaled value * @return the real scaled value
*/ */
public double getDataValue() { public double getDataValue() {
return slider.getValue(); return posToValue(slider.getValue());
} }
/** /**
@ -42,7 +83,7 @@ public abstract class PlaySliderPane {
* @param value the scaled value. * @param value the scaled value.
*/ */
public void setDataValue(double 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); 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.PlaybackControl;
import soundPlayback.PlaybackParameters; import soundPlayback.PlaybackParameters;
import soundPlayback.PlaybackProcess; import soundPlayback.PlaybackProcess;
import soundPlayback.fx.PlayDecimatorSidePane;
import soundPlayback.swing.DecimatorSideBar; import soundPlayback.swing.DecimatorSideBar;
public class PlaybackDecimator implements PlaybackPreprocess { public class PlaybackDecimator implements PlaybackPreprocess {
@ -23,6 +24,8 @@ public class PlaybackDecimator implements PlaybackPreprocess {
private DecimatorSideBar decimatorSideBar; private DecimatorSideBar decimatorSideBar;
private PlayDecimatorSidePane playDecimatorSidePane;
public PlaybackDecimator(PlaybackControl playbackControl) { public PlaybackDecimator(PlaybackControl playbackControl) {
this.playbackControl = playbackControl; this.playbackControl = playbackControl;
decimatorSideBar = new DecimatorSideBar(this); decimatorSideBar = new DecimatorSideBar(this);
@ -72,7 +75,9 @@ public class PlaybackDecimator implements PlaybackPreprocess {
@Override @Override
public PreProcessFXPane getSideParPane() { public PreProcessFXPane getSideParPane() {
// TODO Auto-generated method stub if (playDecimatorSidePane==null) {
return null; playDecimatorSidePane = new PlayDecimatorSidePane(this);
}
return playDecimatorSidePane;
} }
} }

View File

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

View File

@ -1,5 +1,7 @@
package soundPlayback.preprocess; package soundPlayback.preprocess;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
/** /**
@ -21,4 +23,14 @@ public interface PreProcessFXPane {
*/ */
public void update(); 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();
} }