mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-22 15:12:28 +00:00
Merge branch 'main' of https://github.com/douggillespie/PAMGuard.git into main
This commit is contained in:
commit
875073c344
12
.classpath
12
.classpath
@ -1,11 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
@ -16,5 +10,11 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,6 +21,7 @@
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.dll
|
||||
|
||||
# eclipse project file
|
||||
.project
|
||||
|
@ -1,7 +1,12 @@
|
||||
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.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
|
||||
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
|
||||
<stringAttribute key="M2_GOALS" value="package shade:shade"/>
|
||||
<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
|
||||
<booleanAttribute key="M2_OFFLINE" value="false"/>
|
||||
<stringAttribute key="M2_PROFILES" value=""/>
|
||||
<listAttribute key="M2_PROPERTIES"/>
|
||||
<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
|
||||
<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
|
||||
<intAttribute key="M2_THREADS" value="1"/>
|
||||
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-13/"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-mx6000m -Djava.library.path=lib64"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/PamGuard Main}"/>
|
||||
</launchConfiguration>
|
@ -4,7 +4,7 @@
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<name>Pamguard Java12+</name>
|
||||
<version>2.02.03</version>
|
||||
<version>2.02.04</version>
|
||||
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
<organization>
|
||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<version>2.02.03</version>
|
||||
<version>2.02.04</version>
|
||||
<name>Pamguard Java12+</name>
|
||||
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
|
@ -7,6 +7,7 @@ import Acquisition.FolderInputSystem;
|
||||
import Acquisition.WavFileFuncs;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.geometry.Pos;
|
||||
@ -89,6 +90,8 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
*/
|
||||
private SimpleDoubleProperty progressProperty = new SimpleDoubleProperty(0);
|
||||
|
||||
private PamButton runButton;
|
||||
|
||||
/**
|
||||
* Constructor for the CheckWavHeadersPane
|
||||
* @param folderInputSystem - the folder input system.
|
||||
@ -102,20 +105,19 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
this.folderInputSystem=folderInputSystem;
|
||||
|
||||
folderName = new Label(" ");
|
||||
PamGuiManagerFX.titleFont2style(folderName);
|
||||
//PamGuiManagerFX.titleFont2style(folderName);
|
||||
|
||||
textArea = new TextArea();
|
||||
textArea.setEditable(false);
|
||||
ScrollPane scrollPane = new ScrollPane(textArea);
|
||||
scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
|
||||
//scrollPane.setPrefSize(322, 300);
|
||||
this.setCenter(scrollPane);
|
||||
|
||||
PamHBox pamHBox = new PamHBox();
|
||||
pamHBox.setAlignment(Pos.CENTER_LEFT);
|
||||
pamHBox.setSpacing(5);
|
||||
|
||||
PamButton runButton = new PamButton();
|
||||
runButton = new PamButton();
|
||||
runButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play"));
|
||||
runButton.setOnAction((action)->{
|
||||
checkFiles();
|
||||
@ -128,15 +130,15 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
pamHBox.getChildren().addAll(runButton, progressBar);
|
||||
progressBar.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
|
||||
mainPane.getChildren().addAll(folderName, textArea, pamHBox);
|
||||
|
||||
this.setPadding(new Insets(5,0,5,15));
|
||||
|
||||
this.setCenter(mainPane);
|
||||
|
||||
this.setPadding(new Insets(5,0,5,15));
|
||||
}
|
||||
|
||||
|
||||
private void setParams() {
|
||||
void setParams() {
|
||||
running = ran = false;
|
||||
subFolders = folderInputSystem.getFolderInputParameters().subFolders;
|
||||
if (subFolders) {
|
||||
@ -149,7 +151,7 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
textArea.setText(" ");
|
||||
allFiles.clear();
|
||||
nFiles = countFiles(folder);
|
||||
progressBar.setProgress(0);
|
||||
progressProperty.setValue(0);
|
||||
progressBar.progressProperty().bind(progressProperty);
|
||||
//progressBar.setMaximum(Math.max(nFiles, 1));
|
||||
enableControls();
|
||||
@ -213,6 +215,10 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
nErrors = 0;
|
||||
enableControls();
|
||||
checkFilesWorker = new CheckFiles();
|
||||
|
||||
Thread th = new Thread(checkFilesWorker);
|
||||
th.setDaemon(true);
|
||||
th.start();
|
||||
}
|
||||
|
||||
|
||||
@ -245,10 +251,16 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
* for each file, report on progress with it's name and
|
||||
* whether or not it had an error
|
||||
*/
|
||||
int error;
|
||||
File aFile;
|
||||
System.out.println("Analaysing files: Start: " + allFiles.size() );
|
||||
for (int i = 0; i < allFiles.size(); i++) {
|
||||
error = checkFile(aFile = allFiles.get(i));
|
||||
System.out.println("Analaysing files: " + i);
|
||||
final int error = checkFile(aFile = allFiles.get(i));
|
||||
final File aFile1 = aFile;
|
||||
Platform.runLater(()->{
|
||||
textArea.appendText(String.format("\n File %s %s" , aFile1.getName() ,
|
||||
error == AudioFileFuncs.FILE_OK ? "OK" : ("Error " + error)));
|
||||
});
|
||||
//progressBar.progressProperty().bind(null);
|
||||
progressProperty.setValue(100*i/(double) allFiles.size());
|
||||
}
|
||||
|
@ -304,6 +304,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
|
||||
wavFix.setOnAction((action)->{
|
||||
acquisitionPaneFX.getAdvancedLabel().setText("Fix Wave Files");
|
||||
acquisitionPaneFX.getAdvancedPane().setCenter(this.fixWavPane);
|
||||
fixWavPane.setParams();
|
||||
acquisitionPaneFX.getFlipPane().flipToBack();
|
||||
});
|
||||
|
||||
|
@ -380,6 +380,10 @@ abstract public class IshLocProcess extends PamProcess implements SpectrogramMar
|
||||
} else {
|
||||
newTime = oldTime*2;
|
||||
}
|
||||
/*
|
||||
* Above causes same error as in Rocca and needs fixing
|
||||
*/
|
||||
newTime = Math.min(newTime, 600000); // don't let this exceed 10 minutes.
|
||||
// System.out.println("Adjusting raw data natural lifetime from " + oldTime + " ms to " + newTime + " ms");
|
||||
daqBlock.setNaturalLifetimeMillis(newTime); // increase the lifetime to try and prevent this from happening again
|
||||
return;
|
||||
|
@ -31,12 +31,12 @@ public class PamguardVersionInfo {
|
||||
* Version number, major version.minorversion.sub-release.
|
||||
* Note: can't go higher than sub-release 'f'
|
||||
*/
|
||||
static public final String version = "2.02.03";
|
||||
static public final String version = "2.02.04";
|
||||
|
||||
/**
|
||||
* Release date
|
||||
*/
|
||||
static public final String date = "8 February 2022";
|
||||
static public final String date = "11 June 2022";
|
||||
|
||||
// /**
|
||||
// * Release type - Beta or Core
|
||||
|
@ -20,12 +20,22 @@ public class PamDependency {
|
||||
|
||||
private String dataBlockName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param requiredDataType Class of Data unit
|
||||
* @param defaultProvider Class name of default provider.
|
||||
* @param dataBlockName Specific data block name
|
||||
*/
|
||||
public PamDependency(Class requiredDataType, String defaultProvider, String dataBlockName) {
|
||||
this.requiredDataType = requiredDataType;
|
||||
this.defaultProvider = defaultProvider;
|
||||
this.dataBlockName = dataBlockName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requiredDataType Class of Data unit
|
||||
* @param defaultProvider Class name of default provider.
|
||||
*/
|
||||
public PamDependency(Class requiredDataType, String defaultProvider) {
|
||||
this.requiredDataType = requiredDataType;
|
||||
this.defaultProvider = defaultProvider;
|
||||
@ -41,12 +51,10 @@ public class PamDependency {
|
||||
/**
|
||||
* @return Returns the requiredDataType.
|
||||
*/
|
||||
// public DataType getRequiredDataType() {
|
||||
// return requiredDataType;
|
||||
// }
|
||||
public Class getRequiredDataType() {
|
||||
return requiredDataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the dataBlockName.
|
||||
*/
|
||||
|
@ -67,6 +67,8 @@ public interface PamPluginInterface extends CommonPluginInterface {
|
||||
* A short description of the plug in module. This text is used in various informational
|
||||
* windows displayed to the user. The value returned here is typically the same as the text returned
|
||||
* from the {@link #getDefaultName() getDefaultName()} method (e.g. <em>Click Detector</em> or <em>FFT (Spectrogram) Engine</em>).
|
||||
* <br>This is the text used in the main 'Add Modules' menus and is used as the
|
||||
* second argument to PamModuleInfo.registerControlledUnit
|
||||
* <p>
|
||||
* This field cannot be null.
|
||||
* @return String describing the plugin. Cannot be null.
|
||||
|
@ -344,7 +344,7 @@ public class ColourArray implements Cloneable, Serializable, ManagedParameters {
|
||||
* @return a contrasting colour.
|
||||
*/
|
||||
private Color createContrastingColour() {
|
||||
Color[] tryCols = {Color.white, Color.red, Color.blue, Color.green, Color.black};
|
||||
Color[] tryCols = {Color.white, Color.red, Color.CYAN, Color.blue, Color.green, Color.black};
|
||||
if (colours == null) {
|
||||
return tryCols[0];
|
||||
}
|
||||
|
@ -81,6 +81,15 @@ public class ColourComboBox extends PamPanel {
|
||||
|
||||
}
|
||||
|
||||
// private void createImages() {
|
||||
// for (int i = 0; i < ColourArray.ColourArrayType.values().length; i++) {
|
||||
// intArray[i] = new Integer(i);
|
||||
// colourStrings[i]=ColourArray.getName(types[i]);
|
||||
// colourArray=ColourArray.createStandardColourArray(256, ColourArray.ColourArrayType.values()[i]);
|
||||
// images[i]=new ImageIcon(createColourMapImage(colourArray, height, width));
|
||||
// }
|
||||
// }
|
||||
|
||||
public void addActionListener(ActionListener actionListener){
|
||||
colourBox.addActionListener(actionListener);
|
||||
}
|
||||
@ -161,7 +170,7 @@ public class ColourComboBox extends PamPanel {
|
||||
for (int i = 0; i < ColourArray.ColourArrayType.values().length; i++) {
|
||||
intArray[i] = new Integer(i);
|
||||
colourStrings[i]=ColourArray.getName(types[i]);
|
||||
colourArray=ColourArray.createStandardColourArray(256, ColourArray.ColourArrayType.values()[i]);
|
||||
colourArray=ColourArray.createStandardColourArray(width, ColourArray.ColourArrayType.values()[i]);
|
||||
images[i]=new ImageIcon(createColourMapImage(colourArray, height, width));
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public abstract class GeneralProjector<T extends PamCoordinate> {
|
||||
TIME ("Time"), FREQUENCY ("Frequency"), AMPLITUDE ("Amplitude"), LATITUDE ("Latitude"), LONGITUDE ("Longitude") ,
|
||||
BEARING ("Bearing"), RANGE ("Range"), SLANTANGLE ("Slant angle"), ICI ("Inter-click-interval"),
|
||||
DEPTH ("Depth"), SLANTBEARING ("Slant bearing"), AMPLITUDE_STEM ("Amplitude (stem)"), AMPLITUDE_LIN ("Linear Amplitude"),
|
||||
SPEED ("Speed"), PROBABILITY ("Probability"), NCYCLES ("No. cycles"), BANDWIDTH("Bandwidth"), ISHDET("Detector Output");
|
||||
SPEED ("Speed"), PROBABILITY ("Probability"), NCYCLES ("No. cycles"), BANDWIDTH("Bandwidth"), ISHDET("Detector Output"), X("x coordinate"), Y("y coordinate");
|
||||
|
||||
private String unit;
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
package PamView.dialog;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
@ -8,9 +11,9 @@ import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
public class GenericSwingDialog extends PamDialog {
|
||||
|
||||
|
||||
private boolean allOk;
|
||||
|
||||
|
||||
private PamDialogPanel[] dialogPanels;
|
||||
|
||||
private GenericSwingDialog(Window parentFrame, String title, PamDialogPanel ...dialogPanels) {
|
||||
@ -25,15 +28,48 @@ public class GenericSwingDialog extends PamDialog {
|
||||
}
|
||||
mainPanel.add(comp);
|
||||
}
|
||||
|
||||
|
||||
setDialogComponent(mainPanel);
|
||||
}
|
||||
|
||||
public static boolean showDialog(Window parentFrame, String title, PamDialogPanel ...dialogPanels) {
|
||||
|
||||
public static boolean showDialog(Window parentFrame, String title, PamDialogPanel ...dialogPanels) {
|
||||
return showDialog(parentFrame, title, null, dialogPanels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show dialog at a specific location on the screen.
|
||||
* @param parentFrame
|
||||
* @param title
|
||||
* @param screenPoint
|
||||
* @param dialogPanels
|
||||
* @return
|
||||
*/
|
||||
public static boolean showDialog(Window parentFrame, String title, Point screenPoint, PamDialogPanel ...dialogPanels) {
|
||||
GenericSwingDialog swingDialog = new GenericSwingDialog(parentFrame, title, dialogPanels);
|
||||
swingDialog.setParams();
|
||||
swingDialog.pack();
|
||||
if (screenPoint != null) {
|
||||
try {
|
||||
// check we're not going too far off the screen.
|
||||
Dimension sz = swingDialog.getPreferredSize();
|
||||
Dimension screen = null;
|
||||
if (parentFrame != null) {
|
||||
screen = parentFrame.getSize();
|
||||
}
|
||||
else {
|
||||
screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
}
|
||||
screenPoint.y = Math.min(screenPoint.y, screen.height-sz.height-10);
|
||||
screenPoint.y = Math.max(screenPoint.y, 0);
|
||||
screenPoint.x = Math.min(screenPoint.x, screen.width-sz.width-10);
|
||||
screenPoint.x = Math.max(screenPoint.x, 0);
|
||||
|
||||
swingDialog.setLocation(screenPoint);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// shouldn't happen, but if it does, it doesn't matter much
|
||||
}
|
||||
}
|
||||
swingDialog.setVisible(true);
|
||||
return swingDialog.allOk;
|
||||
}
|
||||
|
@ -3,10 +3,14 @@ package PamView.dialog;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
@ -225,6 +229,9 @@ abstract public class PamDialog extends JDialog {
|
||||
synchronized (this) {
|
||||
PamColors.getInstance().notifyContianer(this.getContentPane());
|
||||
}
|
||||
if (getOwner() == null) {
|
||||
moveToMouseLocation();
|
||||
}
|
||||
}
|
||||
try{
|
||||
super.setVisible(visible);
|
||||
@ -235,6 +242,35 @@ abstract public class PamDialog extends JDialog {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* put the dialog near the mouse location.
|
||||
*/
|
||||
public void moveToMouseLocation() {
|
||||
Point mouse = MouseInfo.getPointerInfo().getLocation();
|
||||
moveToLocation(mouse);
|
||||
}
|
||||
|
||||
public void moveToLocation(Point point) {
|
||||
if (point == null) {
|
||||
return;
|
||||
}
|
||||
// check we're not going too far off the screen.
|
||||
Dimension sz = getPreferredSize();
|
||||
Dimension screen = null;
|
||||
if (getOwner() != null) {
|
||||
screen = getOwner().getSize();
|
||||
}
|
||||
else {
|
||||
screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
}
|
||||
point.y = Math.min(point.y, screen.height-sz.height-10);
|
||||
point.y = Math.max(point.y, 0);
|
||||
point.x = Math.min(point.x, screen.width-sz.width-10);
|
||||
point.x = Math.max(point.x, 0);
|
||||
|
||||
setLocation(point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reschedule closing of the window to happen
|
||||
* on the AWT thread using SwingUtilities.invokeLater(...)
|
||||
|
@ -23,6 +23,24 @@ public class CornerLayoutContraint implements Serializable, Cloneable {
|
||||
|
||||
public int anchor = FIRST_LINE_START;
|
||||
|
||||
/**
|
||||
* Construct a corner layout constraint with the given anchor
|
||||
* @param anchor
|
||||
*/
|
||||
public CornerLayoutContraint(int anchor) {
|
||||
super();
|
||||
this.anchor = anchor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* construct a corner layout constraint with the default anchor
|
||||
*/
|
||||
public CornerLayoutContraint() {
|
||||
super();
|
||||
this.anchor = anchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CornerLayoutContraint clone() {
|
||||
try {
|
||||
|
@ -42,7 +42,6 @@ public abstract class OverlayDataManager<TOverlayInfoType extends OverlayDataInf
|
||||
private ParameterType[] parameterTypes;
|
||||
|
||||
private ParameterUnits[] parameterUnits;
|
||||
|
||||
|
||||
/**
|
||||
* @param generalProjector
|
||||
|
@ -87,7 +87,8 @@ public class ExtMouseAdapter {
|
||||
}
|
||||
|
||||
final public boolean mouseWheelMoved(MouseWheelEvent e) {
|
||||
return mouseWheelMoved(fxScroll(e));
|
||||
// return mouseWheelMoved(fxScroll(e));
|
||||
return false;
|
||||
}
|
||||
|
||||
// private MouseEvent swingMouse(javafx.scene.input.MouseEvent e) {
|
||||
|
@ -610,8 +610,6 @@ abstract public class OverlayMarker extends ExtMouseAdapter implements MarkManag
|
||||
}
|
||||
}
|
||||
|
||||
// Debug.out.printf("OverlayMarker: _ 2 In getSelectedMarkedDataUnits with %d available units\n", selectedData.size());
|
||||
|
||||
|
||||
return selectedData;
|
||||
}
|
||||
|
@ -32,12 +32,13 @@ public class SuperDetSymbolWrapper extends SymbolModifier {
|
||||
|
||||
@Override
|
||||
public SymbolData getSymbolData(GeneralProjector projector, PamDataUnit dataUnit) {
|
||||
PamDataUnit superDet = dataUnit.getSuperDetection(superDetDataBlock);
|
||||
PamDataUnit superDet = dataUnit.getSuperDetection(superDetDataBlock, true);
|
||||
if (superDet == null) {
|
||||
return null;
|
||||
}
|
||||
return superDetModifier.getSymbolData(getSymbolChooser().getProjector(), superDet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getToolTipText() {
|
||||
|
@ -986,7 +986,9 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instruction from the viewer scroll manager to load new data.
|
||||
* Instruction from the viewer scroll manager to load new data. <p>This just calls through
|
||||
* to loadViewerData(OfflineDataLoadInfo ...) so this should not be overridden. Override
|
||||
* the other function instead.
|
||||
*
|
||||
* @param dataStart data start time in millis
|
||||
* @param dataEnd data end time in millis.
|
||||
|
@ -943,23 +943,27 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
|
||||
}
|
||||
}
|
||||
|
||||
int nAttotations = getNumDataAnnotations();
|
||||
for (int i = 0; i < nAttotations; i++) {
|
||||
DataAnnotation an = getDataAnnotation(i);
|
||||
DataAnnotationType ant = an.getDataAnnotationType();
|
||||
String anName = ant.getAnnotationName();
|
||||
String anString = an.toString();
|
||||
if (anString == null) {
|
||||
continue;
|
||||
}
|
||||
if (anString.contains("<html>")) {
|
||||
anString = anString.replace("<html>", "");
|
||||
}
|
||||
if (anString.contains("</html>")) {
|
||||
anString = anString.replace("</html>", "");
|
||||
}
|
||||
str += anName + ": " + anString + "<br>";
|
||||
String annotString = getAnnotationsSummaryString();
|
||||
if (annotString != null) {
|
||||
str += annotString;
|
||||
}
|
||||
// int nAttotations = getNumDataAnnotations();
|
||||
// for (int i = 0; i < nAttotations; i++) {
|
||||
// DataAnnotation an = getDataAnnotation(i);
|
||||
// DataAnnotationType ant = an.getDataAnnotationType();
|
||||
// String anName = ant.getAnnotationName();
|
||||
// String anString = an.toString();
|
||||
// if (anString == null) {
|
||||
// continue;
|
||||
// }
|
||||
// if (anString.contains("<html>")) {
|
||||
// anString = anString.replace("<html>", "");
|
||||
// }
|
||||
// if (anString.contains("</html>")) {
|
||||
// anString = anString.replace("</html>", "");
|
||||
// }
|
||||
// str += anName + ": " + anString + "<br>";
|
||||
// }
|
||||
|
||||
|
||||
// add frequency and amplitude information
|
||||
@ -999,6 +1003,36 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string information for the annotations. Kept separate so
|
||||
* it can be called in overridden version of getSummaryString()
|
||||
* @return
|
||||
*/
|
||||
public String getAnnotationsSummaryString() {
|
||||
int nAnnotations = getNumDataAnnotations();
|
||||
if (nAnnotations == 0) {
|
||||
return null;
|
||||
}
|
||||
String str = "";
|
||||
for (int i = 0; i < nAnnotations; i++) {
|
||||
DataAnnotation an = getDataAnnotation(i);
|
||||
DataAnnotationType ant = an.getDataAnnotationType();
|
||||
String anName = ant.getAnnotationName();
|
||||
String anString = an.toString();
|
||||
if (anString == null) {
|
||||
continue;
|
||||
}
|
||||
if (anString.contains("<html>")) {
|
||||
anString = anString.replace("<html>", "");
|
||||
}
|
||||
if (anString.contains("</html>")) {
|
||||
anString = anString.replace("</html>", "");
|
||||
}
|
||||
str += anName + ": " + anString + "<br>";
|
||||
}
|
||||
return str.length() > 0 ? str : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some functions to do with data annotations
|
||||
*/
|
||||
@ -1258,6 +1292,32 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* find a super detection form the parent data block of the super detection.
|
||||
* @param superDataBlock data block of super detection
|
||||
* @param allowSuperSuper Allow iteration through mutilple super detection layers
|
||||
* @return data unit from that block, or null.
|
||||
*/
|
||||
public SuperDetection getSuperDetection(PamDataBlock superDataBlock, boolean allowSuperSuper) {
|
||||
synchronized (superDetectionSyncronisation) {
|
||||
if (superDetections == null) return null;
|
||||
SuperDetection superDet;
|
||||
for (int i = 0; i < superDetections.size(); i++) {
|
||||
superDet = superDetections.get(i);
|
||||
if (superDet.getParentDataBlock() == superDataBlock) {
|
||||
return superDet;
|
||||
}
|
||||
if (allowSuperSuper) {
|
||||
SuperDetection supersuper = superDet.getSuperDetection(superDataBlock, allowSuperSuper);
|
||||
if (supersuper != null) {
|
||||
return supersuper;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public SuperDetection getSuperDetection(int ind) {
|
||||
synchronized (superDetectionSyncronisation) {
|
||||
if (superDetections == null || superDetections.size()<=ind) return null;
|
||||
|
@ -99,35 +99,11 @@ public class RawDataTransforms {
|
||||
*/
|
||||
private int shortestFFTLength;
|
||||
|
||||
/**
|
||||
* Object for synchronization. Get thread lock if this isn't the same as
|
||||
* the object holding the data.
|
||||
*/
|
||||
private Object synchObject;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Raw Data Transforms for a RawDataHolder using the rawDataHolder as the synchronization
|
||||
* object.
|
||||
* @param rawDataHolder RawDataHolder object (e.g. a click)
|
||||
*/
|
||||
public RawDataTransforms(@SuppressWarnings("rawtypes") PamDataUnit rawDataHolder) {
|
||||
this(rawDataHolder, rawDataHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raw Data Transforms for a RawDataHolder.
|
||||
* @param rawDataHolder RawDataHolder object (e.g. a click)
|
||||
* @param synchObject synchronization object, which is most likely the RawDataHolder object.
|
||||
*/
|
||||
public RawDataTransforms(@SuppressWarnings("rawtypes") PamDataUnit rawDataHolder, Object synchObject) {
|
||||
this.rawData=(RawDataHolder) rawDataHolder;
|
||||
this.dataUnit = rawDataHolder;
|
||||
this.synchObject = synchObject;
|
||||
if (this.synchObject == null) {
|
||||
this.synchObject = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -167,25 +143,23 @@ public class RawDataTransforms {
|
||||
* @param fftLength
|
||||
* @return Power spectrum
|
||||
*/
|
||||
public double[] getPowerSpectrum(int channel, int minBin, int maxBin, int fftLength) {
|
||||
synchronized (synchObject) {
|
||||
if (minBin==0 && maxBin>=this.getWaveData(0).length-1) {
|
||||
return getPowerSpectrum(channel, fftLength);
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
|
||||
double[] waveformTrim = new double[maxBin-minBin];
|
||||
|
||||
// System.out.println("minBin: " + minBin + " maxBin: " + maxBin + " raw waveform: " + this.getWaveData(channel).length);
|
||||
|
||||
System.arraycopy(this.getWaveData(channel), minBin, waveformTrim, 0, Math.min(this.getWaveData(channel).length-minBin-1, waveformTrim.length));
|
||||
|
||||
ComplexArray cData = getComplexSpectrumHann(waveformTrim, fftLength);
|
||||
|
||||
return cData.magsq();
|
||||
public synchronized double[] getPowerSpectrum(int channel, int minBin, int maxBin, int fftLength) {
|
||||
if (minBin==0 && maxBin>=this.getWaveData(0).length-1) {
|
||||
return getPowerSpectrum(channel, fftLength);
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
|
||||
double[] waveformTrim = new double[maxBin-minBin];
|
||||
|
||||
//System.out.println("minBin: " + minBin + " maxBin: " + maxBin + " raw waveform: " + this.getWaveData(channel).length);
|
||||
|
||||
System.arraycopy(this.getWaveData(channel), minBin, waveformTrim, 0, Math.min(this.getWaveData(channel).length-minBin-1, waveformTrim.length));
|
||||
|
||||
ComplexArray cData = getComplexSpectrumHann(waveformTrim, fftLength);
|
||||
|
||||
return cData.magsq();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,31 +170,29 @@ public class RawDataTransforms {
|
||||
* @param fftLength
|
||||
* @return Power spectrum
|
||||
*/
|
||||
public double[] getPowerSpectrum(int channel, int fftLength) {
|
||||
synchronized (synchObject) {
|
||||
if (powerSpectra == null) {
|
||||
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
|
||||
if (powerSpectra[channel] == null
|
||||
|| powerSpectra[channel].length != fftLength / 2) {
|
||||
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
|
||||
currentSpecLen = fftLength;
|
||||
powerSpectra[channel] = cData.magsq();
|
||||
if (powerSpectra==null){
|
||||
System.err.println("DLDetection: could not calculate power spectra");
|
||||
return null;
|
||||
|
||||
}
|
||||
if (powerSpectra[channel].length != fftLength/2) {
|
||||
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
|
||||
}
|
||||
}
|
||||
return powerSpectra[channel];
|
||||
public synchronized double[] getPowerSpectrum(int channel, int fftLength) {
|
||||
if (powerSpectra == null) {
|
||||
powerSpectra = new double[PamUtils.getNumChannels(dataUnit.getChannelBitmap())][];
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
|
||||
if (powerSpectra[channel] == null
|
||||
|| powerSpectra[channel].length != fftLength / 2) {
|
||||
ComplexArray cData = getComplexSpectrumHann(channel, fftLength);
|
||||
currentSpecLen = fftLength;
|
||||
powerSpectra[channel] = cData.magsq();
|
||||
if (powerSpectra==null){
|
||||
System.err.println("DLDetection: could not calculate power spectra");
|
||||
return null;
|
||||
|
||||
}
|
||||
if (powerSpectra[channel].length != fftLength/2) {
|
||||
powerSpectra[channel] = Arrays.copyOf(powerSpectra[channel], fftLength/2);
|
||||
}
|
||||
}
|
||||
return powerSpectra[channel];
|
||||
}
|
||||
|
||||
|
||||
@ -230,27 +202,25 @@ public class RawDataTransforms {
|
||||
* @param fftLength
|
||||
* @return Sum of power spectra
|
||||
*/
|
||||
public double[] getTotalPowerSpectrum(int fftLength) {
|
||||
synchronized (synchObject) {
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = PamUtils.getMinFftLength(getSampleDuration());
|
||||
}
|
||||
double[] ps;
|
||||
if (totalPowerSpectrum == null
|
||||
|| totalPowerSpectrum.length != fftLength / 2) {
|
||||
totalPowerSpectrum = new double[fftLength / 2];
|
||||
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
|
||||
ps = getPowerSpectrum(c, fftLength);
|
||||
for (int i = 0; i < fftLength / 2; i++) {
|
||||
totalPowerSpectrum[i] += ps[i];
|
||||
}
|
||||
public synchronized double[] getTotalPowerSpectrum(int fftLength) {
|
||||
if (fftLength == 0) {
|
||||
fftLength = getCurrentSpectrumLength();
|
||||
}
|
||||
if (fftLength == 0) {
|
||||
fftLength = PamUtils.getMinFftLength(getSampleDuration());
|
||||
}
|
||||
double[] ps;
|
||||
if (totalPowerSpectrum == null
|
||||
|| totalPowerSpectrum.length != fftLength / 2) {
|
||||
totalPowerSpectrum = new double[fftLength / 2];
|
||||
for (int c = 0; c < PamUtils.getNumChannels(this.dataUnit.getChannelBitmap()); c++) {
|
||||
ps = getPowerSpectrum(c, fftLength);
|
||||
for (int i = 0; i < fftLength / 2; i++) {
|
||||
totalPowerSpectrum[i] += ps[i];
|
||||
}
|
||||
}
|
||||
return totalPowerSpectrum;
|
||||
}
|
||||
return totalPowerSpectrum;
|
||||
}
|
||||
|
||||
|
||||
@ -265,17 +235,15 @@ public class RawDataTransforms {
|
||||
* @param fftLength - the FFT length to use.
|
||||
* @return the complex spectrum - the comnplex spectrum of the wave data from the specified channel.
|
||||
*/
|
||||
public ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
|
||||
synchronized (synchObject) {
|
||||
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
|
||||
if (complexSpectrum[channel] == null
|
||||
|| complexSpectrum.length != fftLength / 2) {
|
||||
public synchronized ComplexArray getComplexSpectrumHann(int channel, int fftLength) {
|
||||
complexSpectrum = new ComplexArray[PamUtils.getNumChannels(dataUnit.getChannelBitmap())];
|
||||
if (complexSpectrum[channel] == null
|
||||
|| complexSpectrum.length != fftLength / 2) {
|
||||
|
||||
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
|
||||
currentSpecLen = fftLength;
|
||||
}
|
||||
return complexSpectrum[channel];
|
||||
complexSpectrum[channel] = getComplexSpectrumHann(rawData.getWaveData()[channel], fftLength);
|
||||
currentSpecLen = fftLength;
|
||||
}
|
||||
return complexSpectrum[channel];
|
||||
}
|
||||
|
||||
|
||||
@ -314,12 +282,10 @@ public class RawDataTransforms {
|
||||
* @return the spectrogram length.
|
||||
*/
|
||||
private int getCurrentSpectrumLength() {
|
||||
synchronized (synchObject) {
|
||||
if (currentSpecLen<=0) {
|
||||
currentSpecLen = PamUtils.getMinFftLength(dataUnit.getSampleDuration());
|
||||
}
|
||||
return currentSpecLen;
|
||||
if (currentSpecLen<=0) {
|
||||
currentSpecLen = PamUtils.getMinFftLength(dataUnit.getSampleDuration());
|
||||
}
|
||||
return currentSpecLen;
|
||||
}
|
||||
|
||||
|
||||
@ -405,31 +371,29 @@ public class RawDataTransforms {
|
||||
* @param fftLength
|
||||
* @return the complex spectrum
|
||||
*/
|
||||
public ComplexArray getComplexSpectrum(int channel, int fftLength) {
|
||||
synchronized (synchObject) {
|
||||
double[] paddedRawData;
|
||||
double[] rawData;
|
||||
int i, mn;
|
||||
public synchronized ComplexArray getComplexSpectrum(int channel, int fftLength) {
|
||||
double[] paddedRawData;
|
||||
double[] rawData;
|
||||
int i, mn;
|
||||
|
||||
if (complexSpectrum == null) {
|
||||
complexSpectrum = new ComplexArray[getNChan()];
|
||||
}
|
||||
if (complexSpectrum[channel] == null
|
||||
|| complexSpectrum.length != fftLength / 2) {
|
||||
paddedRawData = new double[fftLength];
|
||||
rawData = getWaveData(channel);
|
||||
//double[] rotData = getRotationCorrection(channel);
|
||||
mn = Math.min(fftLength, getSampleDuration().intValue());
|
||||
for (i = 0; i < mn; i++) {
|
||||
paddedRawData[i] = rawData[i];//-rotData[i];
|
||||
}
|
||||
for (i = mn; i < fftLength; i++) {
|
||||
paddedRawData[i] = 0;
|
||||
}
|
||||
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
|
||||
}
|
||||
return complexSpectrum[channel];
|
||||
if (complexSpectrum == null) {
|
||||
complexSpectrum = new ComplexArray[getNChan()];
|
||||
}
|
||||
if (complexSpectrum[channel] == null
|
||||
|| complexSpectrum.length != fftLength / 2) {
|
||||
paddedRawData = new double[fftLength];
|
||||
rawData = getWaveData(channel);
|
||||
//double[] rotData = getRotationCorrection(channel);
|
||||
mn = Math.min(fftLength, getSampleDuration().intValue());
|
||||
for (i = 0; i < mn; i++) {
|
||||
paddedRawData[i] = rawData[i];//-rotData[i];
|
||||
}
|
||||
for (i = mn; i < fftLength; i++) {
|
||||
paddedRawData[i] = 0;
|
||||
}
|
||||
complexSpectrum[channel] = fastFFT.rfft(paddedRawData, fftLength);
|
||||
}
|
||||
return complexSpectrum[channel];
|
||||
}
|
||||
|
||||
|
||||
@ -438,16 +402,14 @@ public class RawDataTransforms {
|
||||
* @param iChan channel index
|
||||
* @return analytic waveform
|
||||
*/
|
||||
public double[] getAnalyticWaveform(int iChan) {
|
||||
synchronized (synchObject) {
|
||||
if (analyticWaveform == null) {
|
||||
analyticWaveform = new double[getNChan()][];
|
||||
}
|
||||
// if (analyticWaveform[iChan] == null) {
|
||||
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
|
||||
// }
|
||||
return analyticWaveform[iChan];
|
||||
public synchronized double[] getAnalyticWaveform(int iChan) {
|
||||
if (analyticWaveform == null) {
|
||||
analyticWaveform = new double[getNChan()][];
|
||||
}
|
||||
// if (analyticWaveform[iChan] == null) {
|
||||
analyticWaveform[iChan] = hilbert.getHilbert(getWaveData(iChan));
|
||||
// }
|
||||
return analyticWaveform[iChan];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -459,14 +421,12 @@ public class RawDataTransforms {
|
||||
* @param fftFilterParams fft filter parameters.
|
||||
* @return analystic waveform.
|
||||
*/
|
||||
public double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
|
||||
synchronized (synchObject) {
|
||||
if (filtered == false || fftFilterParams == null) {
|
||||
return getAnalyticWaveform(iChan);
|
||||
}
|
||||
else {
|
||||
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
|
||||
}
|
||||
public synchronized double[] getAnalyticWaveform(int iChan, boolean filtered, FFTFilterParams fftFilterParams) {
|
||||
if (filtered == false || fftFilterParams == null) {
|
||||
return getAnalyticWaveform(iChan);
|
||||
}
|
||||
else {
|
||||
return getFilteredAnalyticWaveform(fftFilterParams, iChan);
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,8 +437,7 @@ public class RawDataTransforms {
|
||||
* @param iChan channel number
|
||||
* @return envelope of the filtered data.
|
||||
*/
|
||||
public double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
|
||||
synchronized (synchObject) {
|
||||
public synchronized double[] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams, int iChan) {
|
||||
if (analyticWaveform == null) {
|
||||
analyticWaveform = new double[getNChan()][];
|
||||
}
|
||||
@ -487,7 +446,6 @@ public class RawDataTransforms {
|
||||
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
||||
// }
|
||||
return analyticWaveform[iChan];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -497,21 +455,19 @@ public class RawDataTransforms {
|
||||
* @return analystic waveforms
|
||||
*/
|
||||
public double[][] getFilteredAnalyticWaveform(FFTFilterParams fftFilterParams) {
|
||||
synchronized (synchObject) { // new
|
||||
if (analyticWaveform == null) {
|
||||
analyticWaveform = new double[getNChan()][];
|
||||
}
|
||||
for (int iChan = 0; iChan < getNChan(); iChan++) {
|
||||
if (fftFilterParams != null) {
|
||||
analyticWaveform[iChan] = hilbert.
|
||||
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
||||
}
|
||||
else {
|
||||
analyticWaveform[iChan] = getAnalyticWaveform(iChan);
|
||||
}
|
||||
}
|
||||
return analyticWaveform;
|
||||
if (analyticWaveform == null) {
|
||||
analyticWaveform = new double[getNChan()][];
|
||||
}
|
||||
for (int iChan = 0; iChan < getNChan(); iChan++) {
|
||||
if (fftFilterParams != null) {
|
||||
analyticWaveform[iChan] = hilbert.
|
||||
getHilbert(getFilteredWaveData(fftFilterParams, iChan));
|
||||
}
|
||||
else {
|
||||
analyticWaveform[iChan] = getAnalyticWaveform(iChan);
|
||||
}
|
||||
}
|
||||
return analyticWaveform;
|
||||
}
|
||||
|
||||
|
||||
@ -522,7 +478,7 @@ public class RawDataTransforms {
|
||||
* @param channelIndex channel index
|
||||
* @return filtered waveform data
|
||||
*/
|
||||
public double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
|
||||
public synchronized double[] getFilteredWaveData(FFTFilterParams filterParams, int channelIndex) {
|
||||
filteredWaveData = getFilteredWaveData(filterParams);
|
||||
return filteredWaveData[channelIndex];
|
||||
}
|
||||
@ -533,14 +489,12 @@ public class RawDataTransforms {
|
||||
* @param filterParams filter parameters
|
||||
* @return array of filtered data
|
||||
*/
|
||||
public double[][] getFilteredWaveData(FFTFilterParams filterParams) {
|
||||
synchronized (synchObject) {
|
||||
public synchronized double[][] getFilteredWaveData(FFTFilterParams filterParams) {
|
||||
//System.out.println("Make filterred wave data!: " + (filterParams != oldFFTFilterParams));
|
||||
if (filteredWaveData == null || filterParams != oldFFTFilterParams) {
|
||||
filteredWaveData = makeFilteredWaveData(filterParams);
|
||||
}
|
||||
return filteredWaveData;
|
||||
}
|
||||
}
|
||||
|
||||
private double[][] makeFilteredWaveData(FFTFilterParams filterParams) {
|
||||
@ -579,15 +533,13 @@ public class RawDataTransforms {
|
||||
* @return FFT filter object.
|
||||
*/
|
||||
public FFTFilter getFFTFilter(FFTFilterParams fftFilterParams) {
|
||||
synchronized (synchObject) {
|
||||
if (fftFilter == null) {
|
||||
fftFilter = new FFTFilter(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||
}
|
||||
else {
|
||||
fftFilter.setParams(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||
}
|
||||
return fftFilter;
|
||||
if (fftFilter == null) {
|
||||
fftFilter = new FFTFilter(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||
}
|
||||
else {
|
||||
fftFilter.setParams(fftFilterParams, this.dataUnit.getParentDataBlock().getSampleRate());
|
||||
}
|
||||
return fftFilter;
|
||||
}
|
||||
|
||||
|
||||
@ -654,9 +606,7 @@ public class RawDataTransforms {
|
||||
* @return
|
||||
*/
|
||||
private int getNChan() {
|
||||
synchronized (synchObject) { // new
|
||||
return this.rawData.getWaveData().length;
|
||||
}
|
||||
return this.rawData.getWaveData().length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -689,11 +639,9 @@ public class RawDataTransforms {
|
||||
* Free eup some memory by deleting the filtered wave data, power spectra and analytic waveform.
|
||||
*/
|
||||
public void freeMemory() {
|
||||
synchronized (synchObject) {
|
||||
filteredWaveData = null;
|
||||
powerSpectra = null;
|
||||
analyticWaveform = null;
|
||||
}
|
||||
filteredWaveData = null;
|
||||
powerSpectra = null;
|
||||
analyticWaveform = null;
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class DataSelectorSettings implements Serializable, ManagedParameters {
|
||||
* @return Params or null if they don't exist.
|
||||
*/
|
||||
public DataSelectParams getParams(String name) {
|
||||
if (selectorParams == null) {
|
||||
if (selectorParams == null || name == null) {
|
||||
return null;
|
||||
}
|
||||
return selectorParams.get(name);
|
||||
|
@ -471,6 +471,7 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
|
||||
PamDataUnit subDet = subDetectionFinder.findDataUnit(sdInfo);
|
||||
sdInfo.setSubDetection(subDet);
|
||||
if (subDet != null) {
|
||||
aData.addSubDetection(subDet);
|
||||
subDet.addSuperDetection(aData);
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,8 @@
|
||||
-fx-font-color: -fx-text;
|
||||
-fx-font-family: "Ubuntu";
|
||||
|
||||
-fx-border-radius: 5 5 5 5;
|
||||
-fx-background-radius: 5 5 5 5;
|
||||
-fx-border-radius: 5 5 5 5;
|
||||
-fx-background-radius: 5 5 5 5;
|
||||
|
||||
-icons-color: -fx-icon_col;
|
||||
}
|
||||
@ -615,7 +615,7 @@
|
||||
-fx-background: -fx-darkbackground;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
-fx-padding: 7 0 7 0;
|
||||
-fx-padding: 5 0 5 0;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
@ -623,9 +623,9 @@
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-background-radius: 6 6 0 0;
|
||||
-fx-border-radius: 6 6 0 0;
|
||||
-fx-padding: 7 0 7 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-padding: 5 0 5 0;
|
||||
}
|
||||
|
||||
.spinner .increment-arrow {
|
||||
@ -635,16 +635,16 @@
|
||||
.spinner .increment-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 6 6 0 0;
|
||||
-fx-border-radius: 6 6 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
}
|
||||
|
||||
.spinner .decrement-arrow-button {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-background-radius: 0 0 6 6;
|
||||
-fx-border-radius: 0 0 6 6
|
||||
-fx-background-radius: 0 0 5 5;
|
||||
-fx-border-radius: 0 0 5 5
|
||||
}
|
||||
|
||||
.spinner .decrement-arrow {
|
||||
@ -654,8 +654,8 @@
|
||||
.spinner .decrement-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 0 0 6 6;
|
||||
-fx-border-radius: 0 0 6 6;
|
||||
-fx-background-radius: 0 0 5 5;
|
||||
-fx-border-radius: 0 0 5 5;
|
||||
}
|
||||
|
||||
/*Arrows are horizontal either side of text box*/
|
||||
@ -663,7 +663,7 @@
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 0 6 6 0
|
||||
-fx-border-radius: 0 5 5 0
|
||||
}
|
||||
|
||||
|
||||
@ -671,22 +671,22 @@
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 6 0 0 6
|
||||
-fx-border-radius: 5 0 0 5
|
||||
}
|
||||
|
||||
.spinner.split-arrows-horizontal .increment-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 0 6 6 0;
|
||||
-fx-border-radius: 0 6 6 0;
|
||||
-fx-background-radius: 0 5 5 0;
|
||||
-fx-border-radius: 0 5 5 0;
|
||||
}
|
||||
|
||||
|
||||
.spinner.split-arrows-horizontal .decrement-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 6 0 0 6;
|
||||
-fx-border-radius: 6 0 0 6;
|
||||
-fx-background-radius: 5 0 0 5;
|
||||
-fx-border-radius: 5 0 0 5;
|
||||
}
|
||||
|
||||
.spinner.split-arrows-horizontal .text-field {
|
||||
|
@ -146,6 +146,17 @@ public abstract class AnnotationChoiceHandler extends AnnotationHandler {
|
||||
* @param annotationType
|
||||
*/
|
||||
public boolean updateAnnotation(PamDataUnit pamDataUnit, DataAnnotationType annotationType) {
|
||||
/*
|
||||
* need to check this is actually the right data unit, which matches the datablock of
|
||||
* this annotatoin handler. Gets very confused when dealing with superdetections
|
||||
*/
|
||||
if (pamDataUnit.getParentDataBlock() != this.getPamDataBlock()) {
|
||||
pamDataUnit = pamDataUnit.getSuperDetection(getPamDataBlock(), true);
|
||||
if (pamDataUnit == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DataAnnotation existingAnnotation = pamDataUnit.findDataAnnotation(annotationType.getAnnotationClass(), annotationType.getAnnotationName());
|
||||
boolean changed = false;
|
||||
if (annotationType.canAutoAnnotate()) {
|
||||
|
@ -10,6 +10,7 @@ import java.awt.event.WindowEvent;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import annotation.AnnotationDialogPanel;
|
||||
import PamView.DBTextArea;
|
||||
import PamView.dialog.PamDialogPanel;
|
||||
@ -51,13 +52,21 @@ public class StringDialogPanel implements AnnotationDialogPanel {
|
||||
note = note.trim();
|
||||
}
|
||||
if (note != null && note.length() > 0) {
|
||||
StringAnnotation an = (StringAnnotation) pamDataUnit.findDataAnnotation(StringAnnotation.class,
|
||||
stringAnnotationType.getAnnotationName());
|
||||
if (an == null) {
|
||||
StringAnnotation an;
|
||||
/*
|
||||
* always add a new annotation rather than editing the old one since
|
||||
* the old one will get removed to handle annotation types which really
|
||||
* do need to make a new one each time.
|
||||
*/
|
||||
|
||||
// = (StringAnnotation) pamDataUnit.findDataAnnotation(StringAnnotation.class,
|
||||
// stringAnnotationType.getAnnotationName());
|
||||
// if (an == null) {
|
||||
an = new StringAnnotation(stringAnnotationType);
|
||||
pamDataUnit.addDataAnnotation(an);
|
||||
}
|
||||
// }
|
||||
an.setString(textArea.getText());
|
||||
pamDataUnit.setLastUpdateTime(PamCalendar.getTimeInMillis());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1572,6 +1572,9 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
|
||||
}
|
||||
private double clickAngleToY(ClickDetection click) {
|
||||
AbstractLocalisation loc = click.getLocalisation();
|
||||
// if (click.getUID() == 110006089) {
|
||||
// System.out.println("Click 110006089 angle " + click.getAngle());
|
||||
// }
|
||||
if (loc == null) return 0;
|
||||
double angle = 0;
|
||||
GpsData oll;
|
||||
|
@ -210,8 +210,8 @@ public class ClickBinaryDataSource extends BinaryDataSource {
|
||||
// long uid = binaryObjectData.getDataUnitBaseData().getUID();
|
||||
// System.out.printf("Loading click with UID %d at %s\n", uid,
|
||||
// PamCalendar.formatDateTime(binaryObjectData.getTimeMilliseconds()));
|
||||
// if (uid == lastUID) {
|
||||
// System.out.println("Click repeat UID: " + lastUID);
|
||||
// if (uid == 110006089) {
|
||||
// System.out.println("Click UID: " + 110006089);
|
||||
// }
|
||||
// else {
|
||||
// lastUID = binaryObjectData.getDataUnitBaseData().getUID();
|
||||
|
@ -1328,6 +1328,8 @@ public class ClickDetection extends PamDataUnit<PamDataUnit, PamDataUnit> implem
|
||||
|
||||
/**
|
||||
* Returns the angle in degrees for compatibilty with older version of click detector
|
||||
* This is really bad to use for anything apart from two element arrays and it would be
|
||||
* sensible to remove the function entirely.
|
||||
* @return angle of the click detection in degrees
|
||||
*/
|
||||
public double getAngle() {
|
||||
|
@ -217,7 +217,8 @@ public class ClickSelectPaneFX extends DynamicSettingsPane<Boolean> {
|
||||
void setParams() {
|
||||
ClickAlarmParameters clickAlarmParameters = clickDataSelector.getClickAlarmParameters();
|
||||
speciesSelect.getChildren().clear();
|
||||
|
||||
|
||||
|
||||
//species pane setup
|
||||
species = null;
|
||||
weights = null;
|
||||
@ -350,6 +351,7 @@ public class ClickSelectPaneFX extends DynamicSettingsPane<Boolean> {
|
||||
}
|
||||
|
||||
boolean getParams() {
|
||||
|
||||
|
||||
ClickAlarmParameters clickAlarmParameters = clickDataSelector.getClickAlarmParameters().clone();
|
||||
clickAlarmParameters.useEchoes = useEchoes.isSelected();
|
||||
@ -397,6 +399,7 @@ public class ClickSelectPaneFX extends DynamicSettingsPane<Boolean> {
|
||||
|
||||
// btDisplayParameters.showANDEvents = andEvents.isSelected();
|
||||
// btDisplayParameters.showEventsOnly = onlyEvents.isSelected();
|
||||
|
||||
clickDataSelector.setClickAlarmParameters(clickAlarmParameters);
|
||||
return true;
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package clickTrainDetector.classification;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import PamguardMVC.debug.Debug;
|
||||
import clickTrainDetector.CTDataUnit;
|
||||
import clickTrainDetector.ClickTrainControl;
|
||||
import clickTrainDetector.classification.bearingClassifier.BearingClassification;
|
||||
@ -158,10 +157,10 @@ public class CTClassifierManager {
|
||||
//first check the pre-classifier
|
||||
Chi2CTClassification classification = this.preClassifier.classifyClickTrain(ctDataUnit);
|
||||
|
||||
System.out.println("Pre classifier: " + PamCalendar.formatDateTime(ctDataUnit.getTimeMilliseconds()) + " N. " + ctDataUnit.getSubDetectionsCount() + "UID first: " + ctDataUnit.getSubDetection(0).getUID() );
|
||||
//System.out.println("Pre classifier: " + PamCalendar.formatDateTime(ctDataUnit.getTimeMilliseconds()) + " N. " + ctDataUnit.getSubDetectionsCount() + "UID first: " + ctDataUnit.getSubDetection(0).getUID() );
|
||||
|
||||
if (classification.getSpeciesID()==CTClassifier.NOSPECIES) {
|
||||
System.out.println("No SPECIES: chi^2" + ctDataUnit.getCTChi2());
|
||||
//System.out.println("No SPECIES: chi^2" + ctDataUnit.getCTChi2());
|
||||
ctDataUnit.setJunkTrain(true);
|
||||
//no need to do any more classification- the click train has been flagged for deletion.
|
||||
ctDataUnit.clearClassifiers();
|
||||
@ -189,17 +188,17 @@ public class CTClassifierManager {
|
||||
ctDataUnit.clearClassifiers();
|
||||
ctDataUnit.setClassificationIndex(-1);
|
||||
|
||||
System.out.println("Classify species: Num classifier " + this.cTClassifiers.size());
|
||||
//System.out.println("Classify species: Num classifier " + this.cTClassifiers.size());
|
||||
|
||||
for (int i=0; i<this.cTClassifiers.size(); i++) {
|
||||
|
||||
|
||||
System.out.println("Classifier: " + i);
|
||||
//System.out.println("Classifier: " + i);
|
||||
|
||||
//the first classifier
|
||||
ctclassification = this.cTClassifiers.get(i).classifyClickTrain(ctDataUnit);
|
||||
|
||||
System.out.println("Classifier complete: SPECIES: " + ctclassification.getSpeciesID());
|
||||
//System.out.println("Classifier complete: SPECIES: " + ctclassification.getSpeciesID());
|
||||
|
||||
|
||||
// Debug.out.println(i + " ClassifierManager: Classify a click train data unit: " + ctDataUnit + " parent data block: " +
|
||||
@ -208,7 +207,7 @@ public class CTClassifierManager {
|
||||
|
||||
//set the species flag but only if this is the first time the ct data unit has been classified.
|
||||
if (ctclassification.getSpeciesID()>CTClassifier.NOSPECIES && !hasBeenClssfd) {
|
||||
System.out.println("Set classiifcation index: " + i);
|
||||
//System.out.println("Set classiifcation index: " + i);
|
||||
ctDataUnit.setClassificationIndex(i); //set the classification index.
|
||||
hasBeenClssfd = true;
|
||||
}
|
||||
@ -238,12 +237,26 @@ public class CTClassifierManager {
|
||||
System.err.println("CTCLassifier manager: the classifier is null");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctParams[i].uniqueID ==null) {
|
||||
//old versions may not have a unique ID so needs to be added.
|
||||
ctParams[i].uniqueID = UUID.randomUUID().toString();
|
||||
}
|
||||
aClassifier.setParams(ctParams[i]);
|
||||
cTClassifiers.add(aClassifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pre-classifer. This is an intial very broad classifier that is used to determine
|
||||
* whether a click train should be saved or dumped from memory.
|
||||
* @return the pre-classifier.
|
||||
*/
|
||||
public Chi2ThresholdClassifier getPreClassifier() {
|
||||
return preClassifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package clickTrainDetector.classification;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
import PamModel.parametermanager.ManagedParameters;
|
||||
import PamModel.parametermanager.PamParameterSet;
|
||||
@ -20,12 +21,23 @@ public class CTClassifierParams implements Cloneable, Serializable, ManagedParam
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
public CTClassifierParams() {
|
||||
this.uniqueID = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A very simple species flag to indicate what classifier was used. 0 means not classified.
|
||||
* The name of the classifier.
|
||||
*/
|
||||
public String classifierName = "";
|
||||
|
||||
|
||||
/**
|
||||
* A unique ID for the classifier that never changes. This is important for accessing data selectors.
|
||||
*/
|
||||
public String uniqueID;
|
||||
|
||||
|
||||
/**
|
||||
* A very simple species flag to indicate what classifier was used. 0 means not classified.
|
||||
*/
|
||||
|
@ -15,6 +15,7 @@ public class BearingClassifierParams extends CTClassifierParams implements Manag
|
||||
|
||||
|
||||
public BearingClassifierParams(){
|
||||
super();
|
||||
type = CTClassifierType.BEARINGCLASSIFIER;
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,15 @@ import java.io.Serializable;
|
||||
|
||||
import PamModel.parametermanager.ManagedParameters;
|
||||
import clickTrainDetector.classification.CTClassifierParams;
|
||||
import clickTrainDetector.classification.CTClassifierType;
|
||||
|
||||
public class IDIClassifierParams extends CTClassifierParams implements Serializable, Cloneable, ManagedParameters {
|
||||
|
||||
public IDIClassifierParams(){
|
||||
super();
|
||||
type = CTClassifierType.IDICLASSIFIER;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -1,5 +1,7 @@
|
||||
package clickTrainDetector.classification.simplechi2classifier;
|
||||
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.dataSelector.DataSelector;
|
||||
import clickTrainDetector.classification.CTClassification;
|
||||
import clickTrainDetector.classification.CTClassifierType;
|
||||
import clickTrainDetector.classification.ClassifierJSONLogging;
|
||||
@ -22,15 +24,14 @@ public class Chi2CTClassification implements CTClassification {
|
||||
private int speciesCode = -1;
|
||||
|
||||
|
||||
private SimpleClassifierJSONLogging simpleClassifierJSONLogging;
|
||||
private SimpleClassifierJSONLogging simpleClassifierJSONLogging;
|
||||
|
||||
|
||||
|
||||
public Chi2CTClassification(int speciesCode) {
|
||||
this.speciesCode = speciesCode;
|
||||
simpleClassifierJSONLogging=new SimpleClassifierJSONLogging();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the classification from a JSON string
|
||||
@ -62,5 +63,7 @@ public class Chi2CTClassification implements CTClassification {
|
||||
public ClassifierJSONLogging getJSONLogging() {
|
||||
return simpleClassifierJSONLogging;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package clickTrainDetector.classification.simplechi2classifier;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.dataSelector.DataSelector;
|
||||
import PamguardMVC.debug.Debug;
|
||||
import clickTrainDetector.CTDataUnit;
|
||||
import clickTrainDetector.ClickTrainControl;
|
||||
@ -32,10 +34,17 @@ public class Chi2ThresholdClassifier implements CTClassifier {
|
||||
*/
|
||||
private ClickTrainControl clickTrainControl;
|
||||
|
||||
|
||||
/**
|
||||
* Data selector for the chi2 threshold classifier.
|
||||
*/
|
||||
private DataSelector dataSelector;
|
||||
|
||||
|
||||
public Chi2ThresholdClassifier(ClickTrainControl clickTrainControl, int defaultSpeciesID) {
|
||||
this.clickTrainControl=clickTrainControl;
|
||||
clssfrParams.speciesFlag=defaultSpeciesID;
|
||||
createDataSelector(clickTrainControl.getParentDataBlock());
|
||||
}
|
||||
|
||||
|
||||
@ -65,8 +74,62 @@ public class Chi2ThresholdClassifier implements CTClassifier {
|
||||
return new Chi2CTClassification(CTClassifier.NOSPECIES); //no classification
|
||||
}
|
||||
|
||||
if (!isPercClicks(clickTrain)) {
|
||||
// Debug.out.println("Failed on chi2Threshold");
|
||||
return new Chi2CTClassification(CTClassifier.NOSPECIES); //no classification
|
||||
}
|
||||
|
||||
|
||||
return new Chi2CTClassification(clssfrParams.speciesFlag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the percentage of clicks which are correctly classified by the data selector.
|
||||
* @param clickTrain - the click train
|
||||
* @return true if the percentage critera is passed
|
||||
*
|
||||
*/
|
||||
private boolean isPercClicks(CTDataUnit clickTrain) {
|
||||
|
||||
//no point iterating through click if we do not need to.
|
||||
if (clssfrParams.minPercentage==0) return true;
|
||||
|
||||
double count = 0;
|
||||
for (int i=0; i<clickTrain.getSubDetectionsCount(); i++) {
|
||||
if (this.getDataSelector().scoreData(clickTrain.getSubDetection(i))>0) {
|
||||
count = count+1.;
|
||||
}
|
||||
}
|
||||
if (count/clickTrain.getSubDetectionsCount()>=clssfrParams.minPercentage) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the data selector.
|
||||
* @param source - the source data block
|
||||
* @return the data selector.
|
||||
*/
|
||||
public void createDataSelector(PamDataBlock<?> source) {
|
||||
if (dataSelector==null || dataSelector.getPamDataBlock()!=source) {
|
||||
//create the data selector
|
||||
//System.out.println("Data selector: " + dataSelector);
|
||||
if (source!=null) {
|
||||
dataSelector=source.getDataSelectCreator().getDataSelector(clickTrainControl.getUnitName() + " " + clssfrParams.uniqueID
|
||||
+ "_X2_threshold_classifier", false, null);
|
||||
//System.out.println("Data selector: " + dataSelector);
|
||||
}
|
||||
else {
|
||||
dataSelector=null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@ -122,7 +185,6 @@ public class Chi2ThresholdClassifier implements CTClassifier {
|
||||
public void setParams(Chi2ThresholdParams clssfrParams) {
|
||||
//System.out.println("HELLO CLASSIFIER PARAMS: " + clssfrParams.chi2Threahold );
|
||||
this.clssfrParams=clssfrParams;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,4 +207,10 @@ public class Chi2ThresholdClassifier implements CTClassifier {
|
||||
}
|
||||
|
||||
|
||||
public DataSelector getDataSelector() {
|
||||
createDataSelector(clickTrainControl.getParentDataBlock());
|
||||
return dataSelector;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package clickTrainDetector.classification.simplechi2classifier;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
import PamModel.parametermanager.ManagedParameters;
|
||||
import PamModel.parametermanager.PamParameterSet;
|
||||
import clickTrainDetector.classification.CTClassifierParams;
|
||||
@ -12,9 +15,10 @@ import clickTrainDetector.classification.CTClassifierType;
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class Chi2ThresholdParams extends CTClassifierParams implements ManagedParameters {
|
||||
public class Chi2ThresholdParams extends CTClassifierParams implements ManagedParameters, Serializable, Cloneable {
|
||||
|
||||
public Chi2ThresholdParams(){
|
||||
super();
|
||||
super.type=CTClassifierType.CHI2THRESHOLD;
|
||||
}
|
||||
|
||||
@ -25,7 +29,7 @@ public class Chi2ThresholdParams extends CTClassifierParams implements ManagedPa
|
||||
|
||||
/**
|
||||
* The chi2 threshold to set. This is the chi2 value divided by the number of clicks in the train.
|
||||
* If zero then the classification always passes...A bit fo a hack for testing
|
||||
* If zero then the classification always passes...A bit of a hack for testing
|
||||
*/
|
||||
public double chi2Threshold = 1500.;
|
||||
|
||||
@ -33,7 +37,13 @@ public class Chi2ThresholdParams extends CTClassifierParams implements ManagedPa
|
||||
* The minimum number of clicks.
|
||||
*/
|
||||
public int minClicks = 5;
|
||||
|
||||
|
||||
/**
|
||||
* The minimum %percentage which must the parent data selector of clicks/
|
||||
*. values are 0-1.
|
||||
*/
|
||||
public double minPercentage = 0;
|
||||
|
||||
/**
|
||||
* The minimum time in seconds.
|
||||
*/
|
||||
|
@ -130,7 +130,7 @@ public class StandardClassifier implements CTClassifier {
|
||||
|
||||
int speciesID = standardClssfrParams.speciesFlag;
|
||||
|
||||
System.out.println("Standard Classificiation: " );
|
||||
//System.out.println("Standard Classificiation: " );
|
||||
|
||||
//all classifiers have to pass.
|
||||
CTClassification[] ctClassification = new CTClassification[classifiers.size()];
|
||||
@ -138,8 +138,8 @@ public class StandardClassifier implements CTClassifier {
|
||||
|
||||
ctClassification[i] = classifiers.get(i).classifyClickTrain(clickTrain);
|
||||
|
||||
System.out.println("Standard Classificiation: " + i + " speciesID: " + ctClassification[i].getSpeciesID()
|
||||
+ " sub species: "+ classifiers.get(i).getParams().speciesFlag + " standard species: " +speciesID + " use? : " + standardClssfrParams.enable[i]);
|
||||
// System.out.println("Standard Classificiation: " + i + " speciesID: " + ctClassification[i].getSpeciesID()
|
||||
// + " sub species: "+ classifiers.get(i).getParams().speciesFlag + " standard species: " +speciesID + " use? : " + standardClssfrParams.enable[i]);
|
||||
|
||||
if (standardClssfrParams.enable[i]) {
|
||||
if (ctClassification[i].getSpeciesID() != SUB_CLASSIFIER_SPECIESID){
|
||||
@ -148,7 +148,7 @@ public class StandardClassifier implements CTClassifier {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("SPECIES ID: " + speciesID);
|
||||
//System.out.println("SPECIES ID: " + speciesID);
|
||||
|
||||
//create the classification.
|
||||
StandardClassification classification = new StandardClassification(ctClassification, speciesID);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package clickTrainDetector.classification.standardClassifier;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import clickTrainDetector.classification.CTClassifierParams;
|
||||
import clickTrainDetector.classification.CTClassifierType;
|
||||
|
||||
@ -27,6 +29,7 @@ public class StandardClassifierParams extends CTClassifierParams {
|
||||
|
||||
|
||||
public StandardClassifierParams(){
|
||||
super();
|
||||
///very important to set this or else the clasifier manager does not
|
||||
//know which classifier to create.
|
||||
type = CTClassifierType.STANDARDCLASSIFIER;
|
||||
|
@ -22,6 +22,7 @@ public class TemplateClassifierParams extends CTClassifierParams implements Mana
|
||||
private static final long serialVersionUID = 10L;
|
||||
|
||||
public TemplateClassifierParams(){
|
||||
super();
|
||||
super.type=CTClassifierType.TEMPLATECLASSIFIER;
|
||||
// chi2ThresholdParams = new Chi2ThresholdParams();
|
||||
// template = DefualtSpectrumTemplates.getTemplate(SpectrumTemplateType.BEAKED_WHALE);
|
||||
|
@ -39,7 +39,10 @@ public class AmplitudeChi2 extends SimpleChi2VarDelta {
|
||||
@Override
|
||||
public double getDiffValue(PamDataUnit pamDataUnit0, PamDataUnit pamDataUnit1) {
|
||||
//System.out.println("DB: " + pamDataUnit0.getAmplitudeDB());
|
||||
return pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB();
|
||||
//made this abs so it can deal with increasing then decreasing click trains. i.e.
|
||||
//the click trian is not penalised if it gradually increasing then starts to gradually decrease
|
||||
//in amplitude.
|
||||
return Math.abs(pamDataUnit0.getAmplitudeDB()-pamDataUnit1.getAmplitudeDB());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,12 @@
|
||||
package clickTrainDetector.dataselector;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import PamDetection.LocContents;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.dataSelector.DataSelectParams;
|
||||
import PamguardMVC.dataSelector.DataSelector;
|
||||
import clickTrainDetector.CTDataUnit;
|
||||
import clickTrainDetector.CTDetectionGroupDataUnit;
|
||||
import clickTrainDetector.ClickTrainControl;
|
||||
import clickTrainDetector.ClickTrainDataBlock;
|
||||
@ -43,6 +46,8 @@ public class CTDataSelector extends DataSelector {
|
||||
|
||||
private boolean allowScores;
|
||||
|
||||
private boolean[] useSpeciesList;
|
||||
|
||||
public CTDataSelector(ClickTrainControl clickTrainControl, ClickTrainDataBlock clickTrainDataBlock,
|
||||
String selectorName, boolean allowScores) {
|
||||
super(clickTrainDataBlock, selectorName, allowScores);
|
||||
@ -83,6 +88,7 @@ public class CTDataSelector extends DataSelector {
|
||||
|
||||
@Override
|
||||
public DataSelectParams getParams() {
|
||||
getDialogPanel().getParams(ctSelectParams);
|
||||
return ctSelectParams;
|
||||
}
|
||||
|
||||
@ -99,6 +105,8 @@ public class CTDataSelector extends DataSelector {
|
||||
CTDetectionGroupDataUnit ctDataUnit = (CTDetectionGroupDataUnit) pamDataUnit;
|
||||
|
||||
if (ctDataUnit.getSubDetectionsCount()<ctSelectParams.minSubDetections) return 0;
|
||||
|
||||
if (!isClassified(ctDataUnit)) return 0;
|
||||
|
||||
if (ctSelectParams.needsLoc && pamDataUnit.getLocalisation()==null) return 0;
|
||||
|
||||
@ -108,4 +116,31 @@ public class CTDataSelector extends DataSelector {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a click train passes the data selector classification criteria.
|
||||
* @param ctDataUnit - the click train data unit to test.
|
||||
* @return true of the click train passes detection criterea.
|
||||
*/
|
||||
private boolean isClassified(CTDetectionGroupDataUnit ctDataUnit) {
|
||||
|
||||
if (!ctSelectParams.needsClassification) return true;
|
||||
|
||||
if (ctDataUnit instanceof CTDataUnit) {
|
||||
|
||||
CTDataUnit clickTrain = (CTDataUnit) ctDataUnit;
|
||||
|
||||
if (clickTrain.ctClassifications==null) return false;
|
||||
|
||||
//iterate through all the classifiers and allowed classification types.
|
||||
for (int i=0; i<ctSelectParams.classifier.length; i++) {
|
||||
for (int j=0; j<clickTrain.ctClassifications.size(); j++) {
|
||||
if (clickTrain.ctClassifications.get(j).getSpeciesID()==ctSelectParams.classifier[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,6 +33,16 @@ public class CTSelectParams extends DataSelectParams implements Serializable, Cl
|
||||
* The minimum number of sub detections before a click train is plotted.
|
||||
*/
|
||||
public int minSubDetections = 10;
|
||||
|
||||
/**
|
||||
* True of the click train detector needs a classifcation
|
||||
*/
|
||||
public boolean needsClassification = false;
|
||||
|
||||
/**
|
||||
* The classifier type(s) to select
|
||||
*/
|
||||
public int[] classifier = null;
|
||||
|
||||
|
||||
/**
|
||||
@ -56,6 +66,8 @@ public class CTSelectParams extends DataSelectParams implements Serializable, Cl
|
||||
*/
|
||||
public double maxAngleChange = Math.toRadians(5);
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ClickTrainSelectParameters clone() {
|
||||
try {
|
||||
|
@ -73,7 +73,7 @@ public class CTSwingGUI extends PamControlledGUISwing {
|
||||
settingsDialog = new PamDialogFX2AWT<ClickTrainParams>(parentFrame, setPane, false);
|
||||
}
|
||||
|
||||
if (classificationTab!=null) settingsPane.setTab(classificationTab ? 2 : 0); //set the tab to the classification tab
|
||||
if (classificationTab!=null && classificationTab) settingsPane.setTab(2); //set the tab to the classification tab
|
||||
|
||||
ClickTrainParams newParams = settingsDialog.showDialog(this.clickTrainControl.getClickTrainParams());
|
||||
|
||||
|
@ -324,7 +324,13 @@ public class ClickTrainAlgorithmPaneFX extends SettingsPane<ClickTrainParams> {
|
||||
|
||||
popOver.showingProperty().addListener((obs, old, newval)->{
|
||||
if (newval) {
|
||||
clickTrainControl.getDataSelector().getDialogPaneFX().setParams(true);
|
||||
//the dialog has opened
|
||||
clickTrainControl.getDataSelector().getDialogPaneFX().setParams(true);
|
||||
}
|
||||
else {
|
||||
//the dialog has closed
|
||||
clickTrainControl.getDataSelector().getDialogPaneFX().getParams(true);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class PreClassifierPane extends PamBorderPane {
|
||||
|
||||
|
||||
private Pane createClassifierPane() {
|
||||
simpleCTClassifierPane = new SimpleCTClassifierPane(null);
|
||||
simpleCTClassifierPane = new SimpleCTClassifierPane(clickTrainControl.getClassifierManager().getPreClassifier());
|
||||
return (Pane) simpleCTClassifierPane.getContentNode();
|
||||
}
|
||||
|
||||
|
@ -35,14 +35,15 @@ public class SimpleCTClassifierGraphics implements CTClassifierGraphics {
|
||||
if (simpleCTClassiferPane==null) {
|
||||
simpleCTClassiferPane = new SimpleCTClassifierPane(simpleChi2Classifier);
|
||||
}
|
||||
//params are set here.
|
||||
simpleCTClassiferPane.setParams(simpleChi2Classifier.getParams());
|
||||
//System.out.println("SimpleCTClassifierGraphics getCTClassifierPane: " + simpleChi2Classifier.getParams().chi2Threshold);
|
||||
//params are set here. <- do not do this because you may wish to store the classifier params somewhere else.
|
||||
//simpleCTClassiferPane.setParams(simpleChi2Classifier.getParams());
|
||||
return (Pane) simpleCTClassiferPane.getContentNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CTClassifierParams getParams() {
|
||||
Chi2ThresholdParams clssfrParams = simpleCTClassiferPane.getParams(simpleChi2Classifier.getParams());
|
||||
Chi2ThresholdParams clssfrParams = simpleCTClassiferPane.getParams(simpleChi2Classifier.getParams()).clone();
|
||||
if (clssfrParams==null) {
|
||||
System.err.print("Simple Chi2 Classifier returned null params");
|
||||
return null;
|
||||
@ -51,13 +52,14 @@ public class SimpleCTClassifierGraphics implements CTClassifierGraphics {
|
||||
// simpleChi2Classifier.setParams(clssfrParams);
|
||||
// return clssfrParams;
|
||||
// }
|
||||
//System.out.println("SimpleCTClassifierGraphics - getParams: " + clssfrParams.chi2Threshold);
|
||||
return clssfrParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(CTClassifierParams params) {
|
||||
simpleCTClassiferPane.setParams((Chi2ThresholdParams) params);
|
||||
|
||||
//System.out.println("SimpleCTClassifierGraphics - setParams: " + ((Chi2ThresholdParams) params).chi2Threshold);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,18 +1,32 @@
|
||||
package clickTrainDetector.layout.classification.simplechi2classifier;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import org.controlsfx.control.PopOver;
|
||||
|
||||
import PamController.SettingsPane;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import clickTrainDetector.classification.simplechi2classifier.Chi2ThresholdClassifier;
|
||||
import clickTrainDetector.classification.simplechi2classifier.Chi2ThresholdParams;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Control;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.control.SpinnerValueFactory;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.util.StringConverter;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamSpinner;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
import pamViewFX.fxNodes.utilsFX.ControlField;
|
||||
|
||||
/**
|
||||
@ -51,6 +65,17 @@ public class SimpleCTClassifierPane extends SettingsPane<Chi2ThresholdParams> {
|
||||
*/
|
||||
private ControlField<Double> minTime;
|
||||
|
||||
private PamToggleSwitch dataSelectorCheckBox;
|
||||
|
||||
private PamButton dataSelectorButton;
|
||||
|
||||
private PopOver popOver;
|
||||
|
||||
/**
|
||||
* The minimum percentage of clicks for a certain class.
|
||||
*/
|
||||
private ControlField<Double> minPercClicks;
|
||||
|
||||
public SimpleCTClassifierPane(Chi2ThresholdClassifier simpleChi2Classifier) {
|
||||
super(null);
|
||||
this.simpleChi2Classifier=simpleChi2Classifier;
|
||||
@ -96,17 +121,35 @@ public class SimpleCTClassifierPane extends SettingsPane<Chi2ThresholdParams> {
|
||||
chi2Threshold.getSpinner().getValueFactory().setConverter(PamSpinner.createStringConverter(0));
|
||||
chi2Threshold.setTooltip(new Tooltip(
|
||||
"A click train has a X\u00b2 value which is based on the consistancy of inter detection interval \n"
|
||||
+ "amplitude and other factors. The calculation of X\\\\u00b2 changes depending on the click train \n"
|
||||
+ "amplitude and other factors. The calculation of X\u00b2 changes depending on the click train \n"
|
||||
+ "detector is used."));
|
||||
chi2Threshold.getLabel1().setPrefWidth(LABEL_WIDTH);
|
||||
|
||||
minClicks = new ControlField<Double>("Min. Clicks ", "", 0, Integer.MAX_VALUE, 5);
|
||||
minClicks = new ControlField<Double>("Min. clicks ", "", 0, Integer.MAX_VALUE, 5);
|
||||
minClicks.setTooltip(new Tooltip(
|
||||
"The minimum number of detections."));
|
||||
minClicks.getSpinner().setEditable(true);
|
||||
minClicks.getLabel1().setPrefWidth(LABEL_WIDTH);
|
||||
|
||||
|
||||
minPercClicks = new ControlField<Double>("Min. % clicks ", "", 0, 100., 1.);
|
||||
minPercClicks.setTooltip(new Tooltip(
|
||||
"The minimum number of detections."));
|
||||
minPercClicks.getSpinner().setEditable(true);
|
||||
SpinnerValueFactory<Double> valueFactory = new SpinnerValueFactory.DoubleSpinnerValueFactory(0, 100., 0., 1.);
|
||||
valueFactory.setConverter(doubleConverter);
|
||||
minPercClicks.getSpinner().setValueFactory(valueFactory);
|
||||
minPercClicks.getSpinner().setEditable(true);
|
||||
///HACK to get the percentage sign to show?
|
||||
minPercClicks.getSpinner().increment();
|
||||
minPercClicks.getSpinner().decrement();
|
||||
|
||||
minTime = new ControlField<Double>("Min. Time ", "s", 0.0, Double.MAX_VALUE, 1.0);
|
||||
minPercClicks.getLabel1().setPrefWidth(LABEL_WIDTH);
|
||||
|
||||
minPercClicks.getChildren().add( createDataSelectorPane());
|
||||
|
||||
|
||||
minTime = new ControlField<Double>("Min. time ", "s", 0.0, Double.MAX_VALUE, 1.0);
|
||||
minTime.getSpinner().getValueFactory().setConverter(PamSpinner.createStringConverter(2));
|
||||
minTime.setTooltip(new Tooltip(
|
||||
"The minimum time for a click train."));
|
||||
@ -115,29 +158,83 @@ public class SimpleCTClassifierPane extends SettingsPane<Chi2ThresholdParams> {
|
||||
|
||||
chi2Threshold.getSpinner().setEditable(true);
|
||||
|
||||
vBox.getChildren().addAll(chi2Threshold, minClicks, minTime);
|
||||
vBox.getChildren().addAll(chi2Threshold, minClicks, minPercClicks, minTime);
|
||||
|
||||
return vBox;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the data selector.
|
||||
* @return the data selector.
|
||||
*/
|
||||
private Pane createDataSelectorPane() {
|
||||
PamHBox hbox = new PamHBox();
|
||||
hbox.setSpacing(5);
|
||||
hbox.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
dataSelectorButton = new PamButton();
|
||||
// dataSelectorButton.setGraphic(PamGlyphDude.createPamGlyph(MaterialIcon.SETTINGS, PamGuiManagerFX.iconSize));
|
||||
dataSelectorButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog", PamGuiManagerFX.iconSize));
|
||||
dataSelectorButton.setOnAction((action)->{
|
||||
showDataSelectorPane();
|
||||
});
|
||||
hbox.getChildren().addAll(dataSelectorButton);
|
||||
return hbox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates pane allowing the user to change fine scale things such as error limits.
|
||||
* @return the pop over pane.
|
||||
*/
|
||||
public void showDataSelectorPane() {
|
||||
|
||||
if (popOver==null) {
|
||||
popOver = new PopOver();
|
||||
PamBorderPane holder = new PamBorderPane(simpleChi2Classifier.getDataSelector().getDialogPaneFX().getContentNode());
|
||||
holder.setPadding(new Insets(5,5,5,5));
|
||||
popOver.setContentNode(holder);
|
||||
}
|
||||
|
||||
popOver.showingProperty().addListener((obs, old, newval)->{
|
||||
if (newval) {
|
||||
// System.out.println("Data Selector: " + simpleChi2Classifier.getDataSelector());
|
||||
simpleChi2Classifier.getDataSelector().getDialogPaneFX().setParams(true);
|
||||
}
|
||||
else {
|
||||
simpleChi2Classifier.getDataSelector().getDialogPaneFX().getParams(true);
|
||||
}
|
||||
});
|
||||
|
||||
popOver.show(dataSelectorButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chi2ThresholdParams getParams(Chi2ThresholdParams currParams) {
|
||||
//System.out.println("Get PERC spinner value; " + minPercClicks.getSpinner().getValue());
|
||||
|
||||
currParams.chi2Threshold=chi2Threshold.getSpinner().getValue();
|
||||
//HACK - for some reason Integer spinner is returning a double
|
||||
currParams.minClicks=minClicks.getSpinner().getValue().intValue();
|
||||
currParams.minTime=minTime.getSpinner().getValue();
|
||||
currParams.minPercentage=minPercClicks.getSpinner().getValue()/100;
|
||||
|
||||
if (simpleChi2Classifier!=null && simpleChi2Classifier.getDataSelector()!=null) {
|
||||
simpleChi2Classifier.getDataSelector().getDialogPaneFX().getParams(true);
|
||||
}
|
||||
|
||||
return currParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(Chi2ThresholdParams input) {
|
||||
|
||||
chi2Threshold.getSpinner().getValueFactory().setValue(input.chi2Threshold);
|
||||
//HACK - for some reason Integer spinner is returning a double
|
||||
minClicks.getSpinner().getValueFactory().setValue((double) input.minClicks);
|
||||
minTime.getSpinner().getValueFactory().setValue(input.minTime);
|
||||
minPercClicks.getSpinner().getValueFactory().setValue(input.minPercentage*100.);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,6 +261,24 @@ public class SimpleCTClassifierPane extends SettingsPane<Chi2ThresholdParams> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
StringConverter<Double> doubleConverter = new StringConverter<Double>() {
|
||||
private final DecimalFormat df = new DecimalFormat("###.#");
|
||||
@Override
|
||||
public String toString(Double object) {
|
||||
if (object == null) {return "";}
|
||||
return df.format(object)+"%";}
|
||||
@Override
|
||||
public Double fromString(String string) {
|
||||
try {
|
||||
if (string == null) {return null;}
|
||||
string = string.trim();
|
||||
if (string.length() < 1) {return null;}
|
||||
return df.parse(string).doubleValue();
|
||||
} catch (Exception ex) {throw new RuntimeException(ex);}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -118,6 +118,8 @@ public class TemplateClassifierPane extends SettingsPane<TemplateClassifierParam
|
||||
spectrumPane.getChildren().addAll(spectrumthreshold, spectrumTemplatePane);
|
||||
spectrumPane.setPadding(new Insets(5,5,5,5));
|
||||
|
||||
spectrumTemplatePane.prefWidthProperty().bind(spectrumPane.widthProperty());
|
||||
|
||||
|
||||
// tabPane.setSide(Side.LEFT);
|
||||
|
||||
@ -136,6 +138,10 @@ public class TemplateClassifierPane extends SettingsPane<TemplateClassifierParam
|
||||
// tabPane.minWidthProperty().bind(generalPane.widthProperty());
|
||||
// tabPane.getTabs().addAll(tab1, tab2);
|
||||
|
||||
|
||||
spectrumTemplatePane.drawCurrentUnit();
|
||||
|
||||
|
||||
return new PamVBox(generalPane, spectrumPane);
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public class TemplateSpectrumPane extends PamBorderPane {
|
||||
|
||||
//now add the import button.
|
||||
Pane spectrumTemplate = createTemplatePane(templateDisplay);
|
||||
|
||||
|
||||
|
||||
return spectrumTemplate;
|
||||
}
|
||||
@ -121,12 +121,14 @@ public class TemplateSpectrumPane extends PamBorderPane {
|
||||
stackPane.setMaxHeight(prefHeight);
|
||||
stackPane.setMaxWidth(Double.MAX_VALUE);
|
||||
stackPane.setPrefWidth(500); //need this for some reason to make the plot resize.
|
||||
|
||||
|
||||
//stackPane.setStyle("-fx-background-color: red;");
|
||||
|
||||
detectionPlot.prefWidthProperty().bind(stackPane.widthProperty());
|
||||
|
||||
|
||||
|
||||
PamVBox holder = new PamVBox();
|
||||
holder.setSpacing(5);
|
||||
holder.getChildren().addAll(stackPane);
|
||||
@ -363,4 +365,9 @@ public class TemplateSpectrumPane extends PamBorderPane {
|
||||
}
|
||||
|
||||
|
||||
public void drawCurrentUnit() {
|
||||
templateDisplay.drawCurrentUnit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import PamView.dialog.PamDialog;
|
||||
import PamView.dialog.PamDialogPanel;
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import PamguardMVC.dataSelector.DataSelectParams;
|
||||
import clickTrainDetector.classification.CTClassifierManager;
|
||||
import clickTrainDetector.dataselector.CTDataSelector;
|
||||
import clickTrainDetector.dataselector.CTSelectParams;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@ -71,8 +72,15 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
*/
|
||||
private JTextField minUnitsField;
|
||||
|
||||
private JPanel classification;
|
||||
|
||||
private JCheckBox[] classifierCheckBoxes;
|
||||
|
||||
private JCheckBox unclassifiedCheckBox;
|
||||
|
||||
private JPanel classificationFilter;
|
||||
|
||||
public CTDataSelectPanel(CTDataSelector ctDataSelector, boolean allowScores) {
|
||||
// TODO Auto-generated constructor stub
|
||||
this.ctDataSelector=ctDataSelector;
|
||||
mainPanel = createPanel();
|
||||
}
|
||||
@ -84,7 +92,7 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
private JPanel createPanel() {
|
||||
//panel for map options
|
||||
JPanel dataFilter=new JPanel();
|
||||
dataFilter.setBorder(new TitledBorder("ClickTrain Filter"));
|
||||
dataFilter.setBorder(new TitledBorder("General"));
|
||||
GridBagLayout layout = new GridBagLayout();
|
||||
GridBagConstraints constraints = new PamGridBagContraints();
|
||||
dataFilter.setLayout(layout);
|
||||
@ -106,11 +114,22 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
|
||||
constraints.gridx++;
|
||||
PamDialog.addComponent(dataFilter, minUnitsField = new JTextField(4), constraints);
|
||||
|
||||
|
||||
classificationFilter=new JPanel();
|
||||
classificationFilter.setBorder(new TitledBorder("Species classification"));
|
||||
layout = new GridBagLayout();
|
||||
constraints = new PamGridBagContraints();
|
||||
classificationFilter.setLayout(layout);
|
||||
constraints.gridy = 0;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridwidth=3;
|
||||
PamDialog.addComponent(classificationFilter, classification = createClassificationPanel(), constraints);
|
||||
|
||||
|
||||
//panel for map options
|
||||
JPanel filterPanel=new JPanel();
|
||||
filterPanel.setBorder(new TitledBorder("Sub Detection Filter"));
|
||||
filterPanel.setBorder(new TitledBorder("Sub Detections"));
|
||||
layout = new GridBagLayout();
|
||||
constraints = new PamGridBagContraints();
|
||||
filterPanel.setLayout(layout);
|
||||
@ -163,11 +182,120 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
mainPanel.add(dataFilter, BorderLayout.NORTH); //preferred
|
||||
mainPanel.add(classificationFilter, BorderLayout.CENTER); //changes size.
|
||||
mainPanel.add(filterPanel, BorderLayout.SOUTH); //preferred
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private JPanel createClassificationPanel() {
|
||||
JPanel panel = new JPanel();
|
||||
GridBagLayout layout = new GridBagLayout();
|
||||
panel.setLayout(layout);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the classification pane with the right species check boxes etc.
|
||||
*/
|
||||
private void setClassificationPane() {
|
||||
|
||||
GridBagConstraints constraints = new PamGridBagContraints();
|
||||
constraints.gridy = 0;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridwidth=3;
|
||||
|
||||
classification.removeAll(); //clear all previous check boxes.
|
||||
|
||||
CTClassifierManager classifcationManager = ctDataSelector.getClickControl().getClassifierManager();
|
||||
|
||||
if (classifcationManager.getCurrentClassifiers().size()<1) {
|
||||
//don't show the classification pane if there are no classiifcations.
|
||||
this.classificationFilter.setVisible(false);
|
||||
}
|
||||
this.classificationFilter.setVisible(true);
|
||||
|
||||
|
||||
PamDialog.addComponent(classification, unclassifiedCheckBox = new JCheckBox("All"), constraints);
|
||||
unclassifiedCheckBox.addActionListener((action)->{
|
||||
setCheckBoxEnable();
|
||||
});
|
||||
constraints.gridy++;
|
||||
|
||||
classifierCheckBoxes = new JCheckBox[classifcationManager.getCurrentClassifiers().size()];
|
||||
for (int i=0; i<classifcationManager.getCurrentClassifiers().size(); i++) {
|
||||
//System.out.println("Classifications: " + i);
|
||||
PamDialog.addComponent(classification, classifierCheckBoxes[i] = new JCheckBox(classifcationManager.getCurrentClassifiers().get(i).getParams().classifierName), constraints);
|
||||
classifierCheckBoxes[i].setSelected(true); //default should be selected
|
||||
constraints.gridy++;
|
||||
}
|
||||
classification.validate(); //make sure everything is laid out properly.
|
||||
|
||||
setClassifierParams();
|
||||
|
||||
setCheckBoxEnable();
|
||||
}
|
||||
|
||||
private void setCheckBoxEnable() {
|
||||
if (classifierCheckBoxes!=null) {
|
||||
for (int i=0; i<classifierCheckBoxes.length; i++) {
|
||||
classifierCheckBoxes[i].setEnabled(!unclassifiedCheckBox.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the classifier parameters.
|
||||
*/
|
||||
private void setClassifierParams() {
|
||||
|
||||
unclassifiedCheckBox.setSelected(currentParams.needsClassification );
|
||||
|
||||
if (currentParams.classifier==null ) {
|
||||
for (int i=0; i<classifierCheckBoxes.length; i++) {
|
||||
classifierCheckBoxes[i].setSelected(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0; i<classifierCheckBoxes.length; i++) {
|
||||
classifierCheckBoxes[i].setSelected(false);
|
||||
for (int j=0; j<currentParams.classifier.length; j++) {
|
||||
if (ctDataSelector.getClickControl().getClassifierManager().getCurrentClassifiers().get(i).getSpeciesID()==currentParams.classifier[j]) {
|
||||
classifierCheckBoxes[i].setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the parameters for the classifiers to use.
|
||||
*/
|
||||
private void getClassifierParams() {
|
||||
currentParams.needsClassification = unclassifiedCheckBox.isSelected();
|
||||
|
||||
int count = 0;
|
||||
for (int i=0; i<classifierCheckBoxes.length; i++) {
|
||||
if (classifierCheckBoxes[i].isSelected()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
// System.out.println("No. count: " + count);
|
||||
currentParams.classifier = new int[count];
|
||||
for (int i=0; i<classifierCheckBoxes.length; i++) {
|
||||
if (classifierCheckBoxes[i].isSelected()) {
|
||||
currentParams.classifier[i] = ctDataSelector.getClickControl().getClassifierManager().getCurrentClassifiers().get(i).getSpeciesID();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JComponent getDialogComponent() {
|
||||
return mainPanel;
|
||||
@ -182,11 +310,17 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
maxAngleField.setText(String.format("%.2f", Math.toDegrees(currentParams.maxAngleChange)));
|
||||
maxTimeField.setText(String.format("%.2f", currentParams.maxTime/1000.));
|
||||
|
||||
|
||||
//click train plotting
|
||||
minUnitsField.setText(String.format("%d", currentParams.minSubDetections));
|
||||
hasLoc.setSelected(currentParams.needsLoc);
|
||||
|
||||
// System.out.println("No. set classiifers: " + currentParams.classifier.length);
|
||||
|
||||
setClassificationPane();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,6 +340,8 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
currentParams = new CTSelectParams();
|
||||
}
|
||||
try {
|
||||
//System.out.println("Get Params: ");
|
||||
|
||||
Double minTime = (Double.valueOf(minTimeField.getText())*1000.); //millis
|
||||
Double maxTime = (Double.valueOf(maxTimeField.getText())*1000.); //millis
|
||||
Double maxAngleChange = Double.valueOf(maxAngleField.getText());
|
||||
@ -217,6 +353,11 @@ public class CTDataSelectPanel implements PamDialogPanel {
|
||||
//click train plotting
|
||||
currentParams.minSubDetections = Integer.valueOf(minUnitsField.getText());
|
||||
currentParams.needsLoc = hasLoc.isSelected();
|
||||
|
||||
// get the classifier parameters.
|
||||
getClassifierParams();
|
||||
|
||||
//System.out.println("No. getParams classifiers: " + currentParams.classifier.length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -159,25 +159,25 @@ public class MHTSettingsPane extends SettingsPane<MHTParams> {
|
||||
pruneStartSpinner.setEditable(true);
|
||||
pruneBackSpinner.setTooltip(new Tooltip("The minimum number of detections before pruning starts."));
|
||||
gridPane.add(pruneStartSpinner, 1, gridY);
|
||||
gridY++;
|
||||
gridY=0;
|
||||
|
||||
gridPane.add(new Label("Max no. coasts"), 0, gridY);
|
||||
gridPane.add(new Label(" Max no. coasts"), 2, gridY);
|
||||
nCoastsSpinner = new PamSpinner<Integer>(0,Integer.MAX_VALUE,3,1);
|
||||
nCoastsSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
nCoastsSpinner.setPrefWidth(70);
|
||||
nCoastsSpinner.setEditable(true);
|
||||
nCoastsSpinner.setTooltip(new Tooltip("The maximum number of missing detections before a track is closed"));
|
||||
|
||||
gridPane.add(nCoastsSpinner, 1, gridY);
|
||||
gridPane.add(nCoastsSpinner, 3, gridY);
|
||||
gridY++;
|
||||
|
||||
gridPane.add(new Label("Max no. trains"), 0, gridY);
|
||||
gridPane.add(new Label(" Max no. trains"), 2, gridY);
|
||||
nHoldSpinner = new PamSpinner<Integer>(0,1000,3,1);
|
||||
nHoldSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
nHoldSpinner.setPrefWidth(70);
|
||||
nHoldSpinner.setEditable(true);
|
||||
nHoldSpinner.setTooltip(new Tooltip("The maximum number of unique click trains that can be tracked at the same time."));
|
||||
gridPane.add(nHoldSpinner, 1, gridY);
|
||||
gridPane.add(nHoldSpinner, 3, gridY);
|
||||
|
||||
pamVBox.getChildren().addAll(label, gridPane);
|
||||
|
||||
|
@ -8,7 +8,6 @@ import java.util.ArrayList;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import pamScrollSystem.AbstractScrollManager;
|
||||
|
||||
import generalDatabase.DBControlUnit;
|
||||
import binaryFileStorage.BinaryStore;
|
||||
import dataMap.layoutFX.DataMapGUIFX;
|
||||
@ -240,6 +239,32 @@ public class DataMapControl extends PamControlledUnit implements PamSettings {
|
||||
public ArrayList<PamDataBlock> getMappedDataBlocks() {
|
||||
return mappedDataBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single data map. Useful when bringing in data
|
||||
* from 'non standard' sources. Check overall time limits and
|
||||
* redraw, but no total map creation.
|
||||
* @param singleDataMap
|
||||
*/
|
||||
public void updateSingleDataMap(OfflineDataMap<?> singleDataMap) {
|
||||
long newLastTime = singleDataMap.getLastDataTime();
|
||||
long newFirstTime = singleDataMap.getFirstDataTime();
|
||||
if (mappedDataBlocks == null) {
|
||||
return;
|
||||
}
|
||||
for (PamDataBlock aBlock : mappedDataBlocks) {
|
||||
int nMaps = aBlock.getNumOfflineDataMaps();
|
||||
for (int iMap = 0; iMap < nMaps; iMap++) {
|
||||
OfflineDataMap aMap = aBlock.getOfflineDataMap(iMap);
|
||||
newFirstTime = Math.min(newFirstTime, aMap.getFirstDataTime());
|
||||
newLastTime = Math.max(newLastTime, aMap.getLastDataTime());
|
||||
}
|
||||
}
|
||||
firstTime = newFirstTime;
|
||||
lastTime = newLastTime;
|
||||
dataMapPanel.repaintAll();
|
||||
dataMapPanel.getSummaryPanel().newDataSources();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstTime for any data in any data block
|
||||
|
@ -167,5 +167,12 @@ public class DataMapPanel extends PamBorderPanel implements PamTabPanel {
|
||||
}
|
||||
summaryPanel.newDataSources();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the summaryPanel
|
||||
*/
|
||||
public SummaryPanel getSummaryPanel() {
|
||||
return summaryPanel;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ public class SummaryPanel extends HidingDialogComponent {
|
||||
dataEnds[i].setText(" ---No data---");
|
||||
}
|
||||
else {
|
||||
dataStarts[i].setText(PamCalendar.formatDateTime2(dataExtent[0], true));
|
||||
dataEnds[i].setText(PamCalendar.formatDateTime(dataExtent[1], true));
|
||||
dataStarts[i].setText(PamCalendar.formatDateTime2(dataExtent[0], true));
|
||||
dataEnds[i].setText(PamCalendar.formatDateTime(dataExtent[1], true));
|
||||
}
|
||||
}
|
||||
for (int i = offlineDataStores.size(); i < maxDataSources; i++) {
|
||||
|
@ -447,6 +447,11 @@ public class DetectionPlotDisplay extends PamBorderPane implements UserDisplayNo
|
||||
private void drawDataUnit(PamDataUnit newDataUnit) {
|
||||
//Debug.out.println("DetectionPlotDisplay DrawDataUnit: " +newDataUnit);
|
||||
if (currentDataInfo!=null){
|
||||
//sometimes the axis just need a little push to make sure the pane and axis object bindings have been updated
|
||||
for (int i=0; i<Side.values().length; i++) {
|
||||
dDPlotPane.getAxisPane(Side.values()[i]).layout();
|
||||
}
|
||||
|
||||
currentDataInfo.drawData(dDPlotPane.getPlotCanvas().getGraphicsContext2D(),
|
||||
new Rectangle(0,0,dDPlotPane.getPlotCanvas().getWidth(),dDPlotPane.getPlotCanvas().getHeight()),
|
||||
this.detectionPlotProjector, newDataUnit);
|
||||
|
@ -326,7 +326,7 @@ public abstract class SpectrumPlot <D extends PamDataUnit> implements Detection
|
||||
}
|
||||
g2.strokePolyline(scaledDataX, scaledDataY, scaledDataY.length-1);
|
||||
if (fillSpectrum) {
|
||||
// System.out.println("Last point: " + x0 + " y0 " + r.getHeight());
|
||||
//System.out.println("Last point: " + x0 + " y0 " + y0 + " " + scale + " " + clickLineData[iChan][0] + " " + projector.getAxis(Side.LEFT).getMinVal() + " " +projector.getAxis(Side.LEFT).getTotalPixels());
|
||||
scaledDataX[scaledDataX.length-1]=x0; // the last x position
|
||||
scaledDataY[scaledDataY.length-1]= r.getHeight() ; //return the line to zero for polygon drawing
|
||||
// PamUtils.PamArrayUtils.printArray(scaledDataY);
|
||||
|
88
src/fileOfflineData/OfflineFileList.java
Normal file
88
src/fileOfflineData/OfflineFileList.java
Normal file
@ -0,0 +1,88 @@
|
||||
package fileOfflineData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Make a list of files with the given file filter.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class OfflineFileList {
|
||||
|
||||
private ArrayList<File> files = new ArrayList<>();
|
||||
private String folder;
|
||||
private FileFilter fileFilter;
|
||||
private boolean includeSubFolders;
|
||||
|
||||
public OfflineFileList(String folder, FileFilter fileFilter, boolean includeSubFolders) {
|
||||
this.folder = folder;
|
||||
this.fileFilter = fileFilter;
|
||||
this.includeSubFolders = includeSubFolders;
|
||||
updateCatalog();
|
||||
}
|
||||
|
||||
public int updateCatalog() {
|
||||
files.clear();
|
||||
File current = new File(this.folder);
|
||||
addFiles(current);
|
||||
return files.size();
|
||||
}
|
||||
|
||||
private void addFiles(File current) {
|
||||
if (current.exists() == false) {
|
||||
return;
|
||||
}
|
||||
if (current.isFile() && checkFilter(current)) {
|
||||
/*
|
||||
* This can only really happen if the root passed in is a file, not a
|
||||
* folder, since files within the folder structure will get
|
||||
* added from the loop below.
|
||||
*/
|
||||
files.add(current);
|
||||
}
|
||||
else if (current.isDirectory()) {
|
||||
File[] filesList = current.listFiles();
|
||||
if (filesList == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < filesList.length; i++) {
|
||||
File aFile = filesList[i];
|
||||
if (aFile.isFile() && checkFilter(aFile)) {
|
||||
files.add(aFile);
|
||||
}
|
||||
else if (aFile.isDirectory() && includeSubFolders) {
|
||||
addFiles(aFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if there is a filter, the file is accepted.
|
||||
* @param aFile
|
||||
* @return
|
||||
*/
|
||||
private boolean checkFilter(File aFile) {
|
||||
if (fileFilter == null) {
|
||||
return true;
|
||||
}
|
||||
return fileFilter.accept(aFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of files in the catalog as a simple string list.
|
||||
* @return files as strings
|
||||
*/
|
||||
public String[] asStringList() {
|
||||
if (files == null) {
|
||||
return null;
|
||||
}
|
||||
String[] str = new String[files.size()];
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
str[i] = files.get(i).getAbsolutePath();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
@ -426,7 +426,11 @@ public class PamTableItem implements Cloneable {
|
||||
return (Double) value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a float value, being aware that some DBMS may have
|
||||
* decided to store as a Double anyway. Return Float.NaN for null data
|
||||
* @return float value or NaN
|
||||
*/
|
||||
public float getFloatValue() {
|
||||
if (value == null) {
|
||||
return Float.NaN;
|
||||
|
@ -120,6 +120,9 @@ public class DatabaseBackupStream extends FileBackupStream {
|
||||
|
||||
public FileLocation getSourceLocation() {
|
||||
File dbFile = getDatabaesFile();
|
||||
if (dbFile == null) {
|
||||
return null;
|
||||
}
|
||||
FileLocation sl = new FileLocation();
|
||||
sl.path = dbFile.getAbsolutePath();
|
||||
sl.canEditMask = false;
|
||||
|
@ -4,6 +4,7 @@ import generalDatabase.DBControlUnit;
|
||||
import generalDatabase.PamConnection;
|
||||
import generalDatabase.SQLLogging;
|
||||
import generalDatabase.SQLTypes;
|
||||
import generalDatabase.SuperDetLogging;
|
||||
import generalDatabase.clauses.FixedClause;
|
||||
import generalDatabase.clauses.FromClause;
|
||||
import generalDatabase.clauses.PAMSelectClause;
|
||||
@ -354,6 +355,7 @@ public abstract class OfflineTask<T extends PamDataUnit> {
|
||||
}
|
||||
aBlock.clearAll();
|
||||
|
||||
|
||||
|
||||
SQLLogging logging = aBlock.getLogging();
|
||||
if (logging == null) {
|
||||
@ -382,7 +384,15 @@ public abstract class OfflineTask<T extends PamDataUnit> {
|
||||
System.out.println("Unknown data selection option in OfflineTask.deleteOldData: " + taskGroupParams.dataChoice);
|
||||
return;
|
||||
}
|
||||
logging.deleteData(clause);
|
||||
while (logging != null) {
|
||||
logging.deleteData(clause);
|
||||
if (logging instanceof SuperDetLogging) {
|
||||
logging = ((SuperDetLogging) logging).getSubLogging();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,6 +44,14 @@ public abstract class AbstractPamScroller implements DataTimeLimits {
|
||||
*/
|
||||
protected double[] playSpeeds = {.1, 0.25, .5, 1.0, 2, 5, 10};
|
||||
|
||||
// private long realTimerStart;
|
||||
//
|
||||
// private long timerStartPosition;
|
||||
|
||||
private long timerLastCurrentTime;
|
||||
|
||||
// private long timerTimeMillis;
|
||||
|
||||
|
||||
public AbstractPamScroller(String name, int orientation, int stepSizeMillis, long defaultLoadTime, boolean hasMenu){
|
||||
|
||||
@ -630,6 +638,8 @@ public abstract class AbstractPamScroller implements DataTimeLimits {
|
||||
playTimerAction();
|
||||
}
|
||||
});
|
||||
timerLastCurrentTime = System.currentTimeMillis();
|
||||
// timeLastValue = getValueMillis();
|
||||
playTimer.start();
|
||||
playbackStarted();
|
||||
}
|
||||
@ -671,11 +681,17 @@ public abstract class AbstractPamScroller implements DataTimeLimits {
|
||||
stopPlayback();
|
||||
return;
|
||||
}
|
||||
long step = Math.max((long) (timerInterval * scrollerData.getPlaySpeed()), 1);
|
||||
setValueMillis(pos+step);
|
||||
if (pos == getValueMillis()) {
|
||||
playTimer.setDelay(playTimer.getDelay()*2);
|
||||
}
|
||||
/**
|
||||
* Since the action on setValue can take quite some time, the timer can run slow
|
||||
* if we just increment by what we think this delay is, so increment the value
|
||||
* based on how much system time has elapsed between the last call and now
|
||||
*/
|
||||
long now = System.currentTimeMillis();
|
||||
int elapsed = (int) (now - timerLastCurrentTime);
|
||||
int toAdd = (int) (elapsed*scrollerData.getPlaySpeed());
|
||||
timerLastCurrentTime = now;
|
||||
|
||||
setValueMillis(getValueMillis()+toAdd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class PamAxisPane2 extends StackPane {
|
||||
this.getChildren().add(mainPane);
|
||||
}
|
||||
|
||||
private void layoutAxis(){
|
||||
public void layoutAxis(){
|
||||
|
||||
mainPane.setCenter(null);
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package pamViewFX.fxNodes.utilityPanes;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
|
@ -69,6 +69,11 @@ public class RoccaControl extends PamControlledUnit implements PamSettings {
|
||||
*/
|
||||
public static final String unitType = "Rocca";
|
||||
|
||||
/*
|
||||
* Max max data keep time to avoid memory overflows. Currently at 15 minutes.
|
||||
*/
|
||||
private static final int MAXMAXDATAKEEPTIME = 900000;
|
||||
|
||||
/**
|
||||
* reference to the ClickControl module when it is loaded in Viewer mode
|
||||
*/
|
||||
@ -193,6 +198,17 @@ public class RoccaControl extends PamControlledUnit implements PamSettings {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* A bit of a fudge to deal with some old code which kept doubling the
|
||||
* keep time of the raw data, which eventually led to raw data using too
|
||||
* much memory and bringing down PG. I don't fully understand that code so
|
||||
* have left as much of it as possible, but put this in as an absolute
|
||||
* maximum which cannot be exceeded.
|
||||
* @return max in milliseconds as int, which is what's used in PAMDataBlock.
|
||||
*/
|
||||
public int getMaxDataKeepTime() {
|
||||
return MAXMAXDATAKEEPTIME;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param eventList
|
||||
@ -242,18 +258,21 @@ public class RoccaControl extends PamControlledUnit implements PamSettings {
|
||||
(rcdb.getContour().get(RoccaContourStats.ParamIndx.SNR) > 35. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) < 0.005 ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) > 0.6 )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
if (roccaParameters.roccaClassifierModelFilename.getName().equals("HIClick.model") &&
|
||||
(rcdb.getContour().get(RoccaContourStats.ParamIndx.SNR) > 40. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) < 0.01 ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) > 0.6 )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
if (roccaParameters.roccaClassifierModelFilename.getName().equals("NWAtlClick.model") &&
|
||||
(rcdb.getContour().get(RoccaContourStats.ParamIndx.SNR) > 35. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) < 0.005 ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) > 0.6 )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -363,6 +363,9 @@ public class RoccaProcess extends PamProcess {
|
||||
|
||||
// 2017/12/4 set the natural lifetime to Integer.Max, so that we definitely keep all of the data
|
||||
// units during this code block. Set the lifetime back to 0 at the end of the block
|
||||
/*
|
||||
* DG June '22 made sure this is the case when the function returns early !
|
||||
*/
|
||||
rcdb.setNaturalLifetimeMillis(Integer.MAX_VALUE);
|
||||
rcdb.calculateStatistics();
|
||||
|
||||
@ -385,6 +388,7 @@ public class RoccaProcess extends PamProcess {
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) > 1.5 ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQABSSLOPEMEAN) < 2000. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQABSSLOPEMEAN) > 28000. )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
if (roccaControl.roccaParameters.roccaClassifierModelFilename.getName().equals("HIWhist.model") &&
|
||||
@ -398,6 +402,7 @@ public class RoccaProcess extends PamProcess {
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQABSSLOPEMEAN) > 60000. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQRANGE) < 800. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQRANGE) > 14000. )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
if (roccaControl.roccaParameters.roccaClassifierModelFilename.getName().equals("NWAtlWhist.model") &&
|
||||
@ -407,6 +412,7 @@ public class RoccaProcess extends PamProcess {
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.DURATION) > 2.5 ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQABSSLOPEMEAN) < 9100. ||
|
||||
rcdb.getContour().get(RoccaContourStats.ParamIndx.FREQABSSLOPEMEAN) > 82000. )) {
|
||||
rcdb.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -736,13 +742,15 @@ public class RoccaProcess extends PamProcess {
|
||||
PamUtils.makeChannelMap(lowestChanList));
|
||||
int firstIndx = prdb.getUnitIndex(firstRDU);
|
||||
if (firstIndx==-1) {
|
||||
System.out.println("RoccaProcess: Cannot determine firstIndx, raw data lifetime = " + prdb.getNaturalLifetimeMillis() + " ms");
|
||||
int newTime;
|
||||
if (prdb.getNaturalLifetimeMillis() > Integer.MAX_VALUE/2) {
|
||||
newTime = Integer.MAX_VALUE;
|
||||
} else {
|
||||
newTime = prdb.getNaturalLifetimeMillis()*2;
|
||||
}
|
||||
// stop it getting silly.
|
||||
newTime = Math.min(newTime, roccaControl.getMaxDataKeepTime());
|
||||
System.out.println("RoccaProcess: Cannot determine firstIndx, raw data lifetime = " + prdb.getNaturalLifetimeMillis() + " ms");
|
||||
prdb.setNaturalLifetimeMillis(newTime); // increase the lifetime to try and prevent this from happening again
|
||||
return null;
|
||||
}
|
||||
@ -769,13 +777,14 @@ public class RoccaProcess extends PamProcess {
|
||||
PamUtils.makeChannelMap(highestChanList));
|
||||
int lastIndx = prdb.getUnitIndex(lastRDU);
|
||||
if (lastIndx==-1) {
|
||||
System.out.println("RoccaProcess: Cannot determine lastIndx, raw data lifetime = " + prdb.getNaturalLifetimeMillis() + " ms");
|
||||
int newTime;
|
||||
if (prdb.getNaturalLifetimeMillis() > Integer.MAX_VALUE/2) {
|
||||
newTime = Integer.MAX_VALUE;
|
||||
} else {
|
||||
newTime = prdb.getNaturalLifetimeMillis()*2;
|
||||
}
|
||||
newTime = Math.min(newTime, roccaControl.getMaxDataKeepTime());
|
||||
System.out.println("RoccaProcess: Cannot determine lastIndx, raw data lifetime = " + prdb.getNaturalLifetimeMillis() + " ms");
|
||||
prdb.setNaturalLifetimeMillis(newTime); // increase the lifetime to try and prevent this from happening again
|
||||
return null;
|
||||
}
|
||||
|
@ -114,7 +114,10 @@ public class RoccaSidePanel extends PamObserverAdapter implements PamSidePanel
|
||||
this.rsdb = new RoccaSightingDataBlock
|
||||
(roccaControl.roccaProcess,
|
||||
roccaControl.roccaParameters.getChannelMap());
|
||||
|
||||
// this one probably OK to never delete ?
|
||||
rsdb.setNaturalLifetimeMillis(Integer.MAX_VALUE);
|
||||
|
||||
rdl = new RoccaDetectionLogger(this, rsdb);
|
||||
rsdb.SetLogging(rdl);
|
||||
rsdb.setMixedDirection(PamDataBlock.MIX_INTODATABASE);
|
||||
|
@ -171,6 +171,8 @@ public class RoccaWhistleSelect extends PamProcess implements SpectrogramMarkObs
|
||||
roccaControl.roccaSidePanel.sidePanel.addASighting(false);
|
||||
// if the user hit cancel, just exit
|
||||
if (dummy == RoccaSightingDataUnit.NONE) {
|
||||
selectedWhistle.setNaturalLifetimeMillis(0);
|
||||
selectedWhistleRaw.setNaturalLifetimeMillis(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -198,6 +200,14 @@ public class RoccaWhistleSelect extends PamProcess implements SpectrogramMarkObs
|
||||
selectedWhistleRaw,
|
||||
display,
|
||||
channel);
|
||||
|
||||
/**
|
||||
* DG June '22.
|
||||
* I hope IT's K to set these back here. It's possible it's also
|
||||
* done elsewhere.
|
||||
*/
|
||||
selectedWhistle.setNaturalLifetimeMillis(0);
|
||||
selectedWhistleRaw.setNaturalLifetimeMillis(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,10 @@ package spectrogramNoiseReduction.layoutFX;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
import pamViewFX.fxNodes.utilityPanes.SourcePaneFX;
|
||||
import spectrogramNoiseReduction.SpecNoiseMethod;
|
||||
import spectrogramNoiseReduction.SpectrogramNoiseProcess;
|
||||
@ -16,10 +14,8 @@ import spectrogramNoiseReduction.SpectrogramNoiseSettings;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.Pane;
|
||||
import PamController.SettingsPane;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
|
||||
@ -39,7 +35,7 @@ public class SpectrogramNoisePaneFX extends SettingsPane<SpectrogramNoiseSetting
|
||||
|
||||
private SpectrogramNoiseSettings spectrogramNoiseSettings=new SpectrogramNoiseSettings();
|
||||
|
||||
private ToggleSwitch[] enableMethod;
|
||||
private PamToggleSwitch[] enableMethod;
|
||||
|
||||
private PamDataBlock dataSource;
|
||||
|
||||
@ -58,7 +54,7 @@ public class SpectrogramNoisePaneFX extends SettingsPane<SpectrogramNoiseSetting
|
||||
PamVBox methodPane;
|
||||
SpecNoiseNodeFX dC;
|
||||
Node node;
|
||||
enableMethod = new ToggleSwitch[methods.size()];
|
||||
enableMethod = new PamToggleSwitch[methods.size()];
|
||||
|
||||
|
||||
for (int i = 0; i < methods.size(); i++) {
|
||||
@ -66,13 +62,14 @@ public class SpectrogramNoisePaneFX extends SettingsPane<SpectrogramNoiseSetting
|
||||
methodPane.setSpacing(10);
|
||||
//create name
|
||||
Label title=new Label(methods.get(i).getName());
|
||||
PamGuiManagerFX.titleFont2style(title);
|
||||
// title.setFont(PamGuiManagerFX.titleFontSize2);
|
||||
|
||||
PamHBox toggleHolder = new PamHBox();
|
||||
toggleHolder.setSpacing(5);
|
||||
toggleHolder.getChildren().addAll(enableMethod[i] =
|
||||
new ToggleSwitch(), title);
|
||||
new PamToggleSwitch(methods.get(i).getName()));
|
||||
PamGuiManagerFX.titleFont2style(enableMethod[i].getLabel());
|
||||
|
||||
enableMethod[i].setAlignment(Pos.CENTER_LEFT);
|
||||
toggleHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
|
@ -67,7 +67,8 @@ public class SingleLineWarningDisplay implements WarningDisplay {
|
||||
lastWarning.setToolTipText(null);
|
||||
}
|
||||
else {
|
||||
String str = String.format("Warning: %s-%s ", w.getWarningSource(), w.getWarningMessage());
|
||||
String str = w.getWarnignLevel() > 0 ? "Warning: " : "";
|
||||
str += String.format("%s-%s ", w.getWarningSource(), w.getWarningMessage());
|
||||
lastWarning.setText(str);
|
||||
lastWarning.setWarningLevel(w.getWarnignLevel());
|
||||
lastWarning.setToolTipText(w.getWarningTip());
|
||||
|
Loading…
Reference in New Issue
Block a user