This commit is contained in:
Douglas Gillespie 2022-06-17 09:52:49 +01:00
commit 875073c344
74 changed files with 1131 additions and 342 deletions

View File

@ -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
View File

@ -21,6 +21,7 @@
*.zip
*.tar.gz
*.rar
*.dll
# eclipse project file
.project

View File

@ -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

View File

@ -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&#13;&#10;-Djava.library.path=lib64"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/PamGuard Main}"/>
</launchConfiguration>

View File

@ -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>

View File

@ -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>

View File

@ -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());
}

View File

@ -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();
});

View File

@ -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;

View File

@ -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

View File

@ -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.
*/

View File

@ -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.

View File

@ -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];
}

View File

@ -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));
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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(...)

View File

@ -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 {

View File

@ -42,7 +42,6 @@ public abstract class OverlayDataManager<TOverlayInfoType extends OverlayDataInf
private ParameterType[] parameterTypes;
private ParameterUnits[] parameterUnits;
/**
* @param generalProjector

View File

@ -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) {

View File

@ -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;
}

View File

@ -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() {

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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()) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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();

View File

@ -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() {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -15,6 +15,7 @@ public class BearingClassifierParams extends CTClassifierParams implements Manag
public BearingClassifierParams(){
super();
type = CTClassifierType.BEARINGCLASSIFIER;
}

View File

@ -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;
}
/**
*
*/

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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.
*/

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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());

View File

@ -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);
}
});

View File

@ -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();
}

View File

@ -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);
}
}

View File

@ -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);}
}
};

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -167,5 +167,12 @@ public class DataMapPanel extends PamBorderPanel implements PamTabPanel {
}
summaryPanel.newDataSources();
}
/**
* @return the summaryPanel
*/
public SummaryPanel getSummaryPanel() {
return summaryPanel;
}
}

View File

@ -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++) {

View File

@ -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);

View File

@ -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);

View 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;
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -93,7 +93,7 @@ public class PamAxisPane2 extends StackPane {
this.getChildren().add(mainPane);
}
private void layoutAxis(){
public void layoutAxis(){
mainPane.setCenter(null);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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());