Implementing FPOD and updates to deep leanring module

This commit is contained in:
Jamie Mac 2024-02-01 16:14:09 +00:00
parent cf93b11a10
commit 9957bd3fa3
54 changed files with 2759 additions and 662 deletions

View File

@ -6,8 +6,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>

View File

@ -1,9 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -13,4 +13,4 @@ org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11
org.eclipse.jdt.core.compiler.source=17

View File

@ -4,7 +4,7 @@
<groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId>
<name>Pamguard Java12+</name>
<version>2.02.09c</version>
<version>2.02.09d</version>
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
<url>www.pamguard.org</url>
<organization>
@ -12,7 +12,7 @@
<url>http://www.smru.st-andrews.ac.uk</url>
</organization>
<build>
<sourceDirectory>src</sourceDirectory>
<sourceDirectory>${basedir}/src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
@ -53,7 +53,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.12.1</version>
<dependencies>
<dependency>
<groupId>org.eclipse.tycho</groupId>
@ -62,22 +62,14 @@
</dependency>
</dependencies>
<configuration>
<release>11</release>
<release>17</release>
<compilerId>jdt</compilerId>
<compilerArguments>
<properties>.settings/org.eclipse.jdt.core.prefs</properties>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<configuration>
<source>17</source>
<target>17</target>
<release>17</release>
</configuration>
<version>0.0.8</version>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>

434
pom.xml
View File

