diff --git a/.externalToolBuilders/net.sourceforge.metrics.builder.launch b/.externalToolBuilders/net.sourceforge.metrics.builder.launch
new file mode 100644
index 00000000..8e11c919
--- /dev/null
+++ b/.externalToolBuilders/net.sourceforge.metrics.builder.launch
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index 6254b898..1cbbf601 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,3 +111,4 @@ settings.xml
.classpath
.classpath
.settings/org.eclipse.jdt.core.prefs
+.classpath
diff --git a/.project b/.project
index c8e79578..bbeba9cb 100644
--- a/.project
+++ b/.project
@@ -11,8 +11,13 @@
- net.sourceforge.metrics.builder
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/net.sourceforge.metrics.builder.launch
+
diff --git a/README.html b/README.html
index 8f8d31ad..0bc2f9d4 100644
--- a/README.html
+++ b/README.html
@@ -388,7 +388,7 @@ PamguardBeta_ViewerMode.exe):
+Version 2.02.12 June 2024
@@ -465,22 +465,36 @@ Version 2.00.10 June 2017
name="_Latest_Version_2.02.06">Version
-2.02.11 April 2024
+2.02.12 June 2024
New Features
+Deep Learning Classifier. Major upgrade to support for Deep
+Learning models in PAMGuard. See online help for details.
+
Click detector: Remembers locations of displays and doesn’t
continually reset them.
-Help for Matched Click Classifier
+Help for Matched Click Classifier.
+
+Project information dialog. This allows capture of essential
+project information to store with your data. See menu item Settings/Project
+information.
+
+Tethys Database
+
+Many users will be aware that we’re integrating an interface
+to the Tethys Database into PAMGuard.
+Some basic features are available for testing. If interested, please contact
+the PAMGuard support team.
Bug Fixes
Linking clicks to offline clicks table. We had a database
-that had become corrupted so added code to relink offline clicks to their corresponding
-clicks from binary data.
+that had become corrupted so added code to relink offline clicks to their
+corresponding clicks from binary data.
Drawing non-acoustic data: Data that were not associated
with any hydrophones, e.g. visual sightings in Logger forms were not drawing on
@@ -497,14 +511,35 @@ as PAMGuard stops / restarts.
function fixed and now inserts correct times of start and ends of events into
database.
+Clip generator. Changes to ensure PAMGuard keeps audio data
+long enough to make clips. In some circumstances data were being discarded too
+early so clips could not be created.
+
+Acquisition “Skip initial seconds” feature, designed to
+remove high sample levels e.g. from calibration tones at start of a soundtrap
+recording was not working with the click detector. This is fixed but replacing
+all data with 0’s and still sending data. Note that this may lead to
+artificially low noise measures at the start of a file.
+
+Data reprocessing options. Updated to ensure that the option
+"Start normally. Note risk of overwriting!" is always available. Also
+improved code naming binary files to attempt to push them to exact times,
+rather than a couple of seconds after the hour.
+
+improved code naming binary files to attempt to push them to
+exact times, rather than a couple of seconds after the hour.
+
+Updated icons to improve display on high definition screens.
+
+
Version 2.02.10 January 2024
New Features
Importing modules from other configurations: New options from file menu allowing import
-of specific modules, or module settings from other configurations. E.g. if you
-had three similar configurations and had set one of them up with a new
+lang=EN-US> from other configurations: New options from file menu allowing
+import of specific modules, or module settings from other configurations. E.g.
+if you had three similar configurations and had set one of them up with a new
detector, or got the click classifier settings set up just right in one of
those configurations, you can import the additional modules or the click
detector settings easily into the other configurations.
@@ -532,9 +567,9 @@ correctly saving updated bearings to the database. Now fixed.
ROCCA Classifier fixes
-Allow Rocca to run without classifiers: Fixed
-bug that threw an error if no classifier files were specified in Rocca
-Params dialog
+Allow Rocca to run without classifiers:
+Fixed bug that threw an error if no classifier files were specified in
+Rocca Params dialog
Fix memory issue with
RoccaContourDataBlocks not being released for garbage collection
@@ -1128,8 +1163,8 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
4. Bug
- 456. Under certain conditions, the Ishmael detection plugin that is
-shown at the bottom of the spectrogram can disappear about 500 msec behind the
+ 456. Under certain conditions, the Ishmael detection plugin that is shown
+at the bottom of the spectrogram can disappear about 500 msec behind the
current time.
5. Add functionality for bluetooth headsets.
2. Add user-facing option to adjust the startup delay for the time-correction
-(Global Time module). This provides a workaround to speed up analysis of
-thousands of wav files (i.e. by setting startup delay to 0 instead of default
-value of 2000 ms).
+lang=EN-US> Add user-facing option to adjust the startup delay for the
+time-correction (Global Time module). This provides a workaround to speed up
+analysis of thousands of wav files (i.e. by setting startup delay to 0 instead
+of default value of 2000 ms).
3. &nb
Add 15 minute data load option to viewer mode.
5.
-Add 3D map for target motion module.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Add 3D map for target motion module.
6. Added channel display to noise one band measurement display.
11.
-Added Azigram module, to work in conjunction with Difar.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Added Azigram module, to work in conjunction with Difar.
12.
-Added beaked whale to sim sounds
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Added beaked whale to sim sounds
13.
Bug Fixes
1.
-Bug 433. Custom storage options were being lost when Pamguard restarted.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Bug 433. Custom storage options were being lost when
+Pamguard restarted.
2. Bug 434. Pamguard Viewer mode was having problems importing
settings from psfx file.
3.
-Bug 435. Logger forms subtabs not working.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Bug 435. Logger forms subtabs not working.
4.
2. Added option in Sound Acquisition settings dialog to
-override filename time stamp and use PC local time instead.
+lang=EN-US> Added option in Sound Acquisition settings dialog to override
+filename time stamp and use PC local time instead.
3. &nb
Implemented a simple UDP output for PAMGuard alarms.
7.
-Changes to Spectrogram Mark Observers, to allow individual channels to be
-selected instead of the spectrogram panel as a whole.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Changes to Spectrogram Mark Observers, to allow individual
+channels to be selected instead of the spectrogram panel as a whole.
8.
2.
-Java 12 is better at handling Windows scaling issues on high-DPI displays. Beyond
-that, users should not notice much of a difference between this version and
-previous beta releases.
+Java 12 is better at handling Windows scaling issues on high-DPI displays.
+Beyond that, users should not notice much of a difference between this version
+and previous beta releases.
@@ -1688,8 +1724,8 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
Upgrades
1.
-Improvement to Range Rings in Map display.
+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> Improvement to Range Rings in Map display.
2.
@@ -2158,7 +2194,7 @@ showing.
2.
-Bug 323. Difar module. Fixed a couple of small
+Bug 323. Difar module. Fixed a couple of small
bugs in the DIFAR system which caused it to not work if old configuratins were
used.
@@ -2304,8 +2340,8 @@ the new version. However please note the following:
1.
-New classes will be added to the configuration files,
-so they will no longer work with older PAMGuard versions.
+New classes will be added to the configuration files, so
+they will no longer work with older PAMGuard versions.
2.
@@ -2428,8 +2464,8 @@ milliseconds. However, getDuration actually returns the number of samples.
Plug-Ins
-A major change in this version of PAMGuard
-is how plug-ins are managed. PAMGuard now has the ability to dynamically load
+A major change in this version of PAMGuard is
+how plug-ins are managed. PAMGuard now has the ability to dynamically load
plug-in modules (saved as jar files) at runtime. This will greatly simplify the
process of testing and distributing newly developed modules, since only a small
jar file will be required rather than a new bespoke PAMGuard installation.
@@ -2438,9 +2474,9 @@ jar file will be required rather than a new bespoke PAMGuard installation.here. Plug-in modules can be downloaded from the
-PAMGuard website here, but developers are encouraged to host and maintain their
-own modules.
+target="_blank">here. Plug-in modules can be downloaded from the PAMGuard
+website here, but developers are encouraged to host and maintain their own
+modules.
Modules of interest to the general PAM
community will remain as part of the core PAMGuard installation. However,
@@ -2615,9 +2651,9 @@ main click detector display.
Target Motion Analysis
-A major piece of work has been undertaken to
-improve the Target Motion tracking with PAMGuard. Details are available in the
-online help. Users of the Click Detector will notice the following changes:
+A major piece of work has been undertaken
+to improve the Target Motion tracking with PAMGuard. Details are available in
+the online help. Users of the Click Detector will notice the following changes:
1.
@@ -3055,8 +3091,8 @@ allocation to allow more memory for the database interface. Hopefully Fixed.
9.
-Bug 239. Fixed bug in the DIFAR module that was incorrectly
-preventing cross-fixes for some calls.
+Bug 239. Fixed bug in the DIFAR module that was
+incorrectly preventing cross-fixes for some calls.
Details of these bugs can be found at https://sourceforge.net/p/pamguard/bugs
@@ -3515,9 +3551,9 @@ to these menus to provide additional information to users.
Radar Display
-Functionality has been added to the
-radar display so that bearings can be shown relative to either the vessel or to
-true North.
+Functionality has been added to
+the radar display so that bearings can be shown relative to either the vessel
+or to true North.
Better control of data in viewer
mode, making is easy to scroll through and view data for short time periods.
@@ -3872,11 +3908,11 @@ Symbol'>'''
-New menu functionality by right clicking on any of the tabs of the main tab
-control will allow the user to copy the tab contents to the system clipboard
-from where it can be copied into other programs (e.g. Word, Powerpoint,
-etc.).Some modules, such as the map, have this implemented in other menus
-(right click) and also allow printing.
+New menu functionality by right clicking on any of the tabs of the main
+tab control will allow the user to copy the tab contents to the system
+clipboard from where it can be copied into other programs (e.g. Word,
+Powerpoint, etc.).Some modules, such as the map, have this implemented in other
+menus (right click) and also allow printing.
'
@@ -4374,8 +4410,8 @@ online help.
PAMGUARD Mixed Mode operation
-Analyses data from wav or AIF file and synchronises it with GPS
-data reloaded from a database so that detected sounds may be correctly
+
Analyses data from wav or AIF file and synchronises it with
+GPS data reloaded from a database so that detected sounds may be correctly
localised. Multiple display frames - enables PAMGUARD GUI to be split into
multiple display windows, displayed on multiple monitors if desired. Enables
the operator to simultaneously view the map and the click detector for example,
@@ -4566,9 +4602,9 @@ a serial port
New Likelihood detector.
-The likelihood detector module is an implementation of a
-likelihood ratio test with flexible algorithms and configuration to estimate
-likelihood. It is
+The likelihood detector module is an implementation of a likelihood
+ratio test with flexible algorithms and configuration to estimate likelihood.
+It is
suitable for detecting both short duration Odontocete clicks
(Sperm, Beaked, etc.) as well as moderate duration Mysticete calls (Humpback,
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index 1775ad8d..c3db71b0 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -4,7 +4,7 @@
org.pamguard
Pamguard
Pamguard
- 2.02.11d
+ 2.02.12
Pamguard using Maven to control dependencies
www.pamguard.org
diff --git a/lib64/SailDaqJNI.dll b/lib64/SailDaqJNI.dll
index 7da8ea4d..604bac0e 100644
Binary files a/lib64/SailDaqJNI.dll and b/lib64/SailDaqJNI.dll differ
diff --git a/readme.md b/readme.md
index 10d133e1..886f0319 100644
--- a/readme.md
+++ b/readme.md
@@ -6,19 +6,21 @@ PAMGuard is a bioacoustics analysis program designed for use in real time resear
## Why do we need PAMGuard?
PAMGuard fufills two main requirements within marine bioacoustics
-1) **Real time operation**: Almost all PAMGuard features and modules work in real time - this allows scientists and industry to detect, classify and loclaise animals in real time on a standard consumer laptop, enabling mitigations and research survey without expensive bespoke software solutions and the transparncy of open source software.
+1) **Real time operation**: Almost all PAMGuard features and modules work in real time - this allows scientists and industry to detect, classify and localise the position of animals in real time on a standard consumer laptop, enabling mitigation and research surveys without expensive bespoke software solutions and the transparncy of open source software.
-2) **Processing and visuslisation of large datasets**: Off-the-shelf autonomous PAM devices, large scale surveys involving drifters, towed arrays and bottom mounted devices and real time continuous monitoring system all generate huge volumes of data whcih requires automated analysis approaches. PAMGuard allows the processing of very large passive acoustic datasets using automated algorothms and provides visualisation tools for a manual analyst to check the results.
+2) **Processing and visuslisation of large datasets**: Off-the-shelf autonomous PAM devices, large scale surveys involving drifters, towed arrays, glidders, bottom mounted devices and real time continuous monitoring system all generate huge volumes of data whcih requires automated analysis approaches. PAMGuard allows the processing of very large passive acoustic datasets using automated algorothms and crucially provides comprehensive visualisation tools for a manual analyst to check the results.
## Installation
-PAMGuard is available on Windows and can be downloaded from the [PAMGuard website](www.pamguard.org). Note that we are considering MacOS installers but they are not available at this time.
+PAMGuard is available on Windows and can be downloaded from the [PAMGuard website](www.pamguard.org). Note that we are considering MacOS and Linux installers but they are not available at this time.
-## Tutorial
+## Quick start tutorial
PAMGuard is a modular program with two modes; real-time and viewer. Typically a user will start with real-time model, either in the field collecting data or post processing sound files from a recorder. Once data are processed, users move on to viewer mode where data can be explored and further processed.
-Upon opening PAMGuard for the first time you are greeted with a blank screen. You must add a series of modules to create the desired acosutic workflow. For example if processing sound files then first add the Sound Acquisition module **_File->Add Modules->Sound Processing->Sound Acquisition_**. Then add the desired detection algorothms e.g. **_File->Add Modules->Detector->Click Detectors_**. Some modules (such as the click detector) have their own displays, others are added to more generalised displays. For example, the whislte and moan detector module shows detections on a spectrgram display. First add a new tab using **_File->Add Modules->Displays->User Display**. Click on the user display tab and then from the top menu select **_User display-> New Spectrgram_**. Right click on the added spectrgram and select whistle and moan contours to show whistle detections overlaid on the raw spectrgram.
+Upon opening PAMGuard for the first time you are greeted with a blank screen. You must add a series of modules to create the desired acosutic workflow - this is referred to as PAMGuard *data model*. For example if processing sound files then first add the Sound Acquisition module **_File->Add Modules->Sound Processing->Sound Acquisition_**. Then add the desired detection algorothms e.g. **_File->Add Modules->Detector->Click Detectors_**. Some modules (such as the click detector) have their own bespoke displays, others are added to more generalised displays. For example, the whistle and moan detector module shows detections on a spectrgram display, time base display, map etc.. First add a new tab using **_File->Add Modules->Displays->User Display**. Click on the user display tab and then from the top menu select **_User display-> New Spectrogram_**. Right click on the added spectrgram and select whistle and moan contours to show whistle detections overlaid on the raw spectrgram.
-Make sure to add the database and binary file storage modules **_File->Add Modules->Utilities->..._**) to save data then press the run button (red button) and data will process. PAMGuard can handle huge datasets so runing might take hours or even days. Progress is shown on the bottom of the screen.
+Make sure to add the database and binary file storage modules **_File->Add Modules->Utilities->..._**) to save data then press the run button (red button) and data will process. PAMGuard can handle huge datasets so running might take hours or even days. Progress is shown on the bottom of the screen.
+
+Once the data has run, open PAMGuard viewer mode. Select the database you used to process the data along and thebianry file storage path and PAMGuard will open, showing an overview of the dataset in a new _Data map_ tab. Right click anywhere on the data map and select "Center data here" - PAMGuard will load the data for the selected period which can be explored using whichever displays have been added to the data model.
## Features
### Hardware integration
@@ -49,20 +51,22 @@ Almsot all detection data can be visualised on a map. PAMGaurd also supports plo
An important aspect of PAMGuard is the ability for users to explore porcessed data. PAMGuard allows users to visualise data at multiple different times scales, from inspecting individual waveforms microseconds long to datagrams showing detector output or soundscape metrics over days, weeks or even years.
### Advanced manual annotation
-The displays within PAMGuard support a variety of manual annottion tools.
+The displays within PAMGuard support a variety of manual annotation tools. Users can add data to annotations in multiple ways, from simple text annotations to complex forms created by users.
### Deep learning integration
-PAMGuard allows users to run their own deep learning models using the deep learning module. AI can therfore be integrated into PAMGuard workflows, allowing for much more efficient analysis of data.
+PAMGuard allows users to run their own deep learning models using the deep learning module. AI can therfore be integrated into PAMGuard workflows, allowing for more efficient analysis of data.
### Metadata standard and Tethys compatibility
-PAMGuard Integrates with Tethys
+PAMGuard Integrates with Tethys database. Users can export processed PAMGuard data to a Tethys database seamlessly; this ifeature is great for large scale projects or organisatiosn with long term datasets.
## Feature roadmap
There's lots of features we would like to add to PAMGuard. If you want to add a feature you can either code it up yourself in Java and submit a pull request or get in touch with us to discuss how to it might be integrated. Some smaller features might be in our roadmap anyway but larger features usually require funding. Some features we are thinking about (but do not necassarily have time for yet) are;
* Support for decidecade noise bands (base 10 filter bank) in noise band monitor to meet Euopean standards
-* Capabaility to export data directly from PAMGaurd e.g. as MAT files.
-* Automated test suite to make releases more stable. Note that unit and integration tests are also being slowly incorporated.
+* Capabaility to export data directly from PAMGaurd e.g. as MAT files (in progress).
+* Automated test suite to make releases more stable. Note that unit and integration tests are also being slowly incorporated.
+* Support for ARM based computers (in progress).
+* A graphical user interface and Python library for training PAMGuard compatible deep learning models.
## Development
This is the main code repository for the PAMGuard software and was created on 7 January 2022 from a [sourceforge SVN repository](https://sourceforge.net/p/pamguard/svn/HEAD/tree/) revision r6278.
diff --git a/src/Acquisition/FileInputSystem.java b/src/Acquisition/FileInputSystem.java
index 62ffa038..6fd76f3e 100644
--- a/src/Acquisition/FileInputSystem.java
+++ b/src/Acquisition/FileInputSystem.java
@@ -15,6 +15,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
@@ -594,7 +595,7 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
System.out.println("The current file was null");
return false;
}
-// System.out.printf("*********************************** Opening file %s\n", currentFile.getName());
+ System.out.printf("*********************************** Opening file %s\n", currentFile.getName());
try {
@@ -602,7 +603,7 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
audioStream.close();
}
- System.out.println("FileInputSystem - prepareInputFile");
+// System.out.println("FileInputSystem - prepareInputFile");
audioStream = PamAudioFileManager.getInstance().getAudioInputStream(currentFile);
@@ -638,6 +639,9 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
fileInputParameters.bitDepth = audioFormat.getSampleSizeInBits();
loadByteConverter(audioFormat);
+
+// System.out.println("FileInputSystem - prepareInputFile done");
+
} catch (UnsupportedAudioFileException ex) {
ex.printStackTrace();
@@ -1017,9 +1021,11 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
newDataUnit.setRawData(doubleData[ichan]);
- if (1000*(readFileSamples/sampleRate)>=fileInputParameters.skipStartFileTime) {
- newDataUnits.addNewData(newDataUnit);
+ if (1000*(readFileSamples/sampleRate)
* PamController contains a list of PamControlledUnit's each of which
* has it's own process,
- simpleMapRef.gpsTextPanel.setPixelsPerMetre(getPixelsPerMetre()); input and output data and display (Tab Panel,
- * Menus, etc.)
+ * simpleMapRef.gpsTextPanel.setPixelsPerMetre(getPixelsPerMetre());
+ * input and output data and display (Tab Panel, Menus, etc.)
* @see PamController.PamControlledUnit
* @see PamView.PamTabPanel
*
@@ -129,7 +129,7 @@ public class PamController implements PamControllerInterface, PamSettings {
public static final int PAM_COMPLETE = 6;
public static final int PAM_MAPMAKING = 7;
public static final int PAM_OFFLINETASK = 8;
-
+
public static final int BUTTON_START = 1;
public static final int BUTTON_STOP = 2;
private volatile int lastStartStopButton = 0;
@@ -145,20 +145,21 @@ public class PamController implements PamControllerInterface, PamSettings {
public static final int RUN_NETWORKRECEIVER = 5;
private int runMode = RUN_NORMAL;
-
- // flag used in main() to indicate that processing should start immediately.
+
+ // flag used in main() to indicate that processing should start immediately.
public static final String AUTOSTART = "-autostart";
- // flag used in main() to indicate that pamguard should exit as soon as processing ends.
+ // flag used in main() to indicate that pamguard should exit as soon as
+ // processing ends.
public static final String AUTOEXIT = "-autoexit";
/**
- * Never changed. Needed to identify settings for list of modules in prfx files.
+ * Never changed. Needed to identify settings for list of modules in prfx files.
*/
public static final String unitName = "Pamguard Controller";
public static final String unitType = "PamController";
/**
- * The pam model.
+ * The pam model.
*/
private PamModel pamModelInterface;
@@ -169,14 +170,14 @@ public class PamController implements PamControllerInterface, PamSettings {
private volatile int pamStatus = PAM_IDLE;
/**
- * PamGuard view params.
+ * PamGuard view params.
*/
public PamViewParameters pamViewParameters = new PamViewParameters();
- // ViewerStatusBar viewerStatusBar;
+ // ViewerStatusBar viewerStatusBar;
/*
- * Swing GUI manager
+ * Swing GUI manager
*/
private PAMControllerGUI guiFrameManager;
@@ -186,17 +187,16 @@ public class PamController implements PamControllerInterface, PamSettings {
private boolean initializationComplete = false;
/**
- * The java version being run. e.g. Java 8u111 will be 8.111;
+ * The java version being run. e.g. Java 8u111 will be 8.111;
*/
- public static double JAVA_VERSION = getVersion ();
-
+ public static double JAVA_VERSION = getVersion();
// PAMGUARD CREATION IS LAUNCHED HERE !!!
- // private static PamControllerInterface anyController = new PamController();
+ // private static PamControllerInterface anyController = new PamController();
private static PamController uniqueController;
private Timer diagnosticTimer;
-
+
private boolean debugDumpBufferAtRestart = false;
private NetworkController networkController;
@@ -207,67 +207,65 @@ public class PamController implements PamControllerInterface, PamSettings {
private Timer garbageTimer;
/**
- * The UID manager.
+ * The UID manager.
*/
private UIDManager uidManager;
/**
- * A global time manager to manage corrections to the PC clock
- * from various sources.
+ * A global time manager to manage corrections to the PC clock from various
+ * sources.
*/
private GlobalTimeManager globalTimeManager;
/**
- * A global medium manager which handles the type of medium sound is propogating through.
+ * A global medium manager which handles the type of medium sound is propogating
+ * through.
*/
- private GlobalMediumManager globalMediumManager;
+ private GlobalMediumManager globalMediumManager;
/**
- * A reference to the module currently being loaded. Used by the PamExceptionHandler to
- * monitor runtime errors that occur during load
+ * A reference to the module currently being loaded. Used by the
+ * PamExceptionHandler to monitor runtime errors that occur during load
*/
- private static PamControlledUnit unitBeingLoaded=null;
-
+ private static PamControlledUnit unitBeingLoaded = null;
/**
- * Folder where Pamguard is installed and running out of. This string
- * includes the file separator at the end, or is null if there was a
- * problem trying to determine the installation folder
+ * Folder where Pamguard is installed and running out of. This string includes
+ * the file separator at the end, or is null if there was a problem trying to
+ * determine the installation folder
*/
- private String installFolder=null;
+ private String installFolder = null;
private boolean haveGlobalTimeUpdate;
private WatchdogComms watchdogComms;
-
+
private PamWarning statusWarning = new PamWarning("PAMGuard control", "Status", 0);
-
- /**
+
+ /**
* A separate thread that checks all ThreadedObservers to see if they still have
* data in their buffers
*/
private Thread statusCheckThread;
private WaitDetectorThread detectorEndThread;
private boolean firstDataLoadComplete;
- // keep a track of the total number of times PAMGuard is started for debug purposes.
+ // keep a track of the total number of times PAMGuard is started for debug
+ // purposes.
private int nStarts;
private RestartRunnable restartRunnable;
-
private PamController(int runMode, Object object) {
uniqueController = this;
-
+
pamConfiguration = new PamConfiguration();
this.runMode = runMode;
if (runMode == PamController.RUN_PAMVIEW) {
uidManager = new UIDViewerManager(this);
- }
- else {
+ } else {
uidManager = new UIDOnlineManager(this);
}
-
sayMemory();
globalTimeManager = new GlobalTimeManager(this);
@@ -285,11 +283,12 @@ public class PamController implements PamControllerInterface, PamSettings {
}
guiFrameManager = PamGUIManager.createGUI(this, object);
- guiFrameManager.init(); //perform any start up processes for the GUI.
+ guiFrameManager.init(); // perform any start up processes for the GUI.
// figure out the installation folder
try {
- File theURL = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
+ File theURL = new File(
+ this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
installFolder = theURL.getParentFile().getPath() + File.separator;
} catch (URISyntaxException e) {
System.out.println("Error finding installation folder of jar file: " + e.getMessage());
@@ -300,13 +299,12 @@ public class PamController implements PamControllerInterface, PamSettings {
setupPamguard();
setupGarbageCollector();
-
// if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
// }
-
- // diagnosticTimer = new Timer(1000, new DiagnosticTimer());
- // diagnosticTimer.start();
+
+ // diagnosticTimer = new Timer(1000, new DiagnosticTimer());
+ // diagnosticTimer.start();
}
class DiagnosticTimer implements ActionListener {
@@ -318,51 +316,51 @@ public class PamController implements PamControllerInterface, PamSettings {
private void sayMemory() {
Runtime r = Runtime.getRuntime();
- System.out.println(String.format("System memory at %s Max %d, Free %d",
- PamCalendar.formatDateTime(System.currentTimeMillis()),
- r.maxMemory(), r.freeMemory()));
+ System.out.println(String.format("System memory at %s Max %d, Free %d",
+ PamCalendar.formatDateTime(System.currentTimeMillis()), r.maxMemory(), r.freeMemory()));
}
/**
- * Create an instance of the PAMController.
+ * Create an instance of the PAMController.
+ *
* @param runMode - the run mode
*/
public static void create(int runMode) {
if (uniqueController == null) {
PamController pamcontroller = new PamController(runMode, null);
/*
- * I don't see any reason not have have this running with the GUI.
- * It launches in a new thread, so it should be fine to have
- * additional commands afterwards.
+ * I don't see any reason not have have this running with the GUI. It launches
+ * in a new thread, so it should be fine to have additional commands afterwards.
*/
TerminalController tc = new TerminalController(pamcontroller);
tc.getTerminalCommands();
}
-
+
SwingUtilities.invokeLater(new Runnable() {
-
+
@Override
public void run() {
uniqueController.creationComplete();
}
});
}
-
+
/**
- * Not to sound God like, but this will be called on the AWT dispatch thread shortly
- * after all modules are created, PAMGuard should be fully setup and all modules will
- * have recieved INITIALISATION_COMPLETE and should be good to run
+ * Not to sound God like, but this will be called on the AWT dispatch thread
+ * shortly after all modules are created, PAMGuard should be fully setup and all
+ * modules will have recieved INITIALISATION_COMPLETE and should be good to run
*/
private void creationComplete() {
if (GlobalArguments.getParam(PamController.AUTOSTART) != null) {
startLater(); // may as well give AWT time to loop it's queue once more
}
}
-
+
/**
- * Create an instance of the PAMcController.
+ * Create an instance of the PAMcController.
+ *
* @param runMode - the run mode
- * @param object - extra information. Can be null.
+ * @param object - extra information. Can be null.
*/
public static void create(int runMode, Object object) {
if (uniqueController == null) {
@@ -371,21 +369,20 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Setup the PAMController.
+ * Setup the PAMController.
*/
public void setupPamguard() {
/**
- * Set Locale to English so that formated writes to text fields
- * in dialogs use . and not , for the decimal.
+ * Set Locale to English so that formated writes to text fields in dialogs use .
+ * and not , for the decimal.
*/
Locale.setDefault(Locale.ENGLISH);
/*
- * 15/8/07 Changed creation order of model and view.
- * Need to be able to create a database pretty early on
- * (in the Model) in order to read back settings that
- * the GUI may require.
+ * 15/8/07 Changed creation order of model and view. Need to be able to create a
+ * database pretty early on (in the Model) in order to read back settings that
+ * the GUI may require.
*
*/
// create the model
@@ -393,39 +390,42 @@ public class PamController implements PamControllerInterface, PamSettings {
pamModelInterface.createPamModel();
/*
- * 9 February 2009
- * Trying to sort out settings file loading.
- * Was previously done when the first modules registered itself
- * with the settings manager. Gets very confusing. Will be much easier
- * to load up the settings first, depending on the type of module
- * and then have them ready when the modules start asking for them.
+ * 9 February 2009 Trying to sort out settings file loading. Was previously done
+ * when the first modules registered itself with the settings manager. Gets very
+ * confusing. Will be much easier to load up the settings first, depending on
+ * the type of module and then have them ready when the modules start asking for
+ * them.
*/
int loadAns = PamSettingManager.getInstance().loadPAMSettings(runMode);
-
- System.out.println("Pamcontroller: loadPAMSettings: " + loadAns);
+
+ System.out.println("Pamcontroller: loadPAMSettings: " + loadAns);
if (loadAns == PamSettingManager.LOAD_SETTINGS_NEW) {
- // if (runMode == RUN_PAMVIEW) {
- // // no model, no gui, so PAMGAURD will simply exit.
- // String str = String.format("PAMGUARD cannot run in %s mode without a valid database\nPAMGUARD will exit.",
- // getRunModeName());
- // str = "You have opened a database in viewer mode that contains no settings\n" +
- // "Either load settings from the binary store, import a psf settings file or create modules by hand.\n" +
- // "Press OK to continue or Cancel to exit the viewer";
+ // if (runMode == RUN_PAMVIEW) {
+ // // no model, no gui, so PAMGAURD will simply exit.
+ // String str = String.format("PAMGUARD cannot run in %s mode without a valid
+ // database\nPAMGUARD will exit.",
+ // getRunModeName());
+ // str = "You have opened a database in viewer mode that contains no settings\n"
+ // +
+ // "Either load settings from the binary store, import a psf settings file or
+ // create modules by hand.\n" +
+ // "Press OK to continue or Cancel to exit the viewer";
//
- // int ans = JOptionPane.showConfirmDialog(null, str, "PAMGuard viewer", JOptionPane.OK_CANCEL_OPTION);
- // if (ans == JOptionPane.CANCEL_OPTION) {
- // System.exit(0);
- // }
- // }
- // else if (loadAns == ){
- // // normal settings will probably return an error, but it's OK still !
- //// System.exit(0);
- // }
- // return;
- }
- else if (loadAns == PamSettingManager.LOAD_SETTINGS_CANCEL) {
- JOptionPane.showMessageDialog(null, "No settings loaded. PAMGuard will exit", "PAMGuard", JOptionPane.INFORMATION_MESSAGE);
+ // int ans = JOptionPane.showConfirmDialog(null, str, "PAMGuard viewer",
+ // JOptionPane.OK_CANCEL_OPTION);
+ // if (ans == JOptionPane.CANCEL_OPTION) {
+ // System.exit(0);
+ // }
+ // }
+ // else if (loadAns == ){
+ // // normal settings will probably return an error, but it's OK still !
+ //// System.exit(0);
+ // }
+ // return;
+ } else if (loadAns == PamSettingManager.LOAD_SETTINGS_CANCEL) {
+ JOptionPane.showMessageDialog(null, "No settings loaded. PAMGuard will exit", "PAMGuard",
+ JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
@@ -434,44 +434,53 @@ public class PamController implements PamControllerInterface, PamSettings {
}
// get the general settings out of the file immediately.
- // PamSettingManager.getInstance().loadSettingsFileData();
+ // PamSettingManager.getInstance().loadSettingsFileData();
/*
- * prepare to add a database to the model.
- * this will then re-read it's settings from the
- * settings file - which we dont' want yet !!!!!
- * But now we have the database, it should be possible to
- * alter the code that reads in all settings from a selected
- * file and alter it so it gets them from the db instead.
- * Then remove this database module immediately
- * and let Pamguard create a new one based on the settings !
+ * prepare to add a database to the model. this will then re-read it's settings
+ * from the settings file - which we dont' want yet !!!!! But now we have the
+ * database, it should be possible to alter the code that reads in all settings
+ * from a selected file and alter it so it gets them from the db instead. Then
+ * remove this database module immediately and let Pamguard create a new one
+ * based on the settings !
*/
- // PamModuleInfo mi = PamModuleInfo.findModuleInfo("generalDatabase.DBControl");
- // PamControlledUnitSettings dbSettings = PamSettingManager.getInstance().findGeneralSettings(DBControl.getDbUnitType());
- // if (mi != null) {
- // addModule(mi, "Temporary Database");
- // }
+ // PamModuleInfo mi = PamModuleInfo.findModuleInfo("generalDatabase.DBControl");
+ // PamControlledUnitSettings dbSettings =
+ // PamSettingManager.getInstance().findGeneralSettings(DBControl.getDbUnitType());
+ // if (mi != null) {
+ // addModule(mi, "Temporary Database");
+ // }
- // Add a note to the output console for the user to ignore the SLF4J warning (see http://www.slf4j.org/codes.html#StaticLoggerBinder
- // for details). I spent a few hours trying to get rid of this warning, but without any luck. If you do a google search
- // there are a lot of forum suggestions on how to fix, but none seemed to work for me. Added both slf4j-nop and
- // slf4j-simple to dependency list, neither made a difference. Changed order of dependencies, ran purges and updates,
- // added slf4j-api explicitly, made sure I don't have duplicate bindings, but nothing helped.
- //
+ // Add a note to the output console for the user to ignore the SLF4J warning
+ // (see http://www.slf4j.org/codes.html#StaticLoggerBinder
+ // for details). I spent a few hours trying to get rid of this warning, but
+ // without any luck. If you do a google search
+ // there are a lot of forum suggestions on how to fix, but none seemed to work
+ // for me. Added both slf4j-nop and
+ // slf4j-simple to dependency list, neither made a difference. Changed order of
+ // dependencies, ran purges and updates,
+ // added slf4j-api explicitly, made sure I don't have duplicate bindings, but
+ // nothing helped.
+ //
// Error occurs when PamDataBlock.sortTypeInformation() calls
- // superDetectionClass = GenericTypeResolver.resolveReturnType(method, unitClass); (currently line 397). I don't want
- // to add the note there because that gets called every time a PamDataBlock is created. So I add the note here, which
+ // superDetectionClass = GenericTypeResolver.resolveReturnType(method,
+ // unitClass); (currently line 397). I don't want
+ // to add the note there because that gets called every time a PamDataBlock is
+ // created. So I add the note here, which
// is just before the error occurs
//
- // Oddly enough, this warning DOES NOT occur when running the non-Maven version (Java12 branch). The dependencies in the
- // classpath are the same as the ones here in Maven, so I don't know what to say.
+ // Oddly enough, this warning DOES NOT occur when running the non-Maven version
+ // (Java12 branch). The dependencies in the
+ // classpath are the same as the ones here in Maven, so I don't know what to
+ // say.
System.out.println("");
- System.out.println("Note - ignore the following SLF4J warn/error messages, they are not applicable to this application");
+ System.out.println(
+ "Note - ignore the following SLF4J warn/error messages, they are not applicable to this application");
ArrayManager.getArrayManager(); // create the array manager so that it get's it's settings
MetaDataContol.getMetaDataControl();
/**
- * Check for archived files and unpack automatically.
+ * Check for archived files and unpack automatically.
*/
if (runMode == RUN_PAMVIEW && SMRUEnable.isEnable()) {
ZipUnpacker zipUnpacker = new ZipUnpacker(this);
@@ -499,34 +508,34 @@ public class PamController implements PamControllerInterface, PamSettings {
// }
// }
-
/*
* We are running as a remote application, start process straight away!
*/
if (PamSettingManager.RUN_REMOTE == false) {
- addView(guiFrameManager.initPrimaryView(this, pamModelInterface));
+ addView(guiFrameManager.initPrimaryView(this, pamModelInterface));
}
/**
- * Calling this will cause a callback to this.restoreSettings which
- * includes a list of modules which will then get created, and in turn
- * load all of their own settings from the settings manager.
+ * Calling this will cause a callback to this.restoreSettings which includes a
+ * list of modules which will then get created, and in turn load all of their
+ * own settings from the settings manager.
*/
PamSettingManager.getInstance().registerSettings(this);
-
+
/**
- * For offline batch processing a few funnies happen here. We'll be open
- * in viewer mode, but it's likely a psf will have been passed as an input argument.
- * We will therefore have to extract all the modules from that psfx as well and either
- * add them as new modules, or get their settings and use those to update existing settings
- * That should probably be done here before the final calls to setup processes, etc.
+ * For offline batch processing a few funnies happen here. We'll be open in
+ * viewer mode, but it's likely a psf will have been passed as an input
+ * argument. We will therefore have to extract all the modules from that psfx as
+ * well and either add them as new modules, or get their settings and use those
+ * to update existing settings That should probably be done here before the
+ * final calls to setup processes, etc.
*/
if (getRunMode() == RUN_PAMVIEW && PamSettingManager.remote_psf != null) {
loadOtherSettings(PamSettingManager.remote_psf);
}
/*
- * Get any other required modules for this run mode.
+ * Get any other required modules for this run mode.
*/
pamModelInterface.startModel();
@@ -537,107 +546,110 @@ public class PamController implements PamControllerInterface, PamSettings {
*/
if (getRunMode() == RUN_NOTHING) {
- }else if (PamSettingManager.RUN_REMOTE == true) {
+ } else if (PamSettingManager.RUN_REMOTE == true) {
// Initialisation is complete.
initializationComplete = true;
notifyModelChanged(PamControllerInterface.INITIALIZATION_COMPLETE);
System.out.println("Starting Pamguard in REMOTE execution mode.");
pamStart();
- }else{
+ } else {
- // if (getRunMode() == RUN_PAMVIEW) {
- // createViewerStatusBar();
- // }
+ // if (getRunMode() == RUN_PAMVIEW) {
+ // createViewerStatusBar();
+ // }
- // call before initialisation complete, so that processes can re-do.
+ // call before initialisation complete, so that processes can re-do.
createAnnotations();
organiseGUIFrames();
- //sort the frame titles (Swing convenience)
- if (PamGUIManager.isSwing()) sortFrameTitles();
+ // sort the frame titles (Swing convenience)
+ if (PamGUIManager.isSwing())
+ sortFrameTitles();
initializationComplete = true;
notifyModelChanged(PamControllerInterface.INITIALIZATION_COMPLETE);
/**
- * Trigger loading of relationships between markers and mark observers.
- * No need to do anything more than call the constructor and
- * everything else will happen...
+ * Trigger loading of relationships between markers and mark observers. No need
+ * to do anything more than call the constructor and everything else will
+ * happen...
*/
- MarkRelationships.getInstance();
+ MarkRelationships.getInstance();
}
if (getRunMode() == RUN_PAMVIEW) {
/**
- * Tell any modules implementing OfflineDataSource to check
- * their maps.
+ * Tell any modules implementing OfflineDataSource to check their maps.
*/
AWTScheduler.getInstance().scheduleTask(new DataInitialised());
- // PamControlledUnit pcu;
- // OfflineDataSource offlineDataSource;
- // for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
- // pcu = pamControlledUnits.get(iU);
- // if (OfflineDataSource.class.isAssignableFrom(pcu.getClass())) {
- // offlineDataSource = (OfflineDataSource) pcu;
- // offlineDataSource.createOfflineDataMap(null);
- // }
- // }
+ // PamControlledUnit pcu;
+ // OfflineDataSource offlineDataSource;
+ // for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
+ // pcu = pamControlledUnits.get(iU);
+ // if (OfflineDataSource.class.isAssignableFrom(pcu.getClass())) {
+ // offlineDataSource = (OfflineDataSource) pcu;
+ // offlineDataSource.createOfflineDataMap(null);
+ // }
+ // }
- // PamSettingManager.getInstance().registerSettings(new ViewTimesSettings());
- // getNewViewTimes(null);
+ // PamSettingManager.getInstance().registerSettings(new ViewTimesSettings());
+ // getNewViewTimes(null);
}
uidManager.runStartupChecks();
-
+
clearSelectorsAndSymbols();
-
/**
- * Debug code for starting PG as soon as it's initialised.
+ * Debug code for starting PG as soon as it's initialised.
*/
- // SwingUtilities.invokeLater(new Runnable() {
- // @Override
- // public void run() {
- // pamStart();
- // }
- // });
+ // SwingUtilities.invokeLater(new Runnable() {
+ // @Override
+ // public void run() {
+ // pamStart();
+ // }
+ // });
}
-
/**
- * Clear all data selectors and symbol managers. Required since some of these will have loaded as various modules were created,
- * but may also require additional data selectors and symbol managers from super detections which were not availble.
- * Deleting the lot, will cause them to be recreated as soon as they are next needed.
- * Should probably also call these on any call to addModule as well ?
+ * Clear all data selectors and symbol managers. Required since some of these
+ * will have loaded as various modules were created, but may also require
+ * additional data selectors and symbol managers from super detections which
+ * were not availble. Deleting the lot, will cause them to be recreated as soon
+ * as they are next needed. Should probably also call these on any call to
+ * addModule as well ?
*/
- private void clearSelectorsAndSymbols() {
+ private void clearSelectorsAndSymbols() {
DataSelectorCreator.globalClear();
PamSymbolManager.globalClear();
-
+
}
/**
- * This gets called after other data initialisation tasks (such as data mapping).
+ * This gets called after other data initialisation tasks (such as data
+ * mapping).
+ *
* @author dg50
*
*/
class DataInitialised implements Runnable {
@Override
public void run() {
- notifyModelChanged(PamControllerInterface.INITIALIZE_LOADDATA);
- // tell all scrollers to reload their data.
- // loadViewerData();
+ notifyModelChanged(PamControllerInterface.INITIALIZE_LOADDATA);
+ // tell all scrollers to reload their data.
+ // loadViewerData();
}
}
-
/**
* Called when the number of Networked remote stations changes so that the
- * receiver can make a decision as to what to do in terms of
- * preparing detectors, opening files, etc.
- * @param timeMilliseconds
- * @param nPrepared number of remote stations currently prepared (called just before start)
- * @param nStarted number of remote stations currently started
- * @param nStopped number of remote stations currently stopped
+ * receiver can make a decision as to what to do in terms of preparing
+ * detectors, opening files, etc.
+ *
+ * @param timeMilliseconds
+ * @param nPrepared number of remote stations currently prepared (called
+ * just before start)
+ * @param nStarted number of remote stations currently started
+ * @param nStopped number of remote stations currently stopped
*/
public void netReceiveStatus(long timeMilliseconds, int nPrepared, int nStarted, int nStopped) {
if (this.nNetStarted == 0 && nStarted >= 1) {
@@ -653,9 +665,10 @@ public class PamController implements PamControllerInterface, PamSettings {
this.nNetStarted = nStarted;
this.nNetStopped = nStopped;
}
+
/**
- * Loop through all controllers and processes and datablocks and set up all
- * of their annotations.
+ * Loop through all controllers and processes and datablocks and set up all of
+ * their annotations.
*/
private void createAnnotations() {
PamControlledUnit pcu;
@@ -672,32 +685,31 @@ public class PamController implements PamControllerInterface, PamSettings {
if (pp.getSourceDataBlock() == null) {
pp.createAnnotations(true);
}
- // nPdb = pp.getNumOutputDataBlocks();
- // for (int iPdb = 0; iPdb < nPdb; iPdb++) {
- // pdb = pp.getOutputDataBlock(iPdb);
- // pdb.createAnnotations(pp.getSourceDataBlock(), pp);
- // }
+ // nPdb = pp.getNumOutputDataBlocks();
+ // for (int iPdb = 0; iPdb < nPdb; iPdb++) {
+ // pdb = pp.getOutputDataBlock(iPdb);
+ // pdb.createAnnotations(pp.getSourceDataBlock(), pp);
+ // }
}
}
}
/**
- * Organise the GUI frames on start up or after a module was added
- * or after the frames menus have changed.
+ * Organise the GUI frames on start up or after a module was added or after the
+ * frames menus have changed.
*/
private void organiseGUIFrames() {
}
-
- // private void createViewerStatusBar() {
- //
- // viewerStatusBar = new ViewerStatusBar(this);
- // PamStatusBar.getStatusBar().getToolBar().setLayout(new BorderLayout());
- // PamStatusBar.getStatusBar().getToolBar().add(BorderLayout.CENTER,
- // viewerStatusBar.getStatusBarComponent());
- // }
+ // private void createViewerStatusBar() {
+ //
+ // viewerStatusBar = new ViewerStatusBar(this);
+ // PamStatusBar.getStatusBar().getToolBar().setLayout(new BorderLayout());
+ // PamStatusBar.getStatusBar().getToolBar().add(BorderLayout.CENTER,
+ // viewerStatusBar.getStatusBarComponent());
+ // }
void setupProcesses() {
// for (int i = 0; i < pamControlledUnits.size(); i++) {
@@ -707,28 +719,26 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Can PAMGUARD shut down. This question is asked in turn to
- * every module. Each module should attempt to make sure it can
- * answer true, e.g. by closing files, but if any module
- * returns false, then canClose() will return false;
- * @return whether it's possible to close PAMGUARD
- * without corrupting or losing data.
+ * Can PAMGUARD shut down. This question is asked in turn to every module. Each
+ * module should attempt to make sure it can answer true, e.g. by closing files,
+ * but if any module returns false, then canClose() will return false;
+ *
+ * @return whether it's possible to close PAMGUARD without corrupting or losing
+ * data.
*/
public boolean canClose() {
return pamConfiguration.canClose();
}
-
/**
- * Called after canClose has returned true to finally tell
- * all modules that PAMGUARD is definitely closing down.so they
- * can free any resources, etc.
+ * Called after canClose has returned true to finally tell all modules that
+ * PAMGUARD is definitely closing down.so they can free any resources, etc.
*/
@Override
public void pamClose() {
getUidManager().runShutDownOps();
-
+
pamConfiguration.pamClose();
}
@@ -736,24 +746,25 @@ public class PamController implements PamControllerInterface, PamSettings {
* Shut down Pamguard
*/
public void shutDownPamguard() {
- // force close the javaFX thread (because it won't close by itself - see Platform.setImplicitExit(false) in constructor
+ // force close the javaFX thread (because it won't close by itself - see
+ // Platform.setImplicitExit(false) in constructor
Platform.exit();
-
+
// terminate the JVM
System.exit(getPamStatus());
}
/**
- * Go through all data blocks in all modules and tell them to save.
- * This has been built into PamProcess and PamDataBlock since we want
- * it to be easy to override this for specific modules / processes / data blocks.
+ * Go through all data blocks in all modules and tell them to save. This has
+ * been built into PamProcess and PamDataBlock since we want it to be easy to
+ * override this for specific modules / processes / data blocks.
*/
public void saveViewerData() {
ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits();
for (int i = 0; i < pamControlledUnits.size(); i++) {
pamControlledUnits.get(i).saveViewerData();
}
- // Commit the database.
+ // Commit the database.
DBControlUnit dbControl = DBControlUnit.findDatabaseControl();
if (dbControl != null) {
dbControl.commitChanges();
@@ -762,7 +773,7 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public void addControlledUnit(PamControlledUnit controlledUnit) {
-
+
pamConfiguration.addControlledUnit(controlledUnit);
guiFrameManager.addControlledUnit(controlledUnit);
@@ -773,78 +784,87 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public PamControlledUnit addModule(Frame parentFrame, PamModuleInfo moduleInfo) {
// first of all we need to get a name for the new module
- // String question = "Enter a name for the new " + moduleInfo.getDescription();
- // String newName = JOptionPane.showInputDialog(null, question,
- // "New " + moduleInfo.getDescription(), JOptionPane.OK_CANCEL_OPTION);
- //String newName = NewModuleDialog.showDialog(parentFrame ,moduleInfo,null);
- String newName = guiFrameManager.getModuleName(parentFrame, moduleInfo);
+ // String question = "Enter a name for the new " + moduleInfo.getDescription();
+ // String newName = JOptionPane.showInputDialog(null, question,
+ // "New " + moduleInfo.getDescription(), JOptionPane.OK_CANCEL_OPTION);
+ // String newName = NewModuleDialog.showDialog(parentFrame ,moduleInfo,null);
+ String newName = guiFrameManager.getModuleName(parentFrame, moduleInfo);
- if (newName == null) return null;
+ if (newName == null)
+ return null;
return addModule(moduleInfo, newName);
}
/**
- * Add a module to the controller.
+ * Add a module to the controller.
+ *
* @param moduleInfo - the module info i.e. the type of module to add
- * @param moduleName - the module name.
+ * @param moduleName - the module name.
* @return
*/
public PamControlledUnit addModule(PamModuleInfo moduleInfo, String moduleName) {
- // Comment this section out and replace with code below, to provide custom error handling with PamExceptionHandler
- // PamControlledUnit pcu = moduleInfo.create(moduleName);
- // if (pcu == null) return null;
- // addControlledUnit(pcu);
- // if (initializationComplete) {
- // pcu.setupControlledUnit();
- // }
- // return pcu;
+ // Comment this section out and replace with code below, to provide custom error
+ // handling with PamExceptionHandler
+ // PamControlledUnit pcu = moduleInfo.create(moduleName);
+ // if (pcu == null) return null;
+ // addControlledUnit(pcu);
+ // if (initializationComplete) {
+ // pcu.setupControlledUnit();
+ // }
+ // return pcu;
- // try to load the unit. If moduleInfo.create returns null, clear the name and exit. Otherwise, save
+ // try to load the unit. If moduleInfo.create returns null, clear the name and
+ // exit. Otherwise, save
// the name of the module being loaded
unitBeingLoaded = moduleInfo.create(moduleName);
if (unitBeingLoaded == null) {
return null;
}
- // try to add the unit to the list.
+ // try to add the unit to the list.
// Put this method call in a try/catch, in case the developer hasn't coded
- // the plugin properly. We need to catch Throwable, not Exception, in order
+ // the plugin properly. We need to catch Throwable, not Exception, in order
// to catch everything (e.g. if one of the abstract methods is missing, java
- // throws AbstractMethodError. This is an error, not an exception, so if
- // we want to catch it we need to catch Throwable. Same with a ClassDefNotFoundError,
+ // throws AbstractMethodError. This is an error, not an exception, so if
+ // we want to catch it we need to catch Throwable. Same with a
+ // ClassDefNotFoundError,
// in case the plugin is looking for a class in the Pamguard core that no longer
// exists).
// Also check if unitBeingLoaded=null afterwards because this would indicate
- // that the PamExceptionHandler caught a runtime error during the class instantiation and therefore
- // removed the module to prevent further errors. This could also happen due to incompatibilities between
+ // that the PamExceptionHandler caught a runtime error during the class
+ // instantiation and therefore
+ // removed the module to prevent further errors. This could also happen due to
+ // incompatibilities between
// the current version of Pamguard and older plugin modules.
try {
addControlledUnit(unitBeingLoaded);
} catch (Throwable e) {
e.printStackTrace();
String title = "Error adding module";
- String msg = "There is an error with the module " + moduleName + "." +
- "If this is a plug-in, the error may have been caused by an incompatibility between " +
- "it and this version of PAMGuard. Please check the developer's website " +
- "for help.
" +
- "If this is a core Pamguard module, please copy the error message text and email to" +
- "support@pamguard.org.
" +
- "This module will not be loaded.";
+ String msg = "There is an error with the module " + moduleName + ".
"
+ + "If this is a plug-in, the error may have been caused by an incompatibility between "
+ + "it and this version of PAMGuard. Please check the developer's website " + "for help.
"
+ + "If this is a core Pamguard module, please copy the error message text and email to"
+ + "support@pamguard.org.
" + "This module will not be loaded.";
String help = null;
int ans = WarnOnce.showWarning(title, msg, WarnOnce.WARNING_MESSAGE, help, e);
- System.err.println("Exception while loading " + moduleName);
+ System.err.println("Exception while loading " + moduleName);
this.removeControlledUnt(unitBeingLoaded);
- this.clearLoadedUnit();;
+ this.clearLoadedUnit();
+ ;
}
if (unitBeingLoaded == null) {
return null;
}
- // run the unit's setupProcess method. Again, check if nitBeingLoaded=null afterwards because this would indicate
- // that the PamExceptionHandler caught a runtime error during the class instantiation and therefore
- // removed the module to prevent further errors. This could happen due to incompatibilities between
+ // run the unit's setupProcess method. Again, check if nitBeingLoaded=null
+ // afterwards because this would indicate
+ // that the PamExceptionHandler caught a runtime error during the class
+ // instantiation and therefore
+ // removed the module to prevent further errors. This could happen due to
+ // incompatibilities between
// the current version of Pamguard and older plugin modules.
if (initializationComplete) {
unitBeingLoaded.setupControlledUnit();
@@ -855,33 +875,38 @@ public class PamController implements PamControllerInterface, PamSettings {
// move the controlled unit reference to a temp variable, so that we can
// clear the unitBeingLoaded variable and still pass a reference to the
- // new unit back to the calling function. In this way, we can always use
+ // new unit back to the calling function. In this way, we can always use
// the unitBeingLoaded variable as a de facto flag to know whether or not
// a module is currently being loaded
PamControlledUnit unitNowLoaded = unitBeingLoaded;
clearLoadedUnit();
- // guiFrameManager.notifyModelChanged(ADD_CONTROLLEDUNIT); //this should be handled above in addControlledUnit
+ // guiFrameManager.notifyModelChanged(ADD_CONTROLLEDUNIT); //this should be
+ // handled above in addControlledUnit
return unitNowLoaded;
}
- /* (non-Javadoc)
- * @see PamguardMVC.PamControllerInterface#RemoveControlledUnt(PamguardMVC.PamControlledUnit)
+ /*
+ * (non-Javadoc)
+ *
+ * @see PamguardMVC.PamControllerInterface#RemoveControlledUnt(PamguardMVC.
+ * PamControlledUnit)
*/
@Override
public void removeControlledUnt(PamControlledUnit controlledUnit) {
// The PamExceptionHandler will call this to remove a controlled unit that fails
- // during load. Depending when it failed, it may or may not have been instantiated
- // yet. So if the controlledUnit is still null, just exit
- //
- if (controlledUnit==null) {
+ // during load. Depending when it failed, it may or may not have been
+ // instantiated
+ // yet. So if the controlledUnit is still null, just exit
+ //
+ if (controlledUnit == null) {
return;
}
/**
- * NEVER delete the array manager.
+ * NEVER delete the array manager.
*/
if (controlledUnit.getClass() == ArrayManager.class) {
return;
@@ -893,17 +918,19 @@ public class PamController implements PamControllerInterface, PamSettings {
if (removed) {
notifyModelChanged(PamControllerInterface.REMOVE_CONTROLLEDUNIT);
}
- // getMainFrame().revalidate(); //handled inside the GUIFrameManager by notify model changed. The controller should have
- //as few direct GUI calls as possible.
+ // getMainFrame().revalidate(); //handled inside the GUIFrameManager by notify
+ // model changed. The controller should have
+ // as few direct GUI calls as possible.
}
-
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see PamController.PamControllerInterface#orderModules()
*/
@Override
public boolean orderModules(Frame parentFrame) {
- int[] newOrder = ModuleOrderDialog.showDialog(this, parentFrame);
+ int[] newOrder = ModuleOrderDialog.showDialog(this, parentFrame);
if (newOrder != null) {
// re-order the modules according the new list.
pamConfiguration.reOrderModules(newOrder);
@@ -934,8 +961,9 @@ public class PamController implements PamControllerInterface, PamSettings {
// }
/**
- * Swaps the positions of two modules in the main list of modules and
- * also swaps their tabs (if they have them).
+ * Swaps the positions of two modules in the main list of modules and also swaps
+ * their tabs (if they have them).
+ *
* @param m1 First PamControlledUnit to swap
* @param m2 Second PamControlledUnit to swap.
*/
@@ -944,8 +972,9 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Sets the position of a particular PamControlledUnit in the list.
- * Also sets the right tab position, to match that order.
+ * Sets the position of a particular PamControlledUnit in the list. Also sets
+ * the right tab position, to match that order.
+ *
* @param pcu
* @param position
* @return
@@ -967,17 +996,21 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Get a list of PamControlledUnit units of a given type
+ *
* @param unitType Controlled unit type
- * @return list of units.
+ * @return list of units.
*/
public ArrayList findControlledUnits(String unitType) {
return pamConfiguration.findControlledUnits(unitType);
}
+
/**
- * Get a list of PamControlledUnit units of a given type and name, allowing for nulls.
+ * Get a list of PamControlledUnit units of a given type and name, allowing for
+ * nulls.
+ *
* @param unitType Controlled unit type, can be null for all units of name
* @param unitName Controlled unit name, can be null for all units of type
- * @return list of units.
+ * @return list of units.
*/
public ArrayList findControlledUnits(String unitType, String unitName) {
return pamConfiguration.findControlledUnits(unitType, unitName);
@@ -990,37 +1023,45 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Find the first instance of a module with a given class type and name.
- * Name can be null in which case the first module with the correct class
- * will be returned
+ *
+ * Name can be null in which case the first module with the correct class will
+ * be returned
+ *
* @param unitClass Module class (sub class of PamControlledUnit)
- * @param unitName Module Name
- * @return Existing module with that class and name.
+ * @param unitName Module Name
+ * @return Existing module with that class and name.
*/
public PamControlledUnit findControlledUnit(Class unitClass, String unitName) {
return pamConfiguration.findControlledUnit(unitClass, unitName);
}
/**
- * Get an Array list of PamControlledUnits of a particular class (exact matches only).
+ * Get an Array list of PamControlledUnits of a particular class (exact matches
+ * only).
+ *
* @param unitClass PamControlledUnit class
- * @return List of current instances of this class.
+ * @return List of current instances of this class.
*/
public ArrayList findControlledUnits(Class unitClass) {
return pamConfiguration.findControlledUnits(unitClass);
}
-
+
/**
- * Get an Array list of PamControlledUnits of a particular class (exact matches only).
+ * Get an Array list of PamControlledUnits of a particular class (exact matches
+ * only).
+ *
* @param unitClass PamControlledUnit class
- * @return List of current instances of this class.
+ * @return List of current instances of this class.
*/
public ArrayList findControlledUnits(Class unitClass, boolean includeSubClasses) {
return pamConfiguration.findControlledUnits(unitClass, includeSubClasses);
}
/**
- * Check whether a controlled unit exists based on it's name.
- * @param the controlled unit name e.g. "my crazy click detector", not the default name.
+ * Check whether a controlled unit exists based on it's name.
+ *
+ * @param the controlled unit name e.g. "my crazy click detector", not the
+ * default name.
*/
public boolean isControlledUnit(String controlName) {
return pamConfiguration.isControlledUnit(controlName);
@@ -1049,17 +1090,15 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Restart PAMguard. Can be called when something is mildly wrong
- * such as a DAQ glitch, so that acquisition is stopped and
- * restarted.
+ * Restart PAMguard. Can be called when something is mildly wrong such as a DAQ
+ * glitch, so that acquisition is stopped and restarted.
*/
public void restartPamguard() {
pamStop();
-
+
/*
- * launch a restart thread, that won't do ANYTHING until
- * PAMGuard is really idle and buffers are cleared. Can only
- * have one of these at a time !
+ * launch a restart thread, that won't do ANYTHING until PAMGuard is really idle
+ * and buffers are cleared. Can only have one of these at a time !
*/
if (restartRunnable != null) {
System.out.println("Warning !!!! PAMGuard is already trying to restart!");
@@ -1069,7 +1108,7 @@ public class PamController implements PamControllerInterface, PamSettings {
Thread restartThread = new Thread(restartRunnable, "RestartPAMGuard Thread");
restartThread.run();
}
-
+
private class RestartRunnable implements Runnable {
@Override
@@ -1084,20 +1123,16 @@ public class PamController implements PamControllerInterface, PamSettings {
}
long t2 = System.currentTimeMillis();
restartRunnable = null;
- System.out.printf("PAMGuard safe to restart after %d milliseconds\n", t2-t1);
- startLater(false);
-
+ System.out.printf("PAMGuard safe to restart after %d milliseconds\n", t2 - t1);
+ startLater(false);
+
}
-
+
}
-
-
-
-
+
/**
- * calls pamStart using the SwingUtilities
- * invokeLater command to start PAMGAURD
- * later in the AWT event queue.
+ * calls pamStart using the SwingUtilities invokeLater command to start PAMGAURD
+ * later in the AWT event queue.
*/
public void startLater() {
// SwingUtilities.invokeLater(new StartLater(true));
@@ -1107,8 +1142,10 @@ public class PamController implements PamControllerInterface, PamSettings {
public void startLater(boolean saveSettings) {
SwingUtilities.invokeLater(new StartLater(saveSettings));
}
+
/**
- * Runnable for use with startLater.
+ * Runnable for use with startLater.
+ *
* @author Doug
*
*/
@@ -1127,8 +1164,8 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public void run() {
/*
- * do a final check that the stop button hasn't been pressed - can arrive a bit
- * late if the system was continually restarting.
+ * do a final check that the stop button hasn't been pressed - can arrive a bit
+ * late if the system was continually restarting.
*/
if (lastStartStopButton != BUTTON_STOP) {
pamStart(saveSettings);
@@ -1137,9 +1174,8 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * calls pamStop using the SwingUtilities
- * invokeLater command to stop PAMGAURD
- * later in the AWT event queue.
+ * calls pamStop using the SwingUtilities invokeLater command to stop PAMGAURD
+ * later in the AWT event queue.
*/
public void stopLater() {
SwingUtilities.invokeLater(new StopLater());
@@ -1147,6 +1183,7 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Runnable to use with the stopLater() command
+ *
* @author Doug Gillespie
*
*/
@@ -1158,8 +1195,9 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Called from the start button. A little book keeping
- * to distinguish this from automatic starts / restarts
+ * Called from the start button. A little book keeping to distinguish this from
+ * automatic starts / restarts
+ *
* @return true if started.
*/
@Override
@@ -1167,10 +1205,10 @@ public class PamController implements PamControllerInterface, PamSettings {
lastStartStopButton = BUTTON_START;
return pamStart();
}
-
+
/**
- * Called from the stop button. A little book keeping
- * to distinguish this from automatic starts / restarts
+ * Called from the stop button. A little book keeping to distinguish this from
+ * automatic starts / restarts
*/
@Override
public void manualStop() {
@@ -1180,45 +1218,49 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Start PAMGUARD. This function also gets called from the
- * GUI menu start button and from the Network control system.
- * As well as actually starting PAMGUARD it will write
- * settings to the database and to the binary data store.
+ * Start PAMGUARD. This function also gets called from the GUI menu start button
+ * and from the Network control system.
+ *
+ * As well as actually starting PAMGUARD it will write settings to the database
+ * and to the binary data store.
+ *
* @return true if all modules start successfully
*/
@Override
public boolean pamStart() {
- // Debug.println("PAMController: pamStart");
+ // Debug.println("PAMController: pamStart");
setManualStop(false);
return pamStart(true);
}
/**
- * Start PAMGuard with an option on saving settings.
+ * Start PAMGuard with an option on saving settings.
+ *
* @param saveSettings flag to save settings to database and binary store
* @return true if all modules start successfully
*/
public boolean pamStart(boolean saveSettings) {
- // Debug.println("PAMController: pamStart2");
+ // Debug.println("PAMController: pamStart2");
return pamStart(saveSettings, PamCalendar.getTimeInMillis());
}
/**
- * Starts PAMGuard, but with the option to save settings (to binary and to database)
- * and also to give a specific start time for the session. When data are being received over
- * the network, this may be in the past !
- * @param saveSettings flag to say whether or not settings should be saved.
- * @param startTime start time in millis
+ * Starts PAMGuard, but with the option to save settings (to binary and to
+ * database) and also to give a specific start time for the session. When data
+ * are being received over the network, this may be in the past !
+ *
+ * @param saveSettings flag to say whether or not settings should be saved.
+ * @param startTime start time in millis
* @return true if all modules start successfully
*/
public boolean pamStart(boolean saveSettings, long startTime) {
- // Debug.println("PAMController: pamStart3");
+ // Debug.println("PAMController: pamStart3");
- globalTimeManager.waitForGlobalTime(getMainFrame(),
+ globalTimeManager.waitForGlobalTime(getMainFrame(),
globalTimeManager.getGlobalTimeParameters().getStartupDelay());
manualStop = false;
-
+
ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits();
PamCalendar.setSessionStartTime(startTime);
@@ -1232,14 +1274,16 @@ public class PamController implements PamControllerInterface, PamSettings {
}
if (pamControlledUnits.get(iU).getPamProcess(iP).prepareProcessOK() == false) {
setPamStatus(PAM_IDLE);
- System.out.println("Can't start since unable to prepare process " +
- pamControlledUnits.get(iU).getPamProcess(iP).getProcessName());
+ System.out.println("Can't start since unable to prepare process "
+ + pamControlledUnits.get(iU).getPamProcess(iP).getProcessName());
prepErrors++;
- };
+ }
+ ;
}
- // long t2 = System.currentTimeMillis();
- // System.out.printf("***********************************Time taken to prepare %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(), t2-t1);
- // t1 = t2;
+ // long t2 = System.currentTimeMillis();
+ // System.out.printf("***********************************Time taken to prepare
+ // %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(), t2-t1);
+ // t1 = t2;
}
boolean prepError = (runMode == PamController.RUN_NORMAL && prepErrors > 0);
if (prepError) {
@@ -1248,15 +1292,16 @@ public class PamController implements PamControllerInterface, PamSettings {
/*
*
- * This needs to be called after prepareproces.
- * Now we do some extra checks on the stores to see if we want to overwite data,
- * carry on from where we left off, etc.
+ * This needs to be called after prepareproces. Now we do some extra checks on
+ * the stores to see if we want to overwite data, carry on from where we left
+ * off, etc.
*/
- if (saveSettings && getRunMode() == RUN_NORMAL) { // only true on a button press or network start.
+ if (saveSettings && getRunMode() == RUN_NORMAL) { // only true on a button press or network start.
ReprocessManager reprocessManager = new ReprocessManager();
boolean goonthen = reprocessManager.checkOutputDataStatus();
if (goonthen == false) {
- System.out.println("Data processing will not start since you've chosen not to overwrite existing output data");
+ System.out.println(
+ "Data processing will not start since you've chosen not to overwrite existing output data");
pamStop();
setPamStatus(PAM_IDLE);
return false;
@@ -1270,7 +1315,8 @@ public class PamController implements PamControllerInterface, PamSettings {
}
if (++nStarts > 1 && debugDumpBufferAtRestart) {
- // do this here - all processses should have reset buffers to start again by now.
+ // do this here - all processses should have reset buffers to start again by
+ // now.
String msg = String.format("Starting PAMGuard go %d", nStarts);
dumpBufferStatus(msg, false);
}
@@ -1280,28 +1326,32 @@ public class PamController implements PamControllerInterface, PamSettings {
t1 = System.currentTimeMillis();
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
pamControlledUnits.get(iU).pamToStart();
- // long t2 = System.currentTimeMillis();
- // System.out.printf("+++++++++++++++++++++++++++++++++++Time taken to call pamtoStart %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(), t2-t1);
- // t1 = t2;
+ // long t2 = System.currentTimeMillis();
+ // System.out.printf("+++++++++++++++++++++++++++++++++++Time taken to call
+ // pamtoStart %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(),
+ // t2-t1);
+ // t1 = t2;
}
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
- for (int iP = 0; iP < pamControlledUnits.get(iU)
- .getNumPamProcesses(); iP++) {
+ for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStart();
}
- // long t2 = System.currentTimeMillis();
- // System.out.printf("==================================Time taken to call pamStart %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(), t2-t1);
- // t1 = t2;
+ // long t2 = System.currentTimeMillis();
+ // System.out.printf("==================================Time taken to call
+ // pamStart %s was %d millis\n", pamControlledUnits.get(iU).getUnitName(),
+ // t2-t1);
+ // t1 = t2;
}
- // starting the DAQ may take a little while, so recheck and reset the
+ // starting the DAQ may take a little while, so recheck and reset the
// start time.
long startDelay = PamCalendar.getTimeInMillis() - PamCalendar.getSessionStartTime();
if (PamCalendar.isSoundFile() == false) {
PamCalendar.setSessionStartTime(PamCalendar.getTimeInMillis());
}
if (PamCalendar.isSoundFile() == false) {
- System.out.printf("PAMGUARD Startup took %d milliseconds at time %s\n", startDelay, PamCalendar.formatDateTime(PamCalendar.getSessionStartTime()));
+ System.out.printf("PAMGUARD Startup took %d milliseconds at time %s\n", startDelay,
+ PamCalendar.formatDateTime(PamCalendar.getSessionStartTime()));
}
guiFrameManager.pamStarted();
@@ -1309,19 +1359,20 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Stopping PAMGUARD. Harder than you might think !
- * First a pamStop() is sent to all processes, then once
- * that's done, a pamHasStopped is sent to all Controllers.
- * This is necessary when running in a multi-thread mode
- * since some processes may still be receiving data and may still
- * pass if on to other downstream processes, storage, etc.
+ * Stopping PAMGUARD. Harder than you might think ! First a pamStop() is sent to
+ * all processes, then once that's done, a pamHasStopped is sent to all
+ * Controllers.
+ *
+ * This is necessary when running in a multi-thread mode since some processes
+ * may still be receiving data and may still pass if on to other downstream
+ * processes, storage, etc.
*
*/
@Override
public void pamStop() {
setPamStatus(PAM_STOPPING);
-
+
// start the status check timer, so that we know when all the threads have
// actually stopped
// statusCheckThread = new Thread(new StatusTimer());
@@ -1330,28 +1381,28 @@ public class PamController implements PamControllerInterface, PamSettings {
// tell all controlled units to stop
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
- for (int iP = 0; iP < pamControlledUnits.get(iU)
- .getNumPamProcesses(); iP++) {
+ for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStop();
}
}
-
+
dumpBufferStatus("In stopping", false);
/*
- * now launch another thread to wait for everything to have stopped, but
- * leave this function so that AWT is released and graphics can update, the
- * wait thread will make a fresh call into AWT which will continue the stopping
- * of everything.
+ * now launch another thread to wait for everything to have stopped, but leave
+ * this function so that AWT is released and graphics can update, the wait
+ * thread will make a fresh call into AWT which will continue the stopping of
+ * everything.
*/
detectorEndThread = new WaitDetectorThread();
Thread t = new Thread(detectorEndThread);
t.start();
}
-
+
/**
- * Non AWT thread that sits and waits for detectors to actually finish their
- * processing, leaving AWT unblocked. Then calls a function back into AWT to
- * finish stopping, which will do stuff like closing binary files.
+ * Non AWT thread that sits and waits for detectors to actually finish their
+ * processing, leaving AWT unblocked. Then calls a function back into AWT to
+ * finish stopping, which will do stuff like closing binary files.
+ *
* @author dg50
*
*/
@@ -1363,7 +1414,8 @@ public class PamController implements PamControllerInterface, PamSettings {
while (checkRunStatus()) {
long t2 = System.currentTimeMillis();
if (t2 - t1 > 5000) {
- System.out.printf("Stopping, but stuck in loop for CheckRunStatus for %3.1fs\n", (double) (t2-t1)/1000.);
+ System.out.printf("Stopping, but stuck in loop for CheckRunStatus for %3.1fs\n",
+ (double) (t2 - t1) / 1000.);
dumpBufferStatus("Stopping stuck in loop", false);
break; // crap out anyway.
}
@@ -1373,66 +1425,67 @@ public class PamController implements PamControllerInterface, PamSettings {
e.printStackTrace();
}
}
- // arrive here when all detectors have ended.
+ // arrive here when all detectors have ended.
finishStopping();
}
-
+
}
-
+
/**
- * Look in every data block, particularly threaded ones, and dump
- * the buffer status. This will have to go via PamProcess so that
- * additional information can be added from any processes that
- * hold additional data in other internal buffers.
- * @param message Message to print prior to dumping buffers for debug.
- * @param sayEmpties dump info even if a buffer is empty (otherwise, only ones that have stuff still)
+ * Look in every data block, particularly threaded ones, and dump the buffer
+ * status. This will have to go via PamProcess so that additional information
+ * can be added from any processes that hold additional data in other internal
+ * buffers.
+ *
+ * @param message Message to print prior to dumping buffers for debug.
+ * @param sayEmpties dump info even if a buffer is empty (otherwise, only ones
+ * that have stuff still)
*/
public void dumpBufferStatus(String message, boolean sayEmpties) {
- if (debugDumpBufferAtRestart == false) return;
-
+ if (debugDumpBufferAtRestart == false)
+ return;
+
System.out.println("**** Dumping process buffer status: " + message);
ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits();
for (PamControlledUnit aUnit : pamControlledUnits) {
int numProcesses = aUnit.getNumPamProcesses();
- for (int i=0; i pamControlledUnits = pamConfiguration.getPamControlledUnits();
-
+
if (PamModel.getPamModel().isMultiThread()) {
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
pamControlledUnits.get(iU).flushDataBlockBuffers(2000);
@@ -1451,7 +1504,7 @@ public class PamController implements PamControllerInterface, PamSettings {
// e.printStackTrace();
// }
// }
-
+
// send out the pamHasStopped message
// Debug.out.println("PamController letting everyone know PAMGuard has stopped.");
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
@@ -1461,10 +1514,10 @@ public class PamController implements PamControllerInterface, PamSettings {
saveEndSettings(stopTime);
setPamStatus(PAM_IDLE);
-
+
guiFrameManager.pamEnded();
-
- // no good having this here since it get's called at the end of every file.
+
+ // no good having this here since it get's called at the end of every file.
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
//// can exit here, since we've auto started, can auto exit.
// if (canClose()) {
@@ -1473,10 +1526,10 @@ public class PamController implements PamControllerInterface, PamSettings {
// }
// }
}
-
- public void batchProcessingComplete( ) {
+
+ public void batchProcessingComplete() {
if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
- // can exit here, since we've auto started, can auto exit.
+ // can exit here, since we've auto started, can auto exit.
if (canClose()) {
pamClose();
shutDownPamguard();
@@ -1484,12 +1537,10 @@ public class PamController implements PamControllerInterface, PamSettings {
}
}
-
/**
- * Status Timer class. Once started, will run in a thread
- * and constantly check the buffers of all ThreadedObserver
- * objects. Once all the buffers are empty, this will set
- * the pam status to PAM_IDLE and let the thread die
+ * Status Timer class. Once started, will run in a thread and constantly check
+ * the buffers of all ThreadedObserver objects. Once all the buffers are empty,
+ * this will set the pam status to PAM_IDLE and let the thread die
*
* @author mo55
*
@@ -1515,9 +1566,9 @@ public class PamController implements PamControllerInterface, PamSettings {
// }
/**
- * Check the status of every threaded observer to see if it has emptied out
- * it's buffer of events. If the buffer is empty, return true. If the thread
- * is still processing, return false
+ * Check the status of every threaded observer to see if it has emptied out it's
+ * buffer of events. If the buffer is empty, return true. If the thread is still
+ * processing, return false
*
* @return true if ANY process is still running
*/
@@ -1556,15 +1607,15 @@ public class PamController implements PamControllerInterface, PamSettings {
// Debug.out.println(" Are we finished? " + areWeFinished);
// return areWeFinished;
ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits();
-
+
boolean running = false;
for (PamControlledUnit aUnit : pamControlledUnits) {
int numProcesses = aUnit.getNumPamProcesses();
- for (int i=0; i findSettingsSources() {
@@ -1646,6 +1696,7 @@ public class PamController implements PamControllerInterface, PamSettings {
public boolean modelSettings(JFrame frame) {
return pamModelInterface.modelSettings(frame);
}
+
/*
* (non-Javadoc)
*
@@ -1662,9 +1713,8 @@ public class PamController implements PamControllerInterface, PamSettings {
/*
* (non-Javadoc)
*
- * @see PamModel.PamModelInterface#GetFFTDataBlocks() Goes through all
- * processes and makes an array list containing only data blocks of FFT
- * data
+ * @see PamModel.PamModelInterface#GetFFTDataBlocks() Goes through all processes
+ * and makes an array list containing only data blocks of FFT data
*/
@Override
public ArrayList getFFTDataBlocks() {
@@ -1713,27 +1763,27 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public ArrayList getDetectorEventDataBlocks() {
- // return makeDataBlockList(PamguardMVC.DataType.DETEVENT);
+ // return makeDataBlockList(PamguardMVC.DataType.DETEVENT);
return null;
}
@Override
public PamDataBlock getDetectorEventDataBlock(int id) {
- // return getDataBlock(PamguardMVC.DataType.DETEVENT, id);
+ // return getDataBlock(PamguardMVC.DataType.DETEVENT, id);
return null;
}
@Override
public PamDataBlock getDetectorEventDataBlock(String name) {
- // return (PamDataBlock) getDataBlock(PamguardMVC.DataType.DETEVENT, name);
+ // return (PamDataBlock) getDataBlock(PamguardMVC.DataType.DETEVENT, name);
return null;
}
@Override
/**
- * Note that in order to return a list of PamDataBlocks that contain objects implementing
- * the AcousticDataUnit or PamDetection interfaces, the includeSubClasses boolean MUST be
- * true.
+ * Note that in order to return a list of PamDataBlocks that contain objects
+ * implementing the AcousticDataUnit or PamDetection interfaces, the
+ * includeSubClasses boolean MUST be true.
*/
public ArrayList getDataBlocks(Class blockType, boolean includeSubClasses) {
return pamConfiguration.getDataBlocks(blockType, includeSubClasses);
@@ -1749,52 +1799,53 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Makes a list of data blocks for all processes in all controllers for a
- * given DataType or for all DataTypes
+ * Makes a list of data blocks for all processes in all controllers for a given
+ * DataType or for all DataTypes
*
* @param blockType -- PamguardMVC.DataType.FFT, .RAW, etc., or null to
- * get all extant blocks
+ * get all extant blocks
* @return An ArrayList of data blocks
*/
- // private ArrayList makeDataBlockList(Enum blockType) {
- // ArrayList blockList = new ArrayList();
- // PamProcess pP;
+ // private ArrayList makeDataBlockList(Enum blockType) {
+ // ArrayList blockList = new ArrayList();
+ // PamProcess pP;
//
- // for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
- // for (int iP = 0; iP < pamControlledUnits.get(iU)
- // .getNumPamProcesses(); iP++) {
- // pP = pamControlledUnits.get(iU).getPamProcess(iP);
- // for (int j = 0; j < pP.getNumOutputDataBlocks(); j++) {
- // if (blockType == null
- // || pP.getOutputDataBlock(j).getDataType() == blockType) {
- // blockList.add(pP.getOutputDataBlock(j));
- // }
- // }
- // }
- // }
+ // for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
+ // for (int iP = 0; iP < pamControlledUnits.get(iU)
+ // .getNumPamProcesses(); iP++) {
+ // pP = pamControlledUnits.get(iU).getPamProcess(iP);
+ // for (int j = 0; j < pP.getNumOutputDataBlocks(); j++) {
+ // if (blockType == null
+ // || pP.getOutputDataBlock(j).getDataType() == blockType) {
+ // blockList.add(pP.getOutputDataBlock(j));
+ // }
+ // }
+ // }
+ // }
// private ArrayList makeDataBlockList(Class classType, boolean includSubClasses) {
// return pamConfiguration.makeDataBlockList(classType, includSubClasses);
// }
- /**
- * Find a block of a given type with the id number, or null if the number
- * is out of range.
+ /**
+ * Find a block of a given type with the id number, or null if the number is out
+ * of range.
*
- * @param blockType
- * @param id -- the block id number
- * @return block, which you may want to cast to a subtype
+ * @param blockType
+ * @param id -- the block id number
+ * @return block, which you may want to cast to a subtype
*/
@Override
public PamDataBlock getDataBlock(Class blockType, int id) {
return pamConfiguration.getDataBlock(blockType, id);
}
- /**
- * Find a block of a given type with the given name, or null if it
- * doesn't exist.
- * @param blockType -- RAW, FFT, DETECTOR, null, etc.
- * @param name -- the block name
- * @return block, which you may want to cast to a subtype
+ /**
+ * Find a block of a given type with the given name, or null if it doesn't
+ * exist.
+ *
+ * @param blockType -- RAW, FFT, DETECTOR, null, etc.
+ * @param name -- the block name
+ * @return block, which you may want to cast to a subtype
*/
@Override
public PamDataBlock getDataBlock(Class blockType, String name) {
@@ -1803,6 +1854,7 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Find a block with the given long name, or null if it doesn't exist.
+ *
* @param longName the long name of the PamDataBlock
* @return block
*/
@@ -1812,7 +1864,7 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
*
- * @return a list of offline data sources.
+ * @return a list of offline data sources.
*/
public ArrayList findOfflineDataStores() {
ArrayList ods = new ArrayList();
@@ -1828,7 +1880,7 @@ public class PamController implements PamControllerInterface, PamSettings {
}
public OfflineDataStore findOfflineDataStore(Class sourceClass) {
- ArrayList odss = findOfflineDataStores();
+ ArrayList odss = findOfflineDataStores();
for (int i = 0; i < odss.size(); i++) {
if (sourceClass.isAssignableFrom(odss.get(i).getClass())) {
return odss.get(i);
@@ -1838,55 +1890,57 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Updates the entire datamap.
+ * Updates the entire datamap.
*/
- public void updateDataMap(){
- System.out.println("updateDataMap:");
+ public void updateDataMap() {
+ System.out.println("updateDataMap:");
- if (DBControlUnit.findDatabaseControl()==null) return;
-
- System.out.println("updateDataMap: 1");
+ if (DBControlUnit.findDatabaseControl() == null)
+ return;
- ArrayList datablocks=getDataBlocks() ;
-
- System.out.println("updateDataMap: 2");
+ System.out.println("updateDataMap: 1");
+
+ ArrayList datablocks = getDataBlocks();
+
+ System.out.println("updateDataMap: 2");
DBControlUnit.findDatabaseControl().updateDataMap(datablocks);
-
- System.out.println("updateDataMap: 3");
+
+ System.out.println("updateDataMap: 3");
BinaryStore.findBinaryStoreControl().getDatagramManager().updateDatagrams();
-
- System.out.println("updateDataMap: 4");
+
+ System.out.println("updateDataMap: 4");
notifyModelChanged(PamControllerInterface.EXTERNAL_DATA_IMPORTED);
}
-
-
+
/**
- * Create the datamap from the database
+ * Create the datamap from the database
*/
- public void createDataMap(){
- if (DBControlUnit.findDatabaseControl()==null) return;
+ public void createDataMap() {
+ if (DBControlUnit.findDatabaseControl() == null)
+ return;
DBControlUnit.findDatabaseControl().createOfflineDataMap(getMainFrame());
BinaryStore.findBinaryStoreControl().createOfflineDataMap(getMainFrame());
}
-
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see PamguardMVC.PamControllerInterface#NotifyModelChanged()
*/
@Override
public void notifyModelChanged(int changeType) {
- //System.out.println("PamController: notify model changed: " +changeType );
+ // System.out.println("PamController: notify model changed: " +changeType );
if (changeType == CHANGED_MULTI_THREADING) {
changedThreading();
}
// no need for this, since array in now a controlled unit so it
- // will get this notification anyway.
- // ArrayManager.getArrayManager().notifyModelChanged(changeType);
+ // will get this notification anyway.
+ // ArrayManager.getArrayManager().notifyModelChanged(changeType);
guiFrameManager.notifyModelChanged(changeType);
@@ -1898,10 +1952,9 @@ public class PamController implements PamControllerInterface, PamSettings {
PamSettingManager.getInstance().notifyModelChanged(changeType);
-
if (getRunMode() == PamController.RUN_PAMVIEW) {
AbstractScrollManager.getScrollManager().notifyModelChanged(changeType);
- if (changeType == CHANGED_OFFLINE_DATASTORE) { // called from both database and binary data mappers.
+ if (changeType == CHANGED_OFFLINE_DATASTORE) { // called from both database and binary data mappers.
checkOfflineDataUIDs();
}
}
@@ -1915,30 +1968,31 @@ public class PamController implements PamControllerInterface, PamSettings {
StorageOptions.getInstance().setBlockOptions();
}
- // if we've just added a module, try to synchronise the UIDs with the the database and binary stores
+ // if we've just added a module, try to synchronise the UIDs with the the
+ // database and binary stores
if (changeType == INITIALIZATION_COMPLETE || (initializationComplete && changeType == ADD_CONTROLLEDUNIT)) {
uidManager.synchUIDs(true);
}
if (changeType == GLOBAL_TIME_UPDATE) {
haveGlobalTimeUpdate = true;
- }
- else {
+ } else {
globalTimeManager.notifyModelChanged(changeType);
}
-
+
if (moduleChange(changeType)) {
clearSelectorsAndSymbols();
}
-
+
if (changeType == DATA_LOAD_COMPLETE) {
firstDataLoadComplete = true;
}
}
-
+
/**
- * Has there been a module change AFTER initial module loading.
+ * Has there been a module change AFTER initial module loading.
+ *
* @param changeType
* @return true if modules added or removed after initialisation complete
*/
@@ -1956,15 +2010,15 @@ public class PamController implements PamControllerInterface, PamSettings {
}
private void checkOfflineDataUIDs() {
- ArrayList dataBlocks = getDataBlocks();
- for (PamDataBlock dataBlock:dataBlocks) {
+ ArrayList dataBlocks = getDataBlocks();
+ for (PamDataBlock dataBlock : dataBlocks) {
dataBlock.checkOfflineDataUIDs();
}
}
/**
- * loop over all units and processes, telling them to
- * re-subscribe to their principal data source
+ * loop over all units and processes, telling them to re-subscribe to their
+ * principal data source
*/
private void changedThreading() {
PamProcess pamProcess;
@@ -1985,18 +2039,17 @@ public class PamController implements PamControllerInterface, PamSettings {
if (garbageTimer != null) {
garbageTimer.stop();
}
- }
- else {
+ } else {
if (garbageTimer == null) {
- garbageTimer = new Timer(ms.gcInterval*1000, new ActionListener() {
+ garbageTimer = new Timer(ms.gcInterval * 1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
- // System.out.println("Additional Garbage collection called");
+ // System.out.println("Additional Garbage collection called");
Runtime.getRuntime().gc();
}
});
}
- garbageTimer.setDelay(ms.gcInterval*1000);
+ garbageTimer.setDelay(ms.gcInterval * 1000);
garbageTimer.start();
}
}
@@ -2010,7 +2063,7 @@ public class PamController implements PamControllerInterface, PamSettings {
public long getSettingsVersion() {
return 0;
}
-
+
@Override
public String getUnitName() {
return unitName;
@@ -2032,7 +2085,8 @@ public class PamController implements PamControllerInterface, PamSettings {
for (int i = 0; i < usedModules.size(); i++) {
umi = usedModules.get(i);
mi = PamModuleInfo.findModuleInfo(umi.className);
- if (mi == null) continue;
+ if (mi == null)
+ continue;
addModule(mi, umi.unitName);
}
return true;
@@ -2043,7 +2097,8 @@ public class PamController implements PamControllerInterface, PamSettings {
guiFrameManager.destroyModel();
- // also tell all PamControlledUnits since they may want to find their data source
+ // also tell all PamControlledUnits since they may want to find their data
+ // source
// it that was created after they were - i.e. dependencies have got all muddled
pamConfiguration.destroyModel();
@@ -2056,12 +2111,14 @@ public class PamController implements PamControllerInterface, PamSettings {
destroyModel();
- setupPamguard();
+ setupPamguard();
}
+
/**
- * returns the status of Pamguard. The available status' will
- * depend on the run mode. For instance, if run mode is RUN_NORMAL
- * then status can be either PAM_IDLE or PAM_RUNNING.
+ * returns the status of Pamguard. The available status' will depend on the run
+ * mode. For instance, if run mode is RUN_NORMAL then status can be either
+ * PAM_IDLE or PAM_RUNNING.
+ *
* @return Pamguard status
*/
public int getPamStatus() {
@@ -2071,10 +2128,10 @@ public class PamController implements PamControllerInterface, PamSettings {
public void setPamStatus(int pamStatus) {
this.pamStatus = pamStatus;
/*
- * This only get's called once when set idle at viewer mode startup.
+ * This only get's called once when set idle at viewer mode startup.
*/
if (debugDumpBufferAtRestart) {
- System.out.printf("******* PamController.setPamStatus to %d, real status is %d set in thread %s\n",
+ System.out.printf("******* PamController.setPamStatus to %d, real status is %d set in thread %s\n",
pamStatus, getRealStatus(), Thread.currentThread().toString());
}
if (getRunMode() != RUN_PAMVIEW) {
@@ -2085,11 +2142,12 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * This was within the StatusCommand class, but useful to have it here since it's needed
- * in more than one place. In viewer mode at startup there are a number of things going on
- * in different threads, such as the creation of datamaps, and this can (hopefully) handle those bespoke
- * goings on.
- * @return program status for multithreaded statup tasks.
+ * This was within the StatusCommand class, but useful to have it here since
+ * it's needed in more than one place. In viewer mode at startup there are a
+ * number of things going on in different threads, such as the creation of
+ * datamaps, and this can (hopefully) handle those bespoke goings on.
+ *
+ * @return program status for multithreaded statup tasks.
*/
public int getRealStatus() {
PamController pamController = PamController.getInstance();
@@ -2103,28 +2161,29 @@ public class PamController implements PamControllerInterface, PamSettings {
int status = pamController.getPamStatus();
if (status == PamController.PAM_IDLE) {
status = PamController.PAM_IDLE;
- }
- else {
- ArrayList daqs = PamController.getInstance().findControlledUnits(AcquisitionControl.unitType);
- if (daqs != null) for (int i = 0; i < daqs.size(); i++) {
- try {
- AcquisitionControl daq = (AcquisitionControl) daqs.get(i);
- if (daq.isStalled()) {
- status = PamController.PAM_STALLED;
+ } else {
+ ArrayList daqs = PamController.getInstance()
+ .findControlledUnits(AcquisitionControl.unitType);
+ if (daqs != null)
+ for (int i = 0; i < daqs.size(); i++) {
+ try {
+ AcquisitionControl daq = (AcquisitionControl) daqs.get(i);
+ if (daq.isStalled()) {
+ status = PamController.PAM_STALLED;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
- catch (Exception e) {
- e.printStackTrace();
- }
- }
}
WatchdogComms watchdogComms = PamController.getInstance().getWatchdogComms();
status = watchdogComms.getModifiedWatchdogState(status);
/*
- * This function is now being used in batch processing of offline data, where it may be necessary
- * to get status information from many different modules, for example when executing offline tasks
- * or just at startup while generating datamaps and datagrams.
- * So go through all modules and get the highest state of any of them.
+ * This function is now being used in batch processing of offline data, where it
+ * may be necessary to get status information from many different modules, for
+ * example when executing offline tasks or just at startup while generating
+ * datamaps and datagrams. So go through all modules and get the highest state
+ * of any of them.
*/
if (getRunMode() == RUN_PAMVIEW) {
if (firstDataLoadComplete == false) {
@@ -2134,17 +2193,17 @@ public class PamController implements PamControllerInterface, PamSettings {
for (PamControlledUnit aUnit : pamConfiguration.getPamControlledUnits()) {
status = Math.max(status, aUnit.getOfflineState());
}
- }
- catch (Exception e) {
- //just incase there is a concurrent modification at startup.
+ } catch (Exception e) {
+ // just incase there is a concurrent modification at startup.
}
}
-
+
return status;
}
-
+
/**
* show a warning when we're waiting for detectors to stop
+ *
* @param pamStatus
*/
private void showStatusWarning(int pamStatus) {
@@ -2156,17 +2215,17 @@ public class PamController implements PamControllerInterface, PamSettings {
sayStatusWarning(null);
}
}
-
+
/**
- * Show a singleton status warning message.
- * @param warningMessage Message - removes warning if set null.
+ * Show a singleton status warning message.
+ *
+ * @param warningMessage Message - removes warning if set null.
*/
private synchronized void sayStatusWarning(String warningMessage) {
WarningSystem warningSystem = WarningSystem.getWarningSystem();
if (warningMessage == null) {
warningSystem.removeWarning(statusWarning);
- }
- else {
+ } else {
statusWarning.setWarningMessage(warningMessage);
statusWarning.setWarnignLevel(1);
warningSystem.addWarning(statusWarning);
@@ -2175,12 +2234,10 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Gets the Pamguard running mode. This is set at startup (generally
- * through slightly different versions of the main class). It will be
- * one of
- * RUN_NORMAL
- * RUN_PAMVIEW
- * RUN_MIXEDMODE
+ * Gets the Pamguard running mode. This is set at startup (generally through
+ * slightly different versions of the main class). It will be one of RUN_NORMAL
+ * RUN_PAMVIEW RUN_MIXEDMODE
+ *
* @return Pamguards run mode
*/
public int getRunMode() {
@@ -2200,17 +2257,19 @@ public class PamController implements PamControllerInterface, PamSettings {
}
}
- // public void getNewViewTimes(Frame frame) {
+ // public void getNewViewTimes(Frame frame) {
//
- // PamViewParameters newParams = ViewTimesDialog.showDialog(null, pamViewParameters);
- // if (newParams != null) {
- // pamViewParameters = newParams.clone();
- // useNewViewTimes();
- // }
- // }
+ // PamViewParameters newParams = ViewTimesDialog.showDialog(null,
+ // pamViewParameters);
+ // if (newParams != null) {
+ // pamViewParameters = newParams.clone();
+ // useNewViewTimes();
+ // }
+ // }
/**
- * Class to do some extra saving of view times.
+ * Class to do some extra saving of view times.
+ *
* @author Douglas Gillespie
*
*/
@@ -2239,141 +2298,139 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
pamViewParameters = ((PamViewParameters) pamControlledUnitSettings.getSettings()).clone();
- // useNewViewTimes();
+ // useNewViewTimes();
return true;
}
}
+ // private long trueStart;
+ // private long trueEnd;
+ //
+ // public void useNewViewTimes() {
+ // AWTScheduler.getInstance().scheduleTask(new LoadViewerData());
+ // }
+ // public class LoadViewerData extends SwingWorker
+ // {
+ //
+ // /* (non-Javadoc)
+ // * @see javax.swing.SwingWorker#doInBackground()
+ // */
+ // @Override
+ // protected Integer doInBackground() throws Exception {
+ // loadViewData();
+ //
+ // return null;
+ // }
+ //
+ // private void loadViewData() {
+ // setPamStatus(PAM_LOADINGDATA);
+ // PamCalendar.setViewTimes(pamViewParameters.viewStartTime,
+ // pamViewParameters.viewEndTime);
+ // // need to tell all datablocks to dump existing data and read in new.
+ // ArrayList pamDataBlocks = getDataBlocks();
+ // PamDataBlock pamDataBlock;
+ // /*
+ // * also need to get the true max and min load times of the data
+ // *
+ // */
+ // PamDataUnit pdu;
+ // trueStart = Long.MAX_VALUE;
+ // trueEnd = Long.MIN_VALUE;
+ // for (int i = 0; i < pamDataBlocks.size(); i++){
+ // pamDataBlock = pamDataBlocks.get(i);
+ // pamDataBlock.clearAll();
+ // pamDataBlock.loadViewData(this, pamViewParameters);
+ // pdu = pamDataBlock.getFirstUnit();
+ // if (pdu != null) {
+ // trueStart = Math.min(trueStart, pdu.getTimeMilliseconds());
+ // }
+ // pdu = pamDataBlock.getLastUnit();
+ // if (pdu != null) {
+ // trueEnd = Math.max(trueEnd, pdu.getTimeMilliseconds());
+ // }
+ // }
+ // }
+ //
+ // /* (non-Javadoc)
+ // * @see javax.swing.SwingWorker#done()
+ // */
+ // @Override
+ // protected void done() {
+ // if (trueStart != Long.MAX_VALUE) {
+ // pamViewParameters.viewStartTime = trueStart;
+ // pamViewParameters.viewEndTime = trueEnd;
+ // PamCalendar.setViewTimes(trueStart, trueEnd);
+ //// viewerStatusBar.newShowTimes();
+ // }
+ // newViewTime();
+ // setPamStatus(PAM_IDLE);
+ // }
+ //
+ // /* (non-Javadoc)
+ // * @see javax.swing.SwingWorker#process(java.util.List)
+ // */
+ // @Override
+ // protected void process(List vlp) {
+ // // TODO Auto-generated method stub
+ // for (int i = 0; i < vlp.size(); i++) {
+ //// displayProgress(vlp.get(i));
+ // }
+ // }
+ //
+ // /**
+ // * Callback from SQLLogging in worker thread.
+ // * @param viewerLoadProgress
+ // */
+ // public void sayProgress(ViewerLoadProgress viewerLoadProgress) {
+ // this.publish(viewerLoadProgress);
+ // }
+ //
+ // }
- // private long trueStart;
- // private long trueEnd;
+ // public void tellTrueLoadTime(long loadTime) {
+ // trueStart = Math.min(trueStart, loadTime);
+ // trueEnd = Math.max(trueEnd, loadTime);
+ // }
//
- // public void useNewViewTimes() {
- // AWTScheduler.getInstance().scheduleTask(new LoadViewerData());
- // }
+ // public void newViewTime() {
+ // // view time has changed (probably from the slider)
+ // notifyModelChanged(PamControllerInterface.NEW_VIEW_TIME);
+ // }
- // public class LoadViewerData extends SwingWorker {
+ // public void displayProgress(ViewerLoadProgress viewerLoadProgress) {
+ // if (viewerStatusBar == null) {
+ // return;
+ // }
+ //// if (viewerLoadProgress.getTableName() != null) {
+ // viewerStatusBar.setupLoadProgress(viewerLoadProgress.getTableName());
+ //// }
//
- // /* (non-Javadoc)
- // * @see javax.swing.SwingWorker#doInBackground()
- // */
- // @Override
- // protected Integer doInBackground() throws Exception {
- // loadViewData();
- //
- // return null;
- // }
- //
- // private void loadViewData() {
- // setPamStatus(PAM_LOADINGDATA);
- // PamCalendar.setViewTimes(pamViewParameters.viewStartTime, pamViewParameters.viewEndTime);
- // // need to tell all datablocks to dump existing data and read in new.
- // ArrayList pamDataBlocks = getDataBlocks();
- // PamDataBlock pamDataBlock;
- // /*
- // * also need to get the true max and min load times of the data
- // *
- // */
- // PamDataUnit pdu;
- // trueStart = Long.MAX_VALUE;
- // trueEnd = Long.MIN_VALUE;
- // for (int i = 0; i < pamDataBlocks.size(); i++){
- // pamDataBlock = pamDataBlocks.get(i);
- // pamDataBlock.clearAll();
- // pamDataBlock.loadViewData(this, pamViewParameters);
- // pdu = pamDataBlock.getFirstUnit();
- // if (pdu != null) {
- // trueStart = Math.min(trueStart, pdu.getTimeMilliseconds());
- // }
- // pdu = pamDataBlock.getLastUnit();
- // if (pdu != null) {
- // trueEnd = Math.max(trueEnd, pdu.getTimeMilliseconds());
- // }
- // }
- // }
- //
- // /* (non-Javadoc)
- // * @see javax.swing.SwingWorker#done()
- // */
- // @Override
- // protected void done() {
- // if (trueStart != Long.MAX_VALUE) {
- // pamViewParameters.viewStartTime = trueStart;
- // pamViewParameters.viewEndTime = trueEnd;
- // PamCalendar.setViewTimes(trueStart, trueEnd);
- //// viewerStatusBar.newShowTimes();
- // }
- // newViewTime();
- // setPamStatus(PAM_IDLE);
- // }
- //
- // /* (non-Javadoc)
- // * @see javax.swing.SwingWorker#process(java.util.List)
- // */
- // @Override
- // protected void process(List vlp) {
- // // TODO Auto-generated method stub
- // for (int i = 0; i < vlp.size(); i++) {
- //// displayProgress(vlp.get(i));
- // }
- // }
- //
- // /**
- // * Callback from SQLLogging in worker thread.
- // * @param viewerLoadProgress
- // */
- // public void sayProgress(ViewerLoadProgress viewerLoadProgress) {
- // this.publish(viewerLoadProgress);
- // }
- //
- // }
+ // }
- // public void tellTrueLoadTime(long loadTime) {
- // trueStart = Math.min(trueStart, loadTime);
- // trueEnd = Math.max(trueEnd, loadTime);
- // }
- //
- // public void newViewTime() {
- // // view time has changed (probably from the slider)
- // notifyModelChanged(PamControllerInterface.NEW_VIEW_TIME);
- // }
-
- //public void displayProgress(ViewerLoadProgress viewerLoadProgress) {
- // if (viewerStatusBar == null) {
- // return;
- // }
- //// if (viewerLoadProgress.getTableName() != null) {
- // viewerStatusBar.setupLoadProgress(viewerLoadProgress.getTableName());
- //// }
- //
- //}
-
- // public void setupDBLoadProgress(String name) {
+ // public void setupDBLoadProgress(String name) {
//
- // if (viewerStatusBar != null) {
- // viewerStatusBar.setupLoadProgress(name);
- // }
- // }
- // public void setDBLoadProgress(long t) {
+ // if (viewerStatusBar != null) {
+ // viewerStatusBar.setupLoadProgress(name);
+ // }
+ // }
+ // public void setDBLoadProgress(long t) {
//
- // if (viewerStatusBar != null) {
- // viewerStatusBar.setLoadProgress(t);
- // }
- // }
+ // if (viewerStatusBar != null) {
+ // viewerStatusBar.setLoadProgress(t);
+ // }
+ // }
public boolean isInitializationComplete() {
return initializationComplete;
}
-
/**
- * Called from PamDialog whenever the OK button is pressed.
- * Don't do anything immediately to give the module that opened
- * the dialog time to respond to it's closing (e.g. make the new
- * settings from the dialog it's default).
- * Use invokeLater to send out a message as soon as the awt que is clear.
+ * Called from PamDialog whenever the OK button is pressed. Don't do anything
+ * immediately to give the module that opened the dialog time to respond to it's
+ * closing (e.g. make the new settings from the dialog it's default). Use
+ * invokeLater to send out a message as soon as the awt que is clear.
*/
public void dialogOKButtonPressed() {
@@ -2382,61 +2439,66 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Invoked later every time a dialog OK button is pressed. Sends
- * out a message to all modules to say settings have changed.
+ * Invoked later every time a dialog OK button is pressed. Sends out a message
+ * to all modules to say settings have changed.
+ *
* @author Doug
*
*/
class DialogOKButtonPressed implements Runnable {
@Override
public void run() {
- notifyModelChanged(PamControllerInterface.CHANGED_PROCESS_SETTINGS);
+ notifyModelChanged(PamControllerInterface.CHANGED_PROCESS_SETTINGS);
}
}
/**
- * Enables / Disables GUI for input. This is used when data are being loaded
- * in viewer mode to prevetn impatient users from clicking on extra things while
- * long background processes take place.
+ * Enables / Disables GUI for input. This is used when data are being loaded in
+ * viewer mode to prevetn impatient users from clicking on extra things while
+ * long background processes take place.
*
- * Many of the processes loading data are run in the background in SwingWorker threads
- * scheduled with the AWTScheduler so that they are able to update progress on teh screen
- * @param enable enable or disable the GUI.
+ * Many of the processes loading data are run in the background in SwingWorker
+ * threads scheduled with the AWTScheduler so that they are able to update
+ * progress on teh screen
+ *
+ * @param enable enable or disable the GUI.
*/
public void enableGUIControl(boolean enable) {
- // System.out.println("Enable GUI Control = " + enable);
+ // System.out.println("Enable GUI Control = " + enable);
guiFrameManager.enableGUIControl(enable);
}
- // /**
- // * Load viewer data into all the scrollers.
- // */
- // public void loadViewerData() {
- // // TODO Auto-generated method stub
- // AbstractScrollManager scrollManager = AbstractScrollManager.getScrollManager();
- // scrollManager.reLoad();
- //
- // }
+ // /**
+ // * Load viewer data into all the scrollers.
+ // */
+ // public void loadViewerData() {
+ // // TODO Auto-generated method stub
+ // AbstractScrollManager scrollManager =
+ // AbstractScrollManager.getScrollManager();
+ // scrollManager.reLoad();
+ //
+ // }
boolean loadingOldSettings = false;
/**
- * Flagged true if the manual stop button has been pressed.
- * Used to override the watchdog status.
+ * Flagged true if the manual stop button has been pressed. Used to override the
+ * watchdog status.
*/
private boolean manualStop;
-
/**
* Used when in viewer mode and planning batch processing with a modified
* configuration, i.e. the command line has been supplied a normal viewer mode
- * database and also a psfx file. The settings from the database will already have
- * been loaded, this will load any modules that weren't there and will override all the
- * settings in other modules with these ones (except some specials such as data storage locations)
- * @param psfxFile Name of additional psfx file.
+ * database and also a psfx file. The settings from the database will already
+ * have been loaded, this will load any modules that weren't there and will
+ * override all the settings in other modules with these ones (except some
+ * specials such as data storage locations)
+ *
+ * @param psfxFile Name of additional psfx file.
*/
private boolean loadOtherSettings(String psfxName) {
-
+
File psfxFile = new File(psfxName);
if (psfxFile.exists() == false) {
return false;
@@ -2446,43 +2508,43 @@ public class PamController implements PamControllerInterface, PamSettings {
if (settingsGroup == null) {
return false;
}
-
+
BatchViewSettingsImport importer = new BatchViewSettingsImport(this, settingsGroup);
importer.importSettings();
return true;
}
-
+
/**
- * Called to load a specific set of PAMGUARD settings in
- * viewer mode, which were previously loaded in from a
- * database or binary store.
+ * Called to load a specific set of PAMGUARD settings in viewer mode, which were
+ * previously loaded in from a database or binary store.
+ *
* @param settingsGroup settings information
- * @param initialiseNow Immediately data are loaded, initialise which will load data from storages.
+ * @param initialiseNow Immediately data are loaded, initialise which will load
+ * data from storages.
*/
public void loadOldSettings(PamSettingsGroup settingsGroup) {
loadOldSettings(settingsGroup, true);
}
-
+
/**
- * Called to load a specific set of PAMGUARD settings in
- * viewer mode, which were previously loaded in from a
- * database or binary store.
+ * Called to load a specific set of PAMGUARD settings in viewer mode, which were
+ * previously loaded in from a database or binary store.
+ *
* @param settingsGroup settings information
- * @param initialiseNow Immediately data are loaded, initialise which will load data from storages.
+ * @param initialiseNow Immediately data are loaded, initialise which will load
+ * data from storages.
*/
public void loadOldSettings(PamSettingsGroup settingsGroup, boolean initialiseNow) {
/**
- * Three things to do:
- * 1. consider removing modules which exist but are no longer needed
- * 2. Add modules which aren't present but are needed
- * 3. re-order modules
- * 4. Load settings into modules
- * 5. Ping round an initialisation complete message.
+ * Three things to do: 1. consider removing modules which exist but are no
+ * longer needed 2. Add modules which aren't present but are needed 3. re-order
+ * modules 4. Load settings into modules 5. Ping round an initialisation
+ * complete message.
*/
- // 1. get a list of current modules no longer needed.
+ // 1. get a list of current modules no longer needed.
PamControlledUnit pcu;
ArrayList toRemove = new ArrayList();
- for (int i = 0 ; i < getNumControlledUnits(); i++) {
+ for (int i = 0; i < getNumControlledUnits(); i++) {
pcu = getControlledUnit(i);
if (settingsGroup.findUnitSettings(pcu.getUnitType(), pcu.getUnitName()) == null) {
toRemove.add(pcu);
@@ -2501,8 +2563,7 @@ public class PamController implements PamControllerInterface, PamSettings {
try {
moduleClass = Class.forName(aModuleInfo.className);
} catch (ClassNotFoundException e) {
- System.out.println(String.format("The module with class %s is not available",
- aModuleInfo.className));
+ System.out.println(String.format("The module with class %s is not available", aModuleInfo.className));
continue;
}
if (findControlledUnit(moduleClass, aModuleInfo.unitName) == null) {
@@ -2542,11 +2603,9 @@ public class PamController implements PamControllerInterface, PamSettings {
}
}
/*
- * try to get everything in the right order
- * Needs a LUT which converts the current order
- * into the required order, i.e. the first element
- * of the LUT will be the current position of the
- * unit we want to come first.
+ * try to get everything in the right order Needs a LUT which converts the
+ * current order into the required order, i.e. the first element of the LUT will
+ * be the current position of the unit we want to come first.
*/
int[] orderLUT = new int[getNumControlledUnits()];
PamControlledUnit aUnit;
@@ -2562,8 +2621,7 @@ public class PamController implements PamControllerInterface, PamSettings {
try {
moduleClass = Class.forName(aModuleInfo.className);
} catch (ClassNotFoundException e) {
- System.out.println(String.format("The module with class %s is not available",
- aModuleInfo.className));
+ System.out.println(String.format("The module with class %s is not available", aModuleInfo.className));
continue;
}
aUnit = findControlledUnit(moduleClass, aModuleInfo.unitName);
@@ -2575,10 +2633,10 @@ public class PamController implements PamControllerInterface, PamSettings {
nFound++;
}
}
- // reOrderModules(orderLUT);
+ // reOrderModules(orderLUT);
/*
- * Now try to give each module it's settings.
+ * Now try to give each module it's settings.
*/
initializationComplete = true;
@@ -2590,38 +2648,40 @@ public class PamController implements PamControllerInterface, PamSettings {
PamSettingManager.getInstance().loadSettingsGroup(settingsGroup, true);
loadingOldSettings = false;
-
}
/**
- * Load settings for all modules in this group, then
- * export as XML.
+ * Load settings for all modules in this group, then export as XML.
+ *
* @param settingsGroup
*/
public void exportSettingsAsXML(PamSettingsGroup settingsGroup) {
loadOldSettings(settingsGroup, false);
this.exportGeneralXMLSettings((JFrame) getMainFrame(), settingsGroup.getSettingsTime());
- // exportDecimusXMLSettings(settingsGroup.getSettingsTime());
- //now do it with XML encoder to see what it's like ...
- // String fName = String.format("XMLEncoded_%s.xml", PamCalendar.formatFileDateTime(settingsGroup.getSettingsTime()));
- // File f = new File(fName);
- // XMLEncoder encoder=null;
- // try{
- // encoder=new XMLEncoder(new BufferedOutputStream(new FileOutputStream(fName)));
- // }catch(FileNotFoundException fileNotFound){
- // System.out.println("ERROR: While Creating or Opening the File dvd.xml");
- // }
- // Iterator it = settingsGroup.getUnitSettings().iterator();
- // while(it.hasNext()) {
- // PamControlledUnitSettings set = it.next();
- // encoder.writeObject(set);
- // }
- // encoder.close();
+ // exportDecimusXMLSettings(settingsGroup.getSettingsTime());
+ // now do it with XML encoder to see what it's like ...
+ // String fName = String.format("XMLEncoded_%s.xml",
+ // PamCalendar.formatFileDateTime(settingsGroup.getSettingsTime()));
+ // File f = new File(fName);
+ // XMLEncoder encoder=null;
+ // try{
+ // encoder=new XMLEncoder(new BufferedOutputStream(new
+ // FileOutputStream(fName)));
+ // }catch(FileNotFoundException fileNotFound){
+ // System.out.println("ERROR: While Creating or Opening the File dvd.xml");
+ // }
+ // Iterator it =
+ // settingsGroup.getUnitSettings().iterator();
+ // while(it.hasNext()) {
+ // PamControlledUnitSettings set = it.next();
+ // encoder.writeObject(set);
+ // }
+ // encoder.close();
}
/**
- * Get the name of the psf or database used to contain settings
- * for this run.
+ * Get the name of the psf or database used to contain settings for this run.
+ *
* @return name of psf or database
*/
public String getPSFName() {
@@ -2644,11 +2704,11 @@ public class PamController implements PamControllerInterface, PamSettings {
return dbc.getDatabaseName();
}
return null;
- }
+ }
/**
- * Get the name of the psf or database used to contain settings
- * for this run.
+ * Get the name of the psf or database used to contain settings for this run.
+ *
* @return name of psf or database
*/
public String getPSFNameWithPath() {
@@ -2675,8 +2735,7 @@ public class PamController implements PamControllerInterface, PamSettings {
public void toolBarStartButton(PamControlledUnit currentControlledUnit) {
if (getRunMode() == RUN_PAMVIEW) {
- }
- else {
+ } else {
pamStart();
}
}
@@ -2684,17 +2743,23 @@ public class PamController implements PamControllerInterface, PamSettings {
public void toolBarStopButton(PamControlledUnit currentControlledUnit) {
if (getRunMode() == RUN_PAMVIEW) {
PlaybackControl.getViewerPlayback().stopViewerPlayback();
- }
- else {
+ } else {
pamStop();
manualStop = true;
}
}
/**
+<<<<<<< Updated upstream
* Respond to storage options dialog. Selects whether data
* are stored in binary, database or both
* @param parentFrame
+=======
+ * Respond to storage options dialog. Selects whethere data are stored in
+ * binary, database or both
+ *
+ * @param parentFrame
+>>>>>>> Stashed changes
*/
public void storageOptions(JFrame parentFrame) {
StorageOptions.getInstance().showDialog(parentFrame);
@@ -2712,7 +2777,8 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Return a verbose level for debug output
- * @return a verbose level for debug output.
+ *
+ * @return a verbose level for debug output.
*/
public int getVerboseLevel() {
return 10;
@@ -2721,7 +2787,7 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* Create a watchdog which will run independently and keep this thing going !
*/
- public void createWatchDog() {
+ public void createWatchDog() {
String runnableJar = null;
try {
runnableJar = Pamguard.class.getProtectionDomain().getCodeSource().getLocation().toString();
@@ -2739,8 +2805,8 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Returns the module that is currently being loaded. If null, it means we aren't
- * loading anything right now
+ * Returns the module that is currently being loaded. If null, it means we
+ * aren't loading anything right now
*
* @return
*/
@@ -2752,11 +2818,12 @@ public class PamController implements PamControllerInterface, PamSettings {
* Clears the variable holding info about the unit currently being loaded
*/
public void clearLoadedUnit() {
- unitBeingLoaded=null;
+ unitBeingLoaded = null;
}
/**
- * Get the Java compliance, i.e. what Java version is running.
+ * Get the Java compliance, i.e. what Java version is running.
+ *
* @return integer value of java version e.g. Java 8 is return 1.8
*/
public double getJCompliance() {
@@ -2764,16 +2831,17 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Get the Java version. Only show the first decimal place (e.g. 12.0, not 12.0.1). If
- * there is no decimal place (e.g. 13) then just show that.
+ * Get the Java version. Only show the first decimal place (e.g. 12.0, not
+ * 12.0.1). If there is no decimal place (e.g. 13) then just show that.
*
- * @return the Java version.
+ * @return the Java version.
*/
- static double getVersion () {
+ static double getVersion() {
String version = System.getProperty("java.version");
/*
- * strip down to the first non numeric character. and allow 0 or 1 decimal points.
- * This should pull out any valid decimal number from the front of the string.
+ * strip down to the first non numeric character. and allow 0 or 1 decimal
+ * points. This should pull out any valid decimal number from the front of the
+ * string.
*/
int iLen = 0;
int nDot = 0;
@@ -2784,12 +2852,12 @@ public class PamController implements PamControllerInterface, PamSettings {
if (ch == '.') {
nDot++;
}
- }
- else {
+ } else {
break;
- };
+ }
+ ;
}
-
+
// int pos = version.indexOf('.'); // get the index of the first decimal
// if (pos==-1) { // if there is no decimal place (e.g. Java 13) then just use the full string
// pos=version.length();
@@ -2802,21 +2870,21 @@ public class PamController implements PamControllerInterface, PamSettings {
// }
double mainVersion = 0;
try {
- mainVersion = Double.parseDouble (version.substring (0, iLen));
+ mainVersion = Double.parseDouble(version.substring(0, iLen));
+ } catch (NumberFormatException e) {
+
}
- catch (NumberFormatException e) {
-
- }
-
+
return mainVersion;
}
/**
* Notify the PamController that progress has been made in loading something.
- * @param progress - holds progress info.
+ *
+ * @param progress - holds progress info.
*/
public void notifyTaskProgress(PamTaskUpdate progress) {
- if (this.guiFrameManager!=null) {
+ if (this.guiFrameManager != null) {
this.guiFrameManager.notifyLoadProgress(progress);
}
}
@@ -2835,26 +2903,25 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Returns the current installation folder, or null if there was a problem determining
- * the folder location. Note that the default file separator is included at the end
- * of the string.
+ * Returns the current installation folder, or null if there was a problem
+ * determining the folder location. Note that the default file separator is
+ * included at the end of the string.
+ *
* @return
*/
public String getInstallFolder() {
return installFolder;
}
+ /***** Convenience Functions *******/
- /*****Convenience Functions*******/
-
-
- /****Swing GUI*****/
+ /**** Swing GUI *****/
/**
- * Get the main frame if there is one.
- * Can be used by dialogs when no one else has
- * sorted out a frame reference to pass to them.
- * @return reference to main GUI frame.
+ * Get the main frame if there is one. Can be used by dialogs when no one else
+ * has sorted out a frame reference to pass to them.
+ *
+ * @return reference to main GUI frame.
*/
public static Frame getMainFrame() {
PamController c = getInstance();
@@ -2862,31 +2929,29 @@ public class PamController implements PamControllerInterface, PamSettings {
return null;
}
if (c.guiFrameManager instanceof GuiFrameManager) {
- GuiFrameManager guiFrameManager = (GuiFrameManager) c.guiFrameManager;
+ GuiFrameManager guiFrameManager = (GuiFrameManager) c.guiFrameManager;
if (guiFrameManager.getNumFrames() <= 0) {
return null;
}
return guiFrameManager.getFrame(0);
}
- return null;
+ return null;
}
@Override
public GuiFrameManager getGuiFrameManager() {
if (guiFrameManager instanceof GuiFrameManager) {
- return (GuiFrameManager) guiFrameManager;
- }
- else {
+ return (GuiFrameManager) guiFrameManager;
+ } else {
return null;
}
}
- public void sortFrameTitles(){
+ public void sortFrameTitles() {
getGuiFrameManager().sortFrameTitles();
}
-
- /****FX Gui*****/
+ /**** FX Gui *****/
@Deprecated
public PamGuiManagerFX getGuiManagerFX() {
return (PamGuiManagerFX) this.guiFrameManager;
@@ -2897,11 +2962,12 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Set the install folder.
+ * Set the install folder.
+ *
* @param installFolder
*/
public void setInstallFolder(String installFolder) {
- this.installFolder=installFolder;
+ this.installFolder = installFolder;
}
@@ -2944,13 +3010,31 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
- * Gt the main PAMGuard configuration (list of connected modules).
+ * Gt the main PAMGuard configuration (list of connected modules).
+ *
* @return the pamConfiguration
*/
public PamConfiguration getPamConfiguration() {
return pamConfiguration;
}
+ /**
+ * Gets called on a timer when NOT processing from files.
+ * OR if processing files, gets called whenever the Calendar session start time or file time millis gets updated.
+ * @param timeInMillis
+ */
+ public void updateMasterClock(long timeInMillis) {
+ /*
+ * this needs to notify binary stores that time has changed since the BS doesn't subscribe
+ * to anything, so doesn't get other clock updates.
+ */
+ ArrayList bs = findControlledUnits(BinaryStore.class);
+ for (PamControlledUnit aBS : bs) {
+ BinaryStore binStore = (BinaryStore) aBS;
+ binStore.getBinaryStoreProcess().checkFileTime(timeInMillis);
+ }
+ }
+
}
diff --git a/src/PamController/PamguardVersionInfo.java b/src/PamController/PamguardVersionInfo.java
index b40c4afa..49358749 100644
--- a/src/PamController/PamguardVersionInfo.java
+++ b/src/PamController/PamguardVersionInfo.java
@@ -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.11d";
+ static public final String version = "2.02.12";
/**
* Release date
*/
- static public final String date = "30 May 2024";
+ static public final String date = "24 June 2024";
// /**
// * Release type - Beta or Core
diff --git a/src/PamController/fileprocessing/ReprocessChoiceDialog.java b/src/PamController/fileprocessing/ReprocessChoiceDialog.java
index f2b9eee5..985fbb99 100644
--- a/src/PamController/fileprocessing/ReprocessChoiceDialog.java
+++ b/src/PamController/fileprocessing/ReprocessChoiceDialog.java
@@ -4,6 +4,8 @@ import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.ButtonGroup;
@@ -64,15 +66,28 @@ public class ReprocessChoiceDialog extends PamDialog {
List userChoices = choiceSummary.getChoices();
choiceButtons = new JRadioButton[userChoices.size()];
ButtonGroup bg = new ButtonGroup();
+ SelAction selAction = new SelAction();
for (int i = 0; i < userChoices.size(); i++) {
ReprocessStoreChoice aChoice = userChoices.get(i);
choiceButtons[i] = new JRadioButton(aChoice.toString());
choiceButtons[i].setToolTipText(aChoice.getToolTip());
+ bg.add(choiceButtons[i]);
+ choiceButtons[i].addActionListener(selAction);
choicePanel.add(choiceButtons[i], c);
c.gridy++;
}
setDialogComponent(mainPanel);
getCancelButton().setVisible(false);
+ getOkButton().setEnabled(false);
+ }
+
+ private class SelAction implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ getOkButton().setEnabled(true);
+ }
+
}
public static ReprocessStoreChoice showDialog(Window parentFrame, StoreChoiceSummary choices) {
diff --git a/src/PamController/fileprocessing/ReprocessManager.java b/src/PamController/fileprocessing/ReprocessManager.java
index 4f05913a..2541187b 100644
--- a/src/PamController/fileprocessing/ReprocessManager.java
+++ b/src/PamController/fileprocessing/ReprocessManager.java
@@ -62,7 +62,7 @@ public class ReprocessManager {
*/
boolean setupOK = setupInputStream(choiceSummary, choice);
- if (choice == ReprocessStoreChoice.DONTSSTART) {
+ if (choice == null || choice == ReprocessStoreChoice.DONTSSTART) {
return false;
}
@@ -172,6 +172,8 @@ public class ReprocessManager {
choiceSummary.addChoice(ReprocessStoreChoice.STARTNORMAL);
return choiceSummary;
}
+
+ choiceSummary.addChoice(ReprocessStoreChoice.STARTNORMAL);
ArrayList outputStores = PamController.getInstance().findControlledUnits(DataOutputStore.class, true);
boolean partStores = false;
diff --git a/src/PamController/fileprocessing/StoreChoiceSummary.java b/src/PamController/fileprocessing/StoreChoiceSummary.java
index f0f13c3a..571f7aa7 100644
--- a/src/PamController/fileprocessing/StoreChoiceSummary.java
+++ b/src/PamController/fileprocessing/StoreChoiceSummary.java
@@ -65,6 +65,9 @@ public class StoreChoiceSummary {
* @param choice
*/
public void addChoice(ReprocessStoreChoice choice) {
+ if (choices.contains(choice)) {
+ return;
+ }
choices.add(choice);
}
diff --git a/src/PamModel/PamModel.java b/src/PamModel/PamModel.java
index b0776c48..e97b315e 100644
--- a/src/PamModel/PamModel.java
+++ b/src/PamModel/PamModel.java
@@ -472,7 +472,7 @@ final public class PamModel implements PamSettings {
mi.setModulesMenuGroup(utilitiesGroup);
mi.setMaxNumber(1);
//mi.addGUICompatabilityFlag(PamGUIManager.FX); //has FX enabled GUI.
-// mi.setHidden(SMRUEnable.isEnable() == false);
+ mi.setHidden(SMRUEnable.isEnable() == false);
}
/*
diff --git a/src/PamUtils/PamCalendar.java b/src/PamUtils/PamCalendar.java
index 2e1388f9..428130d0 100644
--- a/src/PamUtils/PamCalendar.java
+++ b/src/PamUtils/PamCalendar.java
@@ -25,6 +25,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
@@ -32,6 +33,7 @@ import java.util.TimeZone;
import PamController.PamController;
import PamUtils.time.CalendarControl;
+import binaryFileStorage.BinaryStore;
/**
@@ -85,7 +87,7 @@ public class PamCalendar {
* viewPositions which is the number of milliseconds from the sessionsStartTime.
*/
private static long viewPosition;
-
+
/**
* If files are being analysed, return the time based on the file
@@ -880,14 +882,18 @@ public class PamCalendar {
*/
public static void setSessionStartTime(long sessionStartTime) {
PamCalendar.sessionStartTime = sessionStartTime;
+ PamController.getInstance().updateMasterClock(getTimeInMillis());
}
/**
*
- * @param soundFileTimeMillis The start time of a sound file
+ * Relative time within a sound file. This is always just added to sessionStartTime
+ * to give an absolute time.
+ * @param soundFileTimeMillis The relative time of a sound file.
*/
public static void setSoundFileTimeInMillis(long soundFileTimeMillis) {
PamCalendar.soundFileTimeInMillis = soundFileTimeMillis;
+ PamController.getInstance().updateMasterClock(getTimeInMillis());
}
/**
diff --git a/src/PamView/dialog/GenericSwingDialog.java b/src/PamView/dialog/GenericSwingDialog.java
index 208bd386..72ea3821 100644
--- a/src/PamView/dialog/GenericSwingDialog.java
+++ b/src/PamView/dialog/GenericSwingDialog.java
@@ -10,6 +10,8 @@ import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
+import PamController.PamController;
+
public class GenericSwingDialog extends PamDialog {
private boolean allOk;
@@ -45,6 +47,9 @@ public class GenericSwingDialog extends PamDialog {
* @return
*/
public static boolean showDialog(Window parentFrame, String title, Point screenPoint, PamDialogPanel ...dialogPanels) {
+ if (parentFrame == null) {
+ parentFrame = PamController.getMainFrame();
+ }
GenericSwingDialog swingDialog = new GenericSwingDialog(parentFrame, title, dialogPanels);
swingDialog.setParams();
swingDialog.pack();
diff --git a/src/PamView/dialog/PamDialogPanel.java b/src/PamView/dialog/PamDialogPanel.java
index d8dcc706..19e83808 100644
--- a/src/PamView/dialog/PamDialogPanel.java
+++ b/src/PamView/dialog/PamDialogPanel.java
@@ -5,6 +5,7 @@ import javax.swing.JComponent;
/**
* General class for dialog panels which will be incorporated into one or
* more actual dialogs.
+ * Can be quickly opened with GenericSwingDialog
* @author Doug Gillespie
*
*/
diff --git a/src/PamView/symbol/modifier/SymbolModifier.java b/src/PamView/symbol/modifier/SymbolModifier.java
index 3e33d0eb..96ccfa53 100644
--- a/src/PamView/symbol/modifier/SymbolModifier.java
+++ b/src/PamView/symbol/modifier/SymbolModifier.java
@@ -150,7 +150,8 @@ abstract public class SymbolModifier {
if (dialogPanel == null) {
return null;
}
- JMenuItem menuItem = new JMenuItem("Options ...");
+ JMenuItem menuItem = new JMenuItem("More options ...");
+ menuItem.setToolTipText("More symbol options");
menuItem.addActionListener(new ActionListener() {
@Override
diff --git a/src/PamView/symbol/modifier/swing/ModifierTreeNode.java b/src/PamView/symbol/modifier/swing/ModifierTreeNode.java
index 746fa43b..70285206 100644
--- a/src/PamView/symbol/modifier/swing/ModifierTreeNode.java
+++ b/src/PamView/symbol/modifier/swing/ModifierTreeNode.java
@@ -8,12 +8,13 @@ import java.util.Enumeration;
import javax.swing.tree.TreeNode;
import PamUtils.PamUtils;
+import PamView.dialog.PamDialogPanel;
import PamView.symbol.modifier.SymbolModifier;
public class ModifierTreeNode implements TreeNode {
private SymbolModifier modifier;
private SymbolTreeRoot rootNode;
- private ArrayList choiceNodes;
+ private ArrayList choiceNodes;
public ModifierTreeNode(SymbolTreeRoot rootNode, SymbolModifier modifier) {
super();
@@ -22,17 +23,25 @@ public class ModifierTreeNode implements TreeNode {
int modBits = modifier.getModifyableBits();
int nMod = Integer.bitCount(modBits);
choiceNodes = new ArrayList<>();
+
+ int leafIndex = 0;
+
for (int i = 0; i < nMod; i++) {
- choiceNodes.add(new ChoiceTreeNode(this, 1< children() {
+ return null;
+ }
+
+}
diff --git a/src/PamView/symbol/modifier/swing/SymbolModifierPanel.java b/src/PamView/symbol/modifier/swing/SymbolModifierPanel.java
index 922a4c16..ddef072e 100644
--- a/src/PamView/symbol/modifier/swing/SymbolModifierPanel.java
+++ b/src/PamView/symbol/modifier/swing/SymbolModifierPanel.java
@@ -18,12 +18,10 @@ import javax.swing.tree.TreePath;
import PamView.dialog.DialogScrollPane;
import PamView.dialog.PamDialogPanel;
-import PamView.symbol.PamSymbolChooser;
import PamView.symbol.StandardSymbolChooser;
import PamView.symbol.StandardSymbolOptions;
import PamView.symbol.modifier.SymbolModifier;
import PamView.symbol.modifier.SymbolModifierParams;
-import PamguardMVC.debug.Debug;
/**
* Panel to include in a dialog with options to select and activate a variety of symbol modifiers.
@@ -137,6 +135,7 @@ public class SymbolModifierPanel implements PamDialogPanel {
JMenuItem optsItem = modifier.getModifierOptionsMenu();
if (optsItem != null) {
popMenu.add(optsItem);
+ popMenu.addSeparator();
}
}
if (nodeInd > 0) {
diff --git a/src/PamView/symbol/modifier/swing/SymbolTreeRenderer.java b/src/PamView/symbol/modifier/swing/SymbolTreeRenderer.java
index da04fedf..f96d563b 100644
--- a/src/PamView/symbol/modifier/swing/SymbolTreeRenderer.java
+++ b/src/PamView/symbol/modifier/swing/SymbolTreeRenderer.java
@@ -43,6 +43,10 @@ public class SymbolTreeRenderer extends DefaultTreeCellRenderer {
if (value instanceof ChoiceTreeNode) {
return checkboxChoice(tree, (ChoiceTreeNode) value, sel, expanded, leaf, row, hasFocus);
}
+
+ if (value instanceof OptionsTreeNode) {
+ return ((OptionsTreeNode) value).optionsButton;
+ }
Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof ModifierTreeNode) {
diff --git a/src/PamguardMVC/PamRawDataBlock.java b/src/PamguardMVC/PamRawDataBlock.java
index f1246242..6b06ead5 100644
--- a/src/PamguardMVC/PamRawDataBlock.java
+++ b/src/PamguardMVC/PamRawDataBlock.java
@@ -257,12 +257,13 @@ public class PamRawDataBlock extends AcousticDataBlock {
synchronized public RawDataUnit[] getAvailableSamples(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException {
RawDataUnit firstUnit = getFirstUnit();
if (firstUnit == null) {
- throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, 0,0, startMillis, (int) durationMillis);
}
long firstMillis = firstUnit.getTimeMilliseconds();
long firstSamples = firstUnit.getStartSample();
RawDataUnit lastUnit = getLastUnit();
long lastMillis = lastUnit.getEndTimeInMilliseconds();
+ long lastSample = lastUnit.getStartSample()+lastUnit.getSampleDuration();
long firstAvailableMillis = Math.max(firstMillis, startMillis);
@@ -272,7 +273,8 @@ public class PamRawDataBlock extends AcousticDataBlock {
double[][] data = getSamplesForMillis(firstAvailableMillis, lastAvailableMillis-firstAvailableMillis, channelMap);
if (data == null) {
// this shouldn't happen. If an exception wasn't thrown from getSamples... then data should no tb enull
- throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED,
+ firstSamples, lastSample, startMillis, (int) durationMillis);
}
RawDataUnit[] dataUnits = new RawDataUnit[data.length];
for (int i = 0; i < data.length; i++) {
@@ -298,7 +300,7 @@ public class PamRawDataBlock extends AcousticDataBlock {
synchronized public double[][] getSamplesForMillis(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException {
RawDataUnit firstUnit = getFirstUnit();
if (firstUnit == null) {
- throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, 0, 0, startMillis, (int) durationMillis);
}
long firstMillis = firstUnit.getTimeMilliseconds();
long firstSamples = firstUnit.getStartSample();
@@ -317,23 +319,28 @@ public class PamRawDataBlock extends AcousticDataBlock {
// run a few tests ...
int chanOverlap = channelMap & getChannelMap();
if (chanOverlap != channelMap) {
- throw new RawDataUnavailableException(this, RawDataUnavailableException.INVALID_CHANNEL_LIST, startSample, duration);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.INVALID_CHANNEL_LIST, 0,0,startSample, duration);
}
if (duration < 0) {
- throw new RawDataUnavailableException(this, RawDataUnavailableException.NEGATIVE_DURATION, startSample, duration);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.NEGATIVE_DURATION,0,0, startSample, duration);
}
RawDataUnit dataUnit = getFirstUnit();
if (dataUnit == null) {
return null;
}
- if (dataUnit.getStartSample() > startSample) {
+ RawDataUnit lastUnit = getLastUnit();
+ long firstSample = dataUnit.getStartSample();
+ long lastSample = lastUnit.getStartSample()+lastUnit.getSampleDuration();
+ if (firstSample > startSample) {
// System.out.println("Earliest start sample : " + dataUnit.getStartSample());
- throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_ALREADY_DISCARDED, startSample, duration);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_ALREADY_DISCARDED,
+ firstSample, lastSample, startSample, duration);
}
dataUnit = getLastUnit();
if (hasLastSample(dataUnit, startSample+duration, channelMap) == false) {
- throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startSample, duration);
+ throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED,
+ firstSample, lastSample, startSample, duration);
}
int nChan = PamUtils.getNumChannels(channelMap);
diff --git a/src/PamguardMVC/RawDataUnavailableException.java b/src/PamguardMVC/RawDataUnavailableException.java
index 37e4275a..524f8072 100644
--- a/src/PamguardMVC/RawDataUnavailableException.java
+++ b/src/PamguardMVC/RawDataUnavailableException.java
@@ -21,6 +21,10 @@ public class RawDataUnavailableException extends Exception {
private long startSample;
private int duration;
+
+ private long availableStart;
+
+ private long availableEnd;
/**
* @return the dataCause
*/
@@ -34,10 +38,12 @@ public class RawDataUnavailableException extends Exception {
* @param startSample
* @param cause
*/
- public RawDataUnavailableException(PamRawDataBlock rawDataBlock, int dataCause, long startSample, int duration) {
+ public RawDataUnavailableException(PamRawDataBlock rawDataBlock, int dataCause, long availStart, long availEnd, long startSample, int duration) {
super();
this.rawDataBlock = rawDataBlock;
this.dataCause = dataCause;
+ this.availableStart = availStart;
+ this.availableEnd = availEnd;
this.startSample = startSample;
this.duration = duration;
}
@@ -55,8 +61,8 @@ public class RawDataUnavailableException extends Exception {
public String getMessage() {
switch (dataCause) {
case DATA_ALREADY_DISCARDED:
- return String.format("Samples %d length %d requested from %s have already been discarded", startSample, duration,
- rawDataBlock.getDataName());
+ return String.format("Samples %d length %d requested from %s have already been discarded. %d to %d available", startSample, duration,
+ rawDataBlock.getDataName(), availableStart, availableEnd);
case DATA_NOT_ARRIVED:
return String.format("Samples %d length %d requested from %s have not yet arrived",
startSample, duration, rawDataBlock.getDataName());
@@ -70,6 +76,20 @@ public class RawDataUnavailableException extends Exception {
}
return super.getMessage();
}
+
+ /**
+ * @return the availableStart
+ */
+ public long getAvailableStart() {
+ return availableStart;
+ }
+
+ /**
+ * @return the availableEnd
+ */
+ public long getAvailableEnd() {
+ return availableEnd;
+ }
}
diff --git a/src/PamguardMVC/ThreadedObserver.java b/src/PamguardMVC/ThreadedObserver.java
index 83713af0..1e73c30a 100644
--- a/src/PamguardMVC/ThreadedObserver.java
+++ b/src/PamguardMVC/ThreadedObserver.java
@@ -8,6 +8,7 @@ import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess;
import Acquisition.DaqSystem;
import PamController.PamController;
+import PamModel.PamModel;
import PamUtils.PamCalendar;
import PamguardMVC.debug.Debug;
@@ -130,6 +131,7 @@ public class ThreadedObserver implements PamObserver {
}
}
}
+ h += PamModel.getPamModel().getPamModelSettings().getThreadingJitterMillis()*2;
return h;
}
diff --git a/src/PamguardMVC/dataSelector/CompoundDataSelector.java b/src/PamguardMVC/dataSelector/CompoundDataSelector.java
index 67c58d2d..2060e419 100644
--- a/src/PamguardMVC/dataSelector/CompoundDataSelector.java
+++ b/src/PamguardMVC/dataSelector/CompoundDataSelector.java
@@ -108,4 +108,25 @@ public class CompoundDataSelector extends DataSelector {
return selectorList;
}
+ @Override
+ public DataSelector findDataSelector(Class selectorClass) {
+ /**
+ * Check this, then all in the selector list. Should iterate happily back to
+ * a basic data selector as required even if there are multiple Compound ones.
+ */
+ if (this.getClass() == selectorClass) {
+ return this;
+ }
+ if (selectorList == null) {
+ return null;
+ }
+ for (DataSelector aSelector : selectorList) {
+ DataSelector subSel = aSelector.findDataSelector(selectorClass);
+ if (subSel != null) {
+ return subSel;
+ }
+ }
+ return null;
+ }
+
}
diff --git a/src/PamguardMVC/dataSelector/DataSelectDialog.java b/src/PamguardMVC/dataSelector/DataSelectDialog.java
index 5fd7f81f..9cb541e1 100644
--- a/src/PamguardMVC/dataSelector/DataSelectDialog.java
+++ b/src/PamguardMVC/dataSelector/DataSelectDialog.java
@@ -76,6 +76,22 @@ public class DataSelectDialog extends PamDialog {
// }
}
+ public boolean setTab(int tabIndex) {
+ if (tabPane == null) {
+ return false;
+ }
+ if (tabIndex < 0 || tabIndex >= tabPane.getTabCount()) {
+ return false;
+ }
+ try {
+ tabPane.setSelectedIndex(tabIndex);
+ }
+ catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
public boolean showDialog() {
if (dataPanel != null) {
dataPanel.setParams();
diff --git a/src/PamguardMVC/dataSelector/DataSelector.java b/src/PamguardMVC/dataSelector/DataSelector.java
index b033976c..e1573752 100644
--- a/src/PamguardMVC/dataSelector/DataSelector.java
+++ b/src/PamguardMVC/dataSelector/DataSelector.java
@@ -97,6 +97,23 @@ public abstract class DataSelector {
*/
abstract public DynamicSettingsPane getDialogPaneFX();
+ /**
+ * Find a data selector within a data selector. This is primarily for use with
+ * ComoundDataSelector objects which may encapsulate multiple other selectors,
+ * particularly when annotations are in use. but it's needed here so that it
+ * can be called on any DataSelector object.
+ * @param selectorClass class to data selector to find.
+ * @return DataSelector or null if that class of data selector doesn't exist.
+ */
+ public DataSelector findDataSelector(Class selectorClass) {
+ if (this.getClass() == selectorClass) {
+ return this;
+ }
+ else {
+ return null;
+ }
+ }
+
/**
* Get a menu item for the data selector that can be easily added
* to any other menu.
diff --git a/src/binaryFileStorage/BinaryStore.java b/src/binaryFileStorage/BinaryStore.java
index 1785eb6f..67151c22 100644
--- a/src/binaryFileStorage/BinaryStore.java
+++ b/src/binaryFileStorage/BinaryStore.java
@@ -228,6 +228,7 @@ PamSettingsSource, DataOutputStore {
super.pamToStart();
prepareStores();
openStores();
+ binaryStoreProcess.checkFileTimer();
}
@Override
@@ -245,9 +246,9 @@ PamSettingsSource, DataOutputStore {
* Called from the process to close and reopen each datastream in
* a new file. Probably gets called about once an hour on the hour.
*/
- protected void reOpenStores(int endReason) {
+ protected synchronized void reOpenStores(int endReason, long newFileTime) {
- long dataTime = PamCalendar.getTimeInMillis();
+ long dataTime = newFileTime;//PamCalendar.getTimeInMillis();
long analTime = System.currentTimeMillis();
BinaryOutputStream dataStream;
for (int i = 0; i < storageStreams.size(); i++) {
@@ -536,7 +537,7 @@ PamSettingsSource, DataOutputStore {
*/
if (immediateChanges) {
if (storesOpen) {
- reOpenStores(BinaryFooter.END_UNKNOWN);
+ reOpenStores(BinaryFooter.END_UNKNOWN, PamCalendar.getTimeInMillis());
}
}
@@ -2601,5 +2602,11 @@ PamSettingsSource, DataOutputStore {
public DataIntegrityChecker getInegrityChecker() {
return new BinaryIntegrityChecker(this);
}
+ /**
+ * @return the binaryStoreProcess
+ */
+ public BinaryStoreProcess getBinaryStoreProcess() {
+ return binaryStoreProcess;
+ }
}
diff --git a/src/binaryFileStorage/BinaryStoreProcess.java b/src/binaryFileStorage/BinaryStoreProcess.java
index c3a728b4..d95be814 100644
--- a/src/binaryFileStorage/BinaryStoreProcess.java
+++ b/src/binaryFileStorage/BinaryStoreProcess.java
@@ -7,37 +7,43 @@ import PamUtils.PamCalendar;
import PamguardMVC.PamProcess;
public class BinaryStoreProcess extends PamProcess {
-
+
private BinaryStore binaryStore;
-
+
private long startTime;
-
+
private long nextFileTime;
-
+
private Timer timer;
+ private Object timerSynch = new Object();
+
public BinaryStoreProcess(BinaryStore binaryStore) {
super(binaryStore, null);
this.binaryStore = binaryStore;
}
-
+
@Override
public String getProcessName() {
return "Binary store file control";
}
-
- public synchronized void checkFileTime() {
+
+ public synchronized void checkFileTime(long masterClockTime) {
+ // if (binaryStore.binaryStoreSettings.autoNewFiles &&
+ // PamCalendar.getTimeInMillis() >= nextFileTime) {
+ // startNewFiles();
+ // }
if (binaryStore.binaryStoreSettings.autoNewFiles &&
- PamCalendar.getTimeInMillis() >= nextFileTime) {
- startNewFiles();
+ masterClockTime >= nextFileTime) {
+ startNewFiles(masterClockTime);
}
-
+
}
- private synchronized void startNewFiles() {
+ private synchronized void startNewFiles(long masterClockTime) {
nextFileTime += binaryStore.binaryStoreSettings.fileSeconds * 1000;
- binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG);
+ binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG, masterClockTime);
}
@@ -46,24 +52,55 @@ public class BinaryStoreProcess extends PamProcess {
startTime = PamCalendar.getTimeInMillis();
long round = binaryStore.binaryStoreSettings.fileSeconds * 1000;
nextFileTime = (startTime/round) * round + round;
-// System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
- timer = new Timer();
- timer.schedule(new FileTimerTask(), 1000, 1000);
-
+ // System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
+ }
+
+ public void checkFileTimer() {
+ boolean needTimer = PamCalendar.isSoundFile() == false;
+ if (needTimer) {
+ startTimer();
+ }
+ else {
+ stopTimer();
+ }
}
+ private void startTimer() {
+ synchronized (timerSynch) {
+ if (timer == null) {
+ timer = new Timer();
+ timer.schedule(new FileTimerTask(), 1000, 1000);
+ }
+ }
+ }
+
+ private void stopTimer() {
+ synchronized (timerSynch) {
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ }
+ }
+
+
+
+ // @Override
+ // public void masterClockUpdate(long timeMilliseconds, long sampleNumber) {
+ // super.masterClockUpdate(timeMilliseconds, sampleNumber);
+ // checkFileTime(timeMilliseconds);
+ // }
+
class FileTimerTask extends TimerTask {
@Override
public void run() {
- checkFileTime();
+ checkFileTime(PamCalendar.getTimeInMillis());
}
}
@Override
public void pamStop() {
- if (timer != null) {
- timer.cancel();
- }
+ stopTimer();
}
}
diff --git a/src/clickDetector/BTAmplitudeSelector.java b/src/clickDetector/BTAmplitudeSelector.java
index ba020596..eb7c1b7e 100644
--- a/src/clickDetector/BTAmplitudeSelector.java
+++ b/src/clickDetector/BTAmplitudeSelector.java
@@ -29,6 +29,7 @@ import PamView.PamSymbolType;
import PamView.dialog.PamDialog;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
+import clickDetector.dataSelector.ClickDataSelector;
import pamMaths.HistogramDisplay;
import pamMaths.HistogramGraphicsLayer;
import pamMaths.PamHistogram;
@@ -59,6 +60,7 @@ public class BTAmplitudeSelector implements PamDialogPanel {
private JCheckBox amplitudeSelect;
private JTextField minAmplitude;
private JFrame ownerFrame;
+ private ClickDataSelector dataSelector;
/**
* @param btDisplay
*/
@@ -66,6 +68,7 @@ public class BTAmplitudeSelector implements PamDialogPanel {
super();
this.clickControl = clickControl;
this.btDisplay = btDisplay;
+ dataSelector = btDisplay.getClickDataSelector();
clickDataBlock = clickControl.getClickDataBlock();
histoPlot = new HistogramDisplay();
histoPlot.setGraphicsOverLayer(histoOverLayer = new HistoOverLayer());
@@ -125,7 +128,8 @@ public class BTAmplitudeSelector implements PamDialogPanel {
axMin = allHistogram.getScaleMinVal();
axMax = allHistogram.getScaleMaxVal();
plotRectangle = g.getClipBounds();
- double dx = (btDisplayParameters.minAmplitude - axMin) / (axMax-axMin) * plotRectangle.width;
+// double dx = (btDisplayParameters.minAmplitude - axMin) / (axMax-axMin) * plotRectangle.width;
+ double dx = (dataSelector.getParams().minimumAmplitude - axMin) / (axMax-axMin) * plotRectangle.width;
int x = (int) Math.round(dx);
g.setColor(Color.RED);
g.drawLine(x, 0, x, plotRectangle.height);
@@ -151,7 +155,7 @@ public class BTAmplitudeSelector implements PamDialogPanel {
double newAmp = (double) mouseEvent.getX() / histoOverLayer.plotRectangle.width *
(histoOverLayer.axMax-histoOverLayer.axMin) + histoOverLayer.axMin;
BTDisplayParameters btDisplayParameters = btDisplay.getBtDisplayParameters();
- btDisplayParameters.minAmplitude = newAmp;
+ dataSelector.getParams().minimumAmplitude = newAmp;
ampCtrlPanel.setParams(btDisplayParameters);
redrawHisto();
//
@@ -173,7 +177,7 @@ public class BTAmplitudeSelector implements PamDialogPanel {
if (btDisplayParameters.amplitudeSelect == false) {
return false;
}
- double dx = (btDisplayParameters.minAmplitude - histoOverLayer.axMin) /
+ double dx = (dataSelector.getParams().minimumAmplitude - histoOverLayer.axMin) /
(histoOverLayer.axMax-histoOverLayer.axMin) * histoOverLayer.plotRectangle.width;
int x = (int) Math.round(dx);
if (Math.abs(e.getX()-x) > 10) {
@@ -213,14 +217,14 @@ public class BTAmplitudeSelector implements PamDialogPanel {
}
private void setParams(BTDisplayParameters btParams) {
amplitudeSelect.setSelected(btParams.amplitudeSelect);
- minAmplitude.setText(String.format("%3.1f", btParams.minAmplitude));
+ minAmplitude.setText(String.format("%3.1f", dataSelector.getParams().minimumAmplitude));
enableControls();
}
private boolean getParams(BTDisplayParameters btParams) {
btParams.amplitudeSelect = amplitudeSelect.isSelected();
try {
- btParams.minAmplitude = Double.valueOf(minAmplitude.getText());
+ dataSelector.getParams().minimumAmplitude = Double.valueOf(minAmplitude.getText());
}
catch (NumberFormatException e) {
return false;
diff --git a/src/clickDetector/BTDisplayParameters.java b/src/clickDetector/BTDisplayParameters.java
index bf9604f7..925f0b74 100644
--- a/src/clickDetector/BTDisplayParameters.java
+++ b/src/clickDetector/BTDisplayParameters.java
@@ -44,17 +44,17 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara
public int nBearingGridLines = 1;
public int nAmplitudeGridLines = 0;
public int nICIGridLines = 0;
- public boolean showEchoes = true;
+// public boolean showEchoes = true;
public int minClickLength = 2, maxClickLength = 12;
public int minClickHeight = 2, maxClickHeight = 12;
private double timeRange = 10;
public int displayChannels = 0;
public boolean view360;
public boolean amplitudeSelect = false;
- public double minAmplitude = 0;
+// public double minAmplitude = 0;
public boolean showUnassignedICI = false;
- public boolean showEventsOnly = false;
- public boolean showANDEvents = true;
+// public boolean showEventsOnly = false;
+// public boolean showANDEvents = true;
public boolean logICIScale;
public int angleRotation = ROTATE_TOARRAY;
@@ -65,7 +65,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara
/*
* Show identified species
*/
- private boolean[] showSpeciesList;
+// private boolean[] showSpeciesList;
public int colourScheme = COLOUR_BY_TRAIN;
@@ -83,7 +83,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara
} catch (CloneNotSupportedException Ex) {
Ex.printStackTrace();
}
- showSpeciesList = null;
+// showSpeciesList = null;
return null;
}
@@ -107,49 +107,49 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara
/**
* @return the showSpeciesList
*/
- public boolean getShowSpecies(int speciesIndex) {
- if (showSpeciesList != null && showSpeciesList.length > speciesIndex) {
- return showSpeciesList[speciesIndex];
- }
- makeShowSpeciesList(speciesIndex);
- return true;
- }
- private void makeShowSpeciesList(int maxIndex) {
- if (showSpeciesList == null) {
- showSpeciesList = new boolean[0];
- }
- else if (showSpeciesList.length > maxIndex) {
- return;
- }
- int oldLength = showSpeciesList.length;
- showSpeciesList = Arrays.copyOf(showSpeciesList, maxIndex + 1);
- for (int i = oldLength; i <= maxIndex; i++) {
- showSpeciesList[i] = true;
- }
- }
+// public boolean getShowSpecies(int speciesIndex) {
+// if (showSpeciesList != null && showSpeciesList.length > speciesIndex) {
+// return showSpeciesList[speciesIndex];
+// }
+// makeShowSpeciesList(speciesIndex);
+// return true;
+// }
+// private void makeShowSpeciesList(int maxIndex) {
+// if (showSpeciesList == null) {
+// showSpeciesList = new boolean[0];
+// }
+// else if (showSpeciesList.length > maxIndex) {
+// return;
+// }
+// int oldLength = showSpeciesList.length;
+// showSpeciesList = Arrays.copyOf(showSpeciesList, maxIndex + 1);
+// for (int i = oldLength; i <= maxIndex; i++) {
+// showSpeciesList[i] = true;
+// }
+// }
/**
* @param showSpeciesList the showSpeciesList to set
*/
- public void setShowSpecies(int speciesIndex, boolean showSpecies) {
- makeShowSpeciesList(speciesIndex);
- showSpeciesList[speciesIndex] = showSpecies;
- }
+// public void setShowSpecies(int speciesIndex, boolean showSpecies) {
+// makeShowSpeciesList(speciesIndex);
+// showSpeciesList[speciesIndex] = showSpecies;
+// }
@Override
public PamParameterSet getParameterSet() {
PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR);
- try {
- Field field = this.getClass().getDeclaredField("showSpeciesList");
- ps.put(new PrivatePamParameterData(this, field) {
- @Override
- public Object getData() throws IllegalArgumentException, IllegalAccessException {
- return showSpeciesList;
- }
- });
- } catch (NoSuchFieldException | SecurityException e) {
- e.printStackTrace();
- }
+// try {
+// Field field = this.getClass().getDeclaredField("showSpeciesList");
+// ps.put(new PrivatePamParameterData(this, field) {
+// @Override
+// public Object getData() throws IllegalArgumentException, IllegalAccessException {
+// return showSpeciesList;
+// }
+// });
+// } catch (NoSuchFieldException | SecurityException e) {
+// e.printStackTrace();
+// }
return ps;
}
diff --git a/src/clickDetector/ClickBTDisplay.java b/src/clickDetector/ClickBTDisplay.java
index 637d9578..eaa05353 100644
--- a/src/clickDetector/ClickBTDisplay.java
+++ b/src/clickDetector/ClickBTDisplay.java
@@ -34,6 +34,7 @@ import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
+import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
@@ -115,9 +116,13 @@ import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
+import PamguardMVC.dataSelector.DataSelectDialog;
+import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.superdet.SuperDetection;
import clickDetector.ClickClassifiers.ClickIdInformation;
import clickDetector.ClickClassifiers.ClickIdentifier;
+import clickDetector.alarm.ClickAlarmParameters;
+import clickDetector.dataSelector.ClickDataSelector;
import clickDetector.dialogs.ClickDisplayDialog;
import clickDetector.offlineFuncs.OfflineEventDataBlock;
import clickDetector.offlineFuncs.OfflineEventDataUnit;
@@ -2240,11 +2245,15 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
if (btDisplayParameters.amplitudeSelect == false) {
return;
}
+ ClickDataSelector clickDataSelector = getClickDataSelector();
+ if (clickDataSelector == null) {
+ return;
+ }
int n = countAmplitudeDeselected();
PamDataBlock clickData = clickControl.getClickDataBlock();
int nAll = clickData.getUnitsCount();
String txt = String.format("%d of %d loaded clicks will not be displayed because their amplitude is < %3.1fdB",
- n, nAll, btDisplayParameters.minAmplitude);
+ n, nAll, clickDataSelector.getParams().minimumAmplitude);
Insets insets = getInsets();
int x = insets.left;
int y = getHeight()-5;
@@ -2383,19 +2392,33 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
}
menuItem = new JMenuItem("Settings ...");
+ menuItem.setToolTipText("Display options");
menuItem.addActionListener(new SettingsMenuAction());
menu.add(menuItem);
+ menuItem = new JMenuItem("Click data selector ...");
+ menuItem.setToolTipText("Detailed data selection options");
+ menuItem.addActionListener(new DataSelectorAction());
+ menu.add(menuItem);
menuItem = new JMenuItem("Show amplitude selector ...");
+ menuItem.setToolTipText("Graphical amplitude selector display");
menuItem.addActionListener(new AmplitudeSelector());
menu.add(menuItem);
menu.addSeparator();
- ArrayList colOptList = getSymbolChooser().getQuickMenuItems(clickControl.getGuiFrame(), this, "Colour by ", SymbolModType.EVERYTHING, true);
+ ArrayList colOptList = getSymbolChooser().getQuickMenuItems(clickControl.getGuiFrame(), this, "Colour by ", SymbolModType.EVERYTHING, false);
if (colOptList != null) {
for (JMenuItem menuIt : colOptList) {
menu.add(menuIt);
}
- menu.addSeparator();
}
+ menuItem = new JMenuItem("More symbol options ...");
+ menuItem.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showDataSymbolOptions(1);
+ }
+ });
+ menu.add(menuItem);
+ menu.addSeparator();
// menuItem = new JCheckBoxMenuItem("Colour by species id",
// btDisplayParameters.colourScheme == BTDisplayParameters.COLOUR_BY_SPECIES);
@@ -2470,7 +2493,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
return menu;
}
-
+
/**
* Looks through the current modules and finds if there is a target motion or static localiser
*/
@@ -2771,7 +2794,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
BTDisplayParameters newParameters =
ClickDisplayDialog.showDialog(clickControl,
- clickControl.getGuiFrame(), btDisplayParameters);
+ clickControl.getGuiFrame(), btDisplayParameters, getClickDataSelector().getClickAlarmParameters());
if (newParameters != null){
btDisplayParameters = newParameters.clone();
if (getVScaleManager() != null) {
@@ -2788,6 +2811,30 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
}
}
+
+
+ /**
+ * Get a data selector specific to this display.
+ * @return click data selector specific to this display.
+ */
+ public DataSelector getDataSelector() {
+ return clickControl.getClickDataBlock().getDataSelector(getUnitName(), false);
+ }
+
+ /**
+ * get the click specific data selector which may now be burried in a
+ * CompoundDataSelector if annotations have been used.
+ * @return ClickDataSelector.
+ */
+ public ClickDataSelector getClickDataSelector() {
+ DataSelector baseSel = getDataSelector();
+ if (baseSel == null) {
+ return null;
+ }
+ else {
+ return (ClickDataSelector) baseSel.findDataSelector(ClickDataSelector.class);
+ }
+ }
class AmplitudeSelector implements ActionListener {
@Override
@@ -2795,6 +2842,13 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
showAmplitudeSelector();
}
}
+
+ class DataSelectorAction implements ActionListener {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showDataSelector();
+ }
+ }
private void showAmplitudeSelector() {
@@ -2814,6 +2868,38 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
// }
}
+ /**
+ * Show a dialog with both data and symbol options, but go to the correct tab.
+ * @param selectedTab
+ * @return
+ */
+ private boolean showDataSymbolOptions(int selectedTab) {
+ Window javaFrame = clickControl.getGuiFrame();
+ DataSelectDialog dataSelectDialog = new DataSelectDialog(javaFrame, clickControl.getClickDataBlock(), getDataSelector(), symbolChooser);
+ if (javaFrame == null) {
+ dataSelectDialog.moveToMouseLocation();
+ }
+ dataSelectDialog.setTab(selectedTab);
+ boolean ok = dataSelectDialog.showDialog();
+ if (ok) {
+ repaintBoth();
+ if (clickControl.getOfflineToolbar() != null) {
+ clickControl.getOfflineToolbar().displayActivated(clickBTDisplay);
+ }
+ }
+ return ok;
+ }
+
+ public void showDataSelector() {
+// if (getDataSelector().showSelectDialog(clickControl.getGuiFrame())) {
+// repaintBoth();
+// if (clickControl.getOfflineToolbar() != null) {
+// clickControl.getOfflineToolbar().displayActivated(clickBTDisplay);
+// }
+// };
+ showDataSymbolOptions(0);
+ }
+
private void checkBTAmplitudeSelectHisto() {
if (btAmplitudeSelector == null) {
return;
@@ -3036,15 +3122,15 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
zoomer.paintShape(g, this, true);
}
- // long t1 = System.nanoTime();
- synchronized (clickData.getSynchLock()) {
- // long t2 = System.nanoTime();
- // double ms = ((double) (t2-t1)) / 1000000.;
- // if (btDisplayParameters.VScale == BTDisplayParameters.DISPLAY_ICI) {
- // sortTempICIs();
- // }
+ ArrayList clickCopy = clickData.getDataCopy(displayStartMillis, displayStartMillis+displayLengthMillis, true, getDataSelector());
+ if (clickCopy.size() == 0) {
+ return;
+ }
+ ListIterator clickIterator = clickCopy.listIterator(clickCopy.size()-1);
- ListIterator clickIterator = clickData.getListIterator(PamDataBlock.ITERATOR_END);
+// synchronized (clickData.getSynchLock()) {
+//
+// ListIterator clickIterator = clickData.getListIterator(PamDataBlock.ITERATOR_END);
while (clickIterator.hasPrevious()) {
click = clickIterator.previous();
if (shouldPlot(prevPlottedClick)){
@@ -3060,11 +3146,6 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
if (shouldPlot(prevPlottedClick)){ // and draw the last one !
drawClick(g, prevPlottedClick, clipRectangle);
}
- // g.drawString(String.format("Wait synch %3.3fms", ms), 0, 20);
- }
- // long t3 = System.nanoTime();
- // g.drawString(String.format("Last draw %3.3fms", lastPaintTime), 0, 20);
- // lastPaintTime = ((double) (t3-t0)) / 1000000.;
}
@Override
@@ -3342,7 +3423,9 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
else if (btDisplayParameters.colourScheme == BTDisplayParameters.COLOUR_BY_HYDROPHONE) {
keyPanel.add(new TextKeyItem("Colour by hydrophone"));
}
- if (btDisplayParameters.getShowSpecies(0)) {
+ ClickAlarmParameters selectParams = getClickDataSelector().getParams();
+// if (btDisplayParameters.getShowSpecies(0)) {
+ if (selectParams.onlineAutoEvents | selectParams.onlineManualEvents) {
keyPanel.add(symbolChooser.getDefaultSymbol(true).makeKeyItem("Unidentified species"));
}
@@ -3354,7 +3437,8 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
PamSymbol[] symbols = clickControl.getClickIdentifier().getSymbols();
if (speciesList != null) {
for (int i = 0; i < speciesList.length; i++) {
- if (btDisplayParameters.getShowSpecies(i+1)) {
+ if (selectParams.getUseSpecies(i+1)) {
+// if (btDisplayParameters.getShowSpecies(i+1)) {
if (btDisplayParameters.colourScheme != BTDisplayParameters.COLOUR_BY_TRAIN) {
keyPanel.add(symbols[i].makeKeyItem(speciesList[i]));
}
@@ -3423,11 +3507,12 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
PamDataBlock clickData = clickControl.getClickDataBlock();
ClickDetection click;
int n = 0;
+ double minAmpli = getClickDataSelector().getParams().minimumAmplitude;
synchronized (clickData.getSynchLock()) {
ListIterator clickIterator = clickData.getListIterator(0);
while (clickIterator.hasNext()) {
click = clickIterator.next();
- if (click.getAmplitudeDB() < btDisplayParameters.minAmplitude) {
+ if (click.getAmplitudeDB() < minAmpli) {
n++;
}
}
@@ -3448,29 +3533,30 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
*/
synchronized boolean shouldPlot(ClickDetection click) {
if (click == null) return false;
- if (!clickInTimeWindow(click)) return false;
- if (btDisplayParameters.showEchoes == false && click.isEcho()) {
- return false;
- }
+// if (!clickInTimeWindow(click)) return false;
+// if (btDisplayParameters.showEchoes == false && click.isEcho()) {
+// return false;
+// }
if (btDisplayParameters.VScale == BTDisplayParameters.DISPLAY_ICI) {
// if (btDisplayParameters.showUnassignedICI == false && click.getICI() < 0) return false;
if (btDisplayParameters.showUnassignedICI == false && click.getSuperDetectionsCount() <= 0) return false;
// otherwise may be ok, since will estimate all ici's on teh fly.
}
- if (btDisplayParameters.amplitudeSelect && click.getAmplitudeDB() < btDisplayParameters.minAmplitude) {
- return false;
- }
+// if (btDisplayParameters.amplitudeSelect && click.getAmplitudeDB() < btDisplayParameters.minAmplitude) {
+// return false;
+// }
if (btDisplayParameters.displayChannels > 0 && (btDisplayParameters.displayChannels & click.getChannelBitmap()) == 0) return false;
- int speciesIndex = clickControl.getClickIdentifier().codeToListIndex(click.getClickType());
- boolean showSpecies = btDisplayParameters.getShowSpecies(speciesIndex+1);
- boolean showEvents = (btDisplayParameters.showEventsOnly == false || click.getSuperDetectionsCount() > 0);
- if (btDisplayParameters.showANDEvents) {
- return showSpecies & showEvents;
- }
- else {
- return showSpecies | showEvents;
- }
+// int speciesIndex = clickControl.getClickIdentifier().codeToListIndex(click.getClickType());
+// boolean showSpecies = btDisplayParameters.getShowSpecies(speciesIndex+1);
+// boolean showEvents = (btDisplayParameters.showEventsOnly == false || click.getSuperDetectionsCount() > 0);
+// if (btDisplayParameters.showANDEvents) {
+// return showSpecies & showEvents;
+// }
+// else {
+// return showSpecies | showEvents;
+// }
+ return true;
}
/**
@@ -4085,7 +4171,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
amplitudeSelectorLabel.setText("");
}
else {
- String txt = String.format(" Amplitude Selector showing clicks > %3.1fdB", btDisplayParameters.minAmplitude);
+ String txt = String.format(" Amplitude Selector showing clicks > %3.1fdB", getClickDataSelector().getParams().minimumAmplitude);
amplitudeSelectorLabel.setText(txt);
}
}
diff --git a/src/clickDetector/ClickDetector.java b/src/clickDetector/ClickDetector.java
index 56b9481e..2ee4ece2 100644
--- a/src/clickDetector/ClickDetector.java
+++ b/src/clickDetector/ClickDetector.java
@@ -329,7 +329,7 @@ public class ClickDetector extends PamProcess {
offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging());
triggerBackgroundHandler = new TriggerBackgroundHandler(this);
-
+
clickBackgroundManager = new ClickBackgroundManager(this);
setProcessCheck(new BaseProcessCheck(this, RawDataUnit.class, 1, 0.0000001));
@@ -1378,7 +1378,7 @@ public class ClickDetector extends PamProcess {
private boolean initialiseFilters;
private long clickStartSample, clickEndSample;
-
+
private double maxSignalExcess;
private int clickTriggers;
diff --git a/src/clickDetector/alarm/ClickAlarmParameters.java b/src/clickDetector/alarm/ClickAlarmParameters.java
index 8bed53c6..d126f4c6 100644
--- a/src/clickDetector/alarm/ClickAlarmParameters.java
+++ b/src/clickDetector/alarm/ClickAlarmParameters.java
@@ -17,10 +17,12 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable,
public static final long serialVersionUID = 1L;
private boolean[] useSpeciesList;
private double[] speciesWeightings;
- public boolean useEchoes;
- public boolean scoreByAmplitude;
- public boolean onlineAutoEvents, onlineManualEvents;
+ public boolean useEchoes = true;
+ public boolean scoreByAmplitude; // alarm options, probably not used any more.
+ public double minimumAmplitude;
+ public boolean onlineAutoEvents = true, onlineManualEvents = true;
public int minICIMillis;
+ private boolean clicksOREvents = false;
/*
* Which events to use ...
*/
@@ -165,5 +167,30 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable,
return ps;
}
+ /**
+ * @return the clicksOREvents
+ */
+ public boolean isClicksOREvents() {
+ return clicksOREvents;
+ }
+
+ /**
+ * @param clicksOREvents the clicksOREvents to set
+ */
+ public void setClicksOREvents(boolean clicksOREvents) {
+ this.clicksOREvents = clicksOREvents;
+ }
+ /**
+ * @return the clicksANDEvents
+ */
+ public boolean isClicksANDEvents() {
+ return !clicksOREvents;
+ }
+
+
+ public void setClicksANDEvents(boolean clicksANDEvents) {
+ this.clicksOREvents = !clicksANDEvents;
+ }
+
}
diff --git a/src/clickDetector/dataSelector/ClickDataSelector.java b/src/clickDetector/dataSelector/ClickDataSelector.java
index 5be77c2a..9f2248d3 100644
--- a/src/clickDetector/dataSelector/ClickDataSelector.java
+++ b/src/clickDetector/dataSelector/ClickDataSelector.java
@@ -38,9 +38,9 @@ public class ClickDataSelector extends DataSelector {
@Override
public PamDialogPanel getDialogPanel() {
- if (clickSelectPanel == null) {
+// if (clickSelectPanel == null) {
clickSelectPanel = new ClickSelectPanel(this, allowScores, useEventTypes);
- }
+// }
return clickSelectPanel;
}
@Override
@@ -60,19 +60,25 @@ public class ClickDataSelector extends DataSelector {
if (clickAlarmParameters.useEchoes == false && click.isEcho()) {
return 0;
}
- /**
- * First score based on whether the event panel is in use and
- * criteria satisfied.
- */
+
+ double score = scoreClick(click);
if (useEventTypes) {
- if (wantEventType(click) == false) {
- return 0;
+ double eventScore = scoreEventType(click);
+ if (clickAlarmParameters.isClicksANDEvents()) {
+ score = Math.min(score, eventScore);
+ }
+ else {
+ score = Math.max(score, eventScore);
}
}
+ return score;
- /*
- * Now score based on whether or not it's individual click type is wanted.
- */
+ }
+
+ private double scoreClick(ClickDetection click) {
+ if (click.getAmplitudeDB() < clickAlarmParameters.minimumAmplitude) {
+ return 0;
+ }
ClickIdentifier clickIdentifier = clickControl.getClickIdentifier();
int code = click.getClickType();
if (code > 0 && clickIdentifier != null) {
@@ -81,13 +87,13 @@ public class ClickDataSelector extends DataSelector {
boolean enabled = clickAlarmParameters.getUseSpecies(code);
if (enabled == false) {
return 0;
- }
- if (isAllowScores()) {
+ }if (isAllowScores()) {
return clickAlarmParameters.getSpeciesWeight(code);
}
else {
return 1;
}
+
}
/**
@@ -95,7 +101,7 @@ public class ClickDataSelector extends DataSelector {
* @param click
* @return
*/
- private boolean wantEventType(ClickDetection click) {
+ private double scoreEventType(ClickDetection click) {
OfflineEventDataUnit oev = null;
try {
@@ -107,7 +113,7 @@ public class ClickDataSelector extends DataSelector {
int eventId = click.getOfflineEventID();
if (oev == null) {
- return clickAlarmParameters.unassignedEvents;
+ return clickAlarmParameters.unassignedEvents ? 1 : 0;
}
// see if there is a super detection and see if it's got a comment.
@@ -118,10 +124,10 @@ public class ClickDataSelector extends DataSelector {
isAutomatic = comment.startsWith("Automatic");
}
if (isAutomatic && clickAlarmParameters.onlineAutoEvents) {
- return true;
+ return 1;
}
else if (clickAlarmParameters.onlineManualEvents) {
- return true;
+ return 1;
}
// if (clickAlarmParameters.onlineAutoEvents && comment.startsWith("Automatic")) {
// return true;
@@ -134,7 +140,7 @@ public class ClickDataSelector extends DataSelector {
* list of event types and see if it's wanted.
*/
String evType = oev.getEventType();
- return clickAlarmParameters.isUseEventType(evType);
+ return clickAlarmParameters.isUseEventType(evType) ? 1 : 0;
}
@@ -188,7 +194,7 @@ public class ClickDataSelector extends DataSelector {
* @see PamguardMVC.dataSelector.DataSelector#getParams()
*/
@Override
- public DataSelectParams getParams() {
+ public ClickAlarmParameters getParams() {
return clickAlarmParameters;
}
diff --git a/src/clickDetector/dataSelector/ClickSelectPanel.java b/src/clickDetector/dataSelector/ClickSelectPanel.java
index 512e088d..60e1566a 100644
--- a/src/clickDetector/dataSelector/ClickSelectPanel.java
+++ b/src/clickDetector/dataSelector/ClickSelectPanel.java
@@ -4,6 +4,7 @@ import generalDatabase.lookupTables.LookUpTables;
import generalDatabase.lookupTables.LookupList;
import java.awt.BorderLayout;
+import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
@@ -13,11 +14,13 @@ import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import PamController.PamController;
@@ -42,6 +45,7 @@ public class ClickSelectPanel implements PamDialogPanel {
private ClickDataSelector clickDataSelector;
private JPanel mainPanel;
private boolean isViewer;
+ private JComboBox andOrBox;
public static final String mainTip = "You should select options in both the Click Type and the Event Type panels";
@@ -70,10 +74,12 @@ public class ClickSelectPanel implements PamDialogPanel {
public void setParams() {
eventTypePanel.setParams();
speciesPanel.setParams();
+ andOrBox.setSelectedIndex(clickDataSelector.getParams().isClicksANDEvents() ? 0 : 1);
}
@Override
public boolean getParams() {
+ clickDataSelector.getParams().setClicksANDEvents(andOrBox.getSelectedIndex() == 0);
return (speciesPanel.getParams() & eventTypePanel.getParams());
}
@@ -163,17 +169,26 @@ public class ClickSelectPanel implements PamDialogPanel {
// JRadioButton andEvents, orEvents;
// JRadioButton anyEvents, onlyEvents;
private JCheckBox useEchoes;
+ private JTextField minAmplitude;
private JCheckBox scoreByAmplitude;
private JTextField minICI;
SpeciesPanel () {
super();
- setLayout(new BorderLayout());
+// setLayout(new BorderLayout());
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
northPanel = new JPanel();
northPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new PamGridBagContraints();
- c.gridwidth = 3;
+ c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
+ northPanel.add(new JLabel("Minimum amplitude ", JLabel.RIGHT), c);
+ c.gridx++;
+ northPanel.add(minAmplitude = new JTextField(4), c);
+ c.gridx++;
+ northPanel.add(new JLabel(" dB"));
+ c.gridx = 0;
+ c.gridy++;
northPanel.add(new PamAlignmentPanel(useEchoes = new JCheckBox("Use Echoes"), BorderLayout.WEST), c);
c.gridwidth = 1;
c.gridy++;
@@ -185,35 +200,50 @@ public class ClickSelectPanel implements PamDialogPanel {
// minICI.setToolTipText("Minimum ICI in milliseconds");
// c.gridx++;
// northPanel.add(new JLabel(" ms", JLabel.LEFT), c);
- c.gridwidth = 3;
- c.gridy++;
- c.gridx = 0;
- northPanel.add(scoreByAmplitude = new JCheckBox("Score by amplitude"), c);
- scoreByAmplitude.setVisible(allowScores);
- scoreByAmplitude.addActionListener(new AllSpeciesListener());
+ scoreByAmplitude = new JCheckBox("Score by amplitude");
+ if (allowScores) {
+ c.gridwidth = 3;
+ c.gridy++;
+ c.gridx = 0;
+ northPanel.add(scoreByAmplitude, c);
+ scoreByAmplitude.setVisible(allowScores);
+ scoreByAmplitude.addActionListener(new AllSpeciesListener());
+ }
WestAlignedPanel walpn;
- add(BorderLayout.NORTH, walpn = new WestAlignedPanel(northPanel));
- walpn.setBorder(new SeparatorBorder("Echoes"));
+ this.add(walpn = new WestAlignedPanel(northPanel));
+ walpn.setBorder(new SeparatorBorder("Click Selection"));
JPanel centralOuterPanel = new JPanel(new BorderLayout());
centralPanel.setLayout(new GridBagLayout());
- centralOuterPanel.setBorder(new SeparatorBorder("Click Type Selection"));
+ centralOuterPanel.setBorder(new SeparatorBorder("Click Types"));
- add(BorderLayout.CENTER, centralOuterPanel);
+ this.add(centralOuterPanel);
JScrollPane scrollPane = new DialogScrollPane(new PamAlignmentPanel(centralPanel, BorderLayout.WEST), 10);
centralOuterPanel.add(BorderLayout.CENTER, scrollPane);
centralEastPanel.setLayout(new GridBagLayout());
c = new PamGridBagContraints();
- centralEastPanel.add(selectAll = new JButton("Select All"), c);
- c.gridx++;
- centralEastPanel.add(clearAll = new JButton("Clear All"), c);
+ c.ipady = 0;
+ c.insets.bottom = c.insets.top = c.insets.left = c.insets.right = 0;
+ centralEastPanel.add(selectAll = new JButton("All"), c);
+ c.gridy++;
+ centralEastPanel.add(clearAll = new JButton("None"), c);
+ selectAll.setBorder(new EmptyBorder(3,3,2,3));
+ clearAll.setBorder(new EmptyBorder(3,3,2,3));
selectAll.addActionListener(new AutoSelect(true));
clearAll.addActionListener(new AutoSelect(false));
- centralOuterPanel.add(BorderLayout.SOUTH, new PamAlignmentPanel(centralEastPanel, BorderLayout.WEST));
+ centralOuterPanel.add(BorderLayout.EAST, new PamAlignmentPanel(centralEastPanel, BorderLayout.NORTH));
centralOuterPanel.setToolTipText(mainTip);
+ this.add(andOrBox = new JComboBox<>());
+ andOrBox.setToolTipText("Select how to logically combine the click and event selections");
+ andOrBox.addItem("AND");
+ andOrBox.addItem("OR");
+ JPanel emptyPanel = new JPanel();
+ emptyPanel.setPreferredSize(new Dimension(10, 5));
+ this.add(emptyPanel);
+
setToolTipText(mainTip);
}
@@ -254,6 +284,7 @@ public class ClickSelectPanel implements PamDialogPanel {
}
}
useEchoes.setSelected(clickAlarmParameters.useEchoes);
+ minAmplitude.setText(String.format("%3.1f", clickAlarmParameters.minimumAmplitude));
minICI.setText(String.format("%d", clickAlarmParameters.minICIMillis));
scoreByAmplitude.setSelected(clickAlarmParameters.scoreByAmplitude);
allWeight.setText(String.format("%3.1f", clickAlarmParameters.getSpeciesWeight(0)));
@@ -279,6 +310,12 @@ public class ClickSelectPanel implements PamDialogPanel {
ClickAlarmParameters clickAlarmParameters = clickDataSelector.getClickAlarmParameters().clone();
clickAlarmParameters.useEchoes = useEchoes.isSelected();
+ try {
+ clickAlarmParameters.minimumAmplitude = Double.valueOf(minAmplitude.getText());
+ }
+ catch (NumberFormatException e) {
+ return PamDialog.showWarning(null, "Minimum amplitude", "Invalid minimum amplitude value");
+ }
try {
clickAlarmParameters.minICIMillis = Integer.valueOf(minICI.getText());
}
diff --git a/src/clickDetector/dialogs/ClickDisplayDialog.java b/src/clickDetector/dialogs/ClickDisplayDialog.java
index 0a049c30..5c08f7bd 100644
--- a/src/clickDetector/dialogs/ClickDisplayDialog.java
+++ b/src/clickDetector/dialogs/ClickDisplayDialog.java
@@ -31,6 +31,7 @@ import PamView.dialog.warn.WarnOnce;
import clickDetector.BTDisplayParameters;
import clickDetector.ClickControl;
import clickDetector.ClickClassifiers.ClickIdentifier;
+import clickDetector.alarm.ClickAlarmParameters;
/**
* Dialog for basic click display parameters
@@ -57,6 +58,8 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
private SizePanel sizePanel;
private SpeciesPanel speciesPanel;
private JComboBox angleTypes;
+
+ private ClickAlarmParameters clickSelectParams;
private ClickDisplayDialog(Window owner) {
@@ -86,12 +89,13 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
}
- public static BTDisplayParameters showDialog(ClickControl clickControl, Window parentFrame, BTDisplayParameters btDisplayParameters) {
+ public static BTDisplayParameters showDialog(ClickControl clickControl, Window parentFrame, BTDisplayParameters btDisplayParameters, ClickAlarmParameters clickSelectParams) {
if (singleInstance == null || singleInstance.getOwner() != parentFrame) {
singleInstance = new ClickDisplayDialog(parentFrame);
}
singleInstance.clickControl = clickControl;
singleInstance.btDisplayParameters = btDisplayParameters.clone();
+ singleInstance.clickSelectParams = clickSelectParams;
singleInstance.setParams(btDisplayParameters);
singleInstance.setVisible(true);
return singleInstance.btDisplayParameters;
@@ -514,14 +518,16 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
}
}
}
- showEchoes.setSelected(btDisplayParameters.showEchoes);
+ showEchoes.setSelected(clickSelectParams.useEchoes);
if (species == null) {
showAll.setSelected(true);
}
else {
- showAll.setSelected(btDisplayParameters.getShowSpecies(0));
+// showAll.setSelected(btDisplayParameters.getShowSpecies(0));
+ showAll.setSelected(clickSelectParams.getUseSpecies(0));
for (int i = 0; i < species.length; i++) {
- species[i].setSelected(btDisplayParameters.getShowSpecies(i+1));
+ species[i].setSelected(clickSelectParams.getUseSpecies(i+1));
+// species[i].setSelected(btDisplayParameters.getShowSpecies(i+1));
}
// if (btDisplayParameters.showSpeciesList != null) {
// for (int i = 0; i < Math.min(species.length, btDisplayParameters.showSpeciesList.length);i++) {
@@ -529,9 +535,10 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
// }
// }
}
-
- clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly);
- andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1);
+ clicksInAnEvent.setSelected(clickSelectParams.onlineAutoEvents | clickSelectParams.onlineAutoEvents);
+
+// clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly);
+// andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1);
// orEvents.setSelected(!btDisplayParameters.showANDEvents);
// andEvents.setSelected(btDisplayParameters.showANDEvents);
// anyEvents.setSelected(!btDisplayParameters.showEventsOnly);
@@ -540,19 +547,17 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
enableButtons();
}
boolean getParams() {
- btDisplayParameters.showEchoes = showEchoes.isSelected();
- btDisplayParameters.setShowSpecies(0, showAll.isSelected());
- if (species != null) {
- for (int i = 0; i < species.length; i++) {
- btDisplayParameters.setShowSpecies(i+1, species[i].isSelected());
- }
-
- }
-
- btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected();
- btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0);
-// btDisplayParameters.showANDEvents = andEvents.isSelected();
-// btDisplayParameters.showEventsOnly = onlyEvents.isSelected();
+// clickSelectParams.useEchoes = showEchoes.isSelected();
+// btDisplayParameters.setShowSpecies(0, showAll.isSelected());
+// if (species != null) {
+// for (int i = 0; i < species.length; i++) {
+// btDisplayParameters.setShowSpecies(i+1, species[i].isSelected());
+// }
+//
+// }
+//
+// btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected();
+// btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0);
return true;
}
class AllSpeciesListener implements ActionListener {
diff --git a/src/clickDetector/offlineFuncs/OfflineToolbar.java b/src/clickDetector/offlineFuncs/OfflineToolbar.java
index 9ff5ba5f..f7e1e34c 100644
--- a/src/clickDetector/offlineFuncs/OfflineToolbar.java
+++ b/src/clickDetector/offlineFuncs/OfflineToolbar.java
@@ -31,12 +31,15 @@ import clickDetector.ClickBTDisplay;
import clickDetector.ClickControl;
import clickDetector.ClickDisplay;
import clickDetector.ClickClassifiers.ClickIdentifier;
+import clickDetector.alarm.ClickAlarmParameters;
+import clickDetector.dataSelector.ClickDataSelector;
import PamView.PamToolBar;
import PamView.component.PamSettingsIconButton;
import PamView.dialog.PamCheckBox;
import PamView.dialog.PamLabel;
import PamView.dialog.PamRadioButton;
import PamView.panel.PamPanel;
+import PamguardMVC.dataSelector.DataSelectParams;
public class OfflineToolbar {
@@ -252,19 +255,29 @@ public class OfflineToolbar {
return;
}
try {
+ ClickDataSelector clickDataSelector = currentBTDisplay.getClickDataSelector();
+ ClickAlarmParameters selectParams = clickDataSelector.getParams();
BTDisplayParameters btDisplayParameters = currentBTDisplay.getBtDisplayParameters();
- btDisplayParameters.setShowSpecies(0, showNonSpecies.isSelected());
- btDisplayParameters.showEchoes = showEchoes.isSelected();
+
+ selectParams.setUseSpecies(0, showNonSpecies.isSelected());
+// btDisplayParameters.setShowSpecies(0, showNonSpecies.isSelected());
+// btDisplayParameters.showEchoes = showEchoes.isSelected();
+ selectParams.useEchoes = showEchoes.isSelected();
+
if (clicksInAnEvent != null) {
- btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected();
+// btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected();
+// selectParams.onlineAutoEvents = selectParams.onlineManualEvents = true;
+ selectParams.unassignedEvents =clicksInAnEvent.isSelected() == false;
}
if (andOrSelection != null) {
- btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0);
+ selectParams.setClicksANDEvents(andOrSelection.getSelectedIndex() == 0);
+// btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0);
}
if (speciesButtons != null) {
int n = speciesButtons.length;
for (int i = 0; i < n; i++) {
- btDisplayParameters.setShowSpecies(i+1, speciesButtons[i].isSelected());
+ selectParams.setUseSpecies(i+1, speciesButtons[i].isSelected());
+// btDisplayParameters.setShowSpecies(i+1, speciesButtons[i].isSelected());
}
}
currentBTDisplay.repaintTotal();
@@ -275,23 +288,35 @@ public class OfflineToolbar {
}
private void checkButtons(BTDisplayParameters btDisplayParameters) {
- showEchoes.setSelected(btDisplayParameters.showEchoes);
- showNonSpecies.setSelected(btDisplayParameters.getShowSpecies(0));
+ ClickDataSelector clickDataSelector = currentBTDisplay.getClickDataSelector();
+ ClickAlarmParameters selectParams = clickDataSelector.getParams();
+ showEchoes.setSelected(selectParams.useEchoes);
+ showNonSpecies.setSelected(selectParams.getUseSpecies(0));
+// showNonSpecies.setSelected(btDisplayParameters.getShowSpecies(0));
+ boolean anySel = false;;
if (clicksInAnEvent != null) {
- clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly);
+ clicksInAnEvent.setSelected(selectParams.unassignedEvents == false);
+ anySel |= clicksInAnEvent.isSelected();
+// clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly);
}
if (speciesButtons != null) {
int n = speciesButtons.length;
for (int i = 0; i < n; i++) {
- speciesButtons[i].setSelected(btDisplayParameters.getShowSpecies(i+1));
+ speciesButtons[i].setSelected(selectParams.getUseSpecies(i+1));
+ anySel |= speciesButtons[i].isSelected();
+// speciesButtons[i].setSelected(btDisplayParameters.getShowSpecies(i+1));
}
}
// setting combo box fires actionlistener, so we have to make sure that all checkboxes have been properly set first
// or else they will get cleared later
if (andOrSelection != null) {
- andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1);
+ andOrSelection.setSelectedIndex(selectParams.isClicksANDEvents() ? 0 : 1);
+// andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1);
}
firstSetup = true;
+ if (anySel) {
+ selectParams.setCombinationFlag(DataSelectParams.DATA_SELECT_AND);
+ }
}
}
diff --git a/src/clickDetector/tdPlots/ClickClassSymbolModifier.java b/src/clickDetector/tdPlots/ClickClassSymbolModifier.java
index 2ad9c3c7..e27b9a4a 100644
--- a/src/clickDetector/tdPlots/ClickClassSymbolModifier.java
+++ b/src/clickDetector/tdPlots/ClickClassSymbolModifier.java
@@ -1,7 +1,13 @@
package clickDetector.tdPlots;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.border.TitledBorder;
+
import PamView.GeneralProjector;
import PamView.PamSymbol;
+import PamView.dialog.PamDialogPanel;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModType;
@@ -32,4 +38,41 @@ public class ClickClassSymbolModifier extends SymbolModifier {
}
}
+ @Override
+ public PamDialogPanel getDialogPanel() {
+ // Just a play to check buttons and menus work. Not actually used at all so revert to super: returns null.
+ return super.getDialogPanel();
+// return new DumyPanel();
+ }
+
+ private class DumyPanel implements PamDialogPanel {
+
+ private JPanel mainPanel;
+ public DumyPanel() {
+ super();
+ mainPanel = new JPanel();
+ mainPanel.setBorder(new TitledBorder("More options"));
+ mainPanel.add(new JCheckBox("Dummy option"));
+ }
+
+ @Override
+ public JComponent getDialogComponent() {
+ // TODO Auto-generated method stub
+ return mainPanel;
+ }
+
+ @Override
+ public void setParams() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean getParams() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
}
diff --git a/src/clickDetector/tdPlots/ClickPlotInfo.java b/src/clickDetector/tdPlots/ClickPlotInfo.java
index 18cdfb7a..baa60626 100644
--- a/src/clickDetector/tdPlots/ClickPlotInfo.java
+++ b/src/clickDetector/tdPlots/ClickPlotInfo.java
@@ -9,6 +9,8 @@ import clickDetector.BTDisplayParameters;
import clickDetector.ClickControl;
import clickDetector.ClickDetection;
import clickDetector.ClickDisplayManagerParameters;
+import clickDetector.alarm.ClickAlarmParameters;
+import clickDetector.dataSelector.ClickDataSelector;
import clickDetector.dialogs.ClickDisplayDialog;
import PamView.GeneralProjector.ParameterType;
import PamView.GeneralProjector.ParameterUnits;
@@ -52,6 +54,10 @@ public class ClickPlotInfo extends TDDataInfo {
allScaleInfo[3] = slantScaleInfo;
clickHidingDialog = new ClickHidingDialog(this);
}
+
+ ClickDataSelector getDataSelector() {
+ return (ClickDataSelector) clickControl.getClickDataBlock().getDataSelector("ClickTDPlots", false);
+ }
@Override
public Double getDataValue(PamDataUnit pamDataUnit) {
@@ -110,7 +116,8 @@ public class ClickPlotInfo extends TDDataInfo {
private synchronized boolean shouldPlot(ClickDetection click) {
if (click == null) return false;
- if (btDisplayParams.showEchoes == false && click.isEcho()) {
+ boolean showEchoes = getDataSelector().getClickAlarmParameters().useEchoes;
+ if (showEchoes == false && click.isEcho()) {
return false;
}
@@ -170,7 +177,7 @@ public class ClickPlotInfo extends TDDataInfo {
*/
@Override
public boolean editOptions(Window frame) {
- BTDisplayParameters newParams = ClickDisplayDialog.showDialog(clickControl, frame, btDisplayParams);
+ BTDisplayParameters newParams = ClickDisplayDialog.showDialog(clickControl, frame, btDisplayParams, getDataSelector().getClickAlarmParameters());
if (newParams != null) {
btDisplayParams = newParams.clone();
updateSettings();
diff --git a/src/clipgenerator/ClipProcess.java b/src/clipgenerator/ClipProcess.java
index b61c0a43..112281e3 100644
--- a/src/clipgenerator/ClipProcess.java
+++ b/src/clipgenerator/ClipProcess.java
@@ -140,10 +140,13 @@ public class ClipProcess extends SpectrogramMarkProcess {
clipErr = clipRequest.clipBlockProcess.processClipRequest(clipRequest);
switch (clipErr) {
case 0: // no error - clip should have been created.
+ li.remove();
+ break;
case RawDataUnavailableException.DATA_ALREADY_DISCARDED:
case RawDataUnavailableException.INVALID_CHANNEL_LIST:
- // System.out.println("Clip error : " + clipErr);
+// System.out.println("Clip error : " + clipErr);
li.remove();
+ break;
case RawDataUnavailableException.DATA_NOT_ARRIVED:
continue; // hopefully, will get this next time !
}
@@ -230,6 +233,17 @@ public class ClipProcess extends SpectrogramMarkProcess {
}
minH = Math.max(minH, clipBlockProcesses[i].getRequiredDataHistory(o, arg));
}
+
+ ClipRequest firstClip = null;
+ synchronized(clipRequestSynch) {
+ if (clipRequestQueue.size() > 0) {
+ firstClip = clipRequestQueue.get(0);
+ }
+ }
+ if (firstClip != null) {
+ minH += firstClip.dataUnit.getDurationInMilliseconds();
+ }
+
minH += Math.max(3000, 192000/(long)getSampleRate());
if (specMouseDown) {
minH = Math.max(minH, masterClockTime-specMouseDowntime);
@@ -453,8 +467,7 @@ public class ClipProcess extends SpectrogramMarkProcess {
this.dataBlock = dataBlock;
this.clipGenSetting = clipGenSetting;
clipBudgetMaker = new StandardClipBudgetMaker(this);
- dataBlock.addObserver(this, true);
-
+ dataBlock.addObserver(this, false);
if (rawDataBlock != null) {
int chanMap = decideChannelMap(rawDataBlock.getChannelMap());
@@ -499,6 +512,7 @@ public class ClipProcess extends SpectrogramMarkProcess {
rawData = rawDataBlock.getSamples(rawStart, (int) (rawEnd-rawStart), channelMap);
}
catch (RawDataUnavailableException e) {
+ System.out.println(e.getMessage());
return e.getDataCause();
}
if (rawData==null) {
@@ -583,9 +597,15 @@ public class ClipProcess extends SpectrogramMarkProcess {
public PamObserver getObserverObject() {
return clipProcess.getObserverObject();
}
+
@Override
public long getRequiredDataHistory(PamObservable o, Object arg) {
- return (long) ((clipGenSetting.preSeconds+clipGenSetting.postSeconds) * 1000.);
+ long h = (long) ((clipGenSetting.preSeconds+clipGenSetting.postSeconds) * 1000.);
+// if (dataBlock != null) {
+ // can't do this since dataBlock is observing this, so will wrap.
+// h += dataBlock.getRequiredHistory();
+// }
+ return h;
}
diff --git a/src/dataMap/layoutFX/DataStreamPaneFX.java b/src/dataMap/layoutFX/DataStreamPaneFX.java
index 8d923f0b..96a765af 100644
--- a/src/dataMap/layoutFX/DataStreamPaneFX.java
+++ b/src/dataMap/layoutFX/DataStreamPaneFX.java
@@ -269,7 +269,10 @@ public class DataStreamPaneFX extends PamBorderPane {
});
canvasHolder.setOnScroll(e->{
- wheelMoved(e);
+ //only change colours of the control key is down.
+ if (e.isControlDown()) {
+ wheelMoved(e);
+ }
});
}
diff --git a/src/dataMap/layoutFX/ScrollingDataPaneFX.java b/src/dataMap/layoutFX/ScrollingDataPaneFX.java
index 2faffbdb..edac7e6f 100644
--- a/src/dataMap/layoutFX/ScrollingDataPaneFX.java
+++ b/src/dataMap/layoutFX/ScrollingDataPaneFX.java
@@ -21,6 +21,7 @@ import pamViewFX.fxNodes.PamColorsFX;
import pamViewFX.fxNodes.PamScrollPane;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.pamAxis.PamDateAxis;
+import pamViewFX.fxNodes.pamScrollers.acousticScroller.ScrollBarPane;
public class ScrollingDataPaneFX extends PamBorderPane {
@@ -77,7 +78,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
/**
* Scroll bar for time (horizontal)
*/
- private ScrollBar timeScrollBar;
+ private ScrollBarPane timeScrollBar;
/**
* Settings strip at top of the display. Shows all sorts of detailed info such cursor position and start and end times.
@@ -145,7 +146,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
// //////////
holder.setCenter(mainScrollPane);
- holder.setBottom(createScrollBar());
+ holder.setTop(createScrollBar());
// PamButton test = new PamButton("Test");
// test.setOnAction((action)->{
@@ -208,13 +209,15 @@ public class ScrollingDataPaneFX extends PamBorderPane {
//create the scroll bar and listeners.
- timeScrollBar=new ScrollBar();
- timeScrollBar.valueProperty().addListener((obs_val, old_val, new_val)->{
+ timeScrollBar=new ScrollBarPane();
+ timeScrollBar.addValueListener((obs_val, old_val, new_val)->{
calcStartEndMillis();
updateScrollBarText();
notifyScrollChange();
});
+
+
timeScrollBar.setPrefHeight(20);
holder.setCenter(timeScrollBar);
@@ -228,7 +231,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
*/
private void calcStartEndMillis(){
screenStartMillis = (long) (dataMapControl.getFirstTime() +
- timeScrollBar.getValue() * 1000L);
+ timeScrollBar.getCurrentValue() * 1000L);
screenEndMillis = screenStartMillis + (long) (screenSeconds * 1000);
}
@@ -347,7 +350,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
* Do scrolling in seconds - will give up to 68 years with a
* 32 bit integer control of scroll bar. milliseconds would give < 1 year !
*/
- double currentPos = timeScrollBar.getValue();
+ double currentPos = timeScrollBar.getCurrentValue();
long dataStart = dataMapControl.getFirstTime();
long dataEnd = dataMapControl.getLastTime();
double dataSeconds = ((dataEnd-dataStart)/1000) + 1;
@@ -367,12 +370,12 @@ public class ScrollingDataPaneFX extends PamBorderPane {
else {
//System.out.println("dataSeconds: "+dataSeconds+ " pixsPerHour: " +pixsPerHour+" screenWidth: "+screenWidth+" screenSeconds "+screenSeconds+" holder width: "+holder.getWidth());
timeScrollBar.setVisible(true);
- timeScrollBar.setMax(0);
- timeScrollBar.setMax(Math.ceil(dataSeconds));
+ timeScrollBar.setMinVal(0);
+ timeScrollBar.setMaxVal(Math.ceil(dataSeconds));
timeScrollBar.setBlockIncrement(Math.max(1, screenSeconds * 4/5));
- timeScrollBar.setUnitIncrement(Math.max(1, screenSeconds / 20));
+// timeScrollBar.setUnitIncrement(Math.max(1, screenSeconds / 20));
timeScrollBar.setVisibleAmount(screenSeconds);
- timeScrollBar.setValue(currentPos);
+ timeScrollBar.setCurrentValue(currentPos);
}
}
@@ -394,7 +397,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
public void scrollToData(PamDataBlock dataBlock) {
long startTime = dataBlock.getCurrentViewDataStart();
int val = (int) ((startTime - getScreenStartMillis())/1000 - getScreenSeconds()/5) ;
- timeScrollBar.setValue(val);
+ timeScrollBar.setCurrentValue(val);
}
/**
diff --git a/src/dataPlotsFX/TDGraphParametersFX.java b/src/dataPlotsFX/TDGraphParametersFX.java
index f3f6c691..f009512f 100644
--- a/src/dataPlotsFX/TDGraphParametersFX.java
+++ b/src/dataPlotsFX/TDGraphParametersFX.java
@@ -79,6 +79,18 @@ public class TDGraphParametersFX implements Serializable, Cloneable, ManagedPara
* Used only when saving as Color (javafx) is not serializable.
*/
public String plotFillS = "white";
+
+ /**
+ * Show the hide panel on the left on start up. Note only used when first opening
+ * saved settings or saving settings.
+ */
+ public boolean showHidePaneLeft = true;
+
+ /**
+ * Show the hide panel on the right on start up. Note only used when first opening
+ * saved settings or saving settings.
+ */
+ public boolean showHidePaneRight = false;
/* (non-Javadoc)
diff --git a/src/dataPlotsFX/layout/TDGraphFX.java b/src/dataPlotsFX/layout/TDGraphFX.java
index b3ca0514..77947bba 100644
--- a/src/dataPlotsFX/layout/TDGraphFX.java
+++ b/src/dataPlotsFX/layout/TDGraphFX.java
@@ -350,8 +350,8 @@ public class TDGraphFX extends PamBorderPane {
setOverlayColour(LIGHT_TD_DISPLAY);
- //show the left hiding pane byu default.
- stackPane.getLeftHidingPane().showHidePane(true);
+// //show the left hiding pane byu default.
+// stackPane.getLeftHidingPane().showHidePane(true);
}
/**
@@ -1699,8 +1699,7 @@ public class TDGraphFX extends PamBorderPane {
/**
* A bit different to the standard getter in that this only gets called just
- * before the configuration is serialized into the .psf. It's time to pull any
- * configuration information out about every line drawn on this boomin' thing !
+ * before the configuration is serialized into the .psfx.
*
* @return graph parameters ready to serialised.
*/
@@ -1733,6 +1732,11 @@ public class TDGraphFX extends PamBorderPane {
graphParameters.setScaleInfoData(scaleInfo.getDataTypeInfo(), scaleInfo.getScaleInfoData());
}
}
+
+ //Finally save whether the hiding panels are open or not.
+ graphParameters.showHidePaneLeft = stackPane.getLeftHidingPane().isShowing();
+ graphParameters.showHidePaneRight = stackPane.getRightHidingPane().isShowing();
+
}
return graphParameters;
@@ -1816,6 +1820,11 @@ public class TDGraphFX extends PamBorderPane {
tdAxisSelPane.remakePane();
tdAxisSelPane.selectAxisType();
setAxisName(graphParameters.currentDataType);
+
+ //Open hide panes if needed.
+ //Finally save whether the hiding panels are open or not.
+ stackPane.getLeftHidingPane().showHidePane(graphParameters.showHidePaneLeft);
+ stackPane.getRightHidingPane().showHidePane(graphParameters.showHidePaneRight);
}
diff --git a/src/dataPlotsFX/rawClipDataPlot/RawClipDataInfo.java b/src/dataPlotsFX/rawClipDataPlot/RawClipDataInfo.java
index ea4bb476..f6daeabc 100644
--- a/src/dataPlotsFX/rawClipDataPlot/RawClipDataInfo.java
+++ b/src/dataPlotsFX/rawClipDataPlot/RawClipDataInfo.java
@@ -2,6 +2,7 @@ package dataPlotsFX.rawClipDataPlot;
import java.awt.geom.Path2D;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -14,7 +15,7 @@ import PamguardMVC.PamDataUnit;
import PamguardMVC.RawDataHolder;
import clipgenerator.ClipSpectrogram;
import dataPlotsFX.TDSymbolChooserFX;
-import dataPlotsFX.clickPlotFX.ClickSymbolChooserFX;
+import dataPlotsFX.clickPlotFX.ClickDisplayParams;
import dataPlotsFX.data.TDDataProviderFX;
import dataPlotsFX.data.TDScaleInfo;
import dataPlotsFX.data.generic.GenericDataPlotInfo;
@@ -255,6 +256,36 @@ public class RawClipDataInfo extends GenericDataPlotInfo {
// TODO Auto-generated method stub
}
+
+ /* (non-Javadoc)
+ * @see dataPlots.data.TDDataInfo#getStoredSettings()
+ */
+ @Override
+ public Serializable getStoredSettings() {
+ return rawClipParams;
+ }
+
+ /* (non-Javadoc)
+ * @see dataPlots.data.TDDataInfo#setStoredSettings(java.io.Serializable)
+ */
+ @Override
+ public boolean setStoredSettings(Serializable storedSettings) {
+ if (RawClipParams.class.isAssignableFrom(storedSettings.getClass())) {
+ rawClipParams = (RawClipParams) storedSettings;
+ updateSettings();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Called whenever settings are updated.
+ */
+ private void updateSettings() {
+ // TODO Auto-generated method stub
+
+ }
+
}
diff --git a/src/dataPlotsFX/rawDataPlotFX/RawSoundPlotDataFX.java b/src/dataPlotsFX/rawDataPlotFX/RawSoundPlotDataFX.java
index 04260b9b..e20acecf 100644
--- a/src/dataPlotsFX/rawDataPlotFX/RawSoundPlotDataFX.java
+++ b/src/dataPlotsFX/rawDataPlotFX/RawSoundPlotDataFX.java
@@ -382,7 +382,7 @@ public class RawSoundPlotDataFX {
if (soundStore.currentRawDataMillis==0){
if (++timeErrors < 10) {
- System.err.println("RawSoundPlotData: Raw sound data has no associated millisecond time: "+ soundStore.currentRawDataMillis);
+// System.err.println("RawSoundPlotData: Raw sound data has no associated millisecond time: "+ soundStore.currentRawDataMillis);
}
return;
}
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_animalspot_1.png b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_animalspot_1.png
index 8aa822e3..a406874c 100644
Binary files a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_animalspot_1.png and b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_animalspot_1.png differ
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_1.png b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_1.png
index c70cbffb..96145e72 100644
Binary files a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_1.png and b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_1.png differ
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_2.png b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_2.png
index 70abc303..c70a2d4d 100644
Binary files a/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_2.png and b/src/help/classifiers/rawDeepLearningHelp/docs/images/advanced_settings_generic_2.png differ
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/images/deep_leanring_module_help.png b/src/help/classifiers/rawDeepLearningHelp/docs/images/deep_leanring_module_help.png
index 250486bc..79fff4d3 100644
Binary files a/src/help/classifiers/rawDeepLearningHelp/docs/images/deep_leanring_module_help.png and b/src/help/classifiers/rawDeepLearningHelp/docs/images/deep_leanring_module_help.png differ
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/images/default_settings_humpback_1.png b/src/help/classifiers/rawDeepLearningHelp/docs/images/default_settings_humpback_1.png
new file mode 100644
index 00000000..eaf71e68
Binary files /dev/null and b/src/help/classifiers/rawDeepLearningHelp/docs/images/default_settings_humpback_1.png differ
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Bugs.html b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Bugs.html
index 2139a1b1..3ca4a041 100644
--- a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Bugs.html
+++ b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Bugs.html
@@ -9,8 +9,14 @@
PAMGuard's Deep
Learning Module
- Common Bugs and Mistakes
-
+
+ Common bugs and mistakes
+ The first time you use the module and/or load a different type
+ of model e.g. a tensorflow or pytorch model, you must be connected to
+ the internet.
+ You must install the correct version of CUDA for hardware
+ acceleration using an Nvidea GPU. See the currently supported CUDA
+ versions on the Pytorch and Tensorflow websites.
You should always have deep learning models in their own folder.
Do not have any additional jar files or other programming related
things (like .dll files) in the same or sub folders. This has been
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_CreateAndConfig.html b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_CreateAndConfig.html
index d9394ad4..47d78312 100644
--- a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_CreateAndConfig.html
+++ b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_CreateAndConfig.html
@@ -7,20 +7,18 @@
- PAMGuard Deep
- Learning Module
- Creation and Configuration
-
- Creating an instance
- of the module
+ PAMGuard Deep Learning
+ Module
+
+ Creating an instance
+ of the module
The module can be added from the File> Add modules >
Classifier > Raw deep learning classifier menu or by right
clicking in the data model. More than one instance of the module can
be added if multiple deep learning models are required.
-
- Module settings
+ Module settings
The module settings are opened by selecting the Settings >
Raw deep learning classifier menu. The main settings pane is shown
@@ -28,18 +26,18 @@
and Deep Learning Model
-
+
The main settings pane for the deep learning module with
descriptions
-
Raw Sound Data
The deep learning module accepts any raw data source i.e., any
- data source that contains raw waveform data.
+ data source that contains raw waveform data e.g. clicks, clips and
+ Ishmael detections. Note that the module accepts whislte and moan
+ detections but only if a delphinID classifier has been loaded.
If the data is continuous, e.g. from the Sound Acquisition
module then deep learning detections are saved to PAMGuard's data
management system if they pass a user defined prediction threshold.
@@ -57,7 +55,6 @@
processes. So, for example if channels 0 and 2 are in a group, then
the raw waveform data from both channel 0 and 2 will be saved and can
be used in downstream processes, e.g., for localisation.
-
Segmentation
The segmentation section defines how the raw data is segmented. Some
@@ -72,7 +69,6 @@
re-merge is the maximum number of segments that can form a single
data unit before a new data unit is automatically created.
-
Deep Learning Model
The deep learning model section is used to select the deep
learning model. The drop down menu is used to select the framework the
@@ -92,14 +88,12 @@
Once the model has loaded there some unique options depending on
the currently selected framework.
-
Generic Model
A generic model must be set up via the Advanced menu button.
-
+
@@ -124,8 +118,7 @@
including the shape of the input data e.g. a 100x50 image.
-
+
@@ -146,16 +139,15 @@
transforms and input and output data whenever settings up a new
PAMGuard data model and allow easier sharing of classifiers amongst
researchers.
-
- AnimalSpot and Ketos models
+ Koogu,
+ Ketos, AnimalSpot, PAMGuard zip and delphinID models
- If using an AnimalSpot or Ketos model then all transforms are
- automatically set up. The transforms can be viewed and altered via the
- Advanced menu button but in the majority of cases these settings
- should not be used. It is advisable to select "Use default
- segment length" to change the Window length to the
- default for the selected model. Note that this is often necessary for
- Ketos models but usually not a requirement for AnimalSpot models.
+ If using a deep learning model from a supported framework then all
+ transforms are automatically set up. The transforms can be viewed and
+ altered via the Advanced menu button but in the majority of cases
+ these settings should not be used. For some models, it is advisable to
+ select "Use default segment length" to change the Window
+ length to the default for the selected model.
- An AnimalSpot or Ketos model will automatically create a list
- of transforms with the appropriate settings. These is no need to use
- the advanced pane but it is there in case users wish to change
- transform settings for some reason
+ An AnimalSpot, Ketos or other supported deep learning model
+ will automatically create a list of transforms with the appropriate
+ settings. These is no need to use the advanced pane but it is there
+ in case users wish to change transform settings for some reason
+ Default Models
+ Default models are selectable from the menu button in the Deep
+ Learning Pane. Default models are deep learning classifiers which are
+ open source, known to be effective and have have been published in
+ open access academic litrature; they are downloaded directly from a
+ GitHub repository and then all associated settings are automtically
+ applied. The default model selection pane also contains hyperlinks to
+ the papers descirbing each model which will take users directly to the
+ relvent website.
+
+
+
+
+
+
+ Default models can be downloaded. Default models are models
+ which are published, open and have been known to work well amongst
+ the bioacoustics community. More will be added to PAMGaurd over time.
+ If you you would like your model to become a defualt model then drop
+ PAMGuard support an email.
+
+
- Previous:
- Overview
- Next:
- Running the Deep Learning module
+
+ Previous: Overview
+
+
+ Next: Running the Deep
+ Learning module
+
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Results.html b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Results.html
index c02e5cd2..a84d6eb7 100644
--- a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Results.html
+++ b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Results.html
@@ -9,12 +9,12 @@
PAMGuard's Deep
Learning Module
+
+
Viewing and exporting
results
-
Output from the deep learning module can be viewed in PAMGuard
viewer mode, or extracted from binary files using MATLAB or R.
-
PAMGuard viewer mode
Detections form continuous raw data are shown in the datagram in
the same way as all data streams in PAMGuard.
@@ -32,7 +32,7 @@
manual analyst can quickly navigate to detections with high prediction
values for a certain class. Hovering over or right clicking on a data
unit in the time display and selecting the information button, will
- show the data unit's metadata, including the prediction values for all
+ show the data unit’s metadata, including the prediction values for all
output classes from the deep learning model.
@@ -50,7 +50,6 @@
deep learning prediction values. The spectrogram will also show deep
learning detections as translucent blue boxes (these must be selected
in the right click menu).
-
MATLAB
The easiest way to export to MATLAB is to select the desired
units in the time base display, right click and select the MATLAB
@@ -96,7 +95,7 @@ predicitons = dldetections(1).annotations.dlcla
waveform data in each structure;
-
+
clf
tiledlayout(5,5)
for i=5,5Right whale detections from a deep learning model imported
and then plotted in MATLAB
-
R
In the same way as MATLAB export, the PAMGuard time base display
and export selected data units directly to an R struct which can be
@@ -165,13 +163,17 @@ tiledlayout(5,5here.
+
- Previous:
- Running the Deep Learning module
- Next:
- Common Bugs and Mistakes
+
+ Previous: Running the Deep
+ Learning module
+
+
+ Next: Common Bugs and Mistakes
+
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Running.html b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Running.html
index 5181a525..9d9d2cfe 100644
--- a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Running.html
+++ b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_Running.html
@@ -10,12 +10,10 @@
PAMGuard's Deep
Learning Module
Running
-
Real time
In real time, the deep learning model runs automatically when
processing starts. A warning will appear if there are issues with the
model and/or it cannot cope with real time speeds.
-
Viewer Mode
The deep learning module can be re-run on detector data (e.g.
@@ -26,13 +24,18 @@
Detections without a deep learning annotation will have one added and
detections with an existing annotation will have it overwritten.
+
- Previous:
- Creating and Configuring the Deep Learning module
- Next:
- Viewing and Exporting Results
+
+ Previous: Creating
+ and Configuring the Deep Learning module
+
+
+ Next: Viewing and Exporting
+ Results
+
diff --git a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_overview.html b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_overview.html
index d1b350d9..668b1a52 100644
--- a/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_overview.html
+++ b/src/help/classifiers/rawDeepLearningHelp/docs/rawDeepLearning_overview.html
@@ -7,10 +7,11 @@
- PAMGuard Deep
- Learning Module
+ PAMGuard's deep
+ learning module
+ Note: this module requires an internet connection upon first use
+ to download correct libraries.
Overview
-
PAMGuard's deep learning module allows users to deploy a
large variety of deep learning models natively in PAMGuard. It is core
module, fully integrated into PAMGuard's display and data
@@ -19,9 +20,7 @@
signal and can integrate into multiple types of acoustic analysis
workflows, for example post analysis of recorder data or used as part
of real time localisation workflow.
-
-
- How it works
+ How it works
The deep learning module accepts raw data from different types
of data sources, e.g. from the Sound Acquisition module, clicks and
clips. It segments data into equal sized chunks with a specified
@@ -32,8 +31,7 @@
learning model, then can be automatically set up by PAMGuard.
Currently there are three implemented frameworks
-
+
@@ -44,7 +42,6 @@
the model are saved and can be viewed in real time (e.g. mitigation)
or in post processing (e.g. data from SoundTraps).
-
Generic Model
A generic model allows a user to load any model compatible with the
-
AnimalSpot
ANIMAL-SPOT
is a deep learning based framework which was initially designed for killer
+ href="(https://github.com/ChristianBergler/ORCA-SPOT">killer
whale sound detection) in noise heavy underwater recordings (see Bergler
et al. (2019)). It has now been expanded to a be species independent
@@ -68,21 +64,43 @@
AnimalSpot models will automatically set up their own data transforms
and output classes.
-
Ketos
Ketos is an
acoustic deep learning framework based on Tensorflow and developed by
MERIDIAN. It has excellent
resources and tutorials and Python libraries can be installed easily
- via pip. Imported Ketos model will automatically set up their own data
+ via pip. Imported Ketos (.ktpb) models will automatically set up their
+ own data transforms and output classes.
+
+ Koogu
+
+ Koogu is
+ a Python package which allows users to train a deep learning model.
+ Koogu helps users by integrating with some frequency used annotation
+ programs and provides tools to train and test classifiers. Imported
+ Koogu models (.kgu) will automatically set up their own data
transforms and output classes.
+ PAMGuardZip
+
+ PAMGuard zip models consist of a deep learning model (either a
+ Tensorflow saved_model.pb or PyTorch *.py model) alongside a
+ PAMGuard metdata file (.pdtf*) within a zip archive. The metadata
+ file contains all the information needed for PAMGaurd to set up the
+ model. PAMGuard will import the zip file, decompress it and search for
+ the relevent deep learning model and metadata file then set up all
+ settings accordingly. This framework allows users to easily share
+ pre-tested PAMGuard compatible models.
+
+
- Next:
- Creating and Configuring the Deep Learning module
+
+ Next: Creating and
+ Configuring the Deep Learning module
+
diff --git a/src/hfDaqCard/SmruDaqJNI.java b/src/hfDaqCard/SmruDaqJNI.java
index e1b8356f..18c3b7e3 100644
--- a/src/hfDaqCard/SmruDaqJNI.java
+++ b/src/hfDaqCard/SmruDaqJNI.java
@@ -19,6 +19,9 @@ public class SmruDaqJNI {
static public final int SMRU_VAL_SLAVE_MASTERED = 3;
static public final int SMRU_RET_OK = 0;
+
+ static public final int GREEN_LED = 1;
+ static public final int RED_LED = 0;
/**
* Have rebuilt SAIL Daq interface in 2022, but in principle this was
@@ -29,11 +32,6 @@ public class SmruDaqJNI {
private static final String SILIB = "SailDaqJNI";
// private static final String SILIB = "SailDaqV7";
- /**
- * this is the verbose level for the C code part.
- */
- private static final int verboseLevel = 0;
-
private static final String DEVNAME = "/dev/cypress_smru0";
private static final int MINJNIVERSION = 5;
@@ -265,7 +263,7 @@ public class SmruDaqJNI {
this.smruDaqSystem = smruDaqSystem;
loadLibrary();
if (haveLibrary()) {
- setVerbose(verboseLevel);
+ setVerbose(SmruDaqSystem.VERBOSELEVEL);
/**
* List the devices, but don't do any resetting and
@@ -492,7 +490,7 @@ public class SmruDaqJNI {
public int toggleLED(int board, int led) {
board = boardOrder[board];
int state = getLED(board, led);
- System.out.println("state="+state);
+// System.out.println("LED state="+state);
if (state == 0) {
state = 1;
}
diff --git a/src/hfDaqCard/SmruDaqSystem.java b/src/hfDaqCard/SmruDaqSystem.java
index c6af0d72..b9961924 100644
--- a/src/hfDaqCard/SmruDaqSystem.java
+++ b/src/hfDaqCard/SmruDaqSystem.java
@@ -5,6 +5,7 @@ import java.util.List;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -13,6 +14,7 @@ import soundPlayback.PlaybackControl;
import soundPlayback.PlaybackSystem;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionDialog;
+import Acquisition.AcquisitionProcess;
import Acquisition.DaqSystem;
import Acquisition.AudioDataQueue;
import PamController.PamControlledUnitSettings;
@@ -49,7 +51,8 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
public static final String oldCardName = "SMRU Ltd DAQ Card";
- private static final int VERBOSELEVEL = 0;
+ public static final int VERBOSELEVEL = 0;
+
/**
* @param daqControl
@@ -61,6 +64,11 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
smruDaqJNI = new SmruDaqJNI(this);
nDaqCards = smruDaqJNI.getnDevices();
+ for (int i = 0; i < nDaqCards; i++) {
+ for (int l = 0; l < 2; l++) {
+ smruDaqJNI.setLED(i, l, 0);
+ }
+ }
smruDaqDialogPanel = new SmruDaqDialogPanel(this);
PamSettingManager.getInstance().registerSettings(this);
@@ -275,6 +283,8 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
boolean prepareDaqCard(int iBoard, boolean fullReset) {
// devices are left closed, so will need to reopen them.
// of course, there is a vile lookup table, so...
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.GREEN_LED, 0);
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.RED_LED, 0);
int hardId = smruDaqJNI.getBoardOrder(iBoard);
int prepOk = smruDaqJNI.prepareDevice(hardId, fullReset);
terminalPrint("Opened daq card returned " + prepOk, 1);
@@ -313,6 +323,7 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
if (ans) {
Thread t = new Thread(new DaqThread());
+ t.setPriority(Thread.MAX_PRIORITY);
t.start();
keepRunning = true;
daqThreadRunning = true;
@@ -371,18 +382,43 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
boolean first = true;
boolean needRestart = false;
int iChan;
+ // some flags on checks of incoming data rate
+// long recentSamples = 0;
+// long recentCheckTime = System.currentTimeMillis();
+ int loopCount = 0;
+ for (int iBoard = 0; iBoard < nDaqCards; iBoard++) {
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.GREEN_LED, 1);
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.RED_LED, 0);
+ }
+
while (keepRunning) {
iChan = 0;
dataMillis = daqControl.getAcquisitionProcess().absSamplesToMilliseconds(totalSamples);
+ if (isStalled()) {
+ needRestart = true;
+ for (int iBoard = 0; iBoard < nDaqCards; iBoard++) {
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.GREEN_LED, 0);
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.RED_LED, 1);
+ }
+ // don't set this false or the shutdown doesn't work properly.
+// keepRunning = false;
+ break;
+ }
+ loopCount++;
for (int iBoard = 0; iBoard < nDaqCards && keepRunning; iBoard++) {
+ if ((loopCount % 10000) == 0) {
+// toggleLED(iBoard, 0);
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.GREEN_LED, 1);
+ }
for (int i = 0; i < boardChannels[iBoard] && keepRunning; i++) {
newData = smruDaqJNI.readSamples(iBoard, i, wantedSamples);
if (newData == null) {
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.RED_LED, 1);
System.out.println(String.format("Null data read from smruDaqJNI.readSamples board %d, chan %d, samples %d",
iBoard, i, wantedSamples));
// System.out.println("Issue restart ...");
needRestart = true;
- keepRunning = false;
+// keepRunning = false;
break;
}
readSamples = newData.length;
@@ -409,19 +445,47 @@ public class SmruDaqSystem extends DaqSystem implements PamSettings {
if (++dcOffsetCalls == 100) {
dcOffsetScale = 100.; // after a bit, increase the time constant.
}
+
totalSamples += readSamples;
- }
+ };
daqThreadRunning = false;
- if (needRestart) {
- PamController pamController = PamController.getInstance();
- pamController.pamStop();
- PamDialog.showWarning(daqControl.getGuiFrame(), daqControl.getUnitName(), "Problem with one or more SAIL DAQ Cards.\n"
- + "Restart PAMGuard, check connections and try again." );
-// pamController.startLater();
+
+ for (int iBoard = 0; iBoard < nDaqCards; iBoard++) {
+ smruDaqJNI.setLED(iBoard, SmruDaqJNI.GREEN_LED, 0);
}
+
+ if (needRestart) {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ PamController pamController = PamController.getInstance();
+ pamController.pamStop();
+ System.out.println("Problem with one or more SAIL DAQ Cards. "
+ + "Restart PAMGuard, check connections and try again." );
+// PamDialog.showWarning(daqControl.getGuiFrame(), daqControl.getUnitName(), "Problem with one or more SAIL DAQ Cards.\n"
+// + "Restart PAMGuard, check connections and try again." );
+ pamController.startLater();
+ }
+ });
+ }
+ }
+
+// private long lastFakeStall = 0;
+ private boolean isStalled() {
+// if (lastFakeStall == 0) {
+// lastFakeStall = System.currentTimeMillis();
+// }
+// long now = System.currentTimeMillis();
+// if (now-lastFakeStall > 10000) {
+// System.out.println("Random pretend stalled");
+// lastFakeStall = 0;
+// return true;
+// }
+ return daqControl.getAcquisitionProcess().isStalled();
}
public static short getSample(byte[] buffer, int position) {
diff --git a/src/loggerForms/controls/CounterControl.java b/src/loggerForms/controls/CounterControl.java
index 120256ee..b6edf687 100644
--- a/src/loggerForms/controls/CounterControl.java
+++ b/src/loggerForms/controls/CounterControl.java
@@ -21,6 +21,7 @@ public class CounterControl extends SimpleControl {
Character suffix;
+ public enum CounterSuffix {NOSUFFIX, CHARSUFFIX};
public CounterControl(ControlDescription controlDescription,
LoggerForm loggerForm) {
@@ -36,25 +37,19 @@ public class CounterControl extends SimpleControl {
}
-
-
-
-
-
-
private String calculateCounter() {
int num = FormCounterManagement.getInstance().getCounterNumber(this,controlDescription.getFormDescription().getDBTABLENAME());
- String numSt = Integer.toString(num);
- int nZeros = 3-numSt.length();
-
- String tSt = "";
- for (int i=0;i= 2) {
angs[2] = vectors[1].getPitch();
}
diff --git a/src/pamViewFX/PamGuiFX.java b/src/pamViewFX/PamGuiFX.java
index a9d4c678..f19b12d5 100644
--- a/src/pamViewFX/PamGuiFX.java
+++ b/src/pamViewFX/PamGuiFX.java
@@ -35,6 +35,7 @@ import dataModelFX.DataModelPaneFX;
import org.controlsfx.control.ToggleSwitch;
+
/**
* A pane which holds a set of tabs.
*
@@ -125,7 +126,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
this.pamGuiManagerFX=pamGuiManagerFX;
this.mainTabPane = mainTabPane;
- Pane layout=createMainPane(mainTabPane, stage);
+ Node layout=createMainPane(mainTabPane, stage);
//add main pane to PamGui
this.getChildren().add(layout);
@@ -140,7 +141,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
//create the main tab pane.
this.mainTabPane = new PamTabPane();
- Pane layout=createMainPane(mainTabPane, stage);
+ Node layout=createMainPane(mainTabPane, stage);
//add main pane to PamGui
this.getChildren().add(layout);
@@ -154,7 +155,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
* @param stage - the stage holding this GUI.
* @return a pane which sits in the stage.
*/
- private Pane createMainPane(PamTabPane mainTabPane, Stage stage){
+ private Node createMainPane(PamTabPane mainTabPane, Stage stage){
//create the pane which holds tab pane
final PamBorderPane layout = new PamBorderPane();
@@ -261,7 +262,6 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
PamBorderPane layoutHolder=new PamBorderPane(layout);
layoutHolder.setTop(hidingLoadPane);
-
return layoutHolder;
diff --git a/src/pamViewFX/PamGuiTabFX.java b/src/pamViewFX/PamGuiTabFX.java
index 9e1f3fb2..42fc18d8 100644
--- a/src/pamViewFX/PamGuiTabFX.java
+++ b/src/pamViewFX/PamGuiTabFX.java
@@ -253,6 +253,10 @@ public class PamGuiTabFX extends PamTabFX {
double r1 = 1 - r;
int smallWindows = 0;
+
+
+ //the padding between windows
+ double padding = 10;
ArrayList dw = internalPanes;
@@ -268,7 +272,9 @@ public class PamGuiTabFX extends PamTabFX {
//now place windows in correct position
//large windows
- double x, y, w, h = 0;
+ double x, y, w, h = 0.;
+ double pad =0.;
+
if (largeWindows > 0) {
x = 0;
y = 0;
@@ -284,7 +290,10 @@ public class PamGuiTabFX extends PamTabFX {
if (dw.get(i).getUserDisplayNode().isMinorDisplay()== true) continue;
dw.get(i).setPaneLayout(x, y);
- dw.get(i).setPaneSize(w, h);
+
+ //set the padding if the pane is not the last pane.
+ pad = (i== dw.size()-1) ? 0 : padding;
+ dw.get(i).setPaneSize(w - (horz? pad:0), h - (horz? 0:pad));
if (horz) x += w;
else y += h;
}
@@ -307,7 +316,10 @@ public class PamGuiTabFX extends PamTabFX {
for (int i = 0; i < dw.size(); i++) {
if (dw.get(i).getUserDisplayNode().isMinorDisplay() == false) continue;
dw.get(i).setPaneLayout(x, y);
- dw.get(i).setPaneSize(w, h);
+
+ //set the padding if the pane is not the last pane.
+ pad = (i== dw.size()-1) ? 0 : padding;
+ dw.get(i).setPaneSize(w- (horz? pad:0), h - (horz? 0:pad));
if (horz) x += w;
else y +=h;
}
diff --git a/src/pamViewFX/fxNodes/hidingPane/HidingPane.java b/src/pamViewFX/fxNodes/hidingPane/HidingPane.java
index 9e2ef7d8..2ad19062 100644
--- a/src/pamViewFX/fxNodes/hidingPane/HidingPane.java
+++ b/src/pamViewFX/fxNodes/hidingPane/HidingPane.java
@@ -20,7 +20,6 @@ import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
-import javafx.geometry.Insets;
/**
* Hiding pane which can be added to any node.
@@ -156,7 +155,7 @@ public class HidingPane extends StackPane {
//create a button which hides the side panel
hideButton=createShowButton(false);
styleHideButton(hideButton);
- hideButton.setOnAction(new HideButtonPressed());
+// hideButton.setOnAction(new HideButtonPressed());
hideButton.setVisible(false);
// hideButton.setStyle("close-button-right");
@@ -333,8 +332,6 @@ public class HidingPane extends StackPane {
double dragX=0;
double dragY=0;
double distance=0;
-
-
private PamButton createShowButton(final boolean show){
final PamButton pamButton=new PamButton();
@@ -343,6 +340,7 @@ public class HidingPane extends StackPane {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
+// System.out.println("HidingPane.showButton - setOnMousePressed");
dragX =mouseEvent.getSceneX();
dragY =mouseEvent.getSceneY();
}
@@ -350,10 +348,24 @@ public class HidingPane extends StackPane {
pamButton.setOnMouseReleased(new EventHandler() {
@Override public void handle(MouseEvent mouseEvent) {
- if (distance==0) return;
+// System.out.println("HidingPane.showButton - setOnMouseReleased");
+
+ //the mouse has been pressed
+ if (distance==0) {
+ if (isShowing()) {
+ showHidePane(false);
+ }
+ else {
+ showHidePane(true);
+ }
+ return;
+ }
+
+ //the mouse has been dragged dragged
distance=sideIndex*distance;
// System.out.println("Mouse released: HidePanel distance: "+distance);
if (!overlay) distance=Math.abs(distance);
+
//need to see where the drag has ended-if greater than 50% then open but if less then close.
if (!isHorizontal()){
if (distance=expandedSize/2) showHidePane(overlay? false : true);
}
+
//reset the distance
distance=0;
}
@@ -370,12 +383,14 @@ public class HidingPane extends StackPane {
pamButton.setOnMouseDragged(new EventHandler() {
@Override public void handle(MouseEvent mouseEvent) {
+// System.out.println("HidingPane.showButton - setOnMouseDragged");
if (visibleImmediatly) hidePane.setVisible(true);
else hidePane.setVisible(false);
// hideButton.setVisible(true);
/**
* Work out the distance the panel is to be dragged;
*/
+ double distance = 0;
if (!isHorizontal()){
if (!show) distance=(mouseEvent.getSceneX()-dragX);
else distance=(mouseEvent.getSceneX()-dragX)+sideIndex*expandedSize;
@@ -387,26 +402,28 @@ public class HidingPane extends StackPane {
if (!overlay) distance=expandedSize+sideIndex*distance;
}
// if (show && Math.abs(distance)>expandedSize) return;
-
+
translatePanel(distance);
+
+ HidingPane.this.distance = distance ;
}
});
- pamButton.setOnMouseEntered(new EventHandler() {
- @Override public void handle(MouseEvent mouseEvent) {
-// System.out.println("HidingPane.showButton - mouse entered");
- pamButton.setOpacity(1.0);
- pamButton.setPadding(new Insets(2.,2.,2.,2.));
- }
- });
-
- pamButton.setOnMouseExited(new EventHandler() {
- @Override public void handle(MouseEvent mouseEvent) {
-// System.out.println("HidingPane.showButton - mouse exited");
- if (show) pamButton.setOpacity(showButtonOpacity);
- pamButton.setPadding(new Insets(0.,0.,0.,0.));
- }
- });
+// pamButton.setOnMouseEntered(new EventHandler() {
+// @Override public void handle(MouseEvent mouseEvent) {
+//// System.out.println("HidingPane.showButton - mouse entered");
+// pamButton.setOpacity(1.0);
+// pamButton.setPadding(new Insets(2.,2.,2.,2.));
+// }
+// });
+//
+// pamButton.setOnMouseExited(new EventHandler() {
+// @Override public void handle(MouseEvent mouseEvent) {
+//// System.out.println("HidingPane.showButton - mouse exited");
+// if (show) pamButton.setOpacity(showButtonOpacity);
+// pamButton.setPadding(new Insets(0.,0.,0.,0.));
+// }
+// });
// pamButton.setOnMouseClicked(new EventHandler() {
// @Override public void handle(MouseEvent mouseEvent) {
@@ -415,15 +432,15 @@ public class HidingPane extends StackPane {
// }
// });
- pamButton.addEventHandler(ActionEvent.ACTION,new EventHandler() {
- @Override
- public void handle(ActionEvent e) {
- System.out.println("HidingPane.showButton - action event clicked");
- showHidePane(show);
- }
- });
+// pamButton.addEventHandler(ActionEvent.ACTION,new EventHandler() {
+// @Override
+// public void handle(ActionEvent e) {
+// System.out.println("HidingPane.showButton - action event clicked");
+// showHidePane(show);
+// }
+// });
- if (show) pamButton.setOpacity(showButtonOpacity);
+// if (show) pamButton.setOpacity(showButtonOpacity);
return pamButton;
}
@@ -601,7 +618,7 @@ public class HidingPane extends StackPane {
showing.setValue(true);
if (visibleImmediatly) hidePane.setVisible(true);
//hideButton.setVisible(true);
- //System.out.println("HidingPane: Open Hide Pane");
+// System.out.println("HidingPane: Open Hide Pane");
//open the panel
if (timeLineShow.getStatus()==Status.RUNNING) {
//stops the issue with the hiding pane freezing.
@@ -613,7 +630,7 @@ public class HidingPane extends StackPane {
else{
showing.setValue(false);
if (!visibleImmediatly) hidePane.setVisible(false);
- //System.out.println("HidingPane: Close Hide Pane");
+// System.out.println("HidingPane: Close Hide Pane");
//close the panel
timeLineHide.play();
}
@@ -638,17 +655,17 @@ public class HidingPane extends StackPane {
}
}
- /**
- * Called whenever the pin button is pressed.
- * @author Jamie Macaulay
- */
- class HideButtonPressed implements EventHandler{
-
- @Override
- public void handle(ActionEvent arg0) {
- showHidePane(false);
- }
- }
+// /**
+// * Called whenever the pin button is pressed.
+// * @author Jamie Macaulay
+// */
+// class HideButtonPressed implements EventHandler{
+//
+// @Override
+// public void handle(ActionEvent arg0) {
+// showHidePane(false);
+// }
+// }
/**
* Get the button which hides the pane.
@@ -732,6 +749,15 @@ public class HidingPane extends StackPane {
return this.showing;
}
+ /**
+ * Check whether the hiding pane is showing.
+ * @return true if showing.
+ */
+ public boolean isShowing(){
+ return this.showing.get();
+ }
+
+
/**
* Get the opacity of the show button when the mouse is outside the button.
* @return the opacity of the show button.
diff --git a/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java b/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java
index 36124e0a..02dcd566 100644
--- a/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java
+++ b/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java
@@ -6,6 +6,8 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Node;
@@ -844,5 +846,18 @@ public class ScrollBarPane extends PamBorderPane {
this.showMillis = showMillis;
}
+
+ /**
+ * Convenience function which adds a change listener to the current value and visible amount prooperty.
+ * @param val - the change listener to add.
+ */
+ public void addValueListener(ChangeListener val) {
+ //add listener to visible amount property.
+ visibleAmountProperty.addListener(val);
+
+ //add listener to current value amount property.
+ currentValueProperty.addListener(val);
+ }
+
}
diff --git a/src/pamViewFX/fxPlotPanes/PlotPane.java b/src/pamViewFX/fxPlotPanes/PlotPane.java
index f85fc79b..30355c8e 100644
--- a/src/pamViewFX/fxPlotPanes/PlotPane.java
+++ b/src/pamViewFX/fxPlotPanes/PlotPane.java
@@ -1,6 +1,9 @@
package pamViewFX.fxPlotPanes;
import Layout.PamAxis;
+import javafx.beans.binding.Bindings;
+import javafx.beans.property.SimpleDoubleProperty;
+import javafx.beans.value.ObservableValue;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
@@ -256,13 +259,31 @@ public class PlotPane extends PamBorderPane {
PamHBox horzHolder=new PamHBox();
Pane leftPane=new Pane();
+
+ //create an observable which is the size of the axis pane if the pane is visible and otherwise
+ //is zero.
+ ObservableValue valLeft = Bindings
+ .when(yAxisLeftPane.visibleProperty())
+ .then(yAxisLeftPane.widthProperty())
+ .otherwise(
+ new SimpleDoubleProperty(0.)
+ );
+
//need both min and pref to make binding work properly;
- leftPane.prefWidthProperty().bind(yAxisLeftPane.widthProperty());
- leftPane.minWidthProperty().bind(yAxisLeftPane.widthProperty());
+ leftPane.prefWidthProperty().bind(valLeft);
+ leftPane.minWidthProperty().bind(valLeft);
Pane rightPane=new Pane();
- rightPane.prefWidthProperty().bind(yAxisRightPane.widthProperty());
- rightPane.minWidthProperty().bind(yAxisRightPane.widthProperty());
+
+ ObservableValue valRight = Bindings
+ .when(yAxisRightPane.visibleProperty())
+ .then(yAxisRightPane.widthProperty())
+ .otherwise(
+ new SimpleDoubleProperty(0.)
+ );
+
+ rightPane.prefWidthProperty().bind(valRight);
+ rightPane.minWidthProperty().bind(valRight);
horzHolder.getChildren().addAll(leftPane, axisPane, rightPane);
//axisPane.toFront(); this changes the order of children in a PamHBox.
@@ -369,8 +390,8 @@ public class PlotPane extends PamBorderPane {
//holderPane.getChildren().clear();
- //HACK- 05/08/2016 have to do this because there is a bug in switching children postions in a border pane.
- //casues a duplicate childrne error.
+ //HACK- 05/08/2016 have to do this because there is a bug in switching children positions in a border pane.
+ //causes duplicate children error
holderPane.setRight(null);
holderPane.setLeft(null);
holderPane.setTop(null);
@@ -385,24 +406,30 @@ public class PlotPane extends PamBorderPane {
else if (topBorder > 0) {
// holderPane.setTopSpace(topBorder);
}
+
if (bottom) {
holderPane.setBottom(bottomHolder);
}
else if (bottomBorder > 0) {
// holderPane.setBottomSpace(bottomBorder);
}
+
if (right) {
holderPane.setRight(yAxisRightPane) ;
+ yAxisRightPane.setVisible(true);
}
- else if (rightBorder > 0){
- // holderPane.setRightSpace(rightBorder);
+ else {
+ yAxisRightPane.setVisible(false);
}
+
if (left) {
holderPane.setLeft(yAxisLeftPane) ;
+ yAxisLeftPane.setVisible(true);
}
- else if (leftBorder > 0) {
- // holderPane.setLeftSpace(leftBorder);
+ else {
+ yAxisLeftPane.setVisible(false);
}
+
holderPane.setCenter(canvasHolder);
//bottomHolder.toBack();
diff --git a/src/rawDeepLearningClassifier/DLControl.java b/src/rawDeepLearningClassifier/DLControl.java
index 67126845..a90cfa7f 100644
--- a/src/rawDeepLearningClassifier/DLControl.java
+++ b/src/rawDeepLearningClassifier/DLControl.java
@@ -561,6 +561,7 @@ public class DLControl extends PamControlledUnit implements PamSettings {
* @return the number of classes.
*/
public int getNumClasses() {
+ if (getDLModel()==null) return 0;
return getDLModel().getNumClasses();
}
diff --git a/src/rawDeepLearningClassifier/RawDLParams.java b/src/rawDeepLearningClassifier/RawDLParams.java
index abb21daf..cbc0b1d0 100644
--- a/src/rawDeepLearningClassifier/RawDLParams.java
+++ b/src/rawDeepLearningClassifier/RawDLParams.java
@@ -37,6 +37,13 @@ public class RawDLParams implements Serializable, Cloneable {
* Holds channel and grouping information
*/
public GroupedSourceParameters groupedSourceParams = new GroupedSourceParameters();
+
+ /**
+ * True to enable segmentation. If segmentation is disabled then the raw waveform from
+ * a data unit is passed directly to the model. Note that this is not an option for raw sound
+ * data.
+ */
+ public boolean enableSegmentation = true;
/**
* The number of raw samples to send to the classifier.
@@ -85,7 +92,7 @@ public class RawDLParams implements Serializable, Cloneable {
* different class names. If we change model then the class names may change.
* Previously annotated data will then be messed up. But, in a giant dataset
* that may be an issue. Perhaps users wish to run a new model on some chunk of
- * data without messing up all the other classified detectionS which have used
+ * data without messing up all the other classified detections which have used
* that module. So store the data in binary files? That is super inefficient as
* the same string is stored many times. So instead store a short which
* identifies the string that sits in this table. Everytime a new model is added
diff --git a/src/rawDeepLearningClassifier/dataSelector/DLPredictonPane.java b/src/rawDeepLearningClassifier/dataSelector/DLPredictonPane.java
index 42834e8a..2813708f 100644
--- a/src/rawDeepLearningClassifier/dataSelector/DLPredictonPane.java
+++ b/src/rawDeepLearningClassifier/dataSelector/DLPredictonPane.java
@@ -141,12 +141,12 @@ public class DLPredictonPane extends DynamicSettingsPane {
((GenericModelParams) genericParams).defaultShape = longArr2Long(genericModel.getInputShape().getShape());
((GenericModelParams) genericParams).defualtOuput = longArr2Long(genericModel.getOutShape().getShape());
-
+
}
catch (Exception e) {
diff --git a/src/rawDeepLearningClassifier/segmenter/SegmenterProcess.java b/src/rawDeepLearningClassifier/segmenter/SegmenterProcess.java
index 7012ac68..5b16ade8 100644
--- a/src/rawDeepLearningClassifier/segmenter/SegmenterProcess.java
+++ b/src/rawDeepLearningClassifier/segmenter/SegmenterProcess.java
@@ -486,9 +486,17 @@ public class SegmenterProcess extends PamProcess {
//pass the raw click data to the segmenter
for (int i=0;i