This commit is contained in:
Douglas Gillespie 2025-04-08 14:27:56 +01:00
commit 0126ff83c6
32 changed files with 678 additions and 139 deletions

View File

@ -6,7 +6,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/ojdk-21.0.1">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-21-openjdk-amd64">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>

View File

@ -11,9 +11,9 @@ org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
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=17
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.compliance=21
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@ -23,4 +23,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=17
org.eclipse.jdt.core.compiler.source=21

BIN
build/deb/PAMGuardIcon2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

13
build/deb/control Normal file
View File

@ -0,0 +1,13 @@
Package: PAMGuard
Version: 2.0.1
Section: java
Priority: optional
Architecture: all
Maintainer: Jamie Macaulay <jdjm@st-andrews.ac.uk>
Description: Process passive acoustic data for whales, dolphins and other species.
Icon: pamguard_icon.png
Depends: openjdk-21-jre
postinst script:
#!/bin/bash
# Set JVM options for the application
export JAVA_OPTS="-Xmx4g -Xms512m -Dsun.java2d.uiScale=2 -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true"

8
build/deb/pamguard.desktop Executable file
View File

@ -0,0 +1,8 @@
[Desktop Entry]
Name=PAMGuard
Comment=Application for passive acoustic monitoring v1
Exec=java -jar /usr/share/pamguard/Pamguard -c
Icon=/usr/share/pamguard/PAMGuardIcon2.png
Terminal=true
Type=Application
Categories=Application;

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Name=PAMGuard
Comment=Application for passive acoustic monitoring
Exec=java -jar /usr/share/pamguard/Pamguard-2.02.14a.jar -c
Icon=/path/to/your/icon.png
Terminal=true
Type=Application
Categories=Application;

BIN
data.mat Normal file

Binary file not shown.

View File

@ -26,6 +26,71 @@
</resources>
</build>
<profiles>
<profile>
<id>linux-profile</id>
<build>
<plugins>
<plugin>
<groupId>org.vafer</groupId>
<artifactId>jdeb</artifactId>
<version>1.11</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jdeb</goal>
</goals>
<configuration>
<controlDir>${basedir}/build/deb</controlDir>
<dataSet>
<data>
<src>${project.build.directory}/${project.build.finalName}.jar</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/pamguard</prefix>
</mapper>
</data>
<data>
<src>${basedir}/liblinux</src>
<type>directory</type>
<includes>*.txt</includes>
<includes>*.so</includes>
<mapper>
<type>perm</type>
<prefix>/usr/share/pamguard/liblinux</prefix>
</mapper>
</data>
<data>
<src>${basedir}/build/deb/PAMGuardIcon2.png</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/pamguard</prefix>
</mapper>
</data>
<data>
<src>${basedir}/build/deb/pamguard.desktop</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/applications</prefix>
</mapper>
</data>
<data>
<type>link</type>
<linkName>/usr/share/pamguard/Pamguard</linkName>
<linkTarget>/usr/share/pamguard/${project.build.finalName}.jar</linkTarget>
<symlink>true</symlink>
</data>
</dataSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>macos-profile</id>
<build>
@ -145,36 +210,11 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>21</release>
<compilerId>jdt</compilerId>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<release>21</release>
<compilerId>jdt</compilerId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-jdt</artifactId>
<version>1.5.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<configuration>
@ -207,17 +247,6 @@
</transformer>
<transformer />
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>test/resources/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@ -254,7 +283,7 @@
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>C:\Users\dg50\source\repos\PAMGuardPAMGuard\target/tempDependencies</outputDirectory>
<outputDirectory>${project.build.directory}/tempDependencies</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>

162
pom.xml
View File

@ -51,7 +51,106 @@
earlier. Most OS specific profiles are for generating executables and code signing.
Note use help:active-profiles to see which profiles are active -->
<profiles>
<!-- The Linux profile creates a DMG package for installing PAMGuard on
Linux Ubuntu based systems-->
<!--Note: There is a Maven bug/feature when using profiles when the plugin order is messed up and seemingly quite random.
In PAMGuard it essential that the shade plugin is called before the linux plugin. Therefore explicately call
the package phase using mvn package shade:shade jdeb:jdeb. Note that although a deb file can be created in Windows it
will not have the correct JavaFX libraries and therefore will not work when riun -->
<profile>
<id>linux-profile</id>
<activation>
<os>
<family>linux</family>
</os>
</activation>
<build>
<plugins>
<!--Creates a deb file for Linux-->
<plugin>
<artifactId>jdeb</artifactId>
<groupId>org.vafer</groupId>
<version>1.11</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jdeb</goal>
</goals>
<configuration>
<controlDir>${basedir}/build/deb</controlDir>
<dataSet>
<data>
<!--TODO-really the jar file should be named properly but thos would mean we would
have to change the name in the desktop file too. For now create a link to the jar file
with correct version number-->
<src>
${project.build.directory}/${project.build.finalName}.jar</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/pamguard</prefix>
</mapper>
</data>
<data>
<src>${basedir}/liblinux</src>
<type>directory</type>
<includes>*.txt</includes>
<includes>*.so</includes>
<mapper>
<type>perm</type>
<prefix>
/usr/share/pamguard/liblinux</prefix>
</mapper>
</data>
<data>
<src>
${basedir}/build/deb/PAMGuardIcon2.png</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/pamguard</prefix>
</mapper>
</data>
<!---THe desktop file will create a PAMGuard icon in the applications tray-->
<data>
<src>
${basedir}/build/deb/pamguard.desktop</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/share/applications</prefix>
</mapper>
</data>
<!---Create a link which is just called Pamguard. This means the .desktop file does not need
to be altered depending on the build name-->
<data>
<type>link</type>
<linkName>
/usr/share/pamguard/Pamguard</linkName>
<linkTarget>
/usr/share/pamguard/${project.build.finalName}.jar</linkTarget>
<symlink>true</symlink>
</data>
<!--<data>
<src>${project.basedir}/build/deb/set-java-property.sh</src>
<type>file</type>
<mapper>
<type>perm</type>
<prefix>/usr/bin</prefix>
<filemode>755</filemode>
</mapper>
</data>-->
</dataSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- The MacOS profile creates a DMG package for installing PAMGuard on MacOS-->
<!--Note: There is a Maven bug when using profiles when the plugin order is messed up and seemingly quite random.
In PAMGuard it essential that the shade plugin is called before the macos plugin and so the phase of the
@ -311,11 +410,10 @@
</execution>
-->
</executions>
</plugin>
</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.-->
@ -358,7 +456,52 @@
</profile>
</profiles>
<!-- Plugin which creates a .dmg file for MacOS.
<plugin>
<groupId>de.perdian.maven.plugins</groupId>
<artifactId>macosappbundler-maven-plugin</artifactId>
<version>1.21.1</version>
<configuration>
<plist>
<JVMMainClassName>pamguard.Pamguard</JVMMainClassName>
<CFBundleIconFile>src/Resources/PamguardIcon2.icns</CFBundleIconFile>
<CFBundleDisplayName>PAMGuard</CFBundleDisplayName>
<CFBundleDevelopmentRegion>English</CFBundleDevelopmentRegion>
<CFBundleURLTypes>
<string>msa</string>
</CFBundleURLTypes>
<JVMVersion>21+</JVMVersion>
<JVMArguments>
<string>-c</string>
</JVMArguments>
</plist>
<dmg>
<generate>true</generate>
<additionalResources>
<additionalResource>
<directory>src/target/bundle/</directory>
</additionalResource>
</additionalResources>
</dmg>
<jdk>
<include>false</include>
<location>/Library/Java/JavaVirtualMachines/amazon-corretto-21.jdk</location>
</jdk>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
</plugin>-->
<reporting>
@ -442,7 +585,7 @@
<groupId>io.github.macster110</groupId>
<artifactId>jpamutils</artifactId>
<version>0.0.59f</version>
<!-- com.github.psambit9791:wavfile:jar:0.1 pulls in various junit dependencies which breaks our own testing -->
<!-- com.github.psambit9791:wavfile:jar:0.1 pulls in various junit dependencies which breaks our own testing -->
<!--<exclusions>
<exclusion>
<groupId>org.junit.platform</groupId>
@ -610,7 +753,7 @@
</exclusions>
</dependency>
<!-- html to markdown conversion https://github.com/furstenheim/copy-down -->
<!-- html to markdown conversion https://github.com/furstenheim/copy-down -->
<dependency>
<groupId>io.github.furstenheim</groupId>
<artifactId>copy_down</artifactId>
@ -997,7 +1140,7 @@
<version>2.1.1</version>
</dependency>
<!--
<!--
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
@ -1065,7 +1208,7 @@
-->
<dependency>
<groupId>org.pamguard</groupId>
<artifactId>x3</artifactId>
<artifactId>X3</artifactId>
<version>2.2.8</version>
</dependency>
@ -1154,7 +1297,6 @@
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>

View File

@ -106,10 +106,6 @@ public class GroupLocResult implements Comparable<GroupLocResult>, LocalisationC
this.chi2 = chi2;
}
public GroupLocResult(double[] result, double[] resultErrors, int side, double chi2) {
// TODO Auto-generated constructor stub
}
/**
* @return the latLong
*/

View File

@ -1381,7 +1381,25 @@ public class PamArrayUtils {
}
/**
* Convert a matrix to a
* @param matrix - the MAT file matrix
* @return double[][] array of results
*/
public static float[][] matrix2arrayF(Matrix matrix) {
if (matrix==null) return null;
float[][] arrayOut = new float[matrix.getNumRows()][];
float[] arrayRow;
for (int i=0; i<matrix.getNumRows(); i++) {
arrayRow=new float[matrix.getNumCols()];
for (int j=0; j<matrix.getNumCols(); j++) {
arrayRow[j] = matrix.getFloat(i, j);
}
arrayOut[i]=arrayRow;
}
return arrayOut;
}

View File

@ -54,13 +54,18 @@ public class DataModelConnectPane extends ConnectionPane {
@Override
public void handle(DragEvent event)
{
// System.out.println("START drag over node drag dropped" + dataModelPaneFX.getDraggingStructure());
final Dragboard dragboard = event.getDragboard();
if (dragboard.hasString()
&& dataModelPaneFX.getModuleDragKey().equals(dragboard.getString())
&& dataModelPaneFX.getDraggingModule().get() != null || dataModelPaneFX.getDraggingStructure()!=null)
{
event.acceptTransferModes(TransferMode.MOVE);
event.consume();
// System.out.println("ACCEPT drag over node drag dropped" + dataModelPaneFX.getDraggingStructure());
event.acceptTransferModes(TransferMode.ANY);
//event.consume(); //causesd issues with dropping nodes not being detected
}
}
});
@ -70,6 +75,9 @@ public class DataModelConnectPane extends ConnectionPane {
@Override
public void handle(DragEvent event)
{
System.out.println("Add Some Node drag dropped: " + dataModelPaneFX.getDraggingStructure());
final Dragboard dragboard = event.getDragboard();
if (dragboard.hasString()
&& dataModelPaneFX.getModuleDragKey().equals(dragboard.getString())
@ -80,6 +88,7 @@ public class DataModelConnectPane extends ConnectionPane {
ModuleRectangle moduleRect = dataModelPaneFX.getDraggingModule().get();
// System.out.println("Add Connection Node drag dropped");
dataModelPaneFX.getDraggingModule().set(null);
dataModelPaneFX.getConnectionNodeFactory().addNewModule(moduleRect.getPamModuleInfo(), event.getX(), event.getY());
@ -88,6 +97,7 @@ public class DataModelConnectPane extends ConnectionPane {
if (dragboard.hasString()
&& dataModelPaneFX.getModuleDragKey().equals(dragboard.getString())
&& dataModelPaneFX.getDraggingStructure().get() != null){
// System.out.println("Add Structure Node drag dropped");
dataModelPaneFX.getConnectionNodeFactory().addNewStructure(dataModelPaneFX.getDraggingStructure().get(), event.getX(), event.getY());
dataModelPaneFX.getDraggingStructure().set(null);

View File

@ -121,8 +121,7 @@ public class ConnectionNodeFactory {
* @param y - the pixel y co-ordinate
*/
public StandardConnectionNode addNewStructure(StructureRectangle structureRectangle, double x, double y) {
// System.out.println("DataModelConnectPane: add new structure " + structureRectangle.getStructureType()
// + " no. nodes: " + this.getConnectionNodes().size());
System.out.println("DataModelConnectPane: add new structure " + structureRectangle.getStructureType() );
StandardConnectionNode connectionNode = createConnectionNode(structureRectangle.getStructureType(), null);
if (connectionNode!=null) {

View File

@ -136,6 +136,8 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
System.out.println("GenericDataPlotInfo: Single frequency measure in data unit " + pamDataUnit.toString());
}
//System.out.println("Frequency: " + f[0] + " " + f[1] + " " + pamDataUnit);
// draw a frequency box.
double y0 = tdProjector.getYPix(f[0]);
double y1 = tdProjector.getYPix(f[1]);

View File

@ -153,6 +153,9 @@ public class MLDetectionsManager implements PamDataUnitExporter {
public boolean hasCompatibleUnits(List<PamDataUnit> dataUnits) {
//first need to figure out how many data units there are.
for (int j=0; j<dataUnits.size(); j++){
if (hasCompatibleUnits(dataUnits.get(j).getClass())) return true;
}
return false;

View File

@ -232,7 +232,7 @@ public class Group3DProcess extends PamProcess implements DetectionGroupMonitor
}
}
// System.out.println("Ran localisation " + i + " " + localiserAlgorithm3D.getName() + " got: " + abstractLocalisation.getLatLong(0) + " " + abstractLocalisation.getHeight(0) + " Error: " + abstractLocalisation.getLocError(0));
System.out.println("Ran localisation " + i + " " + localiserAlgorithm3D.getName() + " got: " + abstractLocalisation.getLatLong(0) + " " + abstractLocalisation.getHeight(0) + " Error: " + abstractLocalisation.getLocError(0));
if (abstractLocalisation instanceof GroupLocalisation) {
groupLocalisation = (GroupLocalisation) abstractLocalisation;

View File

@ -388,7 +388,8 @@ public class HyperbolicLocaliser extends TOADBaseAlgorithm {
PamVector centre = geometry.getGeometricCentre();
int[] hydrophones = toadInformation.getHydrophoneList();
double xArray[] = new double[geom.length];
for (int i = 0; i < geom.length; i++) {
//System.out.println("Hyperbolic loc: Geom length: " + hydrophones.length + " " + geom.length);
for (int i = 0; i < hydrophones.length; i++) {
xArray[i] = geom[hydrophones[i]].sub(centre).dotProd(arrayAxes);
}
@ -581,6 +582,8 @@ public class HyperbolicLocaliser extends TOADBaseAlgorithm {
//// glr.setModel(model);
// return groupLocalisation;
LinearLocalisation linLoc = new LinearLocalisation(groupDataUnit, toadInformation.getHydrophoneMap(), geometry.getArrayAxes(), angle, r);
linLoc.setChi2(chiData);
GpsData refPos = new GpsData(geometry.getReferenceGPS().addDistanceMeters(geometry.getGeometricCentre()));
linLoc.setReferencePosition(refPos);
return linLoc;

View File

@ -132,11 +132,14 @@ abstract public class TOADBaseAlgorithm extends LocaliserAlgorithm3D {
// if (superDetection.getSubDetection(0).getUID() == 9035004477L) {
// System.out.println("Found it");
// }
TOADInformation toadInformation = toadCalculator.getTOADInformation(superDetection.getSubDetections(), sampleRate, allChannels, geometry);
boolean toadOK = checkTOADInformation(toadInformation);
// System.out.println("ToadOK: " + toadOK + " toadInformation: " + toadInformation + " allChannels: " + allChannels + " geometry: " + geometry);
//System.out.println("ToadOK: " + toadOK + " toadInformation: " + toadInformation + " allChannels: " + allChannels + " geometry: " + geometry.getGeometry() + "n sub: " + superDetection.getSubDetectionsCount() );
if (!toadOK) {
return null;

View File

@ -0,0 +1,17 @@
package group3dlocaliser.algorithm.toadmimplex;
import Localiser.detectionGroupLocaliser.GroupLocResult;
import group3dlocaliser.localisation.LinearLocalisation;
/**
* Wrapper to make a linear localisation into a group localisation
*/
public class LinearGroupLocResult extends GroupLocResult {
public LinearGroupLocResult(LinearLocalisation linearLocalisation) {
super(linearLocalisation.getReferencePosition(), 0, linearLocalisation.getChi2());
}
}

View File

@ -17,6 +17,7 @@ import group3dlocaliser.algorithm.toadmcmc.MCMCLocaliserPane;
import group3dlocaliser.algorithm.toadmcmc.ToadMCMCLocaliser;
import group3dlocaliser.algorithm.toadsimplex.ToadSimplexLocaliser;
import group3dlocaliser.grouper.DetectionGroupedSet;
import group3dlocaliser.localisation.LinearLocalisation;
/**
@ -94,7 +95,7 @@ public class ToadMimplexLocaliser extends ToadMCMCLocaliser {
*/
public DetectionGroupedSet preFilterLoc(DetectionGroupedSet preGroups) {
System.out.println("Pre filter groups: " + preGroups.getNumGroups());
//System.out.println("Pre filter groups: " + preGroups.getNumGroups());
MimplexParams params = (MimplexParams) group3dLocaliser.getLocaliserAlgorithmParams(this).getAlgorithmParameters();
@ -105,12 +106,12 @@ public class ToadMimplexLocaliser extends ToadMCMCLocaliser {
return preGroups;
}
//no need to do a y more processing.
//no need to do a any more processing.
if (preGroups.getNumGroups()<=2 && params.useFirstCombination) {
return preGroups;
}
//localiser using both hyperbolic and the
//localiser using both hyperbolic and simplex the
// will have to make a data unit for each group now...
Group3DDataUnit[] group3dDataUnits = new Group3DDataUnit[preGroups.getNumGroups()];
@ -121,18 +122,22 @@ public class ToadMimplexLocaliser extends ToadMCMCLocaliser {
group3dDataUnits[i] = new Group3DDataUnit(preGroups.getGroup(i));
//System.out.println("ToadMImplex. group3dDataUnits[i]: " + group3dDataUnits[i] );
GroupLocalisation preAbstractLocalisation = null;
AbstractLocalisation preAbstractLocalisation = null;
double minChi2 = Double.MAX_VALUE;
GroupLocResult locResult = null;
for (LocaliserModel model: preLocaliserModels) {
//System.out.println("ToadMImplex. model: " + model );
locResult = null;
minChi2=Double.MAX_VALUE;
preAbstractLocalisation = null; //must reset this.
try {
preAbstractLocalisation = (GroupLocalisation) model.runModel(group3dDataUnits[i], null, false);
preAbstractLocalisation = model.runModel(group3dDataUnits[i], null, false);
}
catch (Exception e) {
System.out.println("Mimplex pre filter loclaisation failed");
@ -142,12 +147,23 @@ public class ToadMimplexLocaliser extends ToadMCMCLocaliser {
// System.out.println("Pre-localisation result: " + locResult + " " + model.getName() + "N units: " + preGroups.getGroup(i).size());
if (preAbstractLocalisation!=null) {
if (preAbstractLocalisation instanceof GroupLocalisation) {
//now iterate through the potential ambiguities (this is a bit redunadant with Simplex and Hyperbolic)
for (GroupLocResult groupLocResult: preAbstractLocalisation.getGroupLocResults()) {
for (GroupLocResult groupLocResult: ((GroupLocalisation) preAbstractLocalisation).getGroupLocResults()) {
if (groupLocResult.getChi2()<minChi2) {
locResult = groupLocResult;
}
}
}
if (preAbstractLocalisation instanceof LinearLocalisation) {
//if a linear vertical array (exactly) then will return a linear localisation. Need to make this into
//a group localisation to satisfy the mimplex localiser.
if (((LinearLocalisation) preAbstractLocalisation).getChi2()<minChi2) {
locResult = new LinearGroupLocResult(((LinearLocalisation) preAbstractLocalisation));
}
}
}
}

View File

@ -244,6 +244,7 @@ public class DetectionGrouper {
*/
public synchronized void closeMotherGroup() {
processFirstGroup(motherGroup);
if (maxInterGroupSamples==null) return;
motherGroup = new FirstGrouping(maxInterGroupSamples.length, 0, null);
}

View File

@ -5,6 +5,7 @@ import Localiser.detectionGroupLocaliser.LocalisationChi2;
import PamDetection.AbstractLocalisation;
import PamDetection.LocContents;
import PamguardMVC.PamDataUnit;
import group3dlocaliser.algorithm.Chi2Data;
import pamMaths.PamVector;
public class LinearLocalisation extends AbstractLocalisation implements LocalisationChi2{
@ -12,6 +13,7 @@ public class LinearLocalisation extends AbstractLocalisation implements Localisa
private double[] angles;
private Double range;
private GpsData referencePosition;
private Chi2Data chi2Dat;
public LinearLocalisation(PamDataUnit pamDataUnit, int referenceHydrophones, PamVector[] arrayAxes, double bearing, Double range) {
super(pamDataUnit, LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY, referenceHydrophones);
@ -42,8 +44,7 @@ public class LinearLocalisation extends AbstractLocalisation implements Localisa
@Override
public Double getChi2() {
// TODO Auto-generated method stub
return null;
return chi2Dat.getChi2();
}
@Override
@ -84,6 +85,14 @@ public class LinearLocalisation extends AbstractLocalisation implements Localisa
public void setReferencePosition(GpsData referencePosition) {
this.referencePosition = referencePosition;
}
/**
* Set Chi2 data
* @param chi2dat
*/
public void setChi2(Chi2Data chi2dat) {
this.chi2Dat = chi2dat;
}

View File

@ -58,7 +58,13 @@ public class Group3DOfflineTask extends OfflineTask<PamDataUnit>{
@Override
public boolean processDataUnit(PamDataUnit dataUnit) {
try {
group3DProcess.newData(null, dataUnit);
}
catch (Exception e) {
e.printStackTrace();
}
//System.out.println("New data unit added: " +dataUnit);
return false;
}

View File

@ -210,7 +210,7 @@ public class DLClassifyProcess extends PamProcess {
*/
@Override
public void newData(PamObservable obs, PamDataUnit pamRawData) {
//System.out.println("NEW SEGMENTER DATA: " + PamCalendar.formatDateTime2(pamRawData.getTimeMilliseconds(), "dd MMM yyyy HH:mm:ss.SSS", false) + " " + pamRawData.getUID() + " " + pamRawData.getChannelBitmap() + " " + pamRawData);
//System.out.println("NEW SEGMENTER DATA: " + PamCalendar.formatDateTime2(pamRawData.getTimeMilliseconds(), "dd MMM yyyy HH:mm:ss.SSS", false) + " " + pamRawData.getUID() + " " + pamRawData.getChannelBitmap() + " " + pamRawData);
//if grouped data then just run the classifier on the group - do not try and create a buffer.
if (pamRawData instanceof SegmenterDetectionGroup) {
@ -618,10 +618,11 @@ public class DLClassifyProcess extends PamProcess {
*/
public void forceRunClassifier(PamDataUnit dataUnit) {
// System.out.println("CLASSIFICATION BUFFER: " + classificationBuffer.size());
//System.out.println("CLASSIFICATION BUFFER: " + classificationBuffer.size());
if (this.classificationBuffer.size()>0) {
if (classificationBuffer.get(0) instanceof GroupedRawData) {
//System.out.println("Run raw model on: " + classificationBuffer.get(0) + " " + classificationBuffer.get(1));
runRawModel(); //raw data or raw data units
}
if (classificationBuffer.get(0) instanceof SegmenterDetectionGroup) {
@ -689,10 +690,12 @@ public class DLClassifyProcess extends PamProcess {
DataUnitBaseData basicData = groupDataBuffer.get(0).getBasicData().clone();
basicData.setMillisecondDuration(1000.*rawdata[0].length/this.sampleRate);
basicData.setSampleDuration((long) (groupDataBuffer.size()*dlControl.getDLParams().rawSampleSize));
// System.out.println("Model result: " + modelResult.size());
DLDetection dlDetection = new DLDetection(basicData, rawdata, getSampleRate());
addDLAnnotation(dlDetection,modelResult);
dlDetection.setFrequency(new double[] {0, this.getSampleRate()/2});
//create the data unit
return dlDetection;

View File

@ -139,9 +139,8 @@ public class ArchiveModelWorker extends GenericModelWorker {
System.out.println(modelParams.dlTransforms);
ArrayList<DLTransform> transforms = DLTransformsFactory.makeDLTransforms(modelParams.dlTransforms);
// ///HACK here for now to fix an issue with dB and Ketos transforms having zero length somehow...
// for (int i=0; i<modelParams.dlTransforms.size(); i++) {
// System.out.println(modelParams.dlTransforms.get(i));
// System.out.println(modelParams.dlTransforms.get(i).toString());
// }
//only load new transforms if defaults are selected

View File

@ -11,6 +11,7 @@ import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.utils.DLUtils;
import org.jamdev.jpamutils.wavFiles.AudioData;
import PamUtils.PamArrayUtils;
import PamguardMVC.PamDataUnit;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.DLStatus;
@ -82,10 +83,17 @@ public abstract class DLModelWorker<T> {
DLTransform transform = modelTransforms.get(0);
for (int i =0; i<modelTransforms.size(); i++) {
transform = modelTransforms.get(i).transformData(transform);
// //TEMP
// if (transform instanceof FreqTransform) {
// transformedData = ((FreqTransform) transform).getSpecTransfrom().getTransformedData();
// System.out.println("DLModelWorker: transform : " + modelTransforms.get(i).getDLTransformType() + " "+ i + transformedData.length + " " + transformedData[0].length + " minmax: " + PamArrayUtils.minmax(transformedData)[0] + " " + PamArrayUtils.minmax(transformedData)[1]);
// }
// //TEMP
// if (transform instanceof WaveTransform) {
// transformedData1 = ((WaveTransform) transform).getWaveData().getScaledSampleAmplitudes();
// System.out.println("DLModelWorker: transform : " + modelTransforms.get(i).getDLTransformType() + " "+ i + " " + transformedData1.length + " " + PamArrayUtils.minmax(transformedData1)[0] + " " + PamArrayUtils.minmax(transformedData1)[1]);
// }
}

View File

@ -104,6 +104,7 @@ public class GenericModelWorker extends DLModelWorker<StandardPrediction> {
}
setModelTransforms(genericParams.dlTransfroms);
//is this a waveform or a spectrogram model?
setWaveFreqModel(genericParams);

View File

@ -583,10 +583,11 @@ public class DLSettingsPane extends SettingsPane<RawDLParams>{
@Override
public void setParams(RawDLParams currParams) {
sourcePane.setParams(currParams.groupedSourceParams);
sourcePane.sourceChanged();
sourcePane.setSourceList();
sourcePane.setParams(currParams.groupedSourceParams);
dlControl.createDataSelector(sourcePane.getSource());

View File

@ -59,7 +59,7 @@ public class PeakTrimTransformPane extends DLTransformPane {
});
//spinner for changing filter order.
targetLenSpinner = new Spinner<Integer>(1,50,4,1);
targetLenSpinner = new Spinner<Integer>(1,Integer.MAX_VALUE,4,1);
targetLenSpinner.valueProperty().addListener((obsVal, oldVal, newVal)->{
this.notifySettingsListeners();
});

View File

@ -1,5 +1,7 @@
package rawDeepLearningClassifier.offline;
import java.util.ListIterator;
import PamController.PamController;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
@ -8,6 +10,7 @@ import dataMap.OfflineDataMapPoint;
import matchedTemplateClassifer.MTClassifierControl;
import offlineProcessing.OfflineTask;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.segmenter.GroupedRawData;
import rawDeepLearningClassifier.segmenter.SegmenterDetectionGroup;
import rawDeepLearningClassifier.segmenter.SegmenterProcess;
@ -48,7 +51,7 @@ public class DLOfflineTask extends OfflineTask<PamDataUnit<?,?>>{
@Override
public boolean processDataUnit(PamDataUnit<?, ?> dataUnit) {
// System.out.println("--------------");
// System.out.println("Offline task start: " + dataUnit.getUpdateCount() + " UID " + dataUnit.getUID());
//System.out.println("Offline task start: " + dataUnit.getUpdateCount() + " UID " + dataUnit.getUID() + " " + dlControl.getDLParams().enableSegmentation);
boolean saveBinary = false;
try {
@ -79,9 +82,16 @@ public class DLOfflineTask extends OfflineTask<PamDataUnit<?,?>>{
//detection has been added we force the classifier to run on all the segments generated from
//the raw data.
//Process a data unit
//Process a data unit within the segmenter
dlControl.getSegmenter().newData(dataUnit);
//System.out.println("Segments: " + dlControl.getSegmenter().getSegmenterDataBlock().getUnitsCount());
//need to add the segmenter data units into the classification buffer
ListIterator<GroupedRawData> iterator = dlControl.getSegmenter().getSegmenterDataBlock().getListIterator(0);
while (iterator.hasNext()) {
dlControl.getDLClassifyProcess().newData(dlControl.getSegmenter().getSegmenteGroupDataBlock(), iterator.next());
}
//force click data save
dlControl.getDLClassifyProcess().forceRunClassifier(dataUnit);

View File

@ -96,7 +96,7 @@ public class SegmenterProcess extends PamProcess {
segmenterDataBlock = new SegmenterDataBlock("Segmented Raw Data", this,
dlControl.getDLParams().groupedSourceParams.getChanOrSeqBitmap());
segmenterGroupDataBlock = new SegmenterGroupDataBlock("Segmented data units", this,
segmenterGroupDataBlock = new SegmenterGroupDataBlock("Segmented Group Data", this,
dlControl.getDLParams().groupedSourceParams.getChanOrSeqBitmap());
addOutputDataBlock(segmenterDataBlock);
@ -241,7 +241,7 @@ public class SegmenterProcess extends PamProcess {
newRawDataUnit(pamRawData);
}
else if (pamRawData instanceof ClickDetection) {
newClickData( pamRawData);
newClickData(pamRawData);
}
else if (pamRawData instanceof ClipDataUnit) {
newClipData(pamRawData);
@ -491,7 +491,7 @@ public class SegmenterProcess extends PamProcess {
public void newClickData(PamDataUnit pamRawData) {
//the raw data units should appear in sequential channel order
// System.out.println("New raw data in: chan: " + PamUtils.getSingleChannel(pamRawData.getChannelBitmap()) + " Size: " + pamRawData.getSampleDuration());
//System.out.println("New raw data in: chan: " + PamUtils.getSingleChannel(pamRawData.getChannelBitmap()) + " Size: " + pamRawData.getSampleDuration());
ClickDetection clickDataUnit = (ClickDetection) pamRawData;
@ -542,6 +542,12 @@ public class SegmenterProcess extends PamProcess {
//segment the data unit into different chunks.
newRawData(pamDataUnit,
rawDataChunk[i], chans[i], dlControl.getDLParams().rawSampleSize, dlControl.getDLParams().sampleHop, true);
//the way that the newRawdata works is it waits for the next chunk and copies all relevant bits
//from previous chunks into segments. This is fine for continuous data but means that chunks of data
//don't get their last hop...
//got to save the last chunk of raw data -even if the segment has not been filled.
saveRawGroupData(true);
}
else {
// //send the whole data chunk to the deep learning unit
@ -551,13 +557,8 @@ public class SegmenterProcess extends PamProcess {
// pamDataUnit.getStartSample(), rawDataChunk[i].length, rawDataChunk[i].length);
}
//the way that the newRawdata works is it waits for the next chunk and copies all relevant bits
//from previous chunks into segments. This is fine for continuous data but means that chunks of data
//don't get their last hop...
}
//got to save the last chunk of raw data -even if the segment has not been filled.
saveRawGroupData(true);
}
@ -600,7 +601,7 @@ public class SegmenterProcess extends PamProcess {
long timeMilliseconds = unit.getTimeMilliseconds();
long startSampleTime = unit.getStartSample();
//System.out.println("Segmenter: RawDataIn: chan: 1 " + getSourceParams().countChannelGroups() + currentRawChunks);
//System.out.println("Segmenter: RawDataIn: chan: 1 " + getSourceParams().countChannelGroups() + currentRawChunks + " rawSampleSize " + rawSampleSize + " rawSampleHop: " +rawSampleHop);
if (currentRawChunks==null) {
System.err.println("Current raw chunk arrays are null");
@ -753,6 +754,7 @@ public class SegmenterProcess extends PamProcess {
* @param forceSave - true to also save the remaining unfilled segment.
*/
private void saveRawGroupData(boolean forceSave) {
//System.out.println("Segmenter process: saveRawGroupData(boolean forceSave)");
for (int i=0; i<getSourceParams().countChannelGroups(); i++) {
saveRawGroupData(i, forceSave);
}
@ -771,6 +773,7 @@ public class SegmenterProcess extends PamProcess {
* @param i - the group index.
*/
private void saveRawGroupData(int i) {
//System.out.println("Segmenter process: saveRawGroupData(int i)");
saveRawGroupData(i, false);
}

View File

@ -1,23 +1,33 @@
package test.rawDeepLearningClassifier;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import org.jamdev.jdl4pam.transforms.DLTransform;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
import org.jamdev.jdl4pam.transforms.WaveTransform;
import org.jamdev.jdl4pam.utils.DLMatFile;
import org.jamdev.jpamutils.wavFiles.AudioData;
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import org.junit.jupiter.api.Test;
import PamUtils.PamArrayUtils;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.StandardPrediction;
import rawDeepLearningClassifier.segmenter.GroupedRawData;
import us.hebi.matlab.mat.format.Mat5;
import us.hebi.matlab.mat.format.Mat5File;
import us.hebi.matlab.mat.types.MatFile;
import us.hebi.matlab.mat.types.Matrix;
import us.hebi.matlab.mat.types.Struct;
@ -26,18 +36,231 @@ import us.hebi.matlab.mat.types.Struct;
* Model from Thomas webber which is a good way to test the click based stuff is working in PAMGUard.
*/
public class ClickDLTest {
/**
* Test just one click using the zipped classifier
* @throws
*/
@Test
public void clickDLTest() {
public void aclickDLTestZip() {
System.out.println("*****CLickDLTest: Single click test zip*****");
float SAMPLE_RATE = 500000;
//relative paths to the resource folders.
String relModelPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/model_pb.zip";
String clicksPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/example_2000021.mat";
// String matout = "/home/jamiemac/MATLAB-Drive/MATLAB/PAMGUARD/deep_learning/generic_classifier/example_2000021_transforms.mat";
String matout=null;
// load the click data up.
Path clkPath = Paths.get(clicksPath);
PredGroupedRawData clickData = null;
Struct matclkStruct = Mat5.newStruct();
try {
Mat5File mfr = Mat5.readFromFile(clkPath.toAbsolutePath().normalize().toString());
// //get array of a name "my_array" from file
Struct mlArrayRetrived = mfr.getStruct( "newStruct" );
Matrix clickWavM = mlArrayRetrived.get("wave", 0);
double[][] clickWaveform= PamArrayUtils.matrix2array(clickWavM);
clickWaveform=PamArrayUtils.transposeMatrix(clickWaveform);
Matrix clickUID= mlArrayRetrived.get("UID", 0);
Matrix pred= mlArrayRetrived.get("pred", 0);
//create a click object whihc we can pass through transforms etc.
clickData = new PredGroupedRawData(0L, 1, 0, clickWaveform[0].length, clickWaveform[0].length);
clickData.setUID(clickUID.getLong(0));
clickData.setRawData(clickWaveform);
clickData.setPrediction(new double[] {pred.getDouble(0)});
// load the model up
Path path = Paths.get(relModelPath);
ArchiveModelWorker genericModelWorker = new ArchiveModelWorker();
StandardModelParams genericModelParams = new StandardModelParams();
genericModelParams.modelPath = path.toAbsolutePath().normalize().toString();
//prep the model - all setting are included within the model
genericModelWorker.prepModel(genericModelParams, null);
System.out.println("seglen: " + genericModelParams.defaultSegmentLen);
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
groupedData.add(clickData);
System.out.println("Waveform input: " + groupedData.get(0).getRawData().length + " " + groupedData.get(0).getRawData()[0].length);
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,96000, 0);
float[] outputPAMGuard = genericPrediction.get(0).getPrediction();
System.out.println("Model output PAMGuard: " + outputPAMGuard[0]);
assertEquals(outputPAMGuard[0], 0.99, 0.05);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
assertTrue(false); //make sure the unit test fails
return;
}
}
/**
* Test just one click
* @throws
*/
@Test
public void aclickDLTest() {
System.out.println("*****CLickDLTest: Single click test*****");
//relative paths to the resource folders.
System.out.println("*****Click classification Deep Learning C*****");
// //relative paths to the resource folders.
// String relModelPath = "/Users/jdjm/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/model_pb/saved_model.pb";
// String clicksPath = "/Users/jdjm/Library/CloudStorage/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/example_2000021.mat";
//relative paths to the resource folders.
String relModelPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/uniform_model/saved_model.pb";
String clicksPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/clicks.mat";
String relModelPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/model_pb/saved_model.pb";
String clicksPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/example_2000021.mat";
//load the click up
// String matout = "/home/jamiemac/MATLAB-Drive/MATLAB/PAMGUARD/deep_learning/generic_classifier/example_2000021_transforms.mat";
String matout=null;
// load the click data up.
Path clkPath = Paths.get(clicksPath);
PredGroupedRawData clickData = null;
Struct matclkStruct = Mat5.newStruct();
try {
Mat5File mfr = Mat5.readFromFile(clkPath.toAbsolutePath().normalize().toString());
// //get array of a name "my_array" from file
Struct mlArrayRetrived = mfr.getStruct( "newStruct" );
Matrix clickWavM = mlArrayRetrived.get("wave", 0);
Matrix modelInputM= mlArrayRetrived.get("wave_pad", 0);
double[][] clickWaveform= PamArrayUtils.matrix2array(clickWavM);
clickWaveform=PamArrayUtils.transposeMatrix(clickWaveform);
//get the raw model input so we can test the model directly.
double[][] pythonModelInput= PamArrayUtils.matrix2array(modelInputM);
pythonModelInput = PamArrayUtils.transposeMatrix(pythonModelInput);
float[] pythonModelInputF = PamArrayUtils.double2Float(pythonModelInput[0]);
Matrix clickUID= mlArrayRetrived.get("UID", 0);
Matrix pred= mlArrayRetrived.get("pred", 0);
//create a click object whihc we can pass through transforms etc.
clickData = new PredGroupedRawData(0L, 1, 0, clickWaveform[0].length, clickWaveform[0].length);
clickData.setUID(clickUID.getLong(0));
clickData.setRawData(clickWaveform);
clickData.setPrediction(new double[] {pred.getDouble(0)});
// load the model up
Path path = Paths.get(relModelPath);
GenericModelWorker genericModelWorker = new GenericModelWorker();
GenericModelParams genericModelParams = new GenericModelParams();
genericModelParams.modelPath = path.toAbsolutePath().normalize().toString();
//create the transforms.
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
//waveform transforms.
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE_SCIPY, 96000.));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV, 0., 1, AudioData.ZSCORE)); //needs to be here
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PEAK_TRIM, 64, 1));
genericModelParams.dlTransfromParams = dlTransformParamsArr;
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
//create the clicks.
path = Paths.get(clicksPath);
//prep the model
genericModelWorker.prepModel(genericModelParams, null);
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
groupedData.add(clickData);
System.out.println("Waveform input: " + groupedData.get(0).getRawData().length + " " + groupedData.get(0).getRawData()[0].length);
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,96000, 0);
// System.out.println("PAMGuard input len: " + pythonModelInputF.length);
float[] outputPAMGuard = genericPrediction.get(0).getPrediction();
System.out.println("Model output PAMGuard: " + outputPAMGuard[0]);
//run the transforms so we can take a look at the inpout
((WaveTransform) genericModelParams.dlTransfroms.get(0)).setWaveData(new AudioData(groupedData.get(0).getRawData()[0], 248000));;
//create the transformed wave
DLTransform transform = genericModelParams.dlTransfroms.get(0);
double[] audioOut = null;
for (int i=0; i<genericModelParams.dlTransfroms .size(); i++) {
transform = genericModelParams.dlTransfroms.get(i).transformData(transform);
audioOut = ((WaveTransform) transform).getWaveData().getScaledSampleAmplitudes();
matclkStruct.set(transform.getDLTransformType().getJSONString(), DLMatFile.array2Matrix(audioOut));
}
//RUN THE RAW MODEL with Python transformed input
// System.out.println("Python input len: " + pythonModelInputF.length);
// float[] outPutPython = genericModelWorker.getModel().runModel(new float[][] {PamArrayUtils.double2Float(audioOut)});
float[] outPutPython = genericModelWorker.getModel().runModel(new float[][] {pythonModelInputF});
System.out.println("Model output Python: " + outPutPython[0]);
assertEquals(outputPAMGuard[0], outPutPython[0], 0.05);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
assertTrue(false); //make sure the unit test fails
return;
}
if (matout!=null) {
// Create MAT file with a scalar in a nested struct
MatFile matFile = Mat5.newMatFile()
.addArray("click_transforms", matclkStruct);
// Serialize to disk using default configurations
try {
Mat5.writeToFile(matFile, matout);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Test
public void clicksDLTest() {
float SAMPLE_RATE = 96000;
//relative paths to the resource folders.
System.out.println("*****CLickDLTest: Clicks test*****");
//relative paths to the resource folders.
String relModelPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/model_pb/saved_model.pb";
String clicksPath = "/home/jamiemac/Dropbox/PAMGuard_dev/Deep_Learning/click_classifier_Thomas/model_v2/Click_Detector_Click_Detector_Clicks_20220603_111000_classified.mat";
Path path = Paths.get(relModelPath);
@ -46,59 +269,67 @@ public class ClickDLTest {
GenericModelParams genericModelParams = new GenericModelParams();
genericModelParams.modelPath = path.toAbsolutePath().normalize().toString();
//create the transforms.
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
//waveform transforms.
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE_SCIPY, 248000.));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PEAK_TRIM, 128, 1));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE_SCIPY, 96000.));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV, 0., 1, AudioData.ZSCORE));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PEAK_TRIM, 64, 1));
genericModelParams.dlTransfromParams = dlTransformParamsArr;
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
//create the clicks.
path = Paths.get(clicksPath);
ArrayList<PredGroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
ArrayList<PredGroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
//prep the model
genericModelWorker.prepModel(genericModelParams, null);
System.out.println("Model has loaded");
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
for (int i=0; i<1; i++) {
System.out.println("Model has loaded: n clicks " + clicks.size());
float count = 0;
long timeStart = System.currentTimeMillis();
for (int i=0; i<clicks.size(); i++) {
float prediction = (float) clicks.get(i).getPrediction()[0];
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
groupedData.add(clicks.get(i)); //TODO for loop
//System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,SAMPLE_RATE, 0);
float[] output = genericPrediction.get(i).getPrediction();
System.out.println(String.format("Click %d Predicted output: %.2f true output: %.2f passed: %b", clicks.get(i).getUID(),
output[0], prediction, output[0]>prediction*0.9 && output[0]<prediction*1.1));
}
//System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,SAMPLE_RATE, 0);
float[] output = genericPrediction.get(0).getPrediction();
System.out.println(String.format("Click %d Predicted output: %.4f true output: %.4f passed: %b delta %.2f", clicks.get(i).getUID(),
output[0], prediction, output[0]>prediction*0.9 && output[0]<prediction*1.1, (Math.abs(output[0] -prediction))));
if (output[0]>prediction*0.9 && output[0]<prediction*1.1) {
count++;
}
}
long timeEnd = System.currentTimeMillis();
double perctrue = count/clicks.size();
System.out.println(String.format("Percentage clicks passed: %.2f TIme to process %d clicks - %2f seconds", perctrue, clicks.size(), ((double) (timeEnd-timeStart))/1000.));
}
/**
* Import a bunch of clicks from a .mat file
*/
public static ArrayList<PredGroupedRawData> importClicks(String filePath, float sR) {
try {
Mat5File mfr = Mat5.readFromFile(filePath);
Mat5File mfr = Mat5.readFromFile(filePath);
// //get array of a name "my_array" from file
Struct mlArrayRetrived = mfr.getStruct( "clickpreds" );
Struct mlArrayRetrived = mfr.getStruct( "binarydata" );
int numClicks= mlArrayRetrived.getNumCols();
ArrayList<PredGroupedRawData> clicks = new ArrayList<PredGroupedRawData>(numClicks);
@ -106,12 +337,12 @@ public class ClickDLTest {
PredGroupedRawData clickData;
for (int i=0; i<numClicks; i++) {
Matrix clickWav= mlArrayRetrived.get("wave", i);
double[][] clickwaveform= PamArrayUtils.matrix2array(clickWav);
clickwaveform = PamArrayUtils.transposeMatrix(clickwaveform);
//System.out.println("click: " + click[0].length + " num: " + numClicks);
Matrix clickUID= mlArrayRetrived.get("UID", i);
Matrix clickmillis= mlArrayRetrived.get("millis", i);
Matrix channelMap= mlArrayRetrived.get("channelMap", i);
@ -122,11 +353,11 @@ public class ClickDLTest {
clickData = new PredGroupedRawData(clickmillis.getLong(0), channelMap.getInt(0), startSample.getLong(0), sampleDuration.getLong(0), sampleDuration.getInt(0));
clickData.setUID(clickUID.getLong(0));
clickData.setRawData(clickwaveform);
clickData.setPrediction(new double[] {pred.getDouble(0), pred.getDouble(1)});
clickData.setPrediction(new double[] {pred.getDouble(0)});
clicks.add(clickData);
}
return clicks;
}
catch (Exception e) {
@ -135,11 +366,11 @@ public class ClickDLTest {
return null;
}
}
public static class PredGroupedRawData extends GroupedRawData {
private double[] prediction;
public double[] getPrediction() {
return prediction;
}
@ -151,10 +382,10 @@ public class ClickDLTest {
public PredGroupedRawData(long timeMilliseconds, int channelBitmap, long startSample, long duration, int samplesize) {
super(timeMilliseconds, channelBitmap, startSample, duration, samplesize);
}
}
}