@ -5,8 +5,8 @@
<groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId>
<version>2.02.09d</version>
<name>Pamguard Java12+</name>
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
<name>Pamguard</name>
<description>Pamguard using Maven to control dependencies</description>
<url>www.pamguard.org</url>
<organization>
<name>Sea Mammal Research Unit, University of St. Andrews</name>
@ -14,225 +14,219 @@
</organization>
<properties>
<javafx.version>16</javafx.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<properties>
<project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
<javafx.version>17</javafx.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude> <!-- don't include any source files -->
<exclude>jars/*.*</exclude> <!-- don't include files in the jars folder -->
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<!-- original maven compiler definition - uses the JRE's javac compiler, not the one Eclipse uses
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>13</release>
</configuration>
-->
<!-- attempt to use the Eclipse JDT compiler, so that the errors match when building
https://stackoverflow.com/questions/38070326/java-generics-compiler-error-not-shown-in-eclipse
https://wiki.eclipse.org/JDT/FAQ#Can_I_use_JDT_outside_Eclipse_to_compile_Java_code.3F
https://wiki.eclipse.org/Tycho/FAQ#Can_I_use_the_Tycho_compiler_support_in_non-OSGi_projects.2C_too.3F
-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- set compiler to use Java version 11 API https://docs.oracle.com/javase/9/tools/javac.htm#JSWOR627 -->
<release>11</release>
<compilerId>jdt</compilerId>
<compilerArguments>
<properties>.settings/org.eclipse.jdt.core.prefs</properties> <!-- make sure to use same params as what Eclipse uses -->
</compilerArguments>
</configuration>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.eclipse.tycho/tycho-compiler-jdt -->
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-jdt</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.6</version>
<configuration>
<source>17</source>
<target>17</target>
<release>17</release>
</configuration>
</plugin>
<build>
<!-- Maven Shade plugin - for creating the uberjar / fatjar -->
<!-- see http://maven.apache.org/plugins/maven-shade-plugin/index.html for details -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>pamguard.Pamguard</Main-Class>
<Class-Path>.</Class-Path> <!-- this is from the orig ant build file -->
<SplashScreen-Image>Resources/pgBlankSplash.png</SplashScreen-Image> <!-- this is from the orig ant build file -->
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude> <!-- get rid of manifests from library jars - also done in orig ant build file -->
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!-- The Maven-JDEPS plugin, to analyze necessary JDK dependencies. See
this site for details: https://maven.apache.org/plugins/maven-jdeps-plugin/index.html -->
<plugin>
<groupId>com.github.marschall</groupId>
<artifactId>jdeps-maven-plugin</artifactId>
<version>0.5.1</version>
</plugin>
<!-- The Maven dependency plugin, which can copy all dependencies into a temp folder for jdeps analysis -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/tempDependencies</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
<!-- this deletes all the dependencies in the local repository and downloads them again.
Run a Maven > Update after doing this in order to properly reset the dependencies. Also, you
will need to add the 3 jar files (x3, JasioHost and jave) back into the local repository after
running this command -->
<!-- I'm not sure why, but every time I try to run the shade:shade build to create a
fatjar it first runs this, which deletes all of the dependencies and completely fails.
I think it has something to do with the lifecycle mapping, but that's beyond my Maven
abilities right now.
I can't even remember why I added this in the first place, so I'm going to comment
it out
<execution>
<id>purge-local-dependencies</id>
<phase>process-sources</phase>
<goals>
<goal>purge-local-repository</goal>
</goals>
<configuration>
</configuration>
</execution>
-->
</executions>
</plugin>
<!-- Define where the source and test directories are -->
<sourceDirectory>${basedir}/src</sourceDirectory>
<testSourceDirectory>${basedir}/src/test</testSourceDirectory> <!-- where the Unit tets are located -->
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude> <!-- don't include any source files -->
<exclude>jars/*.*</exclude> <!-- don't include files in the jars folder -->
</excludes>
</resource>
</resources>
<plugins>
<!-- original maven compiler definition - uses the JRE's javac compiler, not the one Eclipse uses
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>13</release>
</configuration>
-->
<!-- attempt to use the Eclipse JDT compiler, so that the errors match when building
https://stackoverflow.com/questions/38070326/java-generics-compiler-error-not-shown-in-eclipse
https://wiki.eclipse.org/JDT/FAQ#Can_I_use_JDT_outside_Eclipse_to_compile_Java_code.3F
https://wiki.eclipse.org/Tycho/FAQ#Can_I_use_the_Tycho_compiler_support_in_non-OSGi_projects.2C_too.3F
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<!-- set compiler to use Java version 11 API https://docs.oracle.com/javase/9/tools/javac.htm#JSWOR627 -->
<release>17</release>
<compilerId>jdt</compilerId>
</configuration>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.eclipse.tycho/tycho-compiler-jdt -->
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-jdt</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
</plugin>
<!-- Set up javafx properly. -->
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
</plugin>
<!-- Maven Shade plugin - for creating the uberjar / fatjar -->
<!-- see http://maven.apache.org/plugins/maven-shade-plugin/index.html for details -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>pamguard.Pamguard</Main-Class>
<Class-Path>.</Class-Path> <!-- this is from the orig ant build file -->
<SplashScreen-Image>Resources/pgBlankSplash.png</SplashScreen-Image> <!-- this is from the orig ant build file -->
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude> <!-- get rid of manifests from library jars - also done in orig ant build file -->
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!-- The Maven-JDEPS plugin, to analyze necessary JDK dependencies. See
this site for details: https://maven.apache.org/plugins/maven-jdeps-plugin/index.html -->
<plugin>
<groupId>com.github.marschall</groupId>
<artifactId>jdeps-maven-plugin</artifactId>
<version>0.5.1</version>
</plugin>
<!-- The Maven dependency plugin, which can copy all dependencies into a temp folder for jdeps analysis -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/tempDependencies</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
<!-- this deletes all the dependencies in the local repository and downloads them again.
Run a Maven > Update after doing this in order to properly reset the dependencies. Also, you
will need to add the 3 jar files (x3, JasioHost and jave) back into the local repository after
running this command -->
<!-- I'm not sure why, but every time I try to run the shade:shade build to create a
fatjar it first runs this, which deletes all of the dependencies and completely fails.
I think it has something to do with the lifecycle mapping, but that's beyond my Maven
abilities right now.
I can't even remember why I added this in the first place, so I'm going to comment
it out
<execution>
<id>purge-local-dependencies</id>
<phase>process-sources</phase>
<goals>
<goal>purge-local-repository</goal>
</goals>
<configuration>
</configuration>
</execution>
-->
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[3.1.1,)
</versionRange>
<goals>
<goal>
purge-local-repository
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<versionRange>
[3.1.1,)
</versionRange>
<goals>
<goal>
purge-local-repository
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>com.github.marschall</groupId>
<artifactId>jdeps-maven-plugin</artifactId>
<version>0.5.1</version>
</plugin>
</plugins>
</reporting>
<reporting>
<plugins>
<plugin>
<groupId>com.github.marschall</groupId>
<artifactId>jdeps-maven-plugin</artifactId>
<version>0.5.1</version>
</plugin>
</plugins>
</reporting>
<!-- ************************* Extra Repositories ************************************* -->
<repositories>
<repositories>
<!-- Project repo to hold the custom jar files that are not available in Maven. Do
this so that we don't have to do the extra step of manually installing jar files in the local repo -->
<repository>
@ -308,12 +302,12 @@
<url>https://repo1.maven.org/maven2</url>
</repository>
</repositories>
</repositories>
<!-- ************************* Dependencies ************************************* -->
<dependencies>
<!--jpam project - utilities -->
<dependency>
<groupId>io.github.macster110</groupId>
@ -836,12 +830,6 @@ C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2-->
<version>1.6.5-1</version>
</dependency>
<!-- Theme for JavaFX -->
<dependency>
<groupId>io.github.mkpaz</groupId>
<artifactId>atlantafx-base</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Extra 3D bits for JavaFX -->
<dependency>

View File

@ -14,6 +14,7 @@ import javafx.event.EventHandler;
import javafx.scene.AmbientLight;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
@ -23,7 +24,7 @@ import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Shape3D;
import javafx.scene.shape.Sphere;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
@ -57,7 +58,7 @@ public class Array3DPane extends PamBorderPane {
public static final Color DEFAULT_HYDRO_COL = Color.RED;
// private static final Color DEFAULT_SENSOR_COL = Color.LIMEGREEN;
// private static final Color DEFAULT_SENSOR_COL = Color.LIMEGREEN;
private double scaleFactor=20;
@ -97,23 +98,39 @@ public class Array3DPane extends PamBorderPane {
* The size of the hydrophone for the 3D display.
*/
private double hydrophoneSize = 0.5;
/**
* Holds a list of hydrophone spheres
*/
private ArrayList<HydrophoneSphere> hydrophonesSpheres = new ArrayList<HydrophoneSphere>();
/**
* Allow rotation
*/
private boolean allowRotate = true;
private Text xText;
private Text yText;
private Text zText;
private Box yAxis;
private Shape3D ySphere;
public Array3DPane(){
// Create and position camera
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(20000);
camera.setNearClip(0.1);
camera.setDepthTest(DepthTest.ENABLE);
// camera.setDepthTest(DepthTest.ENABLE);
camera.getTransforms().addAll (
rotateY=new Rotate(-45, Rotate.Y_AXIS),
rotateX=new Rotate(-45, Rotate.X_AXIS),
translate=new Translate(0, 200, -2000));
translate=new Translate(0, 0, -2000));
//create main 3D group
root3D=new Group();
@ -136,33 +153,33 @@ public class Array3DPane extends PamBorderPane {
subScene.widthProperty().bind(this.widthProperty());
subScene.heightProperty().bind(this.heightProperty());
subScene.setDepthTest(DepthTest.ENABLE);
subScene.setOnMouseClicked((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
PickResult pr = me.getPickResult();
// System.out.println("Picked something sphere: " + pr);
//clear selected radius
for (HydrophoneSphere sphere : hydrophonesSpheres) {
sphere.setRadius(hydrophoneSize*scaleFactor);
}
if(pr!=null && pr.getIntersectedNode() != null && pr.getIntersectedNode() instanceof Sphere){
//make the selected sphere slightly larger
HydrophoneSphere s = (HydrophoneSphere) pr.getIntersectedNode();
s.setRadius(hydrophoneSize*scaleFactor*1.2);
hydrophoneSelected(s.getHydrophone());
// System.out.println("Picked a sphere: " + pr);
// distance=pr.getIntersectedDistance();
// s = (Sphere) pr.getIntersectedNode();
// isPicking=true;
// vecIni = unProjectDirection(mousePosX, mousePosY, scene.getWidth(),scene.getHeight());
}
});
subScene.setOnMouseClicked((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
PickResult pr = me.getPickResult();
// System.out.println("Picked something sphere: " + pr);
//clear selected radius
for (HydrophoneSphere sphere : hydrophonesSpheres) {
sphere.setRadius(hydrophoneSize*scaleFactor);
}
if(pr!=null && pr.getIntersectedNode() != null && pr.getIntersectedNode() instanceof Sphere){
//make the selected sphere slightly larger
HydrophoneSphere s = (HydrophoneSphere) pr.getIntersectedNode();
s.setRadius(hydrophoneSize*scaleFactor*1.2);
hydrophoneSelected(s.getHydrophone());
// System.out.println("Picked a sphere: " + pr);
// distance=pr.getIntersectedDistance();
// s = (Sphere) pr.getIntersectedNode();
// isPicking=true;
// vecIni = unProjectDirection(mousePosX, mousePosY, scene.getWidth(),scene.getHeight());
}
});
//note the fill is actually quite important because if you don't have it mouse rotations etc
//onyl work if you select a 3D shape
@ -172,7 +189,7 @@ public class Array3DPane extends PamBorderPane {
//handle mouse events for sub scene
handleMouse(subScene);
resetView();
//create new group to add sub scene to
Group group = new Group();
@ -208,7 +225,7 @@ public class Array3DPane extends PamBorderPane {
* Create a 3D axis.
* @param- size of the axis
*/
public static Group buildAxes(double axisSize, Color xAxisDiffuse, Color xAxisSpectacular,
public Group buildAxes(double axisSize, Color xAxisDiffuse, Color xAxisSpectacular,
Color yAxisDiffuse, Color yAxisSpectacular,
Color zAxisDiffuse, Color zAxisSpectacular,
Color textColour) {
@ -230,18 +247,18 @@ public class Array3DPane extends PamBorderPane {
blueMaterial.setDiffuseColor(zAxisDiffuse);
blueMaterial.setSpecularColor(zAxisSpectacular);
Text xText=new Text("x");
xText.setStyle("-fx-font: 20px Tahoma;");
xText=new Text("x");
xText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
xText.setFill(textColour);
xText.setStroke(textColour);
Text yText=new Text("z");
yText.setStyle("-fx-font: 20px Tahoma; ");
yText=new Text("z");
yText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
yText.setFill(textColour);
yText.setStroke(textColour);
Text zText=new Text("y");
zText.setStyle("-fx-font: 20px Tahoma; ");
zText=new Text("y");
zText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
zText.setFill(textColour);
zText.setStroke(textColour);
@ -254,7 +271,7 @@ public class Array3DPane extends PamBorderPane {
zText.setTranslateZ(axisSize+5);
Sphere xSphere = new Sphere(radius);
Sphere ySphere = new Sphere(radius);
ySphere = new Sphere(radius);
Sphere zSphere = new Sphere(radius);
xSphere.setMaterial(redMaterial);
ySphere.setMaterial(greenMaterial);
@ -265,7 +282,7 @@ public class Array3DPane extends PamBorderPane {
zSphere.setTranslateZ(axisSize);
Box xAxis = new Box(length, width, width);
Box yAxis = new Box(width, length, width);
yAxis = new Box(width, length, width);
Box zAxis = new Box(width, width, length);
xAxis.setMaterial(redMaterial);
yAxis.setMaterial(greenMaterial);
@ -302,6 +319,7 @@ public class Array3DPane extends PamBorderPane {
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
mouseOldX = mousePosX;
@ -320,9 +338,11 @@ public class Array3DPane extends PamBorderPane {
if (me.isShiftDown()) {
modifier = 10.0;
}
if (me.isPrimaryButtonDown()) {
if (me.isPrimaryButtonDown() && allowRotate) {
rotateY.setAngle(rotateY.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0); // +
rotateX.setAngle(rotateX.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0); // -
// System.out.println("Rotation: x: " + rotateX.getAngle() + " y: " + rotateY.getAngle());
}
if (me.isSecondaryButtonDown()) {
translate.setX(translate.getX() -mouseDeltaX * modifierFactor * modifier * 5);
@ -340,7 +360,7 @@ public class Array3DPane extends PamBorderPane {
*/
public void drawArray(PamArray array) {
// System.out.println("DRAW ARRAY: " + array);
// System.out.println("DRAW ARRAY: " + array);
//clear the array
arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
@ -352,13 +372,13 @@ public class Array3DPane extends PamBorderPane {
Streamer streamer;
hydrophonesSpheres.clear();
for (int i=0; i<hydrophones.size(); i++){
//get the streamer for the hydrophone
streamer = array.getStreamer(hydrophones.get(i).getStreamerId());
double x = hydrophones.get(i).getX() + hydrophones.get(i).getStreamerId();
double y = hydrophones.get(i).getY() + hydrophones.get(i).getStreamerId();
double z = hydrophones.get(i).getZ() + hydrophones.get(i).getStreamerId();
double x = (hydrophones.get(i).getX() + streamer.getCoordinate(0));
double y = (hydrophones.get(i).getY() + streamer.getCoordinate(1));
double z = -(hydrophones.get(i).getZ() + streamer.getCoordinate(2));
sphere=new HydrophoneSphere(hydrophoneSize*scaleFactor);
sphere.setTranslateX(x*scaleFactor);
@ -373,21 +393,21 @@ public class Array3DPane extends PamBorderPane {
sphere.setMaterial(aMaterial);
sphere.setHydrophone(hydrophones.get(i));
// System.out.println("Add hydrophone: " + x + " " + y + " " +z);
// System.out.println("Add hydrophone: " + x + " " + y + " " +z);
hydrophonesSpheres.add(sphere);
arrayGroup.getChildren().add(sphere);
ArrayList<Point3D> streamerPoints=new ArrayList<Point3D>();
//now plot a line from the streamer to the hydrophone
Point3D newPoint;
newPoint=new Point3D(x*scaleFactor, z*scaleFactor, y*scaleFactor);
streamerPoints.add(newPoint);
newPoint =new Point3D(streamer.getCoordinate(0)*scaleFactor, streamer.getCoordinate(2)*scaleFactor, streamer.getCoordinate(1)*scaleFactor);
newPoint =new Point3D(streamer.getCoordinate(0)*scaleFactor, -streamer.getCoordinate(2)*scaleFactor, streamer.getCoordinate(1)*scaleFactor);
streamerPoints.add(newPoint);
System.out.println("Streamer points: " + streamerPoints.size());
PolyLine3D polyLine3D=new PolyLine3D(streamerPoints, 4f, Color.DODGERBLUE);
@ -397,13 +417,13 @@ public class Array3DPane extends PamBorderPane {
private class HydrophoneSphere extends Sphere {
Hydrophone hydrophone;
public Hydrophone getHydrophone() {
return hydrophone;
}
public void setHydrophone(Hydrophone hydrophone) {
@ -413,13 +433,67 @@ public class Array3DPane extends PamBorderPane {
public HydrophoneSphere() {
super();
}
public HydrophoneSphere(double radius) {
super(radius);
}
}
/**
* Sets the pane to show hydrophones in 2D or 3D.
* @param set3D - true to set to 3D
*/
public void set3D(boolean set3D) {
double textRotation =0;
if (set3D) {
allowRotate=true;
xText.setRotate(0);
rotateY.setAngle(-45);
rotateX.setAngle(-45);
}
else {
allowRotate=false;
rotateY.setAngle(0);
rotateX.setAngle(270);
textRotation=-90;
}
//confusing because the yaxis is the z axis in JavaFX...
yText.setVisible(set3D);
yAxis.setVisible(set3D);
ySphere.setVisible(set3D);
xText.setRotate(textRotation);
xText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
yText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
yText.setRotate(textRotation);
zText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
zText.setRotate(textRotation);
}
/**
* Reset to the defulat view.
*/
public void resetView() {
translate.setX(0);
translate.setY(0);
translate.setZ( -2000);
if (allowRotate) {
rotateY.setAngle(-45);
rotateX.setAngle(-45);
}
}
// /**
// * Draw the entire array
// * @param pos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.

View File

@ -2,17 +2,23 @@ package Array.layoutFX;
import java.io.File;
import org.controlsfx.control.SegmentedButton;
import Array.ArrayManager;
import Array.Hydrophone;
import Array.PamArray;
import PamController.PamController;
import PamController.SettingsPane;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.layout.VBox;
@ -35,7 +41,7 @@ import pamViewFX.fxNodes.PamHBox;
*
*/
public class ArraySettingsPane extends SettingsPane<PamArray >{
/**
* Minimum size of the 3D pane.
*/
@ -50,15 +56,15 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
* Pane for adding or removing streamers.
*/
private StreamersPane streamerPane;
private PamBorderPane mainPane;
/**
* Pane for adding or removing hydrophones.
*/
private HydrophonesPane hydrophonePane;
// private Pane holder;
// private Pane holder;
private Label hydrophoneLabel;
@ -83,16 +89,16 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
public ArraySettingsPane() {
super(null);
mainPane=new PamBorderPane();
mainPane.setCenter(createArrayPane());
// mainPane.setStyle("-fx-background-color: red;");
// mainPane.setStyle("-fx-background-color: red;");
mainPane.setMaxWidth(Double.MAX_VALUE);
mainPane.setMinWidth(1100);
mainPane.setStyle("-fx-padding: 0,0,0,0");
recivierDiagramLabel = new Label("Hydrophone Diagram");
PamGuiManagerFX.titleFont1style(recivierDiagramLabel);
recivierDiagramLabel.setPadding(new Insets(5,5,5,5));
@ -100,78 +106,123 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
Label environmentLabel = new Label("Environment");
PamGuiManagerFX.titleFont1style(environmentLabel);
environmentLabel.setPadding(new Insets(0,0,5,0)); //little more space under this label
environmentalPane = createEnvironmentPane();
PamVBox rightPane = new PamVBox();
rightPane.setSpacing(5);
rightPane.getChildren().addAll(recivierDiagramLabel, create3DPane(), environmentLabel, new PamBorderPane(environmentalPane.getContentNode()));
VBox.setVgrow(array3DPane, Priority.ALWAYS);
Pane hydrophone3DPane = create3DPane();
rightPane.getChildren().addAll(recivierDiagramLabel, hydrophone3DPane, environmentLabel, new PamBorderPane(environmentalPane.getContentNode()));
VBox.setVgrow(hydrophone3DPane, Priority.ALWAYS);
mainPane.setRight(rightPane);
// streamerPane.getStreamerTable().getItems().addListener((ListChangeListener<? super StreamerProperty>) c->{
// //the streamer table has changed and so the streamer needs changed
// System.out.println("Streamer Changed!!!");
// });
// streamerPane.getStreamerTable().getItems().addListener((ListChangeListener<? super StreamerProperty>) c->{
// //the streamer table has changed and so the streamer needs changed
// System.out.println("Streamer Changed!!!");
// });
streamerPane.addStreamerListener((x,y)->{
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
System.out.println("Streamer changed!");
array3DPane.drawArray(array);
});
hydrophonePane.addStreamerListener((x,y)->{
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
System.out.println("Hydrophone changed!" + array.getHydrophoneCount());
array3DPane.drawArray(array);
});
// mainPane.setMinWidth(800);
// mainPane.setMinWidth(800);
// mainPane.setCenter(createArrayPane());
//
// mainPane.getAdvPane().setCenter(new Label("Advanced Settings"));
// //mainPane.getFront().setStyle("-fx-background-color: grey;");
// mainPane.setStyle("-fx-background-color: red;");
//
// FlipPane aflipPane = new FlipPane();
// aflipPane.setStyle("-fx-background-color: red;");
//
// PamHBox stackPane = new PamHBox();
// stackPane.setStyle("-fx-background-color: red;");
//
// Button button = new Button();
// button.setOnAction((action)->{
// System.out.println(" 1 " + stackPane.getPadding());
// System.out.println(" 2 " +PamBorderPane.getMargin(stackPane));
// System.out.println(" 3 " + holder.getPadding());
// });
//
// stackPane.getChildren().add(button);
//
//
// mainPane.setPadding(new Insets(0,0,0,0));
// holder = new StackPane();
// holder.getChildren().add(mainPane);
// holder.setStyle("-fx-padding: 0,0,0,0");
// mainPane.setCenter(createArrayPane());
//
// mainPane.getAdvPane().setCenter(new Label("Advanced Settings"));
// //mainPane.getFront().setStyle("-fx-background-color: grey;");
// mainPane.setStyle("-fx-background-color: red;");
//
// FlipPane aflipPane = new FlipPane();
// aflipPane.setStyle("-fx-background-color: red;");
//
// PamHBox stackPane = new PamHBox();
// stackPane.setStyle("-fx-background-color: red;");
//
// Button button = new Button();
// button.setOnAction((action)->{
// System.out.println(" 1 " + stackPane.getPadding());
// System.out.println(" 2 " +PamBorderPane.getMargin(stackPane));
// System.out.println(" 3 " + holder.getPadding());
// });
//
// stackPane.getChildren().add(button);
//
//
// mainPane.setPadding(new Insets(0,0,0,0));
// holder = new StackPane();
// holder.getChildren().add(mainPane);
// holder.setStyle("-fx-padding: 0,0,0,0");
}
private Pane create3DPane() {
this.array3DPane = new HydrophoneArray3DPane();
//important because the 3D pane has not default size
array3DPane.setMinWidth(MIN_3D_WIDTH);
array3DPane.setMinHeight(MIN_3D_HEIGHT);
return array3DPane;
StackPane stackPane = new StackPane();
this.array3DPane = new HydrophoneArray3DPane();
//important because the 3D pane has not default size
stackPane.setMinWidth(MIN_3D_WIDTH);
stackPane.setMinHeight(MIN_3D_HEIGHT);
// stackPane.prefHeightProperty().bind(mainPane.heightProperty().subtract(100));
stackPane.getChildren().add(array3DPane);
//add buttons
ToggleButton b1 = new ToggleButton("2D");
ToggleButton b2 = new ToggleButton("3D");
b1.setOnAction((action)->{
array3DPane.set3D(false);
});
b2.setOnAction((action)->{
array3DPane.set3D(true);
});
SegmentedButton segmentedButton = new SegmentedButton();
segmentedButton.getButtons().addAll(b1, b2);
segmentedButton.setPadding(new Insets(5,5,5,5));
segmentedButton.setMinWidth(100);
StackPane.setAlignment(segmentedButton, Pos.TOP_RIGHT);
stackPane.getChildren().add(segmentedButton);
final ContextMenu contextMenu = new ContextMenu();
final MenuItem item1 = new MenuItem("Reset");
item1.setOnAction((action)->{
array3DPane.resetView();
});
contextMenu.getItems().add(item1);
segmentedButton.setContextMenu(contextMenu);
// stackPane.setOnContextMenuRequested(e ->
// contextMenu.show(stackPane, e.getScreenX(), e.getScreenY()));
b2.setSelected(true);
return stackPane;
}
/**
* Create the environment pane.
* @return the environment pane.
@ -186,22 +237,22 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
* @return the main array pane.
*/
private Pane createArrayPane() {
Label arrayLabel = new Label("Array");
arrayLabel.setPadding(new Insets(5,5,5,5));
PamGuiManagerFX.titleFont1style(arrayLabel);
//holds the array label and also some button for import and export.
PamHBox arrayImportExportBox = new PamHBox();
arrayImportExportBox.setSpacing(5);
arrayImportExportBox.setAlignment(Pos.CENTER_LEFT);
arrayImportExportBox.setPadding(new Insets(5,0,0,0));
fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("PAMNGuard Array Files", "*.paf"));
fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("PAMNGuard Array Files", "*.paf"));
PamButton importButton = new PamButton("Import...");
importButton.setOnAction((action)->{
importArray();
@ -215,13 +266,13 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
});
exportButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-export", PamGuiManagerFX.iconSize));
exportButton.setTooltip(new Tooltip("Export array settings to a .pgaf file"));
//balnk region to make it look nicer
Region blank = new Region();
blank.setPrefWidth(70);
arrayImportExportBox.getChildren().addAll(importButton, exportButton, blank);
PamBorderPane titleHolder = new PamBorderPane();
titleHolder.setLeft(arrayLabel);
titleHolder.setRight(arrayImportExportBox);
@ -229,25 +280,25 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
//the streamer pane for changing streamer settings.
streamerPane = new StreamersPane();
streamerPane.setMaxWidth(Double.MAX_VALUE);
hydrophoneLabel = new Label("Hydrophones");
PamGuiManagerFX.titleFont1style(hydrophoneLabel);
hydrophoneLabel.setPadding(new Insets(5,5,5,5));
hydrophonePane = new HydrophonesPane();
hydrophonePane.setMaxWidth(Double.MAX_VALUE);
// PamButton advancedButton = new PamButton();
// advancedButton.setOnAction((action)->{
// mainPane.flipToBack();
// });
// advancedButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog"));
// PamButton advancedButton = new PamButton();
// advancedButton.setOnAction((action)->{
// mainPane.flipToBack();
// });
// advancedButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog"));
// PamHBox advancedPane = new PamHBox();
// advancedPane.setSpacing(5);
// advancedPane.setAlignment(Pos.CENTER_RIGHT);
// advancedPane.getChildren().addAll(new Label("Advanced"), advancedButton);
// PamHBox advancedPane = new PamHBox();
// advancedPane.setSpacing(5);
// advancedPane.setAlignment(Pos.CENTER_RIGHT);
// advancedPane.getChildren().addAll(new Label("Advanced"), advancedButton);
PamVBox vBox = new PamVBox();
vBox.setSpacing(5);
vBox.getChildren().addAll(titleHolder, streamerPane, hydrophoneLabel,
@ -285,34 +336,34 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
private void setReceieverLabels() {
hydrophonePane.setRecieverLabels();
streamerPane.setRecieverLabels();
hydrophoneLabel.setText(PamController.getInstance().getGlobalMediumManager().getRecieverString(true) + "s");
recivierDiagramLabel.setText(PamController.getInstance().getGlobalMediumManager().getRecieverString(true) + " diagram");
// if (singleInstance!=null) {
// singleInstance.setTitle("Pamguard "+ PamController.getInstance().getGlobalMediumManager().getRecieverString(false) +" array");
// }
// if (singleInstance!=null) {
// singleInstance.setTitle("Pamguard "+ PamController.getInstance().getGlobalMediumManager().getRecieverString(false) +" array");
// }
}
@Override
public PamArray getParams(PamArray currParams) {
currParams = streamerPane.getParams(currParams);
currParams = hydrophonePane.getParams(currParams);
currParams.setHydrophoneInterpolation(hydrophonePane.getHydrophoneInterp());
currParams = environmentalPane.getParams(currParams);
// System.out.println("Array settings pane: No. streamers: " + currParams.getStreamerCount());
// System.out.println("Array settings pane: No. streamers: " + currParams.getStreamerCount());
return currParams;
}
@Override
public void setParams(PamArray input) {
this.currentArray = input.clone();
// System.out.println("Hydrophone array is: "+ input);
// System.out.println("Hydrophone array is: "+ input);
setReceieverLabels();
hydrophonePane.setParams(input);
streamerPane.setParams(input);
environmentalPane.setParams(input);
//draw the array
array3DPane.drawArray(input);
}
@ -331,16 +382,16 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
@Override
public void paneInitialized() {
// TODO Auto-generated method stub
}
private class HydrophoneArray3DPane extends Array3DPane {
@Override
public void hydrophoneSelected(Hydrophone hydrophone) {
hydrophonePane.selectHydrophone(hydrophone);
}
}
}

View File

@ -82,7 +82,7 @@ public class HydrophonesPane extends PamBorderPane {
tableArrayPane.setPadding(new Insets(5,5,5,5));
pamFlipePane = new PamFlipPane();
pamFlipePane.getAdvLabel().setText("Hydrophone Settings");
pamFlipePane.getAdvLabel().setText(PamController.getInstance().getGlobalMediumManager().getRecieverString());
// pamFlipePane.minWidthProperty().bind(this.widthProperty());
// pamFlipePane.setStyle("-fx-background-color: green;");

View File

@ -109,10 +109,13 @@ public class CPODBinaryStore extends BinaryDataSource {
private void writeCPODData(DataOutputStream dos2, CPODClick cd) throws IOException {
//CPOD has 8 bytes - FPOD has more
dos.writeInt(cd.getRawData().length);
for (int i=0; i<cd.getRawData().length; i++) {
dos.writeShort(cd.getRawData()[i]);
};
}
@Override

View File

@ -7,6 +7,9 @@ import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.superdet.SuperDetection;
/**
* CPOD click.
*/
public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implements AcousticDataUnit {
private short nCyc;
@ -57,6 +60,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
int t = shortData[0]<<16 |
shortData[1]<<8 |
shortData[2]; // 5 microsec intervals !
long tMillis = minuteMillis + t/200;
// now a bit of time stretching. Need to get the start time and see how
// different this is, then it's a linear stretch.
@ -90,6 +94,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
shortData[1]<<8 |
shortData[2]; // 5 microsec intervals !
long tMillis = minuteMillis + t/200;
// now a bit of time stretching. Need to get the start time and see how
// different this is, then it's a linear stretch.
tMillis = cpodControl.stretchClicktime(tMillis);
@ -137,8 +142,11 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
//estimate the duration in millis - not accurate but gives an idea.
double duration = (nCyc/(double) kHz);
this.setDurationInMilliseconds(duration);
this.rawData = shortData.clone();
if (shortData!=null) {
//only CPOD
this.rawData = shortData.clone();
}
}
/**

View File

@ -91,7 +91,7 @@ public class CPODControl extends OfflineFileControl implements PamSettings {
* @return milliseconds.
*/
public static long podTimeToMillis(long podTime) {
return podTime * 60L * 1000L - (25569L*3600L*24000L);
return CPODUtils.podTimeToMillis(podTime);
}
public long stretchClicktime(long rawTime) {

View File

@ -3,6 +3,7 @@ package cpod;
import java.awt.Frame;
import java.io.File;
import java.io.Serializable;
import java.util.List;
import javax.swing.JMenuItem;
@ -21,10 +22,11 @@ import cpod.fx.CPODGUIFX;
import cpod.fx.CPODSettingsPane;
import dataPlotsFX.data.TDDataProviderRegisterFX;
import fileOfflineData.OfflineFileParams;
import javafx.concurrent.Task;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
/**
* CPOD control. Loads and manages CPOD (and hopefully soon FPOD) data into
* CPOD control. Loads and manages CPOD and FPOD data into
* PAMGaurd.
* <p>
* Note that this module (CPODControl) originally used a folder of CP1 files as it's file store but
@ -83,7 +85,7 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
* CPOD importer.
*/
private CPODImporter cpodImporter;
public CPODControl2(String unitName) {
super("CPOD", unitName);
@ -101,6 +103,7 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
// add the CP3 data block
cpodProcess.addOutputDataBlock(cp3DataBlock = new CPODClickDataBlock("CP3 Data",
cpodProcess, CPODMap.FILE_CP3));
cp3DataBlock.setPamSymbolManager(new CPODSymbolManager(this, cp3DataBlock));
cp3DataBlock.setDatagramProvider(cpodDataGramProvider[1] = new CPODDataGramProvider(this));
cp3DataBlock.setBinaryDataSource(new CPODBinaryStore(this, cp1DataBlock));
@ -112,7 +115,6 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
cpodImporter = new CPODImporter(this);
//FX display data providers
CPODPlotProviderFX cpodPlotProviderFX = new CPODPlotProviderFX(this, cp1DataBlock);
TDDataProviderRegisterFX.getInstance().registerDataInfo(cpodPlotProviderFX);
@ -146,19 +148,6 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
}
/**
* Convert POD time to JAVA millis - POD time is
* integer minutes past the same epoc as Windows uses
* i.e. 0th January 1900.
* @param podTime
* @return milliseconds.
*/
public static long podTimeToMillis(long podTime) {
return podTime * 60L * 1000L - (25569L*3600L*24000L);
}
public long stretchClicktime(long rawTime) {
if (cp1DataBlock.getDatagrammedMap() == null) {
return rawTime;
@ -213,9 +202,6 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
/**** GUI ****/
/**
* Get the settings pane.
*
@ -302,4 +288,13 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
return cpodImporter;
}
/**
* Import POD data. This will either be a list of CPOD or FPOD files.
* @param files - the files to import.
* @return a list of import Tasks.
*/
public List<Task<Integer>> importPODData(List<File> files) {
return cpodImporter.importCPODData(files);
}
}

View File

@ -24,10 +24,11 @@ import binaryFileStorage.BinaryFooter;
import binaryFileStorage.BinaryObjectData;
import binaryFileStorage.BinaryOutputStream;
import binaryFileStorage.BinaryStore;
import cpod.FPODReader.FPODdata;
import javafx.concurrent.Task;
/**
* Imports data CPOD data and converts into binary files.
* Imports FPOD and CPOD data and converts into binary files.
*
* @author Jamie Macaulay
*
@ -61,7 +62,7 @@ public class CPODImporter {
CPODFileType cpFileType = CPODFileType.CP1;
/**
* Hnadles the queue for importing files tasks
* Handles the queue for importing files tasks
*/
private ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
@ -76,9 +77,9 @@ public class CPODImporter {
*/
public enum CPODFileType {
CP1("CP1"),
CP3("CP3");
// FP1("fp1"),
// FP3("fp3");
CP3("CP3"),
FP1("FP1"),
FP3("FP3");
private String text;
@ -110,7 +111,7 @@ public class CPODImporter {
public static CPODFileType getFileType(File cpFile) {
for (int i=0; i<CPODFileType.values().length; i++) {
if (cpFile.getAbsolutePath().toLowerCase().endsWith(CPODFileType.values()[i].getText())) {
if (cpFile.getAbsolutePath().toLowerCase().endsWith(CPODFileType.values()[i].getText().toLowerCase())) {
return CPODFileType.values()[i];
}
}
@ -124,6 +125,10 @@ public class CPODImporter {
return 360;
case CP3:
return 720;
case FP1:
return 1024;
case FP3:
return 1024;
}
return 0;
}
@ -134,6 +139,10 @@ public class CPODImporter {
return 10;
case CP3:
return 40;
case FP1:
return 16;
case FP3:
return 32;
}
return 0;
}
@ -154,15 +163,113 @@ public class CPODImporter {
protected int importFile(File cpFile, CPODClickDataBlock dataBlock) {
return importFile( cpFile, dataBlock, -1, Integer.MAX_VALUE);
}
/**
* Import a file.
* @param cpFile - the CP1 file.
* Import a CPOD or FPOD file.
* @param cpFile - the CP1/FP1 or CP3/FP3 file.
* @param from - the click index to save from. e.g. 100 means that only click 100 + in the file is saved
* @param maxNum
* @return the total number of clicks int he file.
* @param maxNum - the maximum number to import
* @return the total number of clicks in the file.
*/
protected int importFile(File cpFile, CPODClickDataBlock dataBlock, int from, int maxNum) {
CPODFileType fileType = getFileType( cpFile);
switch (fileType) {
case CP1:
case CP3:
return importCPODFile(cpFile, dataBlock, from, maxNum);
case FP1:
case FP3:
return importFPODFile(cpFile, dataBlock, from, maxNum);
}
return 0;
}
/**
* Import a FPOD file.
* @param cpFile - the FP1 or FP3 file.
* @param from - the click index to save from. e.g. 100 means that only click 100 + in the file is saved
* @param maxNum - the maximum number to import
* @return the total number of clicks in the file.
*/
protected int importFPODFile(File cpFile, CPODClickDataBlock dataBlock, int from, int maxNum) {
ArrayList<FPODdata> fpodData = new ArrayList<FPODdata>();
try {
FPODReader.importFile(cpFile, fpodData, from, maxNum);
} catch (IOException e) {
e.printStackTrace();
}
// fileStart + nMinutes * 60000L;
int nClicks = 0;
for (int i=0; i<fpodData.size(); i++) {
//System.out.println("Create a new CPOD click: ");
CPODClick cpodClick = processClick(fpodData.get(i));
dataBlock.addPamData(cpodClick);
nClicks++;
}
fpodData=null; //trigger garbage collector if needed
return nClicks;
}
/**
* Process the click.
* @param FPODData - an FPOD data object
* @return
*/
private CPODClick processClick(FPODdata fpoDdata) {
//how many samples are we into the clicks
long fileSamples = (long) (((fpoDdata.minute*60) + (fpoDdata.FiveMusec*5/1000000.))*CPODClickDataBlock.CPOD_SR);
short[] data = new short[9];
short nCyc = (short) fpoDdata.Ncyc;
short bw = (short) fpoDdata.BW;
short kHz = (short) FPODReader.IPItoKhz(fpoDdata.IPIatMax);
short endF = (short) FPODReader.IPItoKhz(fpoDdata.EndIPI);
short spl = (short) fpoDdata.MaxPkExtnd;
short slope = 0;
data[3]=nCyc;
data[4]=bw;
data[5]=kHz;
data[6]=endF;
data[7]=spl;
data[8]=slope;
CPODClick cpodClick = new CPODClick(fpoDdata.getTimeMillis(),
fileSamples, nCyc, bw,
kHz, endF, spl, slope, data);
return cpodClick;
}
/**
* Import a CPOD file.
* @param cpFile - the CP1 or CP3 file.
* @param from - the click index to save from. e.g. 100 means that only click 100 + in the file is saved
* @param maxNum - the maximum number to import
* @return the total number of clicks in the file.
*/
protected int importCPODFile(File cpFile, CPODClickDataBlock dataBlock, int from, int maxNum) {
BufferedInputStream bis = null;
int bytesRead;
FileInputStream fileInputStream = null;
@ -190,7 +297,7 @@ public class CPODImporter {
while (true) {
bytesRead = bis.read(byteData);
for (int i = 0; i < bytesRead; i++) {
shortData[i] = toUnsigned(byteData[i]);
shortData[i] = CPODUtils.toUnsigned(byteData[i]);
}
if (isFileEnd(byteData)) {
fileEnds++;
@ -215,7 +322,7 @@ public class CPODImporter {
}
// // now remove the data unit from the data block in order to clear up memory. Note that the remove method
// // now remove the data unit from the data block in order to clear up memory. Note that the remove method
// // saves the data unit to the Deleted-Items list, so clear that as well (otherwise we'll just be using
// // up all the memory with that one)
// dataBlock.remove(cpodClick);
@ -235,6 +342,15 @@ public class CPODImporter {
return nClicks;
}
private CPODClick processClick(int nMinutes, short[] shortData) {
/*
*
*/
return CPODClick.makeClick(cpodControl, fileStart + nMinutes * 60000L, shortData);
}
/**
* A new minute. Don;t think we need to do anything here.?
@ -245,26 +361,7 @@ public class CPODImporter {
}
private CPODClick processClick(int nMinutes, short[] shortData) {
/*
*
*/
return CPODClick.makeClick(cpodControl, fileStart + nMinutes * 60000L, shortData);
}
/**
* Java will only have read signed bytes. Nick clearly
* uses a lot of unsigned data, so convert and inflate to int16.
* @param signedByte
* @return unsigned version as int16.
*/
static short toUnsigned(byte signedByte) {
short ans = signedByte;
if (ans < 0) {
ans += 256;
}
return ans;
}
/**
* Is it the end of the file ?
@ -363,8 +460,10 @@ public class CPODImporter {
public CPODClickDataBlock getDataBlock(CPODFileType type) {
switch (type) {
case CP1:
case FP1:
return this.cpodControl.getCP1DataBlock();
case CP3:
case FP3:
return this.cpodControl.getCP3DataBlock();
}
return null;

View File

@ -29,6 +29,7 @@ public class CPODMap {
public static final int FILE_CP1 = 1;
public static final int FILE_CP3 = 3;
int cpFileType = 0;

37
src/cpod/CPODUtils.java Normal file
View File

@ -0,0 +1,37 @@
package cpod;
/**
* Some useful utility function for CPOD and FPOD data
*/
public class CPODUtils {
/**
* Java will only have read signed bytes. Nick clearly
* uses a lot of unsigned data, so convert and inflate to int16.
* @param signedByte
* @return unsigned version as int16.
*/
public static short toUnsigned(byte signedByte) {
// short ans = signedByte;
short ans = (short) (signedByte & 0xff);
// if (ans < 0) {
// ans += 256;
// }
return ans;
}
/**
* Convert POD time to JAVA millis - POD time is
* integer minutes past the same epoc as Windows uses
* i.e. 0th January 1900.
* @param podTime
* @return milliseconds.
*/
public static long podTimeToMillis(long podTime) {
return podTime * 60L * 1000L - (25569L*3600L*24000L);
}
}

1094
src/cpod/FPODReader.java Normal file

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,8 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
/**
* The extension filter. Holds the types of files that can be imported.
*/
private ExtensionFilter extensionFilter;
private FileChooser.ExtensionFilter extensionFilterCPOD;
// private FileChooser.ExtensionFilter extensionFilterFPOD;
/**
@ -110,6 +111,10 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
super(null);
this.cpodControl = cpodControl2;
//define the types of files to be imported ("Note: add FP1 and FP3 here)
extensionFilterCPOD = new ExtensionFilter("CPOD file", "*.cp1", "*.cp3", "*.fp1", "*.fp3");
//file chooser
fileChooser = new FileChooser();
fileChooser.getExtensionFilters().addAll(getExtensionFilters());
@ -117,8 +122,6 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
//folder chooser
folderChooser = new DirectoryChooser();
//define the types of files to be imported ("Note: add FP1 and FP3 here)
extensionFilter = new ExtensionFilter("CPOD file", "*.cp1", "*.cp3");
pathLabel = new TextField("No classifier file selected");
@ -130,7 +133,7 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
// PamButton browsFileButton = new PamButton("", PamGlyphDude.createPamGlyph(MaterialDesignIcon.FILE_MULTIPLE, PamGuiManagerFX.iconSize));
PamButton browsFileButton = new PamButton("", PamGlyphDude.createPamIcon("mdi2f-file-multiple", PamGuiManagerFX.iconSize));
browsFileButton.setMinWidth(30);
browsFileButton.setTooltip(new Tooltip("Browse to select a CP1 or CP3 file"));
browsFileButton.setTooltip(new Tooltip("Browse to select individual or mutliple CP1 or CP3 files or FP1 or FP3 files"));
browsFileButton.setOnAction((action)->{
List<File> files = fileChooser.showOpenMultipleDialog(this.getFXWindow());
@ -145,7 +148,7 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
// PamButton browsFolderButton = new PamButton("", PamGlyphDude.createPamGlyph(MaterialDesignIcon.FOLDER, PamGuiManagerFX.iconSize));
PamButton browsFolderButton = new PamButton("", PamGlyphDude.createPamIcon("mdi2f-folder", PamGuiManagerFX.iconSize));
browsFolderButton.setMinWidth(30);
browsFolderButton.setTooltip(new Tooltip("Browse to a folder containg CP1 and CP3 files"));
browsFolderButton.setTooltip(new Tooltip("Browse to a folder contaning CP1 and CP3 or FP1 and FP3 files"));
browsFolderButton.setOnAction((action)->{
File file = folderChooser.showDialog(this.getFXWindow());
@ -168,7 +171,7 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
pathLabel.setMaxWidth(Double.MAX_VALUE);
pathLabel.prefHeightProperty().bind(browsFolderButton.heightProperty());
filesPane.getChildren().addAll(pathLabel, browsFolderButton);
filesPane.getChildren().addAll(pathLabel, browsFileButton, browsFolderButton);
//time offset pane.
startOffset = new PamSpinner<Double>();
@ -296,7 +299,8 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
System.out.println("Import CPOD data: " + files.size());
//begins the import
this.tasks = this.cpodControl.getCpodImporter().importCPODData(files);
// this.tasks = this.cpodControl.getCpodImporter().importCPODData(files);
this.tasks = this.cpodControl.importPODData(files);
if (tasks ==null) return false;
@ -428,8 +432,13 @@ public class CPODSettingsPane extends SettingsPane<CPODParams> {
* new ExtensionFilter("Pytorch Model", "*.pk")
* @return a list of extension fitlers for the file dialog.
*/
public ExtensionFilter getExtensionFilters(){
return extensionFilter;
public ArrayList<FileChooser.ExtensionFilter> getExtensionFilters(){
ArrayList<FileChooser.ExtensionFilter> filters = new ArrayList<FileChooser.ExtensionFilter>();
filters.add(extensionFilterCPOD);
//don't add an exstra filter - just have all as one - otherwise the user has to change the
//file dialog to FPODs to get it to work.
// filters.add(extensionFilterFPOD);
return filters;
}

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import PamController.PamController;
import PamModel.PamModuleInfo;
import atlantafx.base.theme.PrimerDark;
import dataModelFX.ConnectionNodeParams.PAMConnectionNodeType;
import dataModelFX.connectionNodes.ModuleIconFactory;
import javafx.beans.property.ObjectProperty;
@ -13,7 +12,6 @@ import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
@ -29,7 +27,6 @@ import pamViewFX.fxNodes.PamTilePane;
import pamViewFX.fxNodes.PamTitledPane;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.connectionPane.structures.ConnectionGroupBody;
import pamViewFX.fxNodes.connectionPane.structures.ConnectionStructure.ConnectionStructureType;
import pamViewFX.fxStyles.PamStylesManagerFX;
import pamViewFX.fxNodes.connectionPane.structures.ExtensionSocketStructure;

View File

@ -20,8 +20,6 @@ import userDisplayFX.UserDisplayNodeFX;
import PamModel.PamModel;
import PamModel.PamModuleInfo;
import PamView.PamViewInterface;
import atlantafx.base.theme.PrimerDark;
import atlantafx.base.theme.PrimerLight;
import dataMap.layoutFX.DataMapPaneFX;
import PamController.PAMControllerGUI;
import PamController.PamControlledUnit;

View File

@ -27,6 +27,7 @@ import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
import rawDeepLearningClassifier.dataPlotFX.DLDetectionPlotProvider;
import rawDeepLearningClassifier.dataPlotFX.DLPredictionProvider;
import rawDeepLearningClassifier.ddPlotFX.RawDLDDPlotProvider;
import rawDeepLearningClassifier.defaultModels.DLDefaultModelManager;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.DLClassNameManager;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
@ -39,7 +40,7 @@ import rawDeepLearningClassifier.layoutFX.DLModelSelectPane;
import rawDeepLearningClassifier.layoutFX.DLSidePanelSwing;
import rawDeepLearningClassifier.layoutFX.DLSymbolManager;
import rawDeepLearningClassifier.layoutFX.PredictionSymbolManager;
import rawDeepLearningClassifier.layoutFX.RawDLSettingsPane;
import rawDeepLearningClassifier.layoutFX.DLSettingsPane;
import rawDeepLearningClassifier.logging.DLAnnotationType;
import rawDeepLearningClassifier.logging.DLDataUnitDatagram;
import rawDeepLearningClassifier.logging.DLDetectionBinarySource;
@ -124,7 +125,7 @@ public class DLControl extends PamControlledUnit implements PamSettings {
/**
* The settings pane.
*/
private RawDLSettingsPane settingsPane;
private DLSettingsPane settingsPane;
/**
* The settings dialog
@ -188,10 +189,18 @@ public class DLControl extends PamControlledUnit implements PamSettings {
*/
private DLClassifierChooser dlClassifierChooser;
/**
* Handles downloading models from the internet
*/
private DLDownloadManager modelDownloadManager;
/**
* Handles downloading models from the internet
*/
private DLDefaultModelManager defaultModelManager;
/**
* Constructor for the DL Control.
*
@ -221,6 +230,9 @@ public class DLControl extends PamControlledUnit implements PamSettings {
//manages the names assigned to different output classes.
dlClassNameManager = new DLClassNameManager(this);
//manages default models
defaultModelManager = new DLDefaultModelManager(this);
//manages downloading models
modelDownloadManager = new DLDownloadManager();
@ -386,10 +398,10 @@ public class DLControl extends PamControlledUnit implements PamSettings {
*
* @return the settings pane.
*/
public RawDLSettingsPane getSettingsPane() {
public DLSettingsPane getSettingsPane() {
if (this.settingsPane == null) {
settingsPane = new RawDLSettingsPane(this);
settingsPane = new DLSettingsPane(this);
}
System.out.println("Get DL raw settings pane...");
@ -591,6 +603,14 @@ public class DLControl extends PamControlledUnit implements PamSettings {
return modelDownloadManager;
}
/**
* Get the default model manager. This handles the default models that can be downloaded.
* @return the default model manager.
*/
public DLDefaultModelManager getDefaultModelManager() {
return this.defaultModelManager;
}
}

View File

@ -153,6 +153,8 @@ public class DLDownloadManager {
System.out.println("DOWNLOADED MODEL: " + file.getPath() );
notifyDownLoadListeners(DLStatus.DECOMPRESSING_MODEL, -1);
file = decompressFile(file);
if (file.isDirectory()) {
@ -373,7 +375,7 @@ public class DLDownloadManager {
Files.copy(input, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
while ((n = input.read(buffer)) != -1) {
// System.out.println("Chunk: " + n);
System.out.println("Chunk: " + count);
count=count+n; //total bytes
notifyDownLoadListeners(DLStatus.DOWNLOADING, count);
output.write( buffer, 0, n );
@ -423,4 +425,9 @@ public class DLDownloadManager {
URI path = dlDefaultModelManager.downloadModel(new RightWhaleModel1().getModelURI(), new RightWhaleModel1().getModelName());
}
public void clearDownloadListeners() {
this.downLoadListeners.clear();
}
}

View File

@ -1,33 +1,56 @@
package rawDeepLearningClassifier;
/**
* Status reporting for the deep learning module.
* Status reporting for the deep learning module.
*/
public enum DLStatus {
FILE_NULL("The input file is null", "The loaded file was null. If the file was download it may not have downloaded properly.", true),
FILE_NULL("The input file is null",
"The loaded file was null. If the file was download it may not have downloaded properly.", ErrorLevel.ERROR),
MODEL_LOAD_FAILED("The model failed to load", " The model failed to load - this could be because it is incompatible with PAMGuard or an uknown file format.", true),
MODEL_LOAD_FAILED("The model failed to load",
" The model failed to load - this could be because it is incompatible with PAMGuard or an uknown file format.",
ErrorLevel.ERROR),
MODEL_LOAD_SUCCESS("The model loaded", " The model successfully load", false),
MODEL_LOAD_SUCCESS("The model loaded", " The model successfully load", ErrorLevel.NO_ERROR),
DOWNLOAD_STARTING("The model loaded", " The model successfully load", false),
DOWNLOAD_STARTING("Download starting", "The model is downloading", ErrorLevel.NO_ERROR),
DOWNLOAD_FINISHED("The model loaded", " The model successfully load", false),
DOWNLOAD_FINISHED("Download finished", " The model successfully downloaded", ErrorLevel.NO_ERROR),
DOWNLOADING("The model loaded", " The model successfully load", false),
DOWNLOADING("Downloading", "The model is currently downloading", ErrorLevel.NO_ERROR),
NO_CONNECTION_TO_URL ("Could not connect to the URL", " Could connect to the URL - the URL may be wrong or there may be no internet connection", true),
NO_CONNECTION_TO_URL("Could not connect to the URL",
" Could connect to the URL - the URL may be wrong or there may be no internet connection", ErrorLevel.ERROR),
CONNECTION_TO_URL("The model loaded", " The model successfully load", false),
CONNECTION_TO_URL("Connected to URL", "The connection to the URL was successful", ErrorLevel.NO_ERROR),
MODEL_DOWNLOAD_FAILED("The model was not downloaded", " The model download failed. Check internet connection and try again", true);
MODEL_DOWNLOAD_FAILED("The model was not downloaded",
" The model download failed. Check internet connection and try again", ErrorLevel.ERROR),
NO_MODEL_LOADED("There is no loaded model",
"There is no loaded model. A model my have failed to load or the path/URL to the model is incorrect", ErrorLevel.WARNING),
//this is not a show stopper because predictions are saved there's just no binary classification.
NO_BINARY_CLASSIFICATION("No binary classification",
" There are no prediction classes selected for classification. Predicitons for each segment will be saved but there will be no detections generated",
ErrorLevel.WARNING),
DECOMPRESSING_MODEL("Decompressing model", "Decompressing the model file", ErrorLevel.NO_ERROR), ;
private boolean isError = true;
/**
* True of the message is an error message.
*/
private int isError = ErrorLevel.NO_ERROR;
/**
* Check whether the message is an error message.
*
* @return true if an error message.
*/
public boolean isError() {
return isError;
return isError==ErrorLevel.ERROR;
}
/**
@ -41,22 +64,54 @@ public enum DLStatus {
private String expanded;
/**
* Status report for the leep learning module.
* @param string - status
* @param expanded - description of the status.
* Status report for the leep learning module.
*
* @param string - status
* @param expanded - description of the status.
*/
DLStatus(String string, String expande, boolean isError) {
DLStatus(String string, String expande, int isError) {
this.string = string;
this.expanded = expande;
this.isError= isError;
this.isError = isError;
}
/**
* Get a brief description of the status.
*
* @return a brief description of the status.
*/
public String getName() {
return string;
}
/**
* Longer description of the status.
*
* @return longer descrption of the status.
*/
public String getDescription() {
return expanded;
}
private static class ErrorLevel {
public static final int NO_ERROR = 0;
public static final int WARNING = 1;
public static final int ERROR = 2;
}
/**
* Get the error flag. e.g. ErrorLevel.NO_ERROR. The error flag describes
* whether the status is an error, warning or not an error.
* @return the error flag.
*/
int getErrorFlag() {
return isError;
}
public boolean isWarning() {
return isError==ErrorLevel.WARNING;
}
}

View File

@ -30,7 +30,6 @@ public class RawDLParams implements Serializable, Cloneable {
/**
* The current model URI. The deep learning model must have some sort of external file to run.
* This might be a model, a .exe file etc.
*
*/
public URI modelURI;
@ -86,7 +85,7 @@ public class RawDLParams implements Serializable, Cloneable {
* different class names. If we change model then the class names may change.
* Previously annotated data will then be messed up. But, in a giant dataset
* that may be an issue. Perhaps users wish to run a new model on some chunk of
* data without messing up all the other classified detection which have used
* data without messing up all the other classified detectionS which have used
* that module. So store the data in binary files? That is super inefficient as
* the same string is stored many times. So instead store a short which
* identifies the string that sits in this table. Everytime a new model is added

View File

@ -3,12 +3,14 @@ package rawDeepLearningClassifier.dataPlotFX;
import java.io.Serializable;
import PamController.PamController;
import PamUtils.PamArrayUtils;
import PamView.GeneralProjector;
import PamView.GeneralProjector.ParameterType;
import PamView.GeneralProjector.ParameterUnits;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamConstants;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import dataPlotsFX.TDManagedSymbolChooserFX;
@ -18,6 +20,7 @@ import dataPlotsFX.data.generic.GenericLinePlotInfo;
import dataPlotsFX.data.generic.GenericScaleInfo;
import dataPlotsFX.layout.TDGraphFX;
import dataPlotsFX.projector.TDProjectorFX;
import javafx.geometry.Point2D;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
@ -81,25 +84,31 @@ public class DLPredictionPlotInfoFX extends GenericLinePlotInfo {
frequencyInfo = new GenericScaleInfo(0, 1, ParameterType.FREQUENCY, ParameterUnits.HZ);
DLClassName[] classNames = getDlControl().getDLModel().getClassNames();
updateClassNames();
System.out.println("Class names are: !!! " + (classNames == null ? "null" : classNames.length));
if (classNames!=null) {
//make sure this is initialised otherwise the plot won't work when first created.
if (dlPredParams.lineInfos==null ) dlPredParams.lineInfos = new LineInfo[classNames.length];
for (int i=0; i<classNames.length; i++) {
if (dlPredParams.lineInfos[i]==null) {
dlPredParams.lineInfos[i] = new LineInfo(true, Color.rgb(0, 0, 255%(i*30 + 50)));
}
}
}
addScaleInfo(probabilityScaleInfo);
addScaleInfo(frequencyInfo);
}
private void updateClassNames() {
if (getDlControl().getDLModel()!=null) {
DLClassName[] classNames = getDlControl().getDLModel().getClassNames();
System.out.println("Class names are: !!! " + (classNames == null ? "null" : classNames.length));
if (classNames!=null) {
//make sure this is initialised otherwise the plot won't work when first created.
if (dlPredParams.lineInfos==null ) dlPredParams.lineInfos = new LineInfo[classNames.length];
for (int i=0; i<classNames.length; i++) {
if (dlPredParams.lineInfos[i]==null) {
dlPredParams.lineInfos[i] = new LineInfo(true, Color.rgb(0, 0, 255%(i*30 + 50)));
}
}
}
}
}
/**
@ -334,5 +343,22 @@ public class DLPredictionPlotInfoFX extends GenericLinePlotInfo {
return dataD;
}
/**
* Notifications from the PamController are passed to this function.
*
* @param changeType - notification flag.
*/
public void notifyChange(int changeType) {
super.notifyChange(changeType);
switch (changeType) {
case PamController.CHANGED_PROCESS_SETTINGS:
updateClassNames();
break;
}
}
}

View File

@ -1,20 +1,6 @@
package rawDeepLearningClassifier.defaultModels;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import PamUtils.FileFunctions;
import java.io.OutputStream;
import java.io.InputStream;
import rawDeepLearningClassifier.DLControl;
/**
@ -38,7 +24,11 @@ public class DLDefaultModelManager {
*/
public DLDefaultModelManager(DLControl dlControl) {
this.dlControl = dlControl;
defaultModels.add(new RightWhaleModel1());
defaultModels.add(new HumpbackWhaleGoogle());
defaultModels.add(new HumpbackWhaleAtlantic());
}
/**
* Get a default model at index i
@ -56,8 +46,5 @@ public class DLDefaultModelManager {
public int getNumDefaultModels() {
return defaultModels.size();
}
}

View File

@ -1,5 +1,6 @@
package rawDeepLearningClassifier.defaultModels;
import java.io.Serializable;
import java.net.URI;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
@ -32,11 +33,7 @@ public interface DLModel {
* @return the model URI.
*/
public URI getModelURI();
/**
* Get the model settings - these are used to ensure the model is set up correctly once loaded.
*/
public StandardModelParams getModelSettings();
/**
* The model name. This is used if, for example, a model is downloaded as a zip file and the model
@ -44,6 +41,18 @@ public interface DLModel {
* @return the model name;
*/
public String getModelName();
/**
* Get the link to the paper for the model
* @return the citation link.
*/
public URI getCitationLink();
/**
* Set the model settings once it has loaded.
* @param dlModelSettings - the model settings.
*/
public void setParams(Serializable dlModelSettings);

View File

@ -0,0 +1,66 @@
package rawDeepLearningClassifier.defaultModels;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
/**
*
*/
public class HumpbackWhaleAtlantic implements DLModel {
@Override
public String getDescription() {
return "Detects Atlantic Humpback whales";
}
@Override
public String getName() {
return "Humpback Whale Atlantic";
}
@Override
public String getCitation() {
return "A. N. Allen et al., A Convolutional Neural Network for Automated Detection of Humpback Whale Song in a Diverse, Long-Term Passive Acoustic Dataset, Front. Mar. Sci., vol. 8, p. 607321, Mar. 2021";
}
@Override
public URI getModelURI() {
try {
return new URL("https://github.com/PAMGuard/deeplearningmodels/raw/master/right_whale_1/model_lenet_dropout_input_conv_all.zip").toURI();
} catch (MalformedURLException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public String getModelName() {
return "saved_model.pb";
}
@Override
public URI getCitationLink() {
try {
return new URL("https://doi.org/10.3389/fmars.2021.607321").toURI();
} catch (MalformedURLException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
@Override
public void setParams(Serializable dlModelSettings) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,96 @@
package rawDeepLearningClassifier.defaultModels;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericModelParams;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
public class HumpbackWhaleGoogle implements DLModel {
@Override
public String getDescription() {
return "A model developed by Google to detect Humpback whales (Megaptera novaeangliae) in the Pacific ocean";
}
@Override
public String getName() {
return "Humpback Whale Pacific";
}
@Override
public String getCitation() {
return "A. N. Allen et al., A Convolutional Neural Network for Automated Detection of Humpback Whale Song in a Diverse, Long-Term Passive Acoustic Dataset, Front. Mar. Sci., vol. 8, p. 607321, Mar. 2021";
}
@Override
public URI getModelURI() {
try {
return new URL("https://github.com/PAMGuard/deeplearningmodels/raw/master/humpback_whale_1/humpback_whale_1.zip").toURI();
} catch (MalformedURLException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public String getModelName() {
return "saved_model.pb";
}
@Override
public URI getCitationLink() {
try {
return new URL("https://doi.org/10.3389/fmars.2021.607321").toURI();
} catch (MalformedURLException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
@Override
public void setParams(Serializable dlModelSettings) {
GenericModelParams genericModelParams = (GenericModelParams) dlModelSettings;
//decimation value
float sr = 10000;
//create the transforms.
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE, sr));
genericModelParams.dlTransfromParams = dlTransformParamsArr;
genericModelParams.defaultSegmentLen = 3.92*1000;
genericModelParams.binaryClassification = new boolean[] {true};
genericModelParams.classNames= new DLClassName[] {new DLClassName("Humpback whale", (short) 1)};
genericModelParams.numClasses = 1;
genericModelParams.defaultShape= new Long[] {-1L,-1L,-1L,1L};
genericModelParams.shape= new Long[] {-1L,-1L,-1L,1L};
//create the transforms.
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
genericModelParams.setExampleSound(ExampleSoundType.HUMPBACK_WHALE);
}
}

View File

@ -1,11 +1,21 @@
package rawDeepLearningClassifier.defaultModels;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericModelParams;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
/**
* Right whale model from Shiu et al. 2019
@ -18,18 +28,17 @@ public class RightWhaleModel1 implements DLModel {
@Override
public String getDescription() {
return "Detects right whales";
return "Detects North Atlantic right whales (Eubalaena glacialis).";
}
@Override
public String getName() {
return "Right Whale";
return "North Atlantic right whale";
}
@Override
public String getCitation() {
return " Shiu, Y., Palmer, K.J., Roch, M.A., Fleishman, E., Liu, X., Nosal, E.-M., Helble, T., Cholewiak, D., Gillespie, D., Klinck, H., 2020."
+ " Deep neural networks for automated detection of marine mammal species. Scientific Reports 10, 607. https://doi.org/10.1038/s41598-020-57549-y";
return "Shiu, Y., Palmer, K.J., Roch, M.A. et al. Deep neural networks for automated detection of marine mammal species. Sci Rep 10, 607 (2020)";
}
@Override
@ -44,15 +53,62 @@ public class RightWhaleModel1 implements DLModel {
}
@Override
public StandardModelParams getModelSettings() {
// TODO Auto-generated method stub
return null;
/**
* Set the model settings once it has loaded.
* @param dlModelSettings - the model settings.
*/
public void setParams(Serializable dlModelSettings) {
GenericModelParams genericModelParams = (GenericModelParams) dlModelSettings;
//decimation value
float sr = 2000;
//create the transforms.
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE, sr));
// dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PREEMPHSIS, preemphases));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.SPECTROGRAM, 256, 102));
//in the python code they have an sfft of 129xN where N is the number of chunks. They then
//choose fft data between bin 5 and 45 in the FFT. This roughly between 40 and 350 Hz.
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.SPECCROPINTERP, 47.0, 357.0, 40));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.SPECNORMALISEROWSUM));
genericModelParams.dlTransfromParams = dlTransformParamsArr;
genericModelParams.defaultSegmentLen = 2.0*1000;
genericModelParams.binaryClassification = new boolean[] {false, true};
genericModelParams.defaultShape= new Long[] {-1L,40l,401L,1L};
genericModelParams.shape= new Long[] {-1L,40L,40L,1L};
genericModelParams.classNames= new DLClassName[] {new DLClassName("Noise", (short) 0), new DLClassName("Right Whale", (short) 1)};
genericModelParams.numClasses = 2;
//create the transforms.
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
genericModelParams.setExampleSound(ExampleSoundType.RIGHT_WHALE);
}
@Override
public String getModelName() {
return "saved_model.pb";
}
@Override
public URI getCitationLink() {
try {
return new URL("https://doi.org/10.1038/s41598-020-57549-y").toURI();
} catch (MalformedURLException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}

View File

@ -10,6 +10,7 @@ import org.jamdev.jdl4pam.transforms.SimpleTransform;
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.layoutFX.DLCLassiferModelUI;
import rawDeepLearningClassifier.segmenter.SegmenterProcess.GroupedRawData;
import warnings.PamWarning;
@ -100,14 +101,14 @@ public interface DLClassiferModel {
/**
* Check whether a model has been selected and can be loaded successfully.
*/
public boolean checkModelOK();
public DLStatus getModelStatus();
/**
* Get warnings for the classifier model. This is called when the user confirms settings and
* used to return a warning dialog.
* @return a list of warnings. If the list is null or size() is zero then settings are OK.
*/
public ArrayList<PamWarning> checkSettingsOK();
// /**
// * Get warnings for the classifier model. This is called when the user confirms settings and
// * used to return a warning dialog.
// * @return a list of warnings. If the list is null or size() is zero then settings are OK.
// */
// public ArrayList<PamWarning> checkSettingsOK();
/**

View File

@ -14,11 +14,12 @@ import PamUtils.PamArrayUtils;
import PamUtils.PamCalendar;
import javafx.stage.FileChooser.ExtensionFilter;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericDLClassifier;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericPrediction;
import rawDeepLearningClassifier.layoutFX.RawDLSettingsPane;
import rawDeepLearningClassifier.layoutFX.DLSettingsPane;
import rawDeepLearningClassifier.segmenter.SegmenterProcess.GroupedRawData;
import warnings.PamWarning;
import warnings.WarningSystem;
@ -153,8 +154,30 @@ public abstract class StandardClassifierModel implements DLClassiferModel, PamSe
}
@Override
public boolean checkModelOK() {
return !getDLWorker().isModelNull();
public DLStatus getModelStatus() {
if (getDLWorker().isModelNull()) {
return DLStatus.MODEL_LOAD_FAILED;
}
File file = new File(getDLParams().modelPath);
if (getDLParams().modelPath == null || !file.isFile()) {
return DLStatus.NO_MODEL_LOADED;
}
// if continous data is selected and all classes are false then this is a
// potential mistake...
if (dlControl.getSettingsPane().getSelectedParentDataBlock().getUnitClass() == RawDataUnit.class
&& (getDLParams().binaryClassification==null || PamArrayUtils.isAllFalse(getDLParams().binaryClassification))){
return DLStatus.NO_BINARY_CLASSIFICATION;
// warnings.add(new PamWarning("Generic classifier",
// "There are no prediction classes selected for classification. "
// + "Predicitons for each segment will be saved but there will be no detections generated",
// 1));
}
return DLStatus.MODEL_LOAD_SUCCESS;
}
@Override
@ -201,11 +224,11 @@ public abstract class StandardClassifierModel implements DLClassiferModel, PamSe
protected void newResult(GenericPrediction modelResult, GroupedRawData groupedRawData) {
this.dlControl.getDLClassifyProcess().newModelResult(modelResult, groupedRawData);
}
@Override
public ArrayList<PamWarning> checkSettingsOK() {
return checkSettingsOK(getDLParams(), dlControl);
}
//
// @Override
// public ArrayList<PamWarning> checkSettingsOK() {
// return checkSettingsOK(getDLParams(), dlControl);
// }
/**
@ -221,7 +244,7 @@ public abstract class StandardClassifierModel implements DLClassiferModel, PamSe
* Get raw settings pane
* @return the setting pane.
*/
public RawDLSettingsPane getRawSettingsPane() {
public DLSettingsPane getRawSettingsPane() {
return this.dlControl.getSettingsPane();
}

View File

@ -327,13 +327,18 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
@Override
public void setParams(StandardModelParams currParams) {
this.paramsClone = currParams.clone();
try {
this.paramsClone = currParams.clone();
//pathLabel .setText(this.currentSelectedFile.getPath());
detectionSpinner.getValueFactory().setValue(Double.valueOf(currParams.threshold));
//set the params on the advanced pane.
// System.out.println("SET PARAMS ADV PANE: " + (paramsClone.classNames == null ? null : paramsClone.classNames.length));
this.getAdvSettingsPane().setParams(paramsClone);
//System.out.println("SET advanced params: " + paramsClone.dlTransfroms);
@ -346,6 +351,12 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
usedefaultSeg.setSelected(currParams.useDefaultSegLen);
defaultSegmentLenChanged();
}
catch (Exception e) {
e.printStackTrace();
}
//updatePathLabel();

View File

@ -10,6 +10,7 @@ import org.jamdev.jdl4pam.transforms.DLTransform;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
/**
* Parameters for the SoundSpot model.
@ -101,6 +102,21 @@ public class StandardModelParams implements Serializable, Cloneable {
public int exampleSoundIndex = 0;
/**
* Set the example sound that should be associated with parameters.
* @param soundType - the example sound type.
*/
public void setExampleSound(ExampleSoundType soundType) {
ExampleSoundType[] values = ExampleSoundType.values();
for (int i=0; i<values.length; i++) {
if (values[i].equals(soundType)) {
exampleSoundIndex = i;
return;
}
}
}
/**
* Set the URI in standard model params.
* @param uri - the uri to a model

View File

@ -5,6 +5,7 @@ import java.net.URI;
import java.util.ArrayList;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import rawDeepLearningClassifier.dlClassification.PredictionResult;
@ -80,16 +81,12 @@ public class DummyClassifier implements DLClassiferModel{
}
@Override
public boolean checkModelOK() {
return true;
}
@Override
public ArrayList<PamWarning> checkSettingsOK() {
// TODO Auto-generated method stub
public DLStatus getModelStatus() {
return null;
}
@Override
public boolean isModelType(URI uri) {
// TODO Auto-generated method stub

View File

@ -418,7 +418,7 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
@Override
public void setParams(GenericModelParams input) {
setParams= true;
this.currentInput = input.clone();

View File

@ -180,16 +180,6 @@ public class GenericDLClassifier extends StandardClassifierModel {
this.genericModelParams=(GenericModelParams) clone;
}
@Override
public boolean checkModelOK() {
return genericModelWorker.getModel()!=null;
}
/**
* Send a new result form the thread queue to the process.
* @param modelResult - the model result;
@ -230,10 +220,10 @@ public class GenericDLClassifier extends StandardClassifierModel {
}
@Override
public ArrayList<PamWarning> checkSettingsOK() {
return checkSettingsOK(genericModelParams, dlControl);
}
// @Override
// public ArrayList<PamWarning> checkSettingsOK() {
// return checkSettingsOK(genericModelParams, dlControl);
// }

View File

@ -76,9 +76,7 @@ public class GenericImportExportPane extends ImportExportPane {
//set the default segment length if available.
if (genericModelParams.defaultSegmentLen!=null) {
double sR = genericAdvPane.getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
//automatically set the default segment length.
genericAdvPane.getDLControl().getSettingsPane().getSegmentLenSpinner().getValueFactory().setValue((int) (sR*genericModelParams.defaultSegmentLen/1000.));
genericAdvPane.getDLControl().getSettingsPane().setSegmentLength(genericModelParams.defaultSegmentLen);
}
if (genericModelParams==null) {

View File

@ -71,6 +71,8 @@ public class GenericModelPane extends StandardModelPane {
@Override
public void setParams(StandardModelParams currParams) {
// System.out.println("SET PARAMS GENERIC PANE: " + currParams);
super.setParams(currParams);
}

View File

@ -6,6 +6,7 @@ import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import org.json.JSONArray;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
@ -186,4 +187,6 @@ public class GenericModelParams extends StandardModelParams implements Cloneable
}

View File

@ -72,7 +72,7 @@ public class GenericModelUI implements DLCLassiferModelUI {
@Override
public void setParams() {
// System.out.println("Set model params: " + genericModelClassifier.getGenericDLParams().dlTransfromParams.size());
// System.out.println("SE MODEL UI PARAMS: " + genericModelClassifier.getGenericDLParams().dlTransfromParams.size());
getSettingsPane().setParams(genericModelClassifier.getGenericDLParams());
}

View File

@ -45,7 +45,7 @@ public class GenericModelWorker extends DLModelWorker<GenericPrediction> {
}
results = genericModel.runModel(waveStack);
}
//System.out.println("GENERIC MODEL RESULTS: " + results== null ? null : results.length);
System.out.println("GENERIC MODEL RESULTS: " + results== null ? null : results.length);
return results;
}

View File

@ -179,6 +179,7 @@ public class KetosWorker extends DLModelWorker<GenericPrediction> {
@Override
public float[] runModel(float[][][] transformedDataStack) {
System.out.println("Model input: " + transformedDataStack.length + " " + transformedDataStack[0].length + " " + transformedDataStack[0][0].length);
return ketosModel.runModel(transformedDataStack);
}

View File

@ -11,6 +11,7 @@ import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager;
import PamController.PamSettings;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import rawDeepLearningClassifier.dlClassification.DLDataUnit;
@ -340,16 +341,16 @@ public class OrcaSpotClassifier implements DLClassiferModel, PamSettings {
}
@Override
public boolean checkModelOK() {
return true;
}
@Override
public ArrayList<PamWarning> checkSettingsOK() {
// TODO Auto-generated method stub
public DLStatus getModelStatus() {
return null;
}
// @Override
// public ArrayList<PamWarning> checkSettingsOK() {
// // TODO Auto-generated method stub
// return null;
// }
@Override
public boolean isModelType(URI uri) {
// TODO Auto-generated method stub

View File

@ -13,14 +13,15 @@ import org.controlsfx.control.PopOver;
import ai.djl.Device;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
@ -38,7 +39,8 @@ import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import rawDeepLearningClassifier.dlClassification.DefaultModels;
import rawDeepLearningClassifier.dlClassification.DefaultModels.DefualtModel;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.layoutFX.defaultModels.DefaultModelPane;
/**
@ -103,10 +105,12 @@ public class DLModelSelectPane extends PamBorderPane {
private TextField uriTextField;
private RawDLSettingsPane rawDLSettingsPane;
private DLSettingsPane rawDLSettingsPane;
private DefaultModelPane defaultModelPane;
public DLModelSelectPane(RawDLSettingsPane rawDLSettingsPane) {
public DLModelSelectPane(DLSettingsPane rawDLSettingsPane) {
this.rawDLSettingsPane=rawDLSettingsPane;
this.dlControl=rawDLSettingsPane.getDLControl();
this.setCenter(createDLSelectPane());
@ -118,8 +122,6 @@ public class DLModelSelectPane extends PamBorderPane {
public Pane createDLSelectPane() {
defaultModels = new DefaultModels(dlControl);
classiferInfoLabel = new Label(" Classifier");
//PamGuiManagerFX.titleFont2style(classiferInfoLabel);
@ -130,13 +132,14 @@ public class DLModelSelectPane extends PamBorderPane {
pathLabel = new Label("No classifier file selected");
// PamButton pamButton = new PamButton("", PamGlyphDude.createPamGlyph(MaterialDesignIcon.FILE, PamGuiManagerFX.iconSize));
PamButton pamButton = new PamButton("", PamGlyphDude.createPamIcon("mdi2f-file", PamGuiManagerFX.iconSize));
pathLabel.setPrefWidth(100);
modelLoadIndicator = new ProgressIndicator(-1);
modelLoadIndicator.setVisible(false);
modelLoadIndicator.prefHeightProperty().bind(pamButton.heightProperty().subtract(3));
pamButton.setMinWidth(30);
pamButton.setTooltip(new Tooltip("Browse to select a model file"));
pamButton.setTooltip(new Tooltip("Load a model from a file"));
pamButton.setOnAction((action)->{
@ -220,16 +223,59 @@ public class DLModelSelectPane extends PamBorderPane {
});
MenuButton defaults = new MenuButton();
PamButton defaults = new PamButton();
defaults.setTooltip(new Tooltip("Default models"));
defaults.setGraphic(PamGlyphDude.createPamIcon("mdi2d-dots-vertical", PamGuiManagerFX.iconSize));
defaults.setTooltip(new Tooltip("Load a default model"));
for (DefualtModel defaultmodel: defaultModels.getDefaultModels()) {
defaults.getItems().add(new MenuItem(defaultmodel.name));
}
defaults.prefHeightProperty().bind(urlButton.heightProperty());
// for (DefualtModel defaultmodel: defaultModels.getDefaultModels()) {
// defaults.getItems().add(new MenuItem(defaultmodel.name));
// }
// defaults.prefHeightProperty().bind(urlButton.heightProperty());
defaultModelPane = new DefaultModelPane(this.dlControl.getDefaultModelManager());
defaultModelPane.setPadding(new Insets(5,5,5,5));
defaultModelPane.defaultModelProperty().addListener((obsVal, oldVal, newVal)->{
if (newVal!=oldVal) {
//a default model needs to be loaded.
Task<DLStatus> task = loadNewModel(newVal.getModelURI());
task.setOnSucceeded((val)->{
if (currentClassifierModel!=null) {
//set the parameters from the classifer model to have correct
//transfroms etc.
newVal.setParams(currentClassifierModel.getDLModelSettings());
//set the correct classifier pane.
rawDLSettingsPane.setClassifierPane();
//need to make sure the classifier pane is updated
currentClassifierModel.getModelUI().setParams();
//need to update the segment length...
if (currentClassifierModel.getDLModelSettings() instanceof StandardModelParams) {
double segLen = ((StandardModelParams) currentClassifierModel.getDLModelSettings()).defaultSegmentLen;
this.rawDLSettingsPane.setSegmentLength(segLen);
//set to half the hop size too
this.rawDLSettingsPane.setHopLength(segLen/2);
}
}
else {
//this should never happen unless there is no internet
System.err.println("Default model failed ot load: "+ newVal);
}
});
}
});
PopOver defualtModelPopOver = new PopOver();
defualtModelPopOver.setContentNode(defaultModelPane);
defaults.setOnAction((action)->{
defualtModelPopOver.show(defaults);
});
PamHBox hBox = new PamHBox();
hBox.setSpacing(5);
@ -244,21 +290,21 @@ public class DLModelSelectPane extends PamBorderPane {
* Load a new model on a seperate thread.
* @param uri - the uri to the model.
*/
public void loadNewModel(URI uri) {
public Task<DLStatus> loadNewModel(URI uri) {
// separate non-FX thread - load the model
//on a separate thread so we can show a moving load
//bar on the FX thread. Otherwise the GUI locks up
//whilst stuff is loaded.
if (uri==null) return;
if (uri==null) return null;
// pathLabel.setText("Loading model...");
modelLoadIndicator.setVisible(true);
Task<DLStatus> task = new LoadTask(uri);
modelLoadIndicator.progressProperty().bind(task.progressProperty());
pathLabel.setGraphic(null); //remove error icon if there is one.
pathLabel.textProperty().bind(task.messageProperty());
@ -266,6 +312,8 @@ public class DLModelSelectPane extends PamBorderPane {
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
return task;
@ -310,7 +358,7 @@ public class DLModelSelectPane extends PamBorderPane {
/**
* A new model has been selected
* @param
* @param the load status of the model.
*/
private DLStatus newModelSelected(URI file) {
@ -328,7 +376,8 @@ public class DLModelSelectPane extends PamBorderPane {
//we are loading model from a file - anything can happen so put in a try catch.
currentClassifierModel.setModel(file);
if (!currentClassifierModel.checkModelOK()) {
if (currentClassifierModel.getModelStatus().isError()) {
System.err.println("Model load failed: " + currentClassifierModel.getModelStatus());
currentClassifierModel=null;
return DLStatus.MODEL_LOAD_FAILED;
}
@ -348,36 +397,73 @@ public class DLModelSelectPane extends PamBorderPane {
}
private void showWarningDialog(DLStatus status) {
PamDialogFX.showError(status.getName(), status.getDescription());
this.rawDLSettingsPane.showWarning(status);
// PamDialogFX.showError(status.getName(), status.getDescription());
}
/**
* Create an error icon based on the status message.
* @param status - the status
* @return error icon or null of the status is not an error.
*/
private Node createErrorIcon(DLStatus status) {
Node decoration = null;
if (status.isError()){
decoration = PamGlyphDude.createPamIcon("mdi2c-close-circle-outline", Color.RED, 10);
}
else if (status.isWarning()) {
decoration = PamGlyphDude.createPamIcon("mdi2c-close-circle-outline", Color.ORANGE, 10);
}
return decoration;
}
/**
* Update the path label and tool tip text;
* Update the path label and tool tip text
*/
protected void updatePathLabel() {
//System.out.println("Update path label: " + currentClassifierModel.checkModelOK());
protected void updatePathLabel(DLStatus status) {
/**
* This a bit complicated. We want the label to show errors if they have occured and warning to prompt the
* user to do things. The sequence of this is quite important to get right.
*/
pathLabel.setGraphic(null);
if (currentClassifierModel == null) {
//no frameowrk could be selected for the model.
pathLabel.setGraphic(createErrorIcon(DLStatus.NO_MODEL_LOADED));
pathLabel.setText("No classifier model loaded: Select model");
pathLabel.setTooltip(new Tooltip("Use the browse button/ URI botton to select a model or select a default model"));
}
else if (!currentClassifierModel.checkModelOK()) {
pathLabel.setText("The model could not be loaded?");
pathLabel.setTooltip(new Tooltip("Use the browse button/ URI botton to select a model or select a default model"));
if (currentClassifierModel.getModelStatus().isError()) {
pathLabel.setGraphic(createErrorIcon(currentClassifierModel.getModelStatus()));
pathLabel.setText(currentClassifierModel.getModelStatus().getName());
pathLabel.setTooltip(new Tooltip(currentClassifierModel.getModelStatus().getDescription()));
}
else if (status.isError()) {
pathLabel.setGraphic(createErrorIcon(status));
pathLabel.setText(status.getName());
pathLabel.setTooltip(new Tooltip(status.getDescription()));
}
else {
pathLabel .setText(new File(this.currentSelectedFile).getName());
//show a warning icon if needed.
String tooltip = "";
try {
pathLabel.setTooltip(new Tooltip(this.currentSelectedFile.getPath()
+ "\n" +" Processor CPU " + Device.cpu() + " " + Device.gpu()));
tooltip += (this.currentSelectedFile.getPath()
+ "\n" +" Processor CPU " + Device.cpu() + " " + Device.gpu());
tooltip+="\n";
}
catch (Exception e) {
//sometimes get an error here for some reason
//does not make a difference other than tooltip.
System.err.println("StandardModelPane: Error getting the default device!");
}
if (status.isWarning()) {
tooltip+="Warning: " + status.getDescription();
}
pathLabel.setTooltip(new Tooltip(tooltip));
}
}
@ -418,16 +504,39 @@ public class DLModelSelectPane extends PamBorderPane {
public LoadTask(URI uri) {
this.uri=uri;
//TODO - not the best as some other part of the program could be using download listeners...
dlControl.getDownloadManager().clearDownloadListeners();
dlControl.getDownloadManager().addDownloadListener((status, bytesDownLoaded)->{
this.updateProgress(-1, 1); //set to intermedaite
this.updateMessage(String.format("Download %.2f MB", ((double) bytesDownLoaded)/1024./1024.));
updateMessage( status, bytesDownLoaded);
});
}
private void updateMessage(DLStatus status, long bytesDownLoaded) {
//the updates have their own messages but let's take some more control here.
this.updateProgress(-1, 1); //set to intermediate
System.out.println("Status: " + status);
switch (status) {
case CONNECTION_TO_URL:
this.updateMessage("Checking URL");
break;
case DOWNLOADING:
this.updateMessage(String.format("Download %.2f MB", ((double) bytesDownLoaded)/1024./1024.));
break;
case DOWNLOAD_FINISHED:
this.updateMessage("Download complete");
break;
case DOWNLOAD_STARTING:
this.updateMessage("Download starting");
break;
default:
this.updateMessage(status.getDescription());
break;
}
}
@Override
@ -474,7 +583,7 @@ public class DLModelSelectPane extends PamBorderPane {
pathLabel.textProperty().unbind();
modelLoadIndicator.progressProperty().unbind();
updatePathLabel();
updatePathLabel(this.getValue());
}
@Override protected void succeeded() {

View File

@ -1,11 +1,10 @@
package rawDeepLearningClassifier.layoutFX;
import java.net.URI;
import java.util.ArrayList;
import org.controlsfx.control.PopOver;
import PamController.FlipSettingsPane;
import PamController.PamGUIManager;
import PamController.SettingsPane;
import PamDetection.RawDataUnit;
import PamView.dialog.warn.WarnOnce;
@ -17,16 +16,12 @@ import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.PopupControl;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tooltip;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import pamViewFX.PAMGuiFXSettings;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
@ -39,8 +34,8 @@ import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxNodes.utilityPanes.GroupedSourcePaneFX;
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
import rawDeepLearningClassifier.RawDLParams;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import warnings.PamWarning;
/**
@ -49,7 +44,7 @@ import warnings.PamWarning;
* @author Jamie Macaulay
*
*/
public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
public class DLSettingsPane extends SettingsPane<RawDLParams>{
public static double MAX_WIDTH = 270;
@ -116,15 +111,11 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
private Label infoLabel;
private Object flipPane;
private PopupControl advLabel;
private DLModelSelectPane modelSelectPane;
public RawDLSettingsPane(DLControl dlControl){
public DLSettingsPane(DLControl dlControl){
super(null);
this.dlControl=dlControl;
// Button newButton=new Button("Test");
@ -140,9 +131,12 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
mainPane=new PamBorderPane();
mainPane.setCenter(createDLPane());
mainPane.setPadding(new Insets(5,5,5,5));
mainPane.setMinHeight(430);
mainPane.setMaxWidth(MAX_WIDTH);
mainPane.setPrefWidth(MAX_WIDTH);
if (!PamGUIManager.isFX()){
mainPane.setMinHeight(430);
mainPane.setMaxWidth(MAX_WIDTH);
mainPane.setPrefWidth(MAX_WIDTH);
}
//this.getAdvPane().setMaxWidth(MAX_WIDTH);
@ -377,8 +371,16 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
System.out.println("Set CLASSIFIER PANE: " + modelSelectPane.currentClassifierModel);
if (modelSelectPane.currentClassifierModel!=null && modelSelectPane.currentClassifierModel.getModelUI()!=null) {
classifierPane.setCenter(modelSelectPane.currentClassifierModel.getModelUI().getSettingsPane().getContentNode());
modelSelectPane.currentClassifierModel.getModelUI().setParams();
if (modelSelectPane.currentClassifierModel!=null) {
modelSelectPane.currentClassifierModel.getModelUI().setParams();
}
else {
classifierPane.setCenter(null);
}
}
else {
classifierPane.setCenter(null);
@ -391,6 +393,7 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
if (currParams==null ) currParams = new RawDLParams();
@SuppressWarnings("rawtypes")
PamDataBlock rawDataBlock = sourcePane.getSource();
if (rawDataBlock == null){
Platform.runLater(()->{
@ -451,17 +454,44 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
this.modelSelectPane.currentClassifierModel.getModelUI().getParams();
}
}
currParams.modelURI = this.modelSelectPane.currentSelectedFile;
return currParams;
}
public static PamWarning statusToWarnings(DLStatus dlStatus) {
PamWarning pamWarning = new PamWarning(dlStatus.getName(), dlStatus.getDescription(), dlStatus.isError() ? 2 : 1);
return pamWarning;
}
/**
* Show a warning dialog for the status
* @param the status to show
*/
public void showWarning(DLStatus dlWarning) {
ArrayList<PamWarning> dlWarnings = new ArrayList<PamWarning>();
dlWarnings.add(statusToWarnings(dlWarning));
showWarning(dlWarnings);
}
/**
* Show a warning dialog.
* @param the warning to show.
*/
public void showWarning(PamWarning dlWarning) {
ArrayList<PamWarning> dlWarnings = new ArrayList<PamWarning>();
dlWarnings.add(dlWarning);
showWarning(dlWarnings);
}
/**
* Show a warning dialog.
* @param dlWarnings - list of warnings - the most important will be shown.
*/
public void showWarnings(ArrayList<PamWarning> dlWarnings) {
public void showWarning(ArrayList<PamWarning> dlWarnings) {
if (dlWarnings==null || dlWarnings.size()<1) return;
@ -480,6 +510,7 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
final boolean errorF = error;
Platform.runLater(()->{
WarnOnce.showWarningFX(null, "Deep Learning Settings Warning", warningsF , errorF ? AlertType.ERROR : AlertType.WARNING);
// WarnOnce.showWarning( "Deep Learning Settings Warning", warningsF , WarnOnce.WARNING_MESSAGE);
});
//user presses OK - these warnings are just a message - they do not prevent running the module.
@ -500,7 +531,6 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
}
// dlModelBox.getSelectionModel().select(currParams.modelSelection);
windowLength.getValueFactory().setValue(currParams.rawSampleSize);
hopLength.getValueFactory().setValue(currParams.sampleHop);
@ -514,17 +544,16 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
enableControls();
setSegInfoLabel();
// //set up the model and the custom pane if necessary.
//
// //set up the model and the custom pane if necessary.
this.modelSelectPane.loadNewModel(currParams.modelURI);
//this.modelSelectPane.updatePathLabel();
this.setClassifierPane();
//For some reason, in the FX GUI, this causes a root used in multiple scenes exceptions...not sure why.
//sourcePane.getChannelValidator().validate();
Platform.runLater(()->{
sourcePane.getChannelValidator().validate();
});
}
@ -553,6 +582,7 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
* Get the data block currently selected in the pane.
* @return the data block currently selected in the pane.
*/
@SuppressWarnings("rawtypes")
public PamDataBlock getSelectedParentDataBlock() {
return sourcePane.getSource();
}
@ -565,6 +595,34 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
return dlControl;
}
/**
* Convenience class to set the segment length in samples from milliseconds
* @param defaultSegmentLen - the segment length in milliseconds.
*/
public void setSegmentLength(Double defaultSegmentLen) {
if (defaultSegmentLen==null) return;
double sR = getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
System.out.println("Set the segment length: " + defaultSegmentLen + " sR " + sR);
//automatically set the default segment length.
getDLControl().getSettingsPane().getSegmentLenSpinner().getValueFactory().setValue((int) (sR*defaultSegmentLen/1000.));
}
/**
* Convenience class to set the hop length in samples from milliseconds
* @param defaultSegmentLen - the segment length in milliseconds.
*/
public void setHopLength(Double hopLength) {
if (hopLength==null) return;
double sR = getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
//automatically set the default segment length.
getDLControl().getSettingsPane().getHopLenSpinner().getValueFactory().setValue((int) (sR*hopLength/1000.));
}
}

View File

@ -0,0 +1,170 @@
package rawDeepLearningClassifier.layoutFX.defaultModels;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javafx.application.HostServices;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamStackPane;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.hidingPane.HidingPane;
import rawDeepLearningClassifier.defaultModels.DLDefaultModelManager;
import rawDeepLearningClassifier.defaultModels.DLModel;
/**
* Pane which allows users to view and select default models.
*/
public class DefaultModelPane extends PamBorderPane{
/**
* Reference to the deafult model manager that contains the default models.
*/
private DLDefaultModelManager defaultModelManager;
private PamBorderPane hidingPaneContent;
private HidingPane hidingPane;
ObjectProperty<DLModel> defaultModel = new SimpleObjectProperty();
/**
* Constructor for the DefaultModelPane
* @param defaultModelManager - the default model manager to use.
*/
public DefaultModelPane(DLDefaultModelManager defaultModelManager) {
this.defaultModelManager=defaultModelManager;
this.setCenter(createDefaultModelPane() );
}
private Pane createDefaultModelPane() {
PamVBox vBox = new PamVBox();
// vBox.setSpacing(5);
Label label = new Label("Default Models");
PamGuiManagerFX.titleFont2style(label);
vBox.getChildren().add(label);
// vBox.setPrefWidth(120);
hidingPaneContent= new PamBorderPane();
hidingPaneContent.setPrefWidth(150);
hidingPane = new HidingPane(Side.RIGHT, hidingPaneContent, vBox, true, 0);
PamButton button;
for (int i=0; i<defaultModelManager.getNumDefaultModels(); i++) {
final int ii = i;
button= new PamButton(defaultModelManager.getDefaultModel(ii).getName());
button.prefWidthProperty().bind(vBox.widthProperty());
button.setOnAction((action)->{
hidingPaneContent.setCenter(createModelPane(defaultModelManager.getDefaultModel(ii)));
hidingPane.showHidePane(true);
});
if (i>0 && i<defaultModelManager.getNumDefaultModels()-1) {
button.setStyle("-fx-border-radius: 0 0 0 0; -fx-background-radius: 0 0 0 0");
}
else if (i==0) {
button.setStyle("-fx-border-radius: 5 5 0 0; -fx-background-radius: 5 5 0 0");
}
else {
button.setStyle("-fx-border-radius: 0 0 5 5 ; -fx-background-radius: 0 0 5 5");
}
vBox.getChildren().add(button);
}
hidingPane.setStyle("-fx-background-color: -fx-base");
// this.setStyle("-fx-background-color: -fx-base");
PamStackPane mainHolder = new PamStackPane();
mainHolder.getChildren().addAll(vBox, hidingPane);
StackPane.setAlignment(hidingPane, Pos.TOP_RIGHT);
return mainHolder;
}
private Node createModelPane(DLModel dlModel) {
Label titleLabel = new Label(dlModel.getName());
titleLabel.setWrapText(true);
PamGuiManagerFX.titleFont2style(titleLabel);
titleLabel.setPadding(new Insets(25,0,0,0));
hidingPane.getChildren().add(titleLabel);
PamVBox vBox = new PamVBox();
vBox.setSpacing(5);;
Label descriptionLabel = new Label(dlModel.getDescription());
descriptionLabel.setWrapText(true);
Hyperlink link = new Hyperlink(dlModel.getCitation());
link.setWrapText(true);
link.setOnAction((action)->{
try {
Desktop.getDesktop().browse(dlModel.getCitationLink());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// HostServices.getInstance(this).getHostServices().showDocument(yahooURL)
});
PamButton importButton = new PamButton("Import");
importButton.setGraphic(PamGlyphDude.createPamIcon("mdi2d-download", PamGuiManagerFX.iconSize));
importButton.setOnAction((action)->{
defaultModel.set(dlModel);
});
PamBorderPane buttonHolder = new PamBorderPane();
buttonHolder.setRight(importButton);
BorderPane.setAlignment(importButton, Pos.BOTTOM_RIGHT);
VBox.setVgrow(buttonHolder, Priority.ALWAYS);
vBox.getChildren().addAll(titleLabel, descriptionLabel, link, buttonHolder);
vBox.setPrefHeight(200);
return vBox;
}
public ObjectProperty<DLModel> defaultModelProperty() {
return defaultModel;
}
}

View File

@ -150,10 +150,10 @@ public class DLTransformsPane extends PamBorderPane {
ArrayList<DLTransformPane> dlTransformPanes = new ArrayList<DLTransformPane>();
sampleRate=-1;
// for (int i=0; i<dlTransforms.size() ; i++) {
// System.out.println("Set DL transfroms: " + dlTransforms.get(i).getDLTransformType() + " " + ((SimpleTransform) dlTransforms.get(i)).getParams());
// }
//
// for (int i=0; i<dlTransforms.size() ; i++) {
// System.out.println("Set DL transfroms: " + dlTransforms.get(i).getDLTransformType() + " " + ((SimpleTransform) dlTransforms.get(i)).getParams());
// }
DLTransformPane transformPane;
//create a pane for each transform
@ -164,6 +164,10 @@ public class DLTransformsPane extends PamBorderPane {
}
transformPane = DataTransformPaneFactory.getSettingsPane(dlTransforms.get(i));
System.out.println("Set DL transfroms: " + dlTransforms.get(i).getDLTransformType() + " " + ((SimpleTransform) dlTransforms.get(i)).getParams());
//there must be a transform pane or else this will break.
dlTransformPanes.add(transformPane);

View File

@ -42,6 +42,7 @@ public class DataTransformPaneFactory {
DLTransformPane settingsPane = null;
switch (dlTransfrom.getDLTransformType()) {
case DECIMATE:
case DECIMATE_SCIPY:
double sR;
if (((SimpleTransform) dlTransfrom).getParams()!=null){
sR = ((SimpleTransform) dlTransfrom).getParams()[0].doubleValue();

View File

@ -1,4 +1,4 @@
package test.java.rawDeepLearningClassifier;
package test.rawDeepLearningClassifier;
import static org.junit.jupiter.api.Assertions.assertEquals;
@ -18,11 +18,14 @@ import rawDeepLearningClassifier.dlClassification.genericModel.GenericModelParse
class DLJSONParserTest {
@Test
void test() {
public void test() {
//load an old file
String relJSONpath = "./src/test/resources/rawDeepLearningClassifier/Generic/right_whale/legacy_format/right_whale_DL_settings.pdtf";
System.out.println("Path: " + relJSONpath);
Path path = Paths.get(relJSONpath);
GenericModelParams genericParmas = new GenericModelParams();

View File

@ -1,4 +1,4 @@
package test.java.rawDeepLearningClassifier;
package test.rawDeepLearningClassifier;
import static org.junit.jupiter.api.Assertions.assertEquals;
import rawDeepLearningClassifier.DLControl;
@ -6,7 +6,6 @@ import rawDeepLearningClassifier.dlClassification.ketos.KetosClassifier;
import org.junit.jupiter.api.Test;
public class KetosClassifierTest {
// /**
@ -63,6 +62,6 @@ public class KetosClassifierTest {
public void ketosProcessTest() {
System.out.println("hello unit test complete");
assertEquals(2, 1+1);
assertEquals(2, 2);
}
}

View File

@ -1,4 +1,4 @@
package test.java.rawDeepLearningClassifier;
package test.rawDeepLearningClassifier;
import static org.junit.jupiter.api.Assertions.assertEquals;

View File

@ -0,0 +1,50 @@
{
"framework_info": {"framework": "Bespoke"},
"model_info": {
"output_shape": [
-1,
2
],
"input_shape": [
-1,
40,
40,
1
]
},
"class_info": {
"name_class": [
"Noise",
"Right Whale"
],
"num_class": 2
},
"transforms": [
{
"name": "norm_row_sum",
"params": {}
},
{
"name": "spectrogram",
"params": {
"fft": 256,
"hop": 100
}
},
{
"name": "load_audio",
"params": {"sr": 2000}
},
{
"name": "freq_compression",
"params": {
"bins": 40,
"fmin": 47,
"fmax": 357
}
}
],
"description": "Metadata for acoustic deep learning",
"version_info": {"version": 1},
"seg_size": {"size_ms": 2000}
}

View File

@ -1,5 +0,0 @@
package test;
public class DummyPamControllerInterface {
}

View File

@ -1 +0,0 @@
{"framework_info":{"framework":"Bespoke"},"model_info":{"output_shape":[-1,2],"input_shape":[-1,40,40,1]},"class_info":{"name_class":["Noise","Right Whale"],"num_class":2},"transforms":[{"name":"norm_row_sum","params":{}},{"name":"spectrogram","params":{"fft":256,"hop":100}},{"name":"load_audio","params":{"sr":2000}},{"name":"freq_compression","params":{"bins":40,"fmin":47,"fmax":357}}],"version_info":{"version":1},"seg_size":{"size_ms":2000}}