diff --git a/.project b/.project index 9ee4af40..48129c11 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - PamGuard Main DG + PamGuard Main Tethys diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index ad634f29..4df196f4 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,4 @@ eclipse.preferences.version=1 encoding//src/rawDeepLearningClassifer/segmenter/SegmenterProcess.java=UTF-8 +encoding/=UTF-8 +encoding/src=UTF-8 diff --git a/README.html b/README.html index 69409ed8..ca3211e9 100644 --- a/README.html +++ b/README.html @@ -477,6 +477,10 @@ detector settings easily into the other configurations.

files) file performance when scrolling through audio data in Viewer mode.

+

Viewer Launch by right clicking on sqlite database and selecting ‘open with / Pamguard +ViewerMode launcher’ menu option.

+

Bug Fixes

Logger Forms

@@ -493,7 +497,7 @@ 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 +bug that threw an error if no classifier files were  specified in Rocca Params dialog

Fix memory issue with @@ -506,9 +510,9 @@ and stop PamObserver Timer to

Fix problem tracing whistles in Rocca spectrogram pop-up: Whistle and raw data were being cleared before the user had -time to trace out the whistle, causing PAMGuard to throw an exception.  Both -were already being cleared when the pop-up window is closed, so no need to do -it here.

+time to trace out the whistle, causing PAMGuard to throw an exception.  +Both were already being cleared when the pop-up window is closed, so no need to +do it here.

DIFAR Module: Bug crashing the module with null pointer errors fixed.

@@ -517,9 +521,13 @@ Bug crashing the module with null pointer errors fixed.

lang=EN-US>: Fixed bug which caused the detector to slow to almost zero speed when large complex sounds with many branches were detected.

+

Click Detector Offline Event Marking: Fixed problem of events not being correctly deleted and also of +clicks not being correctly reassigned to different events.

+

Screen Position: When using multiple monitors, if you move a configuration to a -computer with a different monitor layout, the GUI should work out if it’s +computer with a different monitor layout, the GUI should work out if itÂ’s opening on a screen area which no longer exists and move itself onto the primary monitor.

@@ -541,8 +549,8 @@ were reading local time, even when set to use UTC.

which mostly occurred when processing large datasets of many offline files, has been fixed.

-

Data Map: “Scroll To Data” pop-up menu, -which didn’t always scroll to the correct place, is now fixed.

+

Data Map: “Scroll To Data” pop-up menu, +which didn’t always scroll to the correct place, is now fixed.

Bearing Localiser offline: If reprocessing bearings, the localizer was not correctly loading required raw or FFT data to @@ -565,7 +573,7 @@ files and stores them within the PAMGuard configuration. This does not affect processing, but is important for record keeping.

GPS options to use any valid RMC or GGA -string. Not all GPS receivers output their RMC data as GPRMC – e.g. some may +string. Not all GPS receivers output their RMC data as GPRMC – e.g. some may output as GNRMC. A new option allows the GPS module to use any string, whatever the first two characters of the string name may be.

@@ -574,14 +582,14 @@ the first two characters of the string name may be.

Bug Fixes

Use of localization sensor and orientation -data for static hydrophones had a bug whereby it would continually ‘forget’ +data for static hydrophones had a bug whereby it would continually ‘forgetÂ’ angle offsets applied to static hydrophones in viewer mode. This is now fixed.

Click tool bar: Correctly shows event selection options even if no species classification options are in place.

Fixed Landmarks: Earlier versions were -‘losing’ these every time PAMGuard started or new data were loaded in viewer +‘losingÂ’ these every time PAMGuard started or new data were loaded in viewer mode. Now fixed.

ROCCA: Fixed (another) memory leak which @@ -600,11 +608,11 @@ processing.

New sound type for simulated sounds which generates random chirps between around 200 and 800Hz, roughly the frequency -you’d expect sound from higher frequency baleen whales, such as humpbacks, to +youÂ’d expect sound from higher frequency baleen whales, such as humpbacks, to vocalise at.   

Hiding tool tips. A menu item to -permanently turn off all tool tips, or tap the ‘Esc’ key to turn them off for 6 +permanently turn off all tool tips, or tap the ‘EscÂ’ key to turn them off for 6 seconds if they are getting in the way, particularly when trying to interact with displays using the mouse.

@@ -625,7 +633,7 @@ whistle classification module.

New Features

-

SoundTrap SUD file reading. If you’re using +

SoundTrap SUD file reading. If youÂ’re using SoundTrap autonomous recorders from Ocean Instruments, you no longer need to decompress the SoundTrap files prior to processing. This will save time and a lot of disk space. Extraction of clicks from the inbuilt SoundTrap Click @@ -689,7 +697,7 @@ audio files.

Bug Fixes

Soundtrap DWV import. Will now generate -binary files even if DWV file doesn’t exist (which is correct behavior in +binary files even if DWV file doesn’t exist (which is correct behavior in quiet conditions when no clicks were detected).

Spectrogram. Changes to stop occasional @@ -724,8 +732,8 @@ running in real time. Added template names based on file names.

#13 Merging files when offline processing file folders: Had an error introduced in last release which caused it to fail to recognise gaps between files, meaning that some output data (i.e. after a gap) would have an -incorrect time stamp. This did not affect data if the ‘merge contiguous -files’ option was not selected.

+incorrect time stamp. This did not affect data if the ‘merge contiguous +files’ option was not selected.

#14 Logger forms data were not plotting correctly. This was due to the required data selection functions not being fully implemented. This @@ -787,17 +795,16 @@ font-family:"Times New Roman",serif'> 

Localisation Modules

-

Bearing and Group 3D localization modules have been -thoroughly tested and a number of bugs rectified. Documentation has been -developed and is available in the online help. Further, a number of example -configurations have been generated, configuration files for these are available -in the PAMGuard downloads area here.

+

Bearing and Group 3D localization modules have been thoroughly +tested and a number of bugs rectified. Documentation has been developed and is +available in the online help. Further, a number of example configurations have +been generated, configuration files for these are available in the PAMGuard +downloads area here.

Detection Group Localiser

-

This module has been renamed “Detection Grouper”, so +

This module has been renamed “Detection Grouper”, so as to avoid confusion with the Group 3D localizer. This is because the Detection Grouper is more for organizing data into groups to be localized than it is for doing localization.

@@ -919,9 +926,9 @@ included in a future release.

17.        An implementation of the Generalized Power Law Detector, -developed by Tyler Helble ([Helble et al., ‘A generalized power-law -detection algorithm for humpback whale vocalizations’, The Journal of the -Acoustical Society of America, vol. 131, no. 4, pp. 2682–2699, 2012) is now +developed by Tyler Helble ([Helble et al., ‘A generalized power-law +detection algorithm for humpback whale vocalizations’, The Journal of the +Acoustical Society of America, vol. 131, no. 4, pp. 2682–2699, 2012) is now available. For details, see the online help

18. Beta Version 2.00.10 before proceeding with installation and use of this version.

-

This version of PAMGuard has been bundled with Java 13 -(release 13.0.1). PSFX files generated in previous beta releases (2.xx.xx) -should be compatible with this version, and vice-versa. PSF files generated in -core releases (1.15.xx) can be loaded in this version, but will be converted to -PSFX files when PAMGuard exits.

+

This version of PAMGuard has been bundled with Java 13 (release +13.0.1). PSFX files generated in previous beta releases (2.xx.xx) should be +compatible with this version, and vice-versa. PSF files generated in core +releases (1.15.xx) can be loaded in this version, but will be converted to PSFX +files when PAMGuard exits.

Bug Fixes

@@ -1187,8 +1194,8 @@ lang=EN-US> Add option to alarm module to attach screenshots of all frames to email alerts.

7.        -Add Beamformer and Bearing Localiser modules

+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>       Add Beamformer and Bearing Localiser modules

8.       

15.        -Bug 447. Viewer mode throws exception when trying to load beamformer -localisations

+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>       Bug 447. Viewer mode throws exception when trying to load +beamformer localisations

16.       

2.        Added Matched Template Click Classifier. Classifies clicks -based on an ideal template to match and a template to reject. An example of -this is to classify beaked whale clicks in an environment with dolphin clicks.

+lang=EN-US> Added Matched Template Click Classifier. Classifies clicks based +on an ideal template to match and a template to reject. An example of this is +to classify beaked whale clicks in an environment with dolphin clicks.

3.        @@ -1933,12 +1940,12 @@ A number of upgrades and fixes to the Localiser algorithms, including expanding to work with whistles.

3.        -Added option to export all settings and parameters as an XML-formatted file. -Note that this required changes to the structure of the Array Manager, and as -such any settings (psf) files created with this version of Pamguard cannot be -used in older versions. Older psf files can be loaded with this version, but -will be converted.

+lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>       Added option to export all settings and parameters as an +XML-formatted file. Note that this required changes to the structure of the +Array Manager, and as such any settings (psf) files created with this version +of Pamguard cannot be used in older versions. Older psf files can be loaded +with this version, but will be converted.

4.        User is now able to specify Soundtrap date/time format

Beta Version 2.00.11 October 2017

-

PAMGuard Version 2 contains major updates. -You should read and understand the notes listed for PAMGuard Version 2 contains major updates. You +should read and understand the notes listed for Beta Version 2.00.10 before proceeding with installation and use of this version.

@@ -2194,7 +2201,7 @@ file format is the addition of a Unique Data Identifier (UID) to each unit of data. This is intended to aid in offline analysis by making it easier for the user to link what they are seeing on different PAMGuard displays and also to link with any data post processed in Matlab or other custom analysis software. -UID’s are also added to PAMGuard database tables.

+UID’s are also added to PAMGuard database tables.

Converting Old Data

@@ -2202,13 +2209,13 @@ UID’s are also added to PAMGuard database tables.

viewer they will automatically be converted. For safety, the original binary files will not be overwritten and the new data will be placed in a new folder on your computer with the same path as the old data, but suffixed with -‘_WithUID’, e.g. if your binary data were previously stored in the folder +‘_WithUID’, e.g. if your binary data were previously stored in the folder C:\MySurvey\binarydata the new data will be written to C:\MySurvey\binarydata_WithUID.

The additional UID column will be added to all database tables and populated with unique values. For data which are stored -in both the binary files and in database tables, the same UID’s will be used +in both the binary files and in database tables, the same UID’s will be used in both data stores.

New Displays

@@ -2350,10 +2357,9 @@ happens when the user selects save as new configuration. This has been fixed.

6.       -Bug 315. code searched for file in working folder, which is the -installation folder when starting PAMGuard using a shortcut link. But when -double-clicking on a psf, the working folder is the location of the psf. This -has been fixed.

+Bug 315. code searched for file in working folder, which is the installation +folder when starting PAMGuard using a shortcut link. But when double-clicking +on a psf, the working folder is the location of the psf. This has been fixed.

7.      

Other Changes

-

The installer has been updated to handle -both 64 bit and 32 bit installations. PAMGuard psf files are now registered in -the Windows Registry, so double-clicking on a psf file should run PAMGuard in +

The installer has been updated to handle both +64 bit and 32 bit installations. PAMGuard psf files are now registered in the +Windows Registry, so double-clicking on a psf file should run PAMGuard in normal mode (as opposed to Viewer or Mixed modes). Note that the Windows Registry can only hold a single executable reference for psf files; therefore, for users with multiple installations of PAMGuard, double-clicking on a psf @@ -2443,7 +2449,7 @@ November 2016

1.       Bug 303. Some ASIO sound cards not working with either ASIO system in PAMGuard. For the PAMGuard ASIO system, this was due to a data format used by some sound -cards never being properly implemented. For the “New ASIO system” which +cards never being properly implemented. For the “New ASIO system” which is based on jAsioHost, the unpacking of that format contained a bug which returned incorrect numbers, so data were swamped with noise. Both systems are now fixed. By preference, users should use the PAMGuard ASIO system since the @@ -3395,8 +3401,8 @@ whistle.

  • Airgun display. If this was included in the PAMGuard model before the GPS module it would hang PAMGuard. This has been rectified.
  • -
  • Fixed occasional exceptions in - the sound output modules when playing back from files.
  • +
  • Fixed occasional exceptions in the + sound output modules when playing back from files.
  • Fixed exceptions in spectrogram user interface.
  • Fixed National Instruments sound @@ -3478,8 +3484,8 @@ other data sources for the PAMGuard viewer.

    storage to the database offline for any module having both binary and database storage.

    -

    Can create a blank MS Access -database (2007 and later *.accdb formats only).

    +

    Can create a blank MS Access database +(2007 and later *.accdb formats only).

    Can open MS Access from within PAMGuard to make it easier to view database content.

    @@ -3798,10 +3804,10 @@ source, even if that data source is loaded after the FFT module is created.

    1. Binary storage module.

    -

    Performs a parallel role to the PAMGAURD database but uses -binary files in a proprietary format which is considerably more efficient for -data of unknown length such as whistle contours or small clips of click -waveform. This feature is currently implemented in the following modules:

    +

    Performs a parallel role to the PAMGAURD database but uses binary +files in a proprietary format which is considerably more efficient for data of +unknown length such as whistle contours or small clips of click waveform. This +feature is currently implemented in the following modules:

    '         @@ -4010,8 +4016,8 @@ column was setting to zero. This is now fixed

    Ishmael Detectors

    -

    Better rendering of detection boxes on spectrogram display -and more meaningful names in spectrogram display menu.

    +

    Better rendering of detection boxes on spectrogram display and +more meaningful names in spectrogram display menu.

    Sound acquisition

    diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 7b7fa51a..5b4dd67c 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.pamguard Pamguard Pamguard Java12+ - 2.02.09f + 2.02.09aa Pamguard for Java 12+, using Maven to control dependcies www.pamguard.org @@ -17,6 +17,7 @@ src + META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA **/*.java jars/*.* @@ -196,6 +197,10 @@ 11 11 + UTF-8 16 + 2.4.0-b180830.0438 + 2.4.0-b180830.0438 + 2.4.0-b180830.0359 diff --git a/pom.xml b/pom.xml index bf2ea63c..37d9444e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.pamguard Pamguard - 2.02.09f + 2.02.09aa Pamguard Java12+ Pamguard for Java 12+, using Maven to control dependcies www.pamguard.org @@ -14,27 +14,33 @@ - - 16 - 11 - 11 - + + 16 + 11 + 11 + UTF-8 + 2.4.0-b180830.0438 + 2.4.0-b180830.0359 + 2.4.0-b180830.0438 + - - src - - - src - - **/*.java - jars/*.* - - - - - - - + jars/*.* + + + + + + + + - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - - 11 - jdt - - .settings/org.eclipse.jdt.core.prefs - - - - - - - org.eclipse.tycho - tycho-compiler-jdt - 1.5.1 - - - - - - - org.openjfx - javafx-maven-plugin - 0.0.6 - - 17 - 17 - 17 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - - - - - - - package - - shade - - - - - - pamguard.Pamguard - . - Resources/pgBlankSplash.png - - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - + --> + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + - - - com.github.marschall - jdeps-maven-plugin - 0.5.1 - + + 11 + jdt + + .settings/org.eclipse.jdt.core.prefs + + - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - - - copy-dependencies - package - - copy-dependencies - - - ${project.build.directory}/tempDependencies - false - false - true - - - - + + org.eclipse.tycho + tycho-compiler-jdt + 1.5.1 + + + + + + + org.openjfx + javafx-maven-plugin + 0.0.6 + + 17 + 17 + 17 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + package + + shade + + + + + + pamguard.Pamguard + . + Resources/pgBlankSplash.png + + + + + + + + + + + + com.github.marschall + jdeps-maven-plugin + 0.5.1 + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/tempDependencies + false + false + true + + + + - - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins - + maven-dependency-plugin - + [3.1.1,) - - + + purge-local-repository - - - - - - - - - - - - - - - - - - com.github.marschall - jdeps-maven-plugin - 0.5.1 - - - - - - - - + + + + + + + + + + + + + + + + + + com.github.marschall + jdeps-maven-plugin + 0.5.1 + + + + + + + + @@ -246,35 +255,35 @@ file://${project.basedir}/repo - - - + - - - - - - - - - - - - - false - - unidata-all - Unidata netCDF - https://artifacts.unidata.ucar.edu/repository/unidata-all/ - - - + + + + + + + + + + + + false + + unidata-all + Unidata netCDF + https://artifacts.unidata.ucar.edu/repository/unidata-all/ + + + - - - - - false - - bedatadriven - bedatadriven_renjin - https://nexus.bedatadriven.com/content/groups/public/ - - - - - false - - talan - talan - https://nexus.talanlabs.com/content/repositories/releases/ - - - - central - https://repo1.maven.org/maven2 - - + + + + + false + + bedatadriven + bedatadriven_renjin + https://nexus.bedatadriven.com/content/groups/public/ + + + + + false + + talan + talan + https://nexus.talanlabs.com/content/repositories/releases/ + + + + central + https://repo1.maven.org/maven2 + + - - + + - - - io.github.macster110 - jpamutils - 0.0.56 - + + + io.github.macster110 + jpamutils + 0.0.56 + - - - io.github.macster110 - jdl4pam - 0.0.94 - - - - - gov.nist.math - jama - 1.0.3 - - - - - - org.openjfx - javafx-controls - ${javafx.version} - + + io.github.macster110 + jdl4pam + 0.0.94 + - - - - org.openjfx - javafx-swing - ${javafx.version} - - - - - - org.openjfx - javafx-media - ${javafx.version} - + + + gov.nist.math + jama + 1.0.3 + - - + - - org.openjfx - javafx-web - ${javafx.version} - - - - - net.synedra - validatorfx - 0.4.0 - - - - - org.apache.commons - commons-compress - 1.19 - + + org.openjfx + javafx-controls + ${javafx.version} + - - - org.apache.commons - commons-csv - 1.7 - - - - - commons-io - commons-io - 2.6 - - - - - org.apache.commons - commons-lang3 - 3.9 - - - - - org.apache.commons - commons-math3 - 3.6.1 - - - - - org.apache.commons - commons-math - 2.2 - - - - - commons-net - commons-net - 3.6 - - - - - org.controlsfx - controlsfx - 11.0.0 - - - org.openjfx - javafx-base - - - org.openjfx - javafx-controls - - - org.openjfx - javafx-graphics - - - org.openjfx - javafx-media - - - org.openjfx - javafx-web - - - - - - + + + org.openjfx + javafx-swing + ${javafx.version} + + + + + + org.openjfx + javafx-media + ${javafx.version} + + + + + + org.openjfx + javafx-web + ${javafx.version} + + + + + net.synedra + validatorfx + 0.4.0 + + + + + org.apache.commons + commons-compress + 1.19 + + + + + org.apache.commons + commons-csv + 1.7 + + + + + commons-io + commons-io + 2.6 + + + + + org.apache.commons + commons-lang3 + 3.9 + + + + + org.apache.commons + commons-math3 + 3.6.1 + + + + + org.apache.commons + commons-math + 2.2 + + + + + commons-net + commons-net + 3.6 + + + + + org.controlsfx + controlsfx + 11.0.0 + + + org.openjfx + javafx-base + + + org.openjfx + javafx-controls + + + org.openjfx + javafx-graphics + + + org.openjfx + javafx-media + + + org.openjfx + javafx-web + + + + + + - - org.kordamp.ikonli - ikonli-javafx - 12.2.0 - - - - + - - - - org.kordamp.ikonli - ikonli-materialdesign2-pack - 12.2.0 - - - - - net.sf.geographiclib - GeographicLib-Java - 1.50 - - - - - org.jogamp.gluegen - gluegen-rt-main - 2.3.2 - - - - - - - - com.healthmarketscience.jackcess - jackcess - 3.0.1 - - - - - com.fasterxml.jackson.core - jackson-databind - 2.10.1 - - - - - org.jogamp.jogl - jogl-all-main - 2.3.2 - - - + + org.kordamp.ikonli + ikonli-materialdesign2-pack + 12.2.0 + + + + + net.sf.geographiclib + GeographicLib-Java + 1.50 + + + + + org.jogamp.gluegen + gluegen-rt-main + 2.3.2 + + + + + + + + + com.healthmarketscience.jackcess + jackcess + 3.0.1 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.10.1 + + + + + org.jogamp.jogl + jogl-all-main + 2.3.2 + + + - - - - org.jflac - jflac-codec - 1.5.2 - - - - - javax.help - javahelp - 2.0.05 - - - - - net.java.dev.jna - jna - 5.5.0 - - + + + + org.jflac + jflac-codec + 1.5.2 + + + + + javax.help + javahelp + 2.0.05 + + + + + net.java.dev.jna + jna + 5.5.0 + + - - net.java.dev.jna - jna-platform - 5.5.0 - - - - - com.jcraft - jsch - 0.1.55 - - - - - com.fazecast - jSerialComm - 2.5.3 - + + net.java.dev.jna + jna-platform + 5.5.0 + - - - edu.emory.mathcs - JTransforms - 2.4 - + + + com.jcraft + jsch + 0.1.55 + - - - com.sun.mail - javax.mail - 1.6.2 - + + + com.fazecast + jSerialComm + 2.5.3 + - - - com.diffplug.matsim - matfilerw - 3.1.1 - + + + edu.emory.mathcs + JTransforms + 2.4 + - - - com.drewnoakes - metadata-extractor - 2.12.0 - + + + com.sun.mail + javax.mail + 1.6.2 + - - - mysql - mysql-connector-java - 8.0.18 - + + + com.diffplug.matsim + matfilerw + 3.1.1 + - - - + + com.drewnoakes + metadata-extractor + 2.12.0 + + + + + mysql + mysql-connector-java + 8.0.18 + + + + + - - com.google.protobuf - protobuf-java - 3.17.0 - - - - - - edu.ucar - netcdfAll - 4.6.14 - - + com.google.protobuf protobuf-java - - - com.google.protobuf - protobuf-java-util - - - compile - + 3.17.0 + - - - com.opencsv - opencsv - 5.0 - + + + + edu.ucar + netcdfAll + 4.6.14 + + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + + + compile + - + + + com.opencsv + opencsv + 5.0 + - - - org.postgresql - postgresql - 42.2.24 - + - - - org.renjin - renjin-script-engine - 0.9.2725 - - - + + org.postgresql + postgresql + 42.2.24 + + + + + org.renjin + renjin-script-engine + 0.9.2725 + + + - - org.slf4j - slf4j-api - 1.8.0-beta4 - - - - - - - org.slf4j - slf4j-nop - 1.8.0-beta4 - - - + + org.slf4j + slf4j-api + 1.8.0-beta4 + - - + + org.slf4j + slf4j-nop + 1.8.0-beta4 + + + + + - - - org.docx4j - docx4j-JAXB-ReferenceImpl - 11.1.3 - - + - - - org.xerial - sqlite-jdbc - 3.28.0 - + + + org.xerial + sqlite-jdbc + 3.28.0 + - - - net.sf.ucanaccess - ucanaccess - 4.0.4 - + + + net.sf.ucanaccess + ucanaccess + 4.0.4 + - - - nz.ac.waikato.cms.weka - weka-dev - 3.7.7 - + + + nz.ac.waikato.cms.weka + weka-dev + 3.7.7 + - - - javax.vecmath - vecmath - 1.5.2 - + + + javax.vecmath + vecmath + 1.5.2 + - - - - + + org.eclipse.persistence + org.eclipse.persistence.moxy + 2.5.0 + + + javax.xml.bind + jaxb-api + ${jaxb.api.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb.runtime.version} + + + org.glassfish.jaxb + jaxb-xjc + ${jaxb.xjc.version} + + + + com.sun.jersey.contribs + jersey-multipart + 1.18.1 + + + commons-cli + commons-cli + 1.2 + + + org.apache.poi + poi + 3.10-beta1 + + + com.sun.jersey + jersey-client + 1.18.1 + + + com.sun.jersey.contribs + jersey-apache-client + 1.18.1 + + + com.miglayout + miglayout + 3.7.4 + + + ca.juliusdavies + not-yet-commons-ssl + 0.3.11 + + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + + + javax.xml.bind + jaxb-api + 2.2.11 + + + com.sun.xml.bind + jaxb-impl + 2.2.11 + + + javax.activation + activation + 1.1 + + + org.glassfish.jaxb + jaxb-core + 2.2.11 + + + org.glassfish.jersey.core + jersey-common + 2.2 + + + org.apache.commons + commons-text + 1.9 + + + + @@ -789,60 +890,76 @@ C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2--> 2.2.7 - - - - it.sauronsoftware - jave - 1.0.2 - - - - - com.synthbot - jasiohost - 1.0.0 - + - - + + it.sauronsoftware + jave + 1.0.2 + + + + + com.synthbot + jasiohost + 1.0.0 + + + + - - - - org.springframework - spring-core - 5.2.3.RELEASE - - - - - - com.1stleg - jnativehook - 2.1.0 - - - - - - org.swinglabs.swingx - swingx-all - 1.6.5-1 - - - - io.github.mkpaz - atlantafx-base - 1.0.0 - - - - + + + org.springframework + spring-core + 5.2.3.RELEASE + + + + + + com.1stleg + jnativehook + 2.1.0 + + + + + + org.swinglabs.swingx + swingx-all + 1.6.5-1 + + + + + io.github.mkpaz + atlantafx-base + 1.0.0 + + + + \ No newline at end of file diff --git a/repo/tethys/org/javaclient/3.0/_remote.repositories b/repo/tethys/org/javaclient/3.0/_remote.repositories new file mode 100644 index 00000000..432cee9e --- /dev/null +++ b/repo/tethys/org/javaclient/3.0/_remote.repositories @@ -0,0 +1,4 @@ +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:13:37 GMT 2023 +javaclient-3.0.jar>= +javaclient-3.0.pom>= diff --git a/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar b/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar new file mode 100644 index 00000000..d1654195 Binary files /dev/null and b/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar differ diff --git a/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom b/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom new file mode 100644 index 00000000..80fee21c --- /dev/null +++ b/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + tethys.org + javaclient + 3.0 + POM was created from install:install-file + diff --git a/repo/tethys/org/javaclient/maven-metadata-local.xml b/repo/tethys/org/javaclient/maven-metadata-local.xml new file mode 100644 index 00000000..629dfa04 --- /dev/null +++ b/repo/tethys/org/javaclient/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + tethys.org + javaclient + + 3.0 + + 3.0 + + 20231221111337 + + diff --git a/repo/tethys/org/nilus/3.0/_remote.repositories b/repo/tethys/org/nilus/3.0/_remote.repositories new file mode 100644 index 00000000..a5060b8b --- /dev/null +++ b/repo/tethys/org/nilus/3.0/_remote.repositories @@ -0,0 +1,4 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:14:13 GMT 2023 +nilus-3.0.pom>= +nilus-3.0.jar>= diff --git a/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties b/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties new file mode 100644 index 00000000..8382f138 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties @@ -0,0 +1,11 @@ +#Thu Dec 21 16:45:12 GMT 2023 +bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1703177112968 +talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1703177112968 +repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|javadoc=1703177112968 +central|https\://repo1.maven.org/maven2|sources=1703157324238 +unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1703177112968 +repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|sources=1703157324238 +talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1703157324238 +bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1703157324238 +unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1703157324238 +central|https\://repo1.maven.org/maven2|javadoc=1703177112968 diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated b/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated new file mode 100644 index 00000000..34e39dc5 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated @@ -0,0 +1,12 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 16:45:12 GMT 2023 +@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1703177112601 +https\://repo1.maven.org/maven2/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703177110940 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error= +https\://nexus.bedatadriven.com/content/groups/public/.error= +https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703177112519 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1703177112101 +https\://repo1.maven.org/maven2/.lastUpdated=1703177112965 +https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:javadoc\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated b/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated new file mode 100644 index 00000000..8ceb547f --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated @@ -0,0 +1,12 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:15:24 GMT 2023 +@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1703157323819 +https\://repo1.maven.org/maven2/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703157322932 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error= +https\://nexus.bedatadriven.com/content/groups/public/.error= +https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703157323770 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1703157323508 +https\://repo1.maven.org/maven2/.lastUpdated=1703157324237 +https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:sources\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0.jar b/repo/tethys/org/nilus/3.0/nilus-3.0.jar new file mode 100644 index 00000000..195d268e Binary files /dev/null and b/repo/tethys/org/nilus/3.0/nilus-3.0.jar differ diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0.pom b/repo/tethys/org/nilus/3.0/nilus-3.0.pom new file mode 100644 index 00000000..ba47dee9 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + tethys.org + nilus + 3.0 + POM was created from install:install-file + diff --git a/repo/tethys/org/nilus/maven-metadata-local.xml b/repo/tethys/org/nilus/maven-metadata-local.xml new file mode 100644 index 00000000..d053c39d --- /dev/null +++ b/repo/tethys/org/nilus/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + tethys.org + nilus + + 3.0 + + 3.0 + + 20231221111413 + + diff --git a/src/AIS/AISParameters.java b/src/AIS/AISParameters.java index 982b5763..2f902b44 100644 --- a/src/AIS/AISParameters.java +++ b/src/AIS/AISParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class AISParameters implements Serializable, Cloneable, ManagedParameters { @@ -51,7 +52,7 @@ public class AISParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nmeaSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/AIS/AISPositionReport.java b/src/AIS/AISPositionReport.java index fda5b10f..ca23ad50 100644 --- a/src/AIS/AISPositionReport.java +++ b/src/AIS/AISPositionReport.java @@ -5,6 +5,7 @@ import java.io.Serializable; import NMEA.NMEABitArray; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; /** @@ -160,7 +161,7 @@ sensor. @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/AIS/AISStaticData.java b/src/AIS/AISStaticData.java index 7ca318c5..cbf891dc 100644 --- a/src/AIS/AISStaticData.java +++ b/src/AIS/AISStaticData.java @@ -6,6 +6,7 @@ import java.util.Calendar; import NMEA.NMEABitArray; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class AISStaticData extends AISReport implements Serializable, ManagedParameters{ @@ -393,7 +394,7 @@ public class AISStaticData extends AISReport implements Serializable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Acquisition/AcquisitionControl.java b/src/Acquisition/AcquisitionControl.java index 6ef615fb..b9410172 100644 --- a/src/Acquisition/AcquisitionControl.java +++ b/src/Acquisition/AcquisitionControl.java @@ -283,6 +283,16 @@ public class AcquisitionControl extends RawInputControlledUnit implements PamSet return daqControllers; } + @Override + public String getDataLocation() { + if (offlineFileServer == null) { + return null; + } + else { + return offlineFileServer.getDataLocation(); + } + } + public AcquisitionProcess getDaqProcess() { return acquisitionProcess; } diff --git a/src/Acquisition/AcquisitionDialog.java b/src/Acquisition/AcquisitionDialog.java index 50e0d977..cb739bb2 100644 --- a/src/Acquisition/AcquisitionDialog.java +++ b/src/Acquisition/AcquisitionDialog.java @@ -151,6 +151,7 @@ public class AcquisitionDialog extends PamDialog { acquisitionParameters = oldParams.clone(); acquisitionControl = daqControl; +// singleInstance = null; if (singleInstance == null || singleInstance.getOwner() != parentFrame) { singleInstance = new AcquisitionDialog(parentFrame); diff --git a/src/Acquisition/AcquisitionParameters.java b/src/Acquisition/AcquisitionParameters.java index fd79799e..a9c02698 100644 --- a/src/Acquisition/AcquisitionParameters.java +++ b/src/Acquisition/AcquisitionParameters.java @@ -10,6 +10,7 @@ import Array.Preamplifier; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -320,7 +321,7 @@ public class AcquisitionParameters implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("channelList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Acquisition/DaqStatusModuleHeader.java b/src/Acquisition/DaqStatusModuleHeader.java index 5af44a54..5a548a6a 100644 --- a/src/Acquisition/DaqStatusModuleHeader.java +++ b/src/Acquisition/DaqStatusModuleHeader.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; @@ -30,7 +31,7 @@ class DaqStatusModuleHeader extends ModuleHeader implements Serializable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("daqName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Acquisition/FileInputParameters.java b/src/Acquisition/FileInputParameters.java index 6453b2f1..9a3f114d 100644 --- a/src/Acquisition/FileInputParameters.java +++ b/src/Acquisition/FileInputParameters.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Used by FileInputSystem @@ -78,7 +79,7 @@ public class FileInputParameters implements Serializable, Cloneable, ManagedPara return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/Acquisition/FolderInputSystem.java b/src/Acquisition/FolderInputSystem.java index 93107b31..7b20311e 100644 --- a/src/Acquisition/FolderInputSystem.java +++ b/src/Acquisition/FolderInputSystem.java @@ -700,7 +700,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D if (currentFile > 0 && currentFile >= allFiles.size()) { fileListComplete(); } -// System.out.println("FolderinputSytem: daqHasEnded"); + System.out.println("FolderinputSytem: daqHasEnded"); } private void setFolderProgress() { diff --git a/src/Acquisition/SoundCardParameters.java b/src/Acquisition/SoundCardParameters.java index e962db72..a54b62b4 100644 --- a/src/Acquisition/SoundCardParameters.java +++ b/src/Acquisition/SoundCardParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import simulatedAcquisition.SimProcess; /** @@ -47,7 +48,7 @@ public class SoundCardParameters implements Serializable, Cloneable, ManagedPara return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/Acquisition/filedate/StandardFileDateSettings.java b/src/Acquisition/filedate/StandardFileDateSettings.java index 074540f1..b699ca9a 100644 --- a/src/Acquisition/filedate/StandardFileDateSettings.java +++ b/src/Acquisition/filedate/StandardFileDateSettings.java @@ -6,6 +6,7 @@ import java.util.TimeZone; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import soundtrap.STXMLFile; public class StandardFileDateSettings implements Serializable, Cloneable, ManagedParameters { @@ -150,7 +151,7 @@ public class StandardFileDateSettings implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } } diff --git a/src/Acquisition/gpstiming/PPSParameters.java b/src/Acquisition/gpstiming/PPSParameters.java index 76bdd012..478d7728 100644 --- a/src/Acquisition/gpstiming/PPSParameters.java +++ b/src/Acquisition/gpstiming/PPSParameters.java @@ -6,6 +6,7 @@ import Acquisition.AcquisitionControl; import Acquisition.AcquisitionDialog; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class PPSParameters implements Cloneable, Serializable, ManagedParameters { @@ -36,7 +37,7 @@ public class PPSParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/AirgunDisplay/AirgunParameters.java b/src/AirgunDisplay/AirgunParameters.java index fe779657..5fae8317 100644 --- a/src/AirgunDisplay/AirgunParameters.java +++ b/src/AirgunDisplay/AirgunParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; @@ -95,7 +96,7 @@ public class AirgunParameters implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("dimE"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/ArrayDialog.java b/src/Array/ArrayDialog.java index 3469b1a2..4475d7bb 100644 --- a/src/Array/ArrayDialog.java +++ b/src/Array/ArrayDialog.java @@ -44,6 +44,8 @@ public class ArrayDialog extends PamDialog implements ActionListener { private EnvironmentPanel environmentPanel; private HydrophoneDiagram hydrophoneDiagram; + + private InstrumentIdentityPanel instrumentIdentityPanel; private JButton okButton, cancelButton; @@ -69,11 +71,14 @@ public class ArrayDialog extends PamDialog implements ActionListener { eastPanel.add(channelPanel.getChannelPanel()); environmentPanel = new EnvironmentPanel(this); + instrumentIdentityPanel = new InstrumentIdentityPanel(); + // eastPanel.add(environmentPanel.getEnvironmentPanel()); hydrophoneDiagram = new HydrophoneDiagram(this); JPanel westPanel = new JPanel(new BorderLayout()); westPanel.add(BorderLayout.CENTER, hydrophoneDiagram.getPlotPanel()); westPanel.add(BorderLayout.SOUTH, environmentPanel.getEnvironmentPanel()); + westPanel.add(BorderLayout.NORTH, instrumentIdentityPanel.getComponent()); splitPanel.add(westPanel); @@ -144,6 +149,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { hydrophoneDialogPanel.setParams(selArray); channelPanel.setParams(); hydrophoneDiagram.rePaint(); + instrumentIdentityPanel.setParams(selArray); if (selArray != null) { environmentPanel.setNewSpeed(selArray.getSpeedOfSound()); } @@ -171,6 +177,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { array.setSpeedOfSound(environmentPanel.getNewSpeed()); array.setSpeedOfSoundError(environmentPanel.getNewError()); hydrophoneDialogPanel.getParams(); + instrumentIdentityPanel.getParams(array); if (checkDaqChannels(array) == false) { return false; @@ -250,6 +257,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { environmentPanel.setNewSpeed(currentArray.getSpeedOfSound()); environmentPanel.setNewError(currentArray.getSpeedOfSoundError()); } + instrumentIdentityPanel.setParams(currentArray); } void newChannelSelection() { diff --git a/src/Array/Hydrophone.java b/src/Array/Hydrophone.java index ffbda1ac..c2f82bd5 100644 --- a/src/Array/Hydrophone.java +++ b/src/Array/Hydrophone.java @@ -28,6 +28,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import pamMaths.PamVector; import PamView.PamSymbol; @@ -158,7 +159,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { return sensitivity; } - protected void setSensitivity(double sensitivity) { + public void setSensitivity(double sensitivity) { this.sensitivity = sensitivity; } @@ -333,7 +334,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { /** * @return Returns the coordinate. */ - protected double[] getCoordinates() { + public double[] getCoordinates() { return Arrays.copyOf(coordinate,3); } @@ -364,7 +365,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { /** * @param preampGain The preampGain to set. */ - protected void setPreampGain(double preampGain) { + public void setPreampGain(double preampGain) { this.preampGain = preampGain; } @@ -478,7 +479,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet pps = PamParameterSet.autoGenerate(this); + PamParameterSet pps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); Field f; try { f = this.getClass().getDeclaredField("coordinate"); diff --git a/src/Array/HydrophoneLocator.java b/src/Array/HydrophoneLocator.java index d51fafbb..5d6c9d7c 100644 --- a/src/Array/HydrophoneLocator.java +++ b/src/Array/HydrophoneLocator.java @@ -7,6 +7,7 @@ import Array.streamerOrigin.StreamerDataIterator; import GPS.GpsData; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamguardMVC.PamDataBlock; @@ -225,7 +226,7 @@ abstract public class HydrophoneLocator implements Serializable, Cloneable, Mana */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("pamArray"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/InstrumentIdentityPanel.java b/src/Array/InstrumentIdentityPanel.java new file mode 100644 index 00000000..b8f21137 --- /dev/null +++ b/src/Array/InstrumentIdentityPanel.java @@ -0,0 +1,72 @@ +package Array; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; + +/** + * Instrument identity panel, contrians additional fields required by Tethys. + * @author dg50 + * + */ +public class InstrumentIdentityPanel { + + private JPanel mainPanel; + + private JTextField instrumentId; + + private JTextField instrumentType; + + public InstrumentIdentityPanel() { + mainPanel = new WestAlignedPanel(); + mainPanel.setBorder(new TitledBorder("Instrument information")); + mainPanel.setLayout(new GridBagLayout()); + GridBagConstraints c = new PamGridBagContraints(); + mainPanel.add(new JLabel("Instrument Type ", JLabel.RIGHT), c); + c.gridx++; + mainPanel.add(instrumentType = new JTextField(20), c); + c.gridx = 0; + c.gridy++; + mainPanel.add(new JLabel("Instrument Id ", JLabel.RIGHT), c); + c.gridx++; + mainPanel.add(instrumentId = new JTextField(20), c); + + instrumentType.setToolTipText("Instrument type, e.g. Towed array, HARP, EAR, Popup, DMON, Rock Hopper, etc."); + instrumentId.setToolTipText("Instrument identifier, e.g. serial number"); + + } + + public JComponent getComponent() { + return mainPanel; + } + + public void setParams(PamArray currentArray) { + if (currentArray == null) { + currentArray = ArrayManager.getArrayManager().getCurrentArray(); + } + if (currentArray == null) { + return; + } + instrumentType.setText(currentArray.getInstrumentType()); + instrumentId.setText(currentArray.getInstrumentId()); + } + + public void getParams(PamArray currentArray) { + if (currentArray == null) { + currentArray = ArrayManager.getArrayManager().getCurrentArray(); + } + if (currentArray == null) { + return; + } + currentArray.setInstrumentType(instrumentType.getText()); + currentArray.setInstrumentId(instrumentId.getText()); + } +} diff --git a/src/Array/MovingHydrophoneLocator.java b/src/Array/MovingHydrophoneLocator.java index 2c17059f..faf88005 100644 --- a/src/Array/MovingHydrophoneLocator.java +++ b/src/Array/MovingHydrophoneLocator.java @@ -16,5 +16,10 @@ abstract public class MovingHydrophoneLocator extends SimpleHydrophoneLocator { super(pamArray, streamer); } + @Override + public boolean isChangeable() { + return true; + } + } diff --git a/src/Array/PamArray.java b/src/Array/PamArray.java index a351e47d..a116108d 100644 --- a/src/Array/PamArray.java +++ b/src/Array/PamArray.java @@ -35,6 +35,7 @@ import Array.streamerOrigin.StreamerDataIterator; import GPS.GpsData; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamUtils.PamArrayUtils; @@ -90,6 +91,33 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters { private String arrayName; private String arrayFile; + + /** + * Type, used for Tethys and other meta data control + */ + private String instrumentType; + + /** + * Array Id. Can be anything. Compulsory for Tethys. + */ + private String instrumentId; + + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } + + public String getInstrumentId() { + return instrumentId; + } + + public void setInstrumentId(String instrumentId) { + this.instrumentId = instrumentId; + } + // private int originInterpolation = ORIGIN_USE_LATEST; private int originInterpolation = ORIGIN_USE_PRECEEDING; @@ -1574,7 +1602,7 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("streamers"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/Preamplifier.java b/src/Array/Preamplifier.java index 37e77cfe..20a7dc18 100644 --- a/src/Array/Preamplifier.java +++ b/src/Array/Preamplifier.java @@ -25,6 +25,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -79,7 +80,7 @@ public class Preamplifier implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Array/Streamer.java b/src/Array/Streamer.java index 90f69f10..7910da0f 100644 --- a/src/Array/Streamer.java +++ b/src/Array/Streamer.java @@ -17,6 +17,7 @@ import PamController.PamController; import PamController.masterReference.MasterReferencePoint; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamUtils.PamCalendar; @@ -767,7 +768,7 @@ public class Streamer implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("coordinate"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/StreamerDialog.java b/src/Array/StreamerDialog.java index e629b142..73a81469 100644 --- a/src/Array/StreamerDialog.java +++ b/src/Array/StreamerDialog.java @@ -259,6 +259,7 @@ public class StreamerDialog extends PamDialog { // } singleInstance.currentArray = currentArray; singleInstance.defaultStreamer = streamer;//.clone(); +// singleInstance.st singleInstance.setParams(); singleInstance.setVisible(true); return singleInstance.defaultStreamer; @@ -549,6 +550,17 @@ public class StreamerDialog extends PamDialog { pack(); } } + + try { + OriginSettings os = defaultStreamer.getOriginSettings(currentOriginMethod.getClass()); + if (os != null) { + currentOriginMethod.setOriginSettings(os); + } + } + catch (Exception e) { + // will throw if it tries to set the wrong type of settings. + } + enableControls(); } diff --git a/src/Array/streamerOrigin/OriginSettings.java b/src/Array/streamerOrigin/OriginSettings.java index 1beab0f7..9565ea57 100644 --- a/src/Array/streamerOrigin/OriginSettings.java +++ b/src/Array/streamerOrigin/OriginSettings.java @@ -3,6 +3,7 @@ package Array.streamerOrigin; import PamController.SettingsObject; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class to hold settings for the different origin methods. @@ -47,7 +48,7 @@ public abstract class OriginSettings implements SettingsObject, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/ArrayAccelerometer/ArrayAccelParams.java b/src/ArrayAccelerometer/ArrayAccelParams.java index fdf107d5..7ce91290 100644 --- a/src/ArrayAccelerometer/ArrayAccelParams.java +++ b/src/ArrayAccelerometer/ArrayAccelParams.java @@ -5,6 +5,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import mcc.MccJniInterface; import mcc.mccjna.MCCConstants; @@ -67,7 +68,7 @@ public class ArrayAccelParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Azigram/AzigramParameters.java b/src/Azigram/AzigramParameters.java index 94cf50c7..f0f88c71 100644 --- a/src/Azigram/AzigramParameters.java +++ b/src/Azigram/AzigramParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import PamguardMVC.PamConstants; @@ -44,7 +45,7 @@ public class AzigramParameters implements Serializable, ManagedParameters, Clone @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("name"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Filters/FilterParameters_2.java b/src/Filters/FilterParameters_2.java index 0169f6d1..788db4d8 100644 --- a/src/Filters/FilterParameters_2.java +++ b/src/Filters/FilterParameters_2.java @@ -7,6 +7,7 @@ import org.w3c.dom.Element; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * FilterPArameters for use when the filter is on it's own (within a FilterController) @@ -39,7 +40,7 @@ public class FilterParameters_2 implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Filters/FilterParams.java b/src/Filters/FilterParams.java index 0b8f487c..f8260f44 100644 --- a/src/Filters/FilterParams.java +++ b/src/Filters/FilterParams.java @@ -30,6 +30,7 @@ import org.w3c.dom.Element; import PamController.PamControlledUnit; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.FrequencyFormat; /** @@ -358,7 +359,7 @@ public class FilterParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/GPS/GPSParameters.java b/src/GPS/GPSParameters.java index 719a59ca..d907ba75 100644 --- a/src/GPS/GPSParameters.java +++ b/src/GPS/GPSParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class GPSParameters implements Serializable, Cloneable, ManagedParameters { @@ -175,7 +176,7 @@ public class GPSParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nmeaSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/GPS/GpsDataUnit.java b/src/GPS/GpsDataUnit.java index 914920b5..8d6433ca 100644 --- a/src/GPS/GpsDataUnit.java +++ b/src/GPS/GpsDataUnit.java @@ -1,5 +1,6 @@ package GPS; +import PamUtils.PamCalendar; import PamguardMVC.PamDataUnit; public class GpsDataUnit extends PamDataUnit { @@ -52,12 +53,18 @@ public class GpsDataUnit extends PamDataUnit { */ @Override public String getSummaryString() { - // TODO Auto-generated method stub - String str = super.getSummaryString(); +// String str = super.getSummaryString(); + String str = String.format("%s
    UID:%d, Database: %d
    %s
    ", + "GPS Data", getUID(), getDatabaseIndex(), PamCalendar.formatDBDateTime(getTimeMilliseconds(), true)); if (gpsData != null) { str += gpsData.summaryString(); } return str; } + @Override + public double[] getFrequency() { + return null; + } + } diff --git a/src/GPS/GpsLogger.java b/src/GPS/GpsLogger.java index b02c32e6..f0f990c8 100644 --- a/src/GPS/GpsLogger.java +++ b/src/GPS/GpsLogger.java @@ -295,7 +295,8 @@ public class GpsLogger extends SQLLogging { * time from the UTC column which is NOT the GpsData time which was the real GPS time. */ int gpsIntTimeVal = gpsTime.getIntegerValue(); - Object ts = getTableDefinition().getTimeStampItem().getValue(); + PamTableDefinition pamTableDef = (PamTableDefinition) getTableDefinition(); + Object ts = pamTableDef.getTimeStampItem().getValue(); long gpsDate = sqlTypes.millisFromTimeStamp(ts); if (gpsDate%1000 == 0) { // some databases may have stored the milliseconds, in which diff --git a/src/IshmaelDetector/IshDetParams.java b/src/IshmaelDetector/IshDetParams.java index d79b8d60..f8d4c2a9 100644 --- a/src/IshmaelDetector/IshDetParams.java +++ b/src/IshmaelDetector/IshDetParams.java @@ -17,6 +17,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GroupedSourceParameters; public class IshDetParams implements Serializable, Cloneable, ManagedParameters { @@ -96,7 +97,7 @@ public class IshDetParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("inputDataSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/IshmaelDetector/IshDisplayParams.java b/src/IshmaelDetector/IshDisplayParams.java index 609f9c2b..a0dea6aa 100644 --- a/src/IshmaelDetector/IshDisplayParams.java +++ b/src/IshmaelDetector/IshDisplayParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Ishamel display parameters for the Spectrogram plug in. @@ -42,7 +43,7 @@ public class IshDisplayParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/IshmaelDetector/IshLogger.java b/src/IshmaelDetector/IshLogger.java index c9abdcfe..6bd47109 100644 --- a/src/IshmaelDetector/IshLogger.java +++ b/src/IshmaelDetector/IshLogger.java @@ -8,14 +8,13 @@ import java.sql.Types; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; - +import generalDatabase.EmptyTableDefinition; //import pamDatabase.SQLLogging; //import PamguardMVC.RecyclingDataBlock; import generalDatabase.PamDetectionLogging; public class IshLogger extends PamDetectionLogging { IshDetControl ishDetControl; - PamTableDefinition tableDefinition; PamTableItem systemDate, durationSecs, secSinceStart, peakHeight; // Peak is more important than start time for matched filter & spectrogram correlation PamTableItem peakSample, peakDelaySecs; @@ -25,7 +24,7 @@ public class IshLogger extends PamDetectionLogging { super(pamDataBlock, UPDATE_POLICY_WRITENEW); this.ishDetControl = ishDetControl; - tableDefinition = getTableDefinition(); + EmptyTableDefinition tableDefinition = getTableDefinition(); // PamTableItem tableItem; // setUpdatePolicy(UPDATE_POLICY_WRITENEW); diff --git a/src/IshmaelLocator/IshLocSqlLogging.java b/src/IshmaelLocator/IshLocSqlLogging.java index 0b95afe3..c43539d0 100644 --- a/src/IshmaelLocator/IshLocSqlLogging.java +++ b/src/IshmaelLocator/IshLocSqlLogging.java @@ -14,14 +14,13 @@ import IshmaelDetector.IshDetection; import PamUtils.LatLong; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; - +import generalDatabase.EmptyTableDefinition; //import pamDatabase.SQLLogging; //import PamguardMVC.RecyclingDataBlock; import generalDatabase.PamDetectionLogging; public class IshLocSqlLogging extends PamDetectionLogging { IshLocControl ishLocControl; - PamTableDefinition tableDefinition; PamTableItem systemDate, durationSecs, secSinceStart, peakHeight; private PamTableItem latitude, longitude, refLatitude, refLongitude, x, y, z; @@ -30,7 +29,7 @@ public class IshLocSqlLogging extends PamDetectionLogging { super(pamDataBlock, UPDATE_POLICY_WRITENEW); this.ishLocControl = ishDetControl; - tableDefinition = getTableDefinition(); + EmptyTableDefinition tableDefinition = getTableDefinition(); tableDefinition.addTableItem(latitude = new PamTableItem("Latitude", Types.DOUBLE)); tableDefinition.addTableItem(longitude = new PamTableItem("Longitude", Types.DOUBLE)); tableDefinition.addTableItem(refLatitude = new PamTableItem("ReferenceLatitude", Types.DOUBLE)); diff --git a/src/KernelSmoothing/KernelSmoothingParameters.java b/src/KernelSmoothing/KernelSmoothingParameters.java index 8b5f010c..6ddd593b 100644 --- a/src/KernelSmoothing/KernelSmoothingParameters.java +++ b/src/KernelSmoothing/KernelSmoothingParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class KernelSmoothingParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class KernelSmoothingParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/DelayMeasurementParams.java b/src/Localiser/DelayMeasurementParams.java index dc92235d..4a232970 100644 --- a/src/Localiser/DelayMeasurementParams.java +++ b/src/Localiser/DelayMeasurementParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import fftFilter.FFTFilterParams; /** @@ -157,7 +158,7 @@ public class DelayMeasurementParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java b/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java index 1a170d0b..de0c0280 100644 --- a/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java +++ b/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MCMCParams2 implements Serializable, Cloneable, ManagedParameters { @@ -126,7 +127,7 @@ public class MCMCParams2 implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java b/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java index bc3983b6..214f337c 100644 --- a/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java +++ b/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MCMCParams implements Serializable, Cloneable, ManagedParameters { @@ -64,7 +65,7 @@ public class MCMCParams implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java b/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java index d7cdc11f..d012bfdb 100644 --- a/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java +++ b/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** @@ -69,7 +70,7 @@ public class HyperbolicParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/controls/RawOrFFTParams.java b/src/Localiser/controls/RawOrFFTParams.java index 0545ea90..9df83a54 100644 --- a/src/Localiser/controls/RawOrFFTParams.java +++ b/src/Localiser/controls/RawOrFFTParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import Spectrogram.WindowFunction; /** @@ -104,7 +105,7 @@ public class RawOrFFTParams implements Serializable, Cloneable, RawOrFFTParamsIn @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Map/GebcoMapFile.java b/src/Map/GebcoMapFile.java index befe7d3a..acb2112c 100644 --- a/src/Map/GebcoMapFile.java +++ b/src/Map/GebcoMapFile.java @@ -85,7 +85,15 @@ public class GebcoMapFile implements MapFileManager { * @see Map.MapFile#readFileData(java.io.File) */ public boolean readFileData(File file) { - return readMapFile(file, true); + try { + return readMapFile(file, true); + } + catch (Exception e) { + // trap error someone reported at end November 22. Suspect it was their corrupt map file causing problems. + String err = String.format("Map file %s is missing or corrupt and cannot be loaded", file.getName()); + WarnOnce.showWarning("Map File Error", err, WarnOnce.OK_OPTION); + return false; + } } private boolean readMapFile(File gebcoFile, boolean readContours) { diff --git a/src/Map/MapDetectionsParameters.java b/src/Map/MapDetectionsParameters.java index a52aff72..bfc72e9b 100644 --- a/src/Map/MapDetectionsParameters.java +++ b/src/Map/MapDetectionsParameters.java @@ -7,6 +7,7 @@ import java.util.ListIterator; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * PArameters for MapDetectionsManager which @@ -65,7 +66,7 @@ public class MapDetectionsParameters implements Serializable, Cloneable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Map/MapParameters.java b/src/Map/MapParameters.java index b0eee649..11baeb07 100644 --- a/src/Map/MapParameters.java +++ b/src/Map/MapParameters.java @@ -27,6 +27,7 @@ import java.lang.reflect.Field; import Array.Hydrophone; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class MapParameters implements Serializable, Cloneable, ManagedParameters { @@ -301,7 +302,7 @@ public class MapParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Map/MapRectProjector.java b/src/Map/MapRectProjector.java index dd402886..0b7e45a3 100644 --- a/src/Map/MapRectProjector.java +++ b/src/Map/MapRectProjector.java @@ -20,9 +20,15 @@ */ package Map; +import java.awt.Point; import java.awt.event.MouseMotionAdapter; import java.awt.geom.AffineTransform; +import java.util.ListIterator; +import GPS.GPSControl; +import GPS.GPSDataBlock; +import GPS.GpsDataUnit; +import PamController.PamController; import PamUtils.Coordinate3d; import PamUtils.LatLong; import PamUtils.PamCoordinate; @@ -385,6 +391,45 @@ public class MapRectProjector extends MapProjector { return xTrans; } + @Override + public String getHoverText(Point mousePoint, int ploNumberMatch) { + String text = super.getHoverText(mousePoint, ploNumberMatch); + if (text == null) { + return findGpsTrackText(mousePoint, ploNumberMatch); + } + else { + return text; + } + } + + private String findGpsTrackText(Point mousePoint, int ploNumberMatch) { + GPSControl gpsControl = GPSControl.getGpsControl(); + if (gpsControl == null) { + return null; + } + LatLong currentPos = getDataPosition(new Coordinate3d(mousePoint.x, mousePoint.y)); + GPSDataBlock gpsDataBlock = gpsControl.getGpsDataBlock(); + double dist = Double.MAX_VALUE; + GpsDataUnit closest = null; + ListIterator it = gpsDataBlock.getListIterator(0); + while (it.hasNext()) { + GpsDataUnit gpsUnit = it.next(); + double r = gpsUnit.getGpsData().distanceToMetres(currentPos); + if (r < dist) { + dist = r; + closest = gpsUnit; + } + } + if (closest == null) { + return null; + } + double rPix = dist*this.pixelsPerMetre; + if (rPix > 20) { + return null; + } + return closest.getSummaryString(); + } + } diff --git a/src/Map/gridbaselayer/GridbaseParameters.java b/src/Map/gridbaselayer/GridbaseParameters.java index 2af62e75..fe608b8d 100644 --- a/src/Map/gridbaselayer/GridbaseParameters.java +++ b/src/Map/gridbaselayer/GridbaseParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GridbaseParameters implements Cloneable, Serializable, ManagedParameters { @@ -25,7 +26,7 @@ public class GridbaseParameters implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/NMEA/NMEAParameters.java b/src/NMEA/NMEAParameters.java index 42393be3..9da8c22c 100644 --- a/src/NMEA/NMEAParameters.java +++ b/src/NMEA/NMEAParameters.java @@ -24,6 +24,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import serialComms.jserialcomm.PJSerialComm; public class NMEAParameters implements Serializable, Cloneable, ManagedParameters { @@ -149,7 +150,7 @@ public class NMEAParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamController/OfflineDataStore.java b/src/PamController/OfflineDataStore.java index 52e64150..20a34041 100644 --- a/src/PamController/OfflineDataStore.java +++ b/src/PamController/OfflineDataStore.java @@ -33,6 +33,13 @@ public interface OfflineDataStore { */ public String getDataSourceName(); + /** + * Get the data location. This may be a specific file, or might be a folder + * if data are in many files, a URI, etc. + * @return store locations + */ + public String getDataLocation(); + /** * Load data for a given datablock between two time limits. * @param dataBlock datablock owner of the data diff --git a/src/PamController/PamControlledUnit.java b/src/PamController/PamControlledUnit.java index a8a8c96e..5ced4925 100644 --- a/src/PamController/PamControlledUnit.java +++ b/src/PamController/PamControlledUnit.java @@ -23,6 +23,7 @@ package PamController; import java.awt.Component; import java.awt.Frame; import java.util.ArrayList; +import java.util.List; import javax.swing.JFrame; import javax.swing.JMenu; @@ -35,7 +36,9 @@ import offlineProcessing.OfflineTaskGroup; import PamController.status.ModuleStatus; import PamController.status.ModuleStatusManager; import PamController.status.ProcessCheck; +import PamModel.PamModel; import PamModel.PamModuleInfo; +import PamModel.PamPluginInterface; import PamView.ClipboardCopier; import PamView.PamGui; import PamView.PamSidePanel; @@ -886,6 +889,23 @@ public abstract class PamControlledUnit implements SettingsNameProvider { public int getInstanceIndex() { return instanceIndex; } + + /** + * Get detail if this is a plugin. + * @return plugin detail, or null if it's not a plugin. + */ + public PamPluginInterface getPlugin() { + List pluginList = ((PamModel) PamController.getInstance().getModelInterface()).getPluginList(); + if (pluginList == null) { + return null; + } + for (PamPluginInterface plugin : pluginList) { + if (plugin.getClassName().equals(this.getClass().getName())) { + return plugin; + } + } + return null; + } /** * The PamConfiguration holds the master list of modules which form part of a diff --git a/src/PamController/PamControlledUnitSettings.java b/src/PamController/PamControlledUnitSettings.java index ccdc18bf..6522884f 100644 --- a/src/PamController/PamControlledUnitSettings.java +++ b/src/PamController/PamControlledUnitSettings.java @@ -36,6 +36,7 @@ import org.apache.commons.io.input.ClassLoaderObjectInputStream; import PamModel.PamModel; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.dialog.warn.WarnOnce; @@ -398,7 +399,7 @@ public class PamControlledUnitSettings implements Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamController/PamController.java b/src/PamController/PamController.java index 6398f9f1..fd9109a5 100644 --- a/src/PamController/PamController.java +++ b/src/PamController/PamController.java @@ -58,6 +58,7 @@ import fftManager.FFTDataUnit; import generalDatabase.DBControlUnit; import javafx.application.Platform; import javafx.stage.Stage; +import metadata.MetaDataContol; import Array.ArrayManager; import PamController.command.MulticastController; import PamController.command.NetworkController; @@ -457,6 +458,7 @@ public class PamController implements PamControllerInterface, PamSettings { System.out.println(""); 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. @@ -1186,6 +1188,8 @@ public class PamController implements PamControllerInterface, PamSettings { } if (saveSettings) { + startTime = PamCalendar.getSessionStartTime(); +// System.out.printf("Saving settings for start time %s\n", PamCalendar.formatDBDateTime(startTime)); saveSettings(PamCalendar.getSessionStartTime()); } @@ -1344,6 +1348,9 @@ public class PamController implements PamControllerInterface, PamSettings { } guiFrameManager.pamEnded(); + long stopTime = PamCalendar.getTimeInMillis(); + saveEndSettings(stopTime); + // 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. @@ -1462,6 +1469,26 @@ public class PamController implements PamControllerInterface, PamSettings { pamConfiguration.saveSettings(timeNow); } + /** + * Gets called in pamStart and may / will attempt to store all + * PAMGUARD settings via the database and binary storage modules. + */ + private void saveEndSettings(long timeNow) { +// System.out.printf("Updating settings with end time %s\n", PamCalendar.formatDBDateTime(timeNow)); + ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits(); + PamControlledUnit pcu; + PamSettingsSource settingsSource; + for (int iU = 0; iU < pamControlledUnits.size(); iU++) { + pcu = pamControlledUnits.get(iU); + if (PamSettingsSource.class.isAssignableFrom(pcu.getClass())) { + settingsSource = (PamSettingsSource) pcu; + settingsSource.saveEndSettings(timeNow); + } + } + } + + + /** * Export configuration into an XML file * @param parentFrame diff --git a/src/PamController/PamSensor.java b/src/PamController/PamSensor.java new file mode 100644 index 00000000..03e51efe --- /dev/null +++ b/src/PamController/PamSensor.java @@ -0,0 +1,20 @@ +package PamController; + +/** + * Interface to define modules which can be considered as sensors of some sort. + * e.g. depth and orientation modules and the SoundTrap clickdetecotr + * @author dg50 + * + */ +public interface PamSensor { + + public String getUnitName(); + + public String getUnitType(); + + public String getSensorDescription(); + + public String getSensorId(); + + +} diff --git a/src/PamController/PamSettingsSource.java b/src/PamController/PamSettingsSource.java index ed67807a..ba4079cc 100644 --- a/src/PamController/PamSettingsSource.java +++ b/src/PamController/PamSettingsSource.java @@ -20,6 +20,14 @@ public interface PamSettingsSource { */ public boolean saveStartSettings(long timeNow); + /** + * Save settings when processing ends. + * This may just be an update of the settings saves with saveStartSettings, e.g. an end time. + * @param timeNow + * @return true if saved correctly. + */ + public boolean saveEndSettings(long timeNow); + /** * Get the number of different settings * within the settings source. diff --git a/src/PamController/PamguardVersionInfo.java b/src/PamController/PamguardVersionInfo.java index 4d1daa07..2a0720ef 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.09f"; + static public final String version = "2.02.09aa"; /** * Release date */ - static public final String date = "28 December 2023"; + static public final String date = "12 January 20242"; // /** // * Release type - Beta or Core diff --git a/src/PamController/UsedModuleInfo.java b/src/PamController/UsedModuleInfo.java index 390ab1c0..1170027a 100644 --- a/src/PamController/UsedModuleInfo.java +++ b/src/PamController/UsedModuleInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Very simple class used in an ArrayList of used modules that @@ -54,7 +55,7 @@ public class UsedModuleInfo implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamController/settings/output/xml/PamguardXMLWriter.java b/src/PamController/settings/output/xml/PamguardXMLWriter.java index 6b42c4e7..f74edce0 100644 --- a/src/PamController/settings/output/xml/PamguardXMLWriter.java +++ b/src/PamController/settings/output/xml/PamguardXMLWriter.java @@ -29,6 +29,7 @@ import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import com.sun.javafx.runtime.VersionInfo; @@ -42,12 +43,14 @@ import PamController.PamguardVersionInfo; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; import PamUtils.XMLUtils; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.PamProcess; import binaryFileStorage.BinaryStore; +import tethys.TethysControl; /** * Class for writing XML configuration output to a file. @@ -62,6 +65,8 @@ public class PamguardXMLWriter implements PamSettings { private static final Set> WRAPPER_TYPES = getWrapperTypes(); private XMLWriterSettings writerSettings = new XMLWriterSettings(); + private boolean excludeDisplaySettings; +// private String xmlNameSpace; private static PamguardXMLWriter singleInstance; @@ -83,6 +88,19 @@ public class PamguardXMLWriter implements PamSettings { } return singleInstance; } + + /** + * Recursively walk the tree and add a namespace to every + * single element. + * @param doc + * @param nameSpace + * @return + */ + public boolean addNameSpaceToElements(Document doc, Element el, String nameSpace) { +// el.setAttributeNS(nameSpace, nameSpace, nameSpace); + NamedNodeMap attributes = el.getAttributes(); + return true; + } /** * Make a document with the options specified in writerSettings. @@ -371,6 +389,32 @@ public class PamguardXMLWriter implements PamSettings { * @return xml content as a a string. */ public String getAsString(Document doc) { + return getAsString(doc, true); +// try { +// DOMSource domSource = new DOMSource(doc); +// StringWriter writer = new StringWriter(); +// StreamResult result = new StreamResult(writer); +// TransformerFactory tf = TransformerFactory.newInstance(); +// Transformer transformer = tf.newTransformer(); +// transformer.setOutputProperty(OutputKeys.METHOD, "xml"); +// transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); +//// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); +// transformer.setOutputProperty(OutputKeys.INDENT, "yes"); +// transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); +// transformer.transform(domSource, result); +// return writer.toString(); +// } catch (TransformerException e) { +// e.printStackTrace(); +// return null; +// } + } + /** + * Get the xml document as a String. + * @param doc xml document + * @param indent Indent / format the document. + * @return xml content as a a string. + */ + public String getAsString(Document doc, boolean indent) { try { DOMSource domSource = new DOMSource(doc); StringWriter writer = new StringWriter(); @@ -380,7 +424,7 @@ public class PamguardXMLWriter implements PamSettings { transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); // transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.transform(domSource, result); return writer.toString(); @@ -411,8 +455,7 @@ public class PamguardXMLWriter implements PamSettings { * @param pamSettingsUnit * @return xml element */ - private Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit) { - + public Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit) { int[] settingInds = findSettings(null, pamSettingsUnit.getUnitName()); PamSettings[] settingsObjects = null; if (settingInds != null) { @@ -436,7 +479,7 @@ public class PamguardXMLWriter implements PamSettings { * can be temporary settings objects when writing temporary settings from dialogs. * @return new XML element. */ - private Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit, PamSettings[] toWrite) { + public Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit, PamSettings[] toWrite) { Element moduleData = doc.createElement("MODULE"); moduleData.setAttribute("Java.class", pamSettingsUnit.getClass().getName()); moduleData.setAttribute("UnitType", pamSettingsUnit.getUnitType()); @@ -457,6 +500,9 @@ public class PamguardXMLWriter implements PamSettings { Element settingEl = doc.createElement("CONFIGURATION"); moduleData.appendChild(settingEl); for (int i = 0; i < toWrite.length; i++) { + if (wantObject(toWrite[i]) == false) { + continue; + } Element setEl = writeSettings(doc, toWrite[i], new ArrayList()); if (setEl != null) { settingEl.appendChild(setEl); @@ -467,6 +513,32 @@ public class PamguardXMLWriter implements PamSettings { return moduleData; } + /** + * USed by the Tethys writer to avoid writing display settings. + * @param pamSettings + * @return + */ + private boolean wantObject(PamSettings pamSettings) { + if (excludeDisplaySettings == false) { + return true; + } + Object obj = pamSettings.getSettingsReference(); + if (obj == null) { + return false; + } + if (obj instanceof ManagedParameters) { + ManagedParameters managedParams = (ManagedParameters) obj; + PamParameterSet paramSet = managedParams.getParameterSet(); + if (paramSet == null) { + return false; + } + if (paramSet.getParameterSetType() == ParameterSetType.DISPLAY && excludeDisplaySettings) { + return false; + } + } + return true; + } + /** * Write settings for a settings object, using the standard retreived object * from the settings. @@ -478,6 +550,14 @@ public class PamguardXMLWriter implements PamSettings { private Element writeSettings(Document doc, PamSettings pamSettings, ArrayList objectHierarchy) { return writeSettings(doc, pamSettings, pamSettings.getSettingsReference(), objectHierarchy); } + + public Document writeOneObject(Object data) { + Document doc = XMLUtils.createBlankDoc(); + Element el = doc.createElement("Settings"); + Element newel = writeObjectData(doc, el, data, new ArrayList()); + doc.appendChild(newel); + return doc; + } /** * Write settings using an object of choice instead of the standard one from PamSettings. @@ -489,6 +569,7 @@ public class PamguardXMLWriter implements PamSettings { * @return */ private Element writeSettings(Document doc, PamSettings pamSettings, Object data, ArrayList objectHierarchy) { + Element el = doc.createElement("SETTINGS"); el.setAttribute("Type", pamSettings.getUnitType()); el.setAttribute("Name", pamSettings.getUnitName()); @@ -500,10 +581,13 @@ public class PamguardXMLWriter implements PamSettings { return el; } - private Element writeObjectData(Document doc, Element el, Object data, ArrayList objectHierarchy) { + public Element writeObjectData(Document doc, Element el, Object data, ArrayList objectHierarchy) { if (data == null) { return null; } + if (objectHierarchy == null) { + objectHierarchy = new ArrayList<>(); + } if (objectHierarchy.contains(data)) { // just write the reference, but nothing else or we'll end up in an infinite loop of objects. Element e = doc.createElement("Object"); @@ -525,8 +609,10 @@ public class PamguardXMLWriter implements PamSettings { if (parameterSet == null) { return null; } - - objectHierarchy.add(data); + + if (objectHierarchy != null) { + objectHierarchy.add(data); + } for (PamParameterData pamParam:parameterSet.getParameterCollection()) { try { Object paramData = pamParam.getData(); @@ -765,9 +851,10 @@ public class PamguardXMLWriter implements PamSettings { processData.setAttribute("Name", process.getProcessName()); PamDataBlock source = process.getParentDataBlock(); if (source != null) { - Element inputEl = doc.createElement("Input"); - inputEl.setAttribute("Name", source.getLongDataName()); - inputEl.setAttribute("Channels", String.format("0x%X", source.getChannelMap())); + Element inputEl = source.getDataBlockXML(doc); +// Element inputEl = doc.createElement("Input"); +// inputEl.setAttribute("Name", source.getLongDataName()); +// inputEl.setAttribute("Channels", String.format("0x%X", source.getChannelMap())); processData.appendChild(inputEl); } int nOut = process.getNumOutputDataBlocks(); @@ -798,7 +885,16 @@ public class PamguardXMLWriter implements PamSettings { */ private int[] findSettings(String type, String name) { if (settingsSets == null) { - return null; + makeSettingsList(); + if (settingsSets == null) { + return null; + } + } + if (usedSettingsSets == null) { + usedSettingsSets = new boolean[settingsSets.size()]; + } + else if (usedSettingsSets.length < settingsSets.size()) { + usedSettingsSets = Arrays.copyOf(usedSettingsSets, settingsSets.size()); } int[] found = new int[settingsSets.size()]; int nFound = 0; @@ -818,7 +914,7 @@ public class PamguardXMLWriter implements PamSettings { return Arrays.copyOf(found, nFound); } - private ArrayList makeSettingsList() { + public ArrayList makeSettingsList() { PamSettingManager settingsManager = PamSettingManager.getInstance(); settingsSets = settingsManager.getOwners(); if (settingsSets == null) { @@ -850,6 +946,14 @@ public class PamguardXMLWriter implements PamSettings { return doc; } + /** + * Is this element a writable type ? Basically, this means + * that it's a primitive of some sort. Otherwise it's + * probably an object and may even be a list in which case + * it will need treating differently. + * @param clazz + * @return + */ public static boolean isWritableType(Class clazz) { if (clazz.isEnum()) return true; @@ -940,5 +1044,23 @@ public class PamguardXMLWriter implements PamSettings { return true; } + /** + * @return the excludeDisplaySettings + */ + public boolean isExcludeDisplaySettings() { + return excludeDisplaySettings; + } + + /** + * @param excludeDisplaySettings the excludeDisplaySettings to set + */ + public void setExcludeDisplaySettings(boolean excludeDisplaySettings) { + this.excludeDisplaySettings = excludeDisplaySettings; + } + +// public void setStaticNameSpace(String xmlNameSpace) { +// this.xmlNameSpace = xmlNameSpace; +// } + } diff --git a/src/PamController/settings/output/xml/XMLWriterSettings.java b/src/PamController/settings/output/xml/XMLWriterSettings.java index 8e5d0969..dcd60b83 100644 --- a/src/PamController/settings/output/xml/XMLWriterSettings.java +++ b/src/PamController/settings/output/xml/XMLWriterSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class XMLWriterSettings implements Serializable, Cloneable, ManagedParameters { @@ -34,7 +35,7 @@ public class XMLWriterSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamController/soundMedium/GlobalMediumParams.java b/src/PamController/soundMedium/GlobalMediumParams.java index 0a52ac83..8bf10f27 100644 --- a/src/PamController/soundMedium/GlobalMediumParams.java +++ b/src/PamController/soundMedium/GlobalMediumParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.soundMedium.GlobalMedium.SoundMedium; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Stores parameters for the current medium. @@ -41,7 +42,7 @@ public class GlobalMediumParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamModel/PamModel.java b/src/PamModel/PamModel.java index 3b0aa6d0..774611e5 100644 --- a/src/PamModel/PamModel.java +++ b/src/PamModel/PamModel.java @@ -44,11 +44,15 @@ import whistlesAndMoans.AbstractWhistleDataUnit; import fftManager.FFTDataUnit; import fftManager.PamFFTControl; import group3dlocaliser.Group3DLocaliserControl; +import metadata.MetaDataContol; import meygenturbine.MeygenTurbine; import printscreen.PrintScreenControl; import rockBlock.RockBlockControl; +import tethys.TethysControl; import turbineops.TurbineOperationControl; import GPS.GpsDataUnit; +import Map.MapController; +import Map.gridbaselayer.GridbaseControl; import NMEA.NMEADataUnit; import PamController.PamControlledUnitSettings; import PamController.PamController; @@ -62,6 +66,7 @@ import PamguardMVC.PamDataBlock; import analogarraysensor.ArraySensorControl; import backupmanager.BackupManager; import beamformer.continuous.BeamFormerControl; +import beamformer.localiser.BeamFormLocaliserControl; import bearinglocaliser.BearingLocaliserControl; import binaryFileStorage.SecondaryBinaryStore; import cepstrum.CepstrumControl; @@ -454,6 +459,19 @@ final public class PamModel implements PamSettings { mi.setToolTipText("Manage automated data backups"); mi.setModulesMenuGroup(utilitiesGroup); mi.setMaxNumber(1); + + +// mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType); +// mi.setToolTipText("Project Meta Data"); +// mi.setModulesMenuGroup(utilitiesGroup); +// mi.setMaxNumber(1); + + if (isViewer) { + mi = PamModuleInfo.registerControlledUnit(TethysControl.class.getName(), TethysControl.defaultName); + mi.setToolTipText("Interface to Tethys Database"); + mi.setModulesMenuGroup(utilitiesGroup); + mi.setMaxNumber(1); + } /* * ************* End Utilities Group ******************* @@ -1064,7 +1082,7 @@ final public class PamModel implements PamSettings { // clear the current list pluginList.clear(); daqList.clear(); - + /* * If developing a new PAMPlugin in eclipse, the easiest way to do it is to make a new * Eclipse project for your plugin code. Within that project, copy this PamModel class @@ -1079,6 +1097,8 @@ final public class PamModel implements PamSettings { * When you export the code for your plugin to a jar file, remember to NOT inlcude the copy of * PamModel ! */ + +// pluginList.add(new MorlaisWP1aPlugin()); // Load up whatever default classloader was used to create this class. Must use the same classloader // for all plugins, or else we will not be able to create proper dependencies between them or be able @@ -1146,11 +1166,30 @@ final public class PamModel implements PamSettings { // to add that URL to the default classloader path. URL newURL = jarList.get(i).toURI().toURL(); + // original method +// Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); +// method.setAccessible(true); +// method.invoke(cl, newURL); + + // first fix attempt - create a brand new URLClassLoader. As expected, we get a ClassCastException when trying + // to load the parameters so we can't save params using this method +// URL[] newURLArray = new URL[1]; +// newURLArray[0] = newURL; +// cl = new URLClassLoader(newURLArray); // second attempt - custom class loader with the system app loader specified as the parent. Loads controlled unit, but // as before it doesn't load the parameters classLoader.addURL(newURL); + // third attempt +// Class genericClass = cl.getClass(); +// Method method = genericClass.getSuperclass().getDeclaredMethod("addURL", new Class[] {URL.class}); +// method.setAccessible(true); +// method.invoke(cl, new Object[] {newURL}); + + + + // Save the name of the class to the global pluginBeingLoaded variable, and load the class. this.setPluginBeingLoaded(className); // Class c = cl.loadClass(className); @@ -1231,8 +1270,9 @@ final public class PamModel implements PamSettings { "for help.

    " + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); System.err.println("Exception while loading " + className); + System.err.println(e1.getMessage()); continue; } } @@ -1245,7 +1285,7 @@ final public class PamModel implements PamSettings { "for help.

    " + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, ex); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, ex); System.err.println("Exception while loading " + jarList.get(i).getName()); continue; } @@ -1270,7 +1310,7 @@ final public class PamModel implements PamSettings { // instantiate the plugin control class using the custom class loader try { -// File classFile = new File(pf.getJarFile()); + File classFile = new File(pf.getJarFile()); //URLClassLoader cl = new URLClassLoader(new URL[]{classFile.toURI().toURL()}); // mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),cl); mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),classLoader); @@ -1336,7 +1376,7 @@ final public class PamModel implements PamSettings { "for help.

    " + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); System.err.println("Exception while loading " + pf.getDefaultName()); pluginList.remove(pf); continue; diff --git a/src/PamModel/PamModelSettings.java b/src/PamModel/PamModelSettings.java index 9e4b0632..667747b8 100644 --- a/src/PamModel/PamModelSettings.java +++ b/src/PamModel/PamModelSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class PamModelSettings implements Cloneable, Serializable, ManagedParameters { @@ -74,7 +75,7 @@ public class PamModelSettings implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamModel/parametermanager/PamParameterData.java b/src/PamModel/parametermanager/PamParameterData.java index a15a3c15..79944a90 100644 --- a/src/PamModel/parametermanager/PamParameterData.java +++ b/src/PamModel/parametermanager/PamParameterData.java @@ -34,6 +34,11 @@ abstract public class PamParameterData { */ private String postTitle; + /** + * field length for automatic dialogs. + */ + private int fieldLength; + /** * @param parentObject @@ -45,6 +50,21 @@ abstract public class PamParameterData { this.field = field; } + /** + * @param parentObject + * @param field + * @param shortName + * @param toolTip + * @param fieldLength length of text in automatic dialogs. + */ + public PamParameterData(Object parentObject, Field field, String shortName, String toolTip, int fieldLength) { + super(); + this.field = field; + this.shortName = shortName; + this.toolTip = toolTip; + this.fieldLength = fieldLength; + } + /** * @param parentObject * @param field @@ -58,7 +78,6 @@ abstract public class PamParameterData { this.toolTip = toolTip; } - /** * @param shortName the shortName to set */ @@ -66,6 +85,20 @@ abstract public class PamParameterData { this.shortName = shortName; } + /** + * Set info about a parameter + * @param shortName short name, e.g. to use in a dialog + * @param postTitle post title, e.g. text coming after a data entry field in a dialog + * @param toolTip tool tip to display over the component in a dialog. + * @param fieldLength length of text in automatic dialogs. + */ + public void setInfo(String shortName, String postTitle, String toolTip, int fieldLength) { + this.shortName = shortName; + this.postTitle = postTitle; + this.toolTip = toolTip; + this.fieldLength = fieldLength; + } + /** * Set info about a parameter * @param shortName short name, e.g. to use in a dialog @@ -136,6 +169,9 @@ abstract public class PamParameterData { * @return a short name for the field, suitable for use in dialogs. */ public String getShortName() { + if (shortName == null) { + return getFieldName(); + } return shortName; } @@ -166,5 +202,19 @@ abstract public class PamParameterData { return String.format("Param %s class %s", getFieldName(), getDataClass()); } + /** + * @return the fieldLength + */ + public int getFieldLength() { + return fieldLength; + } + + /** + * @param fieldLength the fieldLength to set + */ + public void setFieldLength(int fieldLength) { + this.fieldLength = fieldLength; + } + } diff --git a/src/PamModel/parametermanager/PamParameterDataGetter.java b/src/PamModel/parametermanager/PamParameterDataGetter.java index 3947f2dc..9a3e99b0 100644 --- a/src/PamModel/parametermanager/PamParameterDataGetter.java +++ b/src/PamModel/parametermanager/PamParameterDataGetter.java @@ -59,9 +59,12 @@ public class PamParameterDataGetter extends PrivatePamParameterData { if (setter == null) { return false; } + // need to convert the type + Object convObj = convertStringType(data); try { - setter.invoke(getParentObject(), data); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + Object parentObj = getParentObject(); + setter.invoke(parentObj, convObj); + } catch (InvocationTargetException e) { e.printStackTrace(); return false; } diff --git a/src/PamModel/parametermanager/PamParameterSet.java b/src/PamModel/parametermanager/PamParameterSet.java index 751f3d27..c7108e0a 100644 --- a/src/PamModel/parametermanager/PamParameterSet.java +++ b/src/PamModel/parametermanager/PamParameterSet.java @@ -29,6 +29,9 @@ public class PamParameterSet { private static boolean printDebug = false; + public enum ParameterSetType {DETECTOR, DISPLAY}; + + private ParameterSetType parameterSetType; /** * Standard modifiers to exclude. This is important for many classes which will tend to * do crazy things such as incorporate ALL of their final fields, e.g. when a Color @@ -55,8 +58,10 @@ public class PamParameterSet { * in the STANDARD_MODIFIER_EXCLUSIONS list (FINAL or STATIC). * @return Created parameter set. */ - public static PamParameterSet autoGenerate(Object parentObject) { - return autoGenerate(parentObject, STANDARD_MODIFIER_EXCLUSIONS); + public static PamParameterSet autoGenerate(Object parentObject, ParameterSetType parameterSetType) { + PamParameterSet paramSet = autoGenerate(parentObject, STANDARD_MODIFIER_EXCLUSIONS); + paramSet.setParameterSetType(parameterSetType); + return paramSet; } /** @@ -286,4 +291,19 @@ public class PamParameterSet { public PamParameterData removeParameterData(String paramName) { return parameterDatas.remove(paramName); } + + /** + * @return the parameterSetType + */ + public ParameterSetType getParameterSetType() { + return parameterSetType; + } + + /** + * @param parameterSetType the parameterSetType to set + */ + public void setParameterSetType(ParameterSetType parameterSetType) { + this.parameterSetType = parameterSetType; + } + } diff --git a/src/PamModel/parametermanager/ParameterSetManager.java b/src/PamModel/parametermanager/ParameterSetManager.java new file mode 100644 index 00000000..3420a7c4 --- /dev/null +++ b/src/PamModel/parametermanager/ParameterSetManager.java @@ -0,0 +1,73 @@ +package PamModel.parametermanager; + +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JMenuItem; + +import PamModel.parametermanager.swing.ManagedParameterDialog; +import generalDatabase.parameterstore.ParameterDatabaseStore; + +/** + * Just about everything giving overall control of some managed parameters. + * May be a bit too specific on first cut and need to be abstracted. + * Testing on 'Deployment' data. + * @author dg50 + * + * @param + */ +public class ParameterSetManager { + + private T managedParams; + private String name; + + public ParameterSetManager(T defaultParams, String name) { + setManagedParams(defaultParams); + this.name = name; +// if (managedParams == null) { +// managedParams = new T(); +// } + } + + /** + * @return the managedParams + */ + public T getManagedParams() { + return managedParams; + } + + /** + * @param managedParams the managedParams to set + */ + public void setManagedParams(T managedParams) { + this.managedParams = managedParams; + } + + public JMenuItem getMenuItem(Window parent) { + if (managedParams == null) { + return null; + } + JMenuItem menuItem = new JMenuItem(name + " ..."); + menuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + showDialog(parent); + } + }); + + return menuItem; + } + + protected void showDialog(Window parent) { + ManagedParameterDialog dialog = new ManagedParameterDialog(parent, name, managedParams); + T newParams = dialog.showDialog(parent, name, managedParams); + + if (newParams != null) { + ParameterDatabaseStore paramDatabase = new ParameterDatabaseStore("MetaData"); + paramDatabase.saveParameterSet(newParams); + } + } + +} diff --git a/src/PamModel/parametermanager/PrivatePamParameterData.java b/src/PamModel/parametermanager/PrivatePamParameterData.java index e3fed547..6b29d9cd 100644 --- a/src/PamModel/parametermanager/PrivatePamParameterData.java +++ b/src/PamModel/parametermanager/PrivatePamParameterData.java @@ -1,6 +1,7 @@ package PamModel.parametermanager; import java.lang.reflect.Field; +import java.lang.reflect.Type; /** * Abstract instance of PamParameterDataInterface which implements everything @@ -36,9 +37,48 @@ public abstract class PrivatePamParameterData extends PamParameterData { * This should really be implemented in every concrete class, but no time to do that now. Aim to delete * this function here, then go through and implement everywhere ... */ - return false; +// return false; + Object convData = convertStringType(data); + getField().set(this, convData); + + return true; } + /** + * convert a string type to a different type appropriate for the field in + * question. + * @param value + * @return + */ + public Object convertStringType(Object value) { + if (value == null) { + return null; + } + if (value instanceof String == false) { + return value; + } + String str = (String) value; + Type type = getField().getGenericType(); + Class cls = getField().getType(); + String clsName = cls.getName(); + switch (clsName) { + case "int": + case "Integer": + return Integer.valueOf(str); + case "double": + case "Double": + return Double.valueOf(str); + case "float": + case "Float": + return Float.valueOf(str); + case "short": + case "Short": + return Short.valueOf(str); + + } + + return value; + } } diff --git a/src/PamModel/parametermanager/swing/ManagedParameterDialog.java b/src/PamModel/parametermanager/swing/ManagedParameterDialog.java new file mode 100644 index 00000000..9a3aa995 --- /dev/null +++ b/src/PamModel/parametermanager/swing/ManagedParameterDialog.java @@ -0,0 +1,49 @@ +package PamModel.parametermanager.swing; + +import java.awt.Window; + +import PamModel.parametermanager.ManagedParameters; +import PamView.dialog.PamDialog; + +public class ManagedParameterDialog extends PamDialog { + + private T params; + + private ManagedParameterPanel parameterPanel; + + public ManagedParameterDialog(Window parentFrame, String title, T params) { + super(parentFrame, title, false); + parameterPanel = new ManagedParameterPanel(params); + setDialogComponent(parameterPanel.getPanel()); + } + + public T showDialog(Window parentFrame, String title, T parameters) { +// ManagedParameterDialog dialog = new ManagedParameterDialog<>(parentFrame, title, parameters); + setParams(parameters); + setVisible(true); + + return params; + } + + private void setParams(T params) { + this.params = params; + this.parameterPanel.setParams(params); + } + + @Override + public boolean getParams() { + return parameterPanel.getParams(params); + } + + @Override + public void cancelButtonPressed() { + params = null; + } + + @Override + public void restoreDefaultSettings() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/PamModel/parametermanager/swing/ManagedParameterPanel.java b/src/PamModel/parametermanager/swing/ManagedParameterPanel.java new file mode 100644 index 00000000..416bef77 --- /dev/null +++ b/src/PamModel/parametermanager/swing/ManagedParameterPanel.java @@ -0,0 +1,149 @@ +package PamModel.parametermanager.swing; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.Collection; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.text.JTextComponent; + +import PamModel.parametermanager.FieldNotFoundException; +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterData; +import PamModel.parametermanager.PamParameterSet; +import PamView.dialog.PamDialog; +import PamView.dialog.PamGridBagContraints; + +public class ManagedParameterPanel { + + private JPanel mainPanel; + private Collection parameterSet; + + private static final int DEFAULT_TEXT_LENGTH = 6; + private static final int MAX_SINGLE_LINE_LENGTH = 40; + + private JTextComponent[] textComponents; + + public ManagedParameterPanel(T parameterExample) { + + mainPanel = new JPanel(new GridBagLayout()); + GridBagConstraints c = new PamGridBagContraints(); + PamParameterSet exampleSet = parameterExample.getParameterSet(); + parameterSet = exampleSet.getParameterCollection(); + int n = parameterSet.size(); + textComponents = new JTextComponent[n]; + int i = 0; + for (PamParameterData paramData : parameterSet) { + textComponents[i] = createComponent(paramData); + c.gridx = 0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.NORTHEAST; + mainPanel.add(new JLabel(paramData.getShortName(), JLabel.RIGHT), c); + c.gridx++; + if (textComponents[i] instanceof JTextArea) { + c.fill = GridBagConstraints.HORIZONTAL; + } + else { + c.fill = GridBagConstraints.NONE; + } + c.anchor = GridBagConstraints.WEST; + mainPanel.add(textComponents[i], c); + + textComponents[i].setToolTipText(getTipText(paramData)); + + c.gridy++; + i++; + } + } + + private String getTipText(PamParameterData paramData) { + String tip = paramData.getToolTip(); + if (tip != null) { + return tip; + } + else { + return paramData.getFieldName(); + } + } + + private JTextComponent createComponent(PamParameterData paramData) { + int textLen = paramData.getFieldLength(); + if (textLen == 0) { + textLen = DEFAULT_TEXT_LENGTH; + } + if (textLen <= MAX_SINGLE_LINE_LENGTH) { + return new JTextField(textLen); + } + else { + JTextField dummyField = new JTextField(2); +// dummyField.getBorder(). + JTextArea textArea = new JTextArea(textLen/MAX_SINGLE_LINE_LENGTH+1, MAX_SINGLE_LINE_LENGTH); + textArea.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); + return textArea; + } + } + + public JComponent getPanel() { + return mainPanel; + } + + public void setParams(T params) { + int i = 0; + PamParameterData newParamData = null; + Object data = null; + for (PamParameterData paramData : this.parameterSet) { + // find the parameter in the new parameters (parameterSet is just a formatting placeholder) + try { + newParamData = params.getParameterSet().findParameterData(paramData.getFieldName()); + } catch (FieldNotFoundException e) { + e.printStackTrace(); + } + try { + data = newParamData.getData(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + if (data != null) { + textComponents[i].setText(data.toString()); + } + else { + textComponents[i].setText(null); + } + i++; + } + } + + public boolean getParams(T params) { + int i = 0; + PamParameterData newParamData = null; + Object data = null; + for (PamParameterData paramData : this.parameterSet) { + // find the parameter in the new parameters (parameterSet is just a formatting placeholder) + try { + newParamData = params.getParameterSet().findParameterData(paramData.getFieldName()); + } catch (FieldNotFoundException e) { + e.printStackTrace(); + } + String txt = textComponents[i].getText(); + try { + newParamData.setData(txt); + } catch (IllegalArgumentException | IllegalAccessException e) { + String msg = "Invalid parameter. Data type should be " + paramData.getField().getType().getName(); + return PamDialog.showWarning(null, newParamData.getShortName(), msg); + } + + i++; + } + + return true; + } + +} diff --git a/src/PamUtils/Coordinate3d.java b/src/PamUtils/Coordinate3d.java index 57a859f4..a8b6d156 100644 --- a/src/PamUtils/Coordinate3d.java +++ b/src/PamUtils/Coordinate3d.java @@ -26,6 +26,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class definition for a x,y coordinate number type. @@ -168,7 +169,7 @@ public class Coordinate3d implements Serializable , Cloneable, PamCoordinate, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamUtils/LatLong.java b/src/PamUtils/LatLong.java index 6b8f9df9..6d465ee6 100644 --- a/src/PamUtils/LatLong.java +++ b/src/PamUtils/LatLong.java @@ -15,6 +15,7 @@ import java.text.NumberFormat; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamConstants; import net.sf.geographiclib.Geodesic; import net.sf.geographiclib.PolygonArea; @@ -833,7 +834,7 @@ public class LatLong implements Serializable, Cloneable, Transferable, PamCoordi */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("height"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamUtils/PamCalendar.java b/src/PamUtils/PamCalendar.java index 452e06e5..7c4c3eb8 100644 --- a/src/PamUtils/PamCalendar.java +++ b/src/PamUtils/PamCalendar.java @@ -47,10 +47,7 @@ public class PamCalendar { public static TimeZone defaultTimeZone = TimeZone.getTimeZone("UTC"); - /* - * Not used: all now handled in PamCalendar. - */ -// private static TimeZone localTimeZone = defaultTimeZone;// TimeZone.getDefault(); + private static TimeZone localTimeZone = defaultTimeZone;// TimeZone.getDefault(); public static final long millisPerDay = 1000L*24L*3600L; @@ -63,7 +60,7 @@ public class PamCalendar { private static boolean soundFile; /** - * time from the start of the file to the current moment. + * time from the start of the file to the currentmoment. * This is updated every time data re read from the file, so is * accurate to about 1/10 second. * For accurate timing within detectors, always try to use sample number @@ -180,44 +177,8 @@ public class PamCalendar { public static TimeZone getDisplayTimeZone(boolean useLocal) { // return TimeZone.getTimeZone("UTC"); - return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone; -// return useLocal ? localTimeZone : defaultTimeZone; - } - - /** - * Get the display time zone offset in milliseconds. - * @param useLocal - * @return - */ - public static long getDisplayTimeZoneOffest(boolean useLocal) { - TimeZone tz = getDisplayTimeZone(useLocal); - return tz.getOffset(getTimeInMillis()); - } - - /** - * Get a short string describing the time zone. This should be less than - * 10 characters. So if the full name of the TZ is long, then write it - * in the format "UTC+..." - * @param useLocal - * @return - */ - public static String getShortDisplayTimeZoneString(boolean useLocal) { - TimeZone tz = getDisplayTimeZone(useLocal); - String str = tz.getDisplayName(); - str = CalendarControl.getInstance().getTZCode(true); - if (str.length() <= 10) { - return str; - } - // otherwise make up a string. - long offset = getDisplayTimeZoneOffest(useLocal) / 1000; - boolean isInt = offset % 3600 == 0; - if (isInt) { - str = String.format("UTC%+d", offset/3600); - } - else { - str = String.format("UTC%+3.1f", (double) offset/3600.); - } - return str; +// return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone; + return useLocal ? localTimeZone : defaultTimeZone; } public static String formatDateTime(Date date) { @@ -430,13 +391,8 @@ public class PamCalendar { public static String formatDBStyleTime(long timeInMillis, boolean showMillis, boolean useLocal) { Calendar c = Calendar.getInstance(); - TimeZone tz = getDisplayTimeZone(useLocal); -// if (tz != null) { -// long offs = tz.getOffset(timeInMillis); -// timeInMillis += tz.getOffset(timeInMillis); -// } c.setTimeInMillis(timeInMillis); - c.setTimeZone(tz); + c.setTimeZone(getDisplayTimeZone(useLocal)); DateFormat df; if (showMillis) { df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @@ -444,7 +400,7 @@ public class PamCalendar { else { df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } - df.setTimeZone(tz); + df.setTimeZone(getDisplayTimeZone(useLocal)); Date d = c.getTime(); // return String.format("%tY-% { JComponent toolTipComponent; + /** + * Gets an adapter that can provide tooltips automatically based on plotted data units. + * @param component + * @return + */ public MouseHoverAdapter getMouseHoverAdapter(JComponent component) { ToolTipManager tt = ToolTipManager.sharedInstance(); tt.registerComponent(component); @@ -384,7 +389,9 @@ public abstract class GeneralProjector { } String hintText = dataBlock.getHoverText(this, hoveredDataUnit, hoverData.get(unitIndex).getAmbiguity()); - if (hintText == null) return null; + if (hintText == null) { + return null; + } // System.out.println(hintText); return hintText; } diff --git a/src/PamView/GroupedSourceParameters.java b/src/PamView/GroupedSourceParameters.java index f26cdafd..fb0b7509 100644 --- a/src/PamView/GroupedSourceParameters.java +++ b/src/PamView/GroupedSourceParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamView.dialog.GroupedSourcePanel; @@ -210,7 +211,7 @@ public class GroupedSourceParameters implements Serializable, Cloneable, Managed */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamView/GuiFrameSettings.java b/src/PamView/GuiFrameSettings.java index d367c1e3..3445c790 100644 --- a/src/PamView/GuiFrameSettings.java +++ b/src/PamView/GuiFrameSettings.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamController.PamControlledUnit; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -55,7 +56,7 @@ public class GuiFrameSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("unitFrameInfo"); ps.put(new PrivatePamParameterData(this, field) { @@ -89,7 +90,7 @@ public class GuiFrameSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("guiFrame"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamView/PamGui.java b/src/PamView/PamGui.java index bbb4fc73..b5d91e8f 100644 --- a/src/PamView/PamGui.java +++ b/src/PamView/PamGui.java @@ -61,6 +61,7 @@ import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JRootPane; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -73,6 +74,7 @@ import javax.swing.event.MenuListener; import Acquisition.DaqSystemInterface; import annotation.tasks.AnnotationManager; +import metadata.MetaDataContol; import performanceTests.PerformanceDialog; import tipOfTheDay.TipOfTheDayManager; import Array.ArrayManager; @@ -601,6 +603,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { fileMenu.add(menuItem); } + // if (SMRUEnable.isEnable()) { menuItem = new JMenuItem("Import PAMGuard Modules"); menuItem.setToolTipText("Import module settings from a different PAMGuard configuration (psfx files only"); menuItem.addActionListener(new ActionListener() { @@ -610,6 +613,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { } }); fileMenu.add(menuItem); +// } fileMenu.addSeparator(); @@ -759,6 +763,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { //for changing "hydrophones" to "microphone" and vice versa if medium changes. menu.addMenuListener(new SettingsMenuListener()); + menu.add(MetaDataContol.getMetaDataControl().createMenu(frame)); menu.addSeparator(); @@ -1664,10 +1669,10 @@ public class PamGui extends PamView implements WindowListener, PamSettings { protected void getGuiParameters() { guiParameters.extendedState = frame.getExtendedState(); guiParameters.state = frame.getState(); - if (guiParameters.state != Frame.MAXIMIZED_BOTH) { +// if (guiParameters.state != Frame.MAXIMIZED_BOTH) { guiParameters.size = frame.getSize(); guiParameters.bounds = frame.getBounds(); - } +// } } /** @@ -1982,6 +1987,30 @@ public class PamGui extends PamView implements WindowListener, PamSettings { public PamTabbedPane getTabbedPane() { return this.mainTab; } + + /** + * find a parent window for a JComponent. This can be useful in + * finding windows to open child dialogs when the object holding + * the component may not have a direct reference back to it's dialog. + * @param component any Swing component + * @return parent Window (or frame) if it can be found + */ + public static Window findComponentWindow(JComponent component) { + if (component == null) { + return null; + } + JRootPane root = component.getRootPane(); + if (root == null) { + return null; + } + Container rootP = root.getParent(); + if (rootP instanceof Window) { + return (Window) rootP; + } + else { + return null; + } + } } \ No newline at end of file diff --git a/src/PamView/PamSymbol.java b/src/PamView/PamSymbol.java index 00c471f6..2a4f4061 100644 --- a/src/PamView/PamSymbol.java +++ b/src/PamView/PamSymbol.java @@ -38,6 +38,7 @@ import javax.swing.JPanel; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamColors.PamColor; import PamView.symbol.SymbolData; @@ -808,7 +809,7 @@ public class PamSymbol extends PamSymbolBase implements Serializable, Icon, Clon @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamView/dialog/warn/WarnOnce.java b/src/PamView/dialog/warn/WarnOnce.java index 93ed4618..cd7ad08d 100644 --- a/src/PamView/dialog/warn/WarnOnce.java +++ b/src/PamView/dialog/warn/WarnOnce.java @@ -48,6 +48,7 @@ public class WarnOnce implements PamSettings { int ans = showWarning(parent, "Warning Messages", "Show all PAMGuard warning messages", WarnOnce.OK_CANCEL_OPTION); if (ans == WarnOnce.CANCEL_OPTION) return; singleInstance.warnOnceList.clearList(); + singleInstance.showThisSess.clear(); } @Override diff --git a/src/PamView/paneloverlay/OverlayDataInfo.java b/src/PamView/paneloverlay/OverlayDataInfo.java index 3c3ed86b..fd590d82 100644 --- a/src/PamView/paneloverlay/OverlayDataInfo.java +++ b/src/PamView/paneloverlay/OverlayDataInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OverlayDataInfo implements Serializable, Cloneable, ManagedParameters { @@ -31,7 +32,7 @@ public class OverlayDataInfo implements Serializable, Cloneable, ManagedParamete */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java b/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java index f6c8d446..ae081fc1 100644 --- a/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java +++ b/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamDataBlock; @@ -73,7 +74,7 @@ public class MarkDataSelectorParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("overlayChoices"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamView/symbol/ManagedSymbolData.java b/src/PamView/symbol/ManagedSymbolData.java index 23bb555d..19789f61 100644 --- a/src/PamView/symbol/ManagedSymbolData.java +++ b/src/PamView/symbol/ManagedSymbolData.java @@ -3,7 +3,11 @@ package PamView.symbol; import java.io.Serializable; import java.util.Hashtable; -public class ManagedSymbolData implements Cloneable, Serializable { +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; + +public class ManagedSymbolData implements Cloneable, Serializable, ManagedParameters { public static final long serialVersionUID = 1L; @@ -34,5 +38,10 @@ public class ManagedSymbolData implements Cloneable, Serializable { return symbolOptions; } + @Override + public PamParameterSet getParameterSet() { + return PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); + } + } diff --git a/src/PamView/wizard/PamWizard.java b/src/PamView/wizard/PamWizard.java new file mode 100644 index 00000000..9ba67e01 --- /dev/null +++ b/src/PamView/wizard/PamWizard.java @@ -0,0 +1,160 @@ +package PamView.wizard; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import PamView.dialog.PamDialog; +import tethys.swing.export.ExportStreamInfoPanel; +import tethys.swing.export.ExportWizardCard; + +abstract public class PamWizard extends PamDialog { + + private static final long serialVersionUID = 1L; + + private JPanel cardPanel; + + private CardLayout cardLayout; + + private JPanel mainPanel; + + private JButton prevButton; + + private ArrayList wizardCards = new ArrayList(); + + public PamWizard(Window parentFrame, String title) { + super(parentFrame, title, false); + + cardLayout = new CardLayout(); + mainPanel = new JPanel(new BorderLayout()); + cardPanel = new JPanel(cardLayout); + mainPanel.add(BorderLayout.CENTER, cardPanel); + + setDialogComponent(mainPanel); + + getOkButton().setText("Finish"); + prevButton = new JButton("Previous"); + getButtonPanel().add(prevButton, 0); + prevButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + previousButton(); + } + }); + + setResizable(true); + } + + public void addCard(PamWizardCard wizPanel) { + cardPanel.add(wizPanel, wizPanel.getTitle()); + wizardCards.add(wizPanel); + } + + /** + * Get the main panel. This is the main dialog panel and uses a borderlayout + * with the cards in the CENTER of the panel. Additional information panels + * (generally fixed and not changing with the dialog) can be added NORTH, SOUTH, WEST and EAST. + * @return main Panel. + */ + public JPanel getMainPanel() { + return mainPanel; + } + + /** + * Called when 'previous' button is clicked. + */ + protected void previousButton() { + cardLayout.previous(cardPanel); + enableControls(); + } + + public void enableControls() { + int iCard = getCardIndex(); + prevButton.setEnabled(iCard > 0); + boolean isLast = iCard == wizardCards.size()-1; +// getOkButton().setEnabled(!isLast); + getOkButton().setText(isLast ? "Finish" : "Next"); + } + + private boolean checkCurrentCard() { + int iCard = getCardIndex(); + if (iCard < 0) { + return true; + } + return getCardParams(wizardCards.get(iCard)); + } + + abstract public void setCardParams(PamWizardCard wizardCard); + + abstract public boolean getCardParams(PamWizardCard wizardCard); + + public int getCardIndex() { + for (int i = 0; i < cardPanel.getComponentCount(); i++) { + Component component = cardPanel.getComponent(i); + if (component.isVisible()) { + return i; + } + } + return -1; + } + + public JButton getPreviousButton() { + return prevButton; + } + + public void setParams() { + for (PamWizardCard wizCard : wizardCards) { + setCardParams(wizCard); + } + enableControls(); + } + + @Override + public boolean getParams() { + /** + * This is the OK button, so we need to NOT return OK, which would close the + * dialog until we're on the last card. + */ + if (checkCurrentCard() == false) { + return false; + } + int iCard = getCardIndex(); + if (iCard < wizardCards.size()-1) { + cardLayout.next(cardPanel); + enableControls(); + return false; + } + + return true; + } + + + + @Override + public void restoreDefaultSettings() { + // TODO Auto-generated method stub + + } + + /** + * Move to the first card in the stack + */ + public void moveFirst() { + cardLayout.first(cardPanel); + } + + /** + * Move to the last card in the stack + */ + public void moveLast() { + cardLayout.last(cardPanel); + } + +} diff --git a/src/PamView/wizard/PamWizardCard.java b/src/PamView/wizard/PamWizardCard.java new file mode 100644 index 00000000..bc0d9e14 --- /dev/null +++ b/src/PamView/wizard/PamWizardCard.java @@ -0,0 +1,45 @@ +package PamView.wizard; + +import java.io.Serializable; + +import javax.swing.JPanel; + + +/** + * Base class for PAMGuard wizard cards. + * @author dg50 + * + * @param class type for parameters to set and get. + */ +abstract public class PamWizardCard extends JPanel { + + private static final long serialVersionUID = 1L; + + private String title; + + private PamWizard pamWizard; + + /** + * @param title + */ + public PamWizardCard(PamWizard pamWizard, String title) { + this.pamWizard = pamWizard; + this.title = title; + } + + public abstract boolean getParams(T cardParams); + + public abstract void setParams(T cardParams); + + public String getTitle() { + return title; + } + + /** + * @return the pamWizard + */ + public PamWizard getPamWizard() { + return pamWizard; + } + +} diff --git a/src/PamguardMVC/AcousticDataBlock.java b/src/PamguardMVC/AcousticDataBlock.java index ec7477c1..f7fb5c8e 100644 --- a/src/PamguardMVC/AcousticDataBlock.java +++ b/src/PamguardMVC/AcousticDataBlock.java @@ -1,5 +1,8 @@ package PamguardMVC; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import PamController.PamControllerInterface; import PamguardMVC.nanotime.NanosFromSamples; @@ -90,5 +93,12 @@ abstract public class AcousticDataBlock extends PamD return parentSourceData; } + @Override + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + el.setAttribute("SampleRate", String.format("%3.1f", getSampleRate())); + return el; + } + } diff --git a/src/PamguardMVC/DataAutomation.java b/src/PamguardMVC/DataAutomation.java new file mode 100644 index 00000000..cd424c60 --- /dev/null +++ b/src/PamguardMVC/DataAutomation.java @@ -0,0 +1,29 @@ +package PamguardMVC; + +/** + * @author dg50 + * Levels of automation for the various datas in PAMGuard. + * Should be used within DataAutomationInfo to perhaps combine with other info in the future. + * + */ +public enum DataAutomation { + + AUTOMATIC, MANUAL, MANUALANDAUTOMATIC; + + @Override + public String toString() { + switch (this) { + case AUTOMATIC: + return "Automatic"; + case MANUAL: + return "Manual"; + case MANUALANDAUTOMATIC: + return "Manual and automatic"; + default: + break; + + } + return null; + } + +} diff --git a/src/PamguardMVC/DataAutomationInfo.java b/src/PamguardMVC/DataAutomationInfo.java new file mode 100644 index 00000000..42c7e42d --- /dev/null +++ b/src/PamguardMVC/DataAutomationInfo.java @@ -0,0 +1,44 @@ +package PamguardMVC; + +/** + * Returned by datablocks, though default is null, to give information on how + * automatic the process was. + * @author dg50 + * + */ +public class DataAutomationInfo { + + + private DataAutomation automation; + + /** + * @param automation + */ + public DataAutomationInfo(DataAutomation automation) { + this.setAutomation(automation); + } + + /** + * @return the automation + */ + public DataAutomation getAutomation() { + return automation; + } + + /** + * @param automation the automation to set + */ + public void setAutomation(DataAutomation automation) { + this.automation = automation; + } + + @Override + public String toString() { + if (automation == null) { + return "Unknown data automation"; + } + return automation.toString(); + } + + +} diff --git a/src/PamguardMVC/DataBlock2D.java b/src/PamguardMVC/DataBlock2D.java index beae1e15..89eb0ec9 100644 --- a/src/PamguardMVC/DataBlock2D.java +++ b/src/PamguardMVC/DataBlock2D.java @@ -1,5 +1,8 @@ package PamguardMVC; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import dataPlotsFX.data.DataTypeInfo; abstract public class DataBlock2D extends AcousticDataBlock { @@ -39,4 +42,18 @@ abstract public class DataBlock2D extends AcousticDat * @return data type information. */ abstract public DataTypeInfo getScaleInfo(); + + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + DataTypeInfo dti = getScaleInfo(); + if (dti != null) { + if (dti.dataType != null) { + el.setAttribute("DataType", dti.dataType.toString()); + } + if (dti.dataUnits != null) { + el.setAttribute("DataUnits", dti.dataUnits.toString()); + } + } + return el; + } } diff --git a/src/PamguardMVC/PamDataBlock.java b/src/PamguardMVC/PamDataBlock.java index 97bd709c..b865d572 100644 --- a/src/PamguardMVC/PamDataBlock.java +++ b/src/PamguardMVC/PamDataBlock.java @@ -44,10 +44,16 @@ import javax.swing.Timer; import javax.swing.border.EmptyBorder; import org.springframework.core.GenericTypeResolver; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import Acquisition.AcquisitionControl; import Acquisition.AcquisitionProcess; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.AutoTethysProvider; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; import dataGram.DatagramProvider; import dataMap.BespokeDataMapGraphic; import dataMap.OfflineDataMap; @@ -62,6 +68,7 @@ import PamController.PamController; import PamController.PamControllerInterface; import PamDetection.LocContents; import PamDetection.LocalisationInfo; +import PamDetection.PamDetection; import PamUtils.PamCalendar; import PamUtils.PamUtils; import PamView.symbol.PamSymbolManager; @@ -69,8 +76,10 @@ import PamguardMVC.background.BackgroundDataBlock; import PamguardMVC.background.BackgroundManager; import PamguardMVC.dataOffline.OfflineDataLoadInfo; import PamguardMVC.dataOffline.OfflineDataLoading; +import PamguardMVC.dataSelector.DataSelectParams; import PamguardMVC.dataSelector.DataSelector; import PamguardMVC.dataSelector.DataSelectorCreator; +import PamguardMVC.dataSelector.DataSelectorSettings; import PamguardMVC.dataSelector.NullDataSelectorCreator; import PamguardMVC.datamenus.DataMenuParent; import PamguardMVC.nanotime.NanoTimeCalculator; @@ -2833,7 +2842,7 @@ public class PamDataBlock extends PamObservable { * @return temporary copy of the data */ public ArrayList getDataCopy(long t1, long t2, boolean assumeOrder, DataSelector dataSelector) { - if (dataSelector == null) { + if (dataSelector == null || dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) { return getDataCopy(t1, t2, assumeOrder); } else { @@ -2865,6 +2874,7 @@ public class PamDataBlock extends PamObservable { private SQLLogging logging; private JSONObjectDataSource jsonDataSource; + public Vector getProcessAnnotations() { return processAannotations; @@ -3074,6 +3084,34 @@ public class PamDataBlock extends PamObservable { public SQLLogging getLogging() { return logging; } + + /** + * Gets a data provider for Tethys. These will probably need + * to be bespoke, but for now will autogenerate based on the SQLLogging information. + * @return the tethysDataProvider + */ + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + return null; + } + + /** + * Get the level of automation employed by the generation of these data. + * Should ideally be completed for everything providing data to Tethys. + * @return level of automation for this data block. + */ + public DataAutomationInfo getDataAutomationInfo() { + return null; + } + + /** + * Get information about species types that may occur within this data + * block. Primarily for conversion into Tethys compatible data, but may + * prove to have other uses. + * @return Types of species information available within this datablock. + */ + public DataBlockSpeciesManager getDatablockSpeciesManager() { + return null; + } final public boolean getCanLog() { return (logging != null); @@ -4229,4 +4267,23 @@ public class PamDataBlock extends PamObservable { public void setBackgroundManager(BackgroundManager backgroundManager) { this.backgroundManager = backgroundManager; } + + /** + * Get a brief summary of datablock to include in XML descriptions. + * Basic output is very simple. Expect other datablock to extend this by + * adding additional attributes. + * @param doc + * @return XML element with description of data. + */ + public Element getDataBlockXML(Document doc) { + Element inputEl = doc.createElement("Input"); + if (getParentProcess() != null && getParentProcess().getPamControlledUnit() != null) { + PamControlledUnit pcu = getParentProcess().getPamControlledUnit(); + inputEl.setAttribute("ModuleType", pcu.getUnitType()); + inputEl.setAttribute("ModuleName", pcu.getUnitName()); + } + inputEl.setAttribute("Name", getLongDataName()); + inputEl.setAttribute("Channels", String.format("0x%X", getChannelMap())); + return inputEl; + } } diff --git a/src/PamguardMVC/PamDataUnit.java b/src/PamguardMVC/PamDataUnit.java index 3295381f..8630a7d1 100644 --- a/src/PamguardMVC/PamDataUnit.java +++ b/src/PamguardMVC/PamDataUnit.java @@ -974,8 +974,13 @@ abstract public class PamDataUnit // add frequency and amplitude information - str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "
    "; - str += String.format("Amplitude: %3.1fdB
    ", getAmplitudeDB()); + double[] frequency = this.getFrequency(); + if (frequency != null) { + str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "
    "; + } + if (getAmplitudeDB() != 0) { + str += String.format("Amplitude: %3.1fdB
    ", getAmplitudeDB()); + } if (getSignalSPL() != null) { str += String.format("SPL: %3.1fdBre1uPa
    ",linAmplitudeToDB(getSignalSPL())); } diff --git a/src/PamguardMVC/RawDataDisplayOptions.java b/src/PamguardMVC/RawDataDisplayOptions.java index 9ed8355c..6ff49562 100644 --- a/src/PamguardMVC/RawDataDisplayOptions.java +++ b/src/PamguardMVC/RawDataDisplayOptions.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class RawDataDisplayOptions implements Serializable, Cloneable, ManagedParameters { @@ -13,7 +14,7 @@ public class RawDataDisplayOptions implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamguardMVC/RawDataUnavailableException.java b/src/PamguardMVC/RawDataUnavailableException.java index 581f981d..37e4275a 100644 --- a/src/PamguardMVC/RawDataUnavailableException.java +++ b/src/PamguardMVC/RawDataUnavailableException.java @@ -61,7 +61,7 @@ public class RawDataUnavailableException extends Exception { return String.format("Samples %d length %d requested from %s have not yet arrived", startSample, duration, rawDataBlock.getDataName()); case INVALID_CHANNEL_LIST: - return String.format("Samples %d length %d requested from %s do not contain the reqeusted channels %s", + return String.format("Samples %d length %d requested from %s do not contain the reqeusted channels", startSample, duration, rawDataBlock.getDataName()); case NEGATIVE_DURATION: return String.format("Negative data duration request for %d samples" , duration); diff --git a/src/PamguardMVC/blockprocess/PamBlockParams.java b/src/PamguardMVC/blockprocess/PamBlockParams.java index 249d98e1..aaaed713 100644 --- a/src/PamguardMVC/blockprocess/PamBlockParams.java +++ b/src/PamguardMVC/blockprocess/PamBlockParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import gpl.GPLParameters; /** @@ -44,7 +45,7 @@ public class PamBlockParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamguardMVC/dataSelector/DataSelectParams.java b/src/PamguardMVC/dataSelector/DataSelectParams.java index da0f5e74..0d4af3fb 100644 --- a/src/PamguardMVC/dataSelector/DataSelectParams.java +++ b/src/PamguardMVC/dataSelector/DataSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Data select parameters. @@ -53,7 +54,7 @@ abstract public class DataSelectParams implements Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamguardMVC/dataSelector/DataSelector.java b/src/PamguardMVC/dataSelector/DataSelector.java index 0503479f..b033976c 100644 --- a/src/PamguardMVC/dataSelector/DataSelector.java +++ b/src/PamguardMVC/dataSelector/DataSelector.java @@ -9,7 +9,10 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JMenuItem; +import org.w3c.dom.Document; + import PamController.PamController; +import PamController.settings.output.xml.PamguardXMLWriter; import PamView.dialog.PamDialogPanel; import PamView.dialog.SettingsButton; import PamguardMVC.PamDataBlock; @@ -39,7 +42,7 @@ public abstract class DataSelector { private String selectorTitle; private boolean allowScores; - + /** * Create a data selector for a DataBlock. If allowScores is * true, then the selector MAY (but may not) offer a more complicated @@ -104,18 +107,8 @@ public abstract class DataSelector { if (parentFrame == null) { parentFrame = PamController.getMainFrame(); } - Window localWin = parentFrame; - DataSelectorChangeListener localChangeListener = changeListener; JMenuItem menuItem = new JMenuItem("Data selection ..."); - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - boolean ok = showSelectDialog(localWin); - if (ok && changeListener != null) { - changeListener.selectorChange(DataSelector.this); - } - } - }); + menuItem.addActionListener(new ShowSettingsButton(parentFrame, changeListener)); return menuItem; } @@ -129,6 +122,24 @@ public abstract class DataSelector { return ok; } + /** + * Get descriptive text about the data selector which can be + * added to dialogs and other information panels. + * @return descriptive text. Default is a xml dump of params. + */ + public String getDescription() { + if (getParams() == null) { + return null; + } + PamguardXMLWriter xmlWriter = PamguardXMLWriter.getXMLWriter(); + Document doc = xmlWriter.writeOneObject(getParams()); + if (doc != null) { + String str = xmlWriter.getAsString(doc, true); + return str; + } + return null; + } + /** * Score a PAMDataUnit. this is used in preference * to a boolean select function so that the user can add different @@ -228,25 +239,40 @@ public abstract class DataSelector { * @param parentWindow */ public JButton getDialogButton(Window parentWindow) { + return getDialogButton(parentWindow, null); + } + /** + * Create a settings type button that can be inserted into a + * larger dialog. + * @param parentWindow + */ + + public JButton getDialogButton(Window parentWindow, DataSelectorChangeListener changeListener) { JButton button = new SettingsButton(); - button.addActionListener(new ShowSettingsButton(parentWindow)); + button.addActionListener(new ShowSettingsButton(parentWindow, changeListener)); button.setToolTipText("Data selection options for " + getSelectorTitle()); return button; } private class ShowSettingsButton implements ActionListener { private Window parentWindow; + private DataSelectorChangeListener changeListener; /** * @param parentWindow + * @param changeListener */ - public ShowSettingsButton(Window parentWindow) { + public ShowSettingsButton(Window parentWindow, DataSelectorChangeListener changeListener) { super(); this.parentWindow = parentWindow; + this.changeListener = changeListener; } @Override public void actionPerformed(ActionEvent e) { - showSelectDialog(parentWindow); + boolean ok = showSelectDialog(parentWindow); + if (ok && changeListener != null) { + changeListener.selectorChange(DataSelector.this); + } } } diff --git a/src/PamguardMVC/dataSelector/DataSelectorSettings.java b/src/PamguardMVC/dataSelector/DataSelectorSettings.java index f29c8103..df66d20e 100644 --- a/src/PamguardMVC/dataSelector/DataSelectorSettings.java +++ b/src/PamguardMVC/dataSelector/DataSelectorSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataSelectorSettings implements Serializable, ManagedParameters { @@ -42,7 +43,7 @@ public class DataSelectorSettings implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("selectorParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamguardMVC/datakeeper/DataKeeperSettings.java b/src/PamguardMVC/datakeeper/DataKeeperSettings.java index 446669c6..3765ef72 100644 --- a/src/PamguardMVC/datakeeper/DataKeeperSettings.java +++ b/src/PamguardMVC/datakeeper/DataKeeperSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataKeeperSettings implements Serializable, Cloneable, ManagedParameters { @@ -51,7 +52,7 @@ public class DataKeeperSettings implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("keepTimeData"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamguardMVC/toad/GenericTOADSourceParams.java b/src/PamguardMVC/toad/GenericTOADSourceParams.java index e0c2237c..cd12140a 100644 --- a/src/PamguardMVC/toad/GenericTOADSourceParams.java +++ b/src/PamguardMVC/toad/GenericTOADSourceParams.java @@ -6,6 +6,7 @@ import Localiser.DelayMeasurementParams; import Localiser.controls.RawOrFFTParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * General parameters for detection TOAD measurement. Is split @@ -67,7 +68,7 @@ public class GenericTOADSourceParams implements Cloneable, Serializable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java b/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java index c08a3f68..3b7546c2 100644 --- a/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java +++ b/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java @@ -218,7 +218,7 @@ public class RWEBinaryDataSource extends BinaryDataSource { binaryObjectData.getDataUnitBaseData().setSampleDuration(duration); // rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, channelMap, // startSample, duration, aSound); - rweDataUnit = new RWEDataUnit(binaryObjectData.getDataUnitBaseData(), aSound); + rweDataUnit = new RWEDataUnit(rweProcess, binaryObjectData.getDataUnitBaseData(), aSound); rweDataUnit.setSequenceBitmap(sequenceMap); double f[] = new double[2]; f[0] = aSound.minFreq * rweDataBlock.getSampleRate()/rweDataBlock.getFftLength(); diff --git a/src/RightWhaleEdgeDetector/RWEDataBlock.java b/src/RightWhaleEdgeDetector/RWEDataBlock.java index 1969bca0..90c9a616 100644 --- a/src/RightWhaleEdgeDetector/RWEDataBlock.java +++ b/src/RightWhaleEdgeDetector/RWEDataBlock.java @@ -2,19 +2,29 @@ package RightWhaleEdgeDetector; import PamView.GroupedDataSource; import PamView.GroupedSourceParameters; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamProcess; import PamguardMVC.dataOffline.OfflineDataLoadInfo; import PamguardMVC.dataSelector.DataSelectorCreator; import RightWhaleEdgeDetector.datasel.RWDataSelCreator; +import RightWhaleEdgeDetector.species.RWSpeciesManager; +import RightWhaleEdgeDetector.species.RWTethysDataProvider; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; import whistlesAndMoans.AbstractWhistleDataBlock; -public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDataSource { +public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDataSource { private double[] rwFreqRange = {50., 250.}; private RWEControl rweControl; private RWEProcess rweProcess; private RWDataSelCreator dataSelCreator; + + private RWSpeciesManager rwSpeciesManager; + private RWTethysDataProvider rwTethysDataProvider; public RWEDataBlock(RWEControl rweControl, String dataName, RWEProcess rweProcess, int channelMap) { @@ -53,4 +63,25 @@ public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDat return dataSelCreator; } + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (rwSpeciesManager == null) { + rwSpeciesManager = new RWSpeciesManager(this); + } + return rwSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (rwTethysDataProvider == null) { + rwTethysDataProvider = new RWTethysDataProvider(tethysControl, rweProcess.getRweDataBlock()); + } + return rwTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + } diff --git a/src/RightWhaleEdgeDetector/RWEDataUnit.java b/src/RightWhaleEdgeDetector/RWEDataUnit.java index 226e0f64..c3144ebf 100644 --- a/src/RightWhaleEdgeDetector/RWEDataUnit.java +++ b/src/RightWhaleEdgeDetector/RWEDataUnit.java @@ -6,26 +6,31 @@ import whistlesAndMoans.AbstractWhistleDataUnit; public class RWEDataUnit extends AbstractWhistleDataUnit { public RWESound rweSound; + private RWEProcess rweProcess; - public RWEDataUnit(long timeMilliseconds, int channelBitmap, + public RWEDataUnit(RWEProcess rweProcess, long timeMilliseconds, int channelBitmap, long startSample, long duration, RWESound rweSound) { super(timeMilliseconds, channelBitmap, startSample, duration); this.rweSound = rweSound; + this.rweProcess = rweProcess; // TODO Auto-generated constructor stub } - public RWEDataUnit(DataUnitBaseData basicData, RWESound rweSound) { + public RWEDataUnit(RWEProcess rweProcess, DataUnitBaseData basicData, RWESound rweSound) { super(basicData); this.rweSound = rweSound; + this.rweProcess = rweProcess; } - double[] freqsHz; @Override public double[] getFreqsHz() { - if (freqsHz == null) { - freqsHz = new double[rweSound.sliceCount]; + double[] f = new double[rweSound.sliceCount]; + RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock(); + double binToHz = rweDataBlock.getSampleRate() / rweDataBlock.getFftLength(); + for (int i = 0; i < f.length; i++) { + f[i] = (double) rweSound.peakFreq[i] * binToHz; } - return null; + return f; } @Override @@ -35,8 +40,16 @@ public class RWEDataUnit extends AbstractWhistleDataUnit { @Override public double[] getTimesInSeconds() { - // TODO Auto-generated method stub - return null; + if (rweSound == null) { + return null; + } + double[] t = new double[rweSound.sliceCount]; + RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock(); + double binToT = rweDataBlock.getFftHop() / rweDataBlock.getSampleRate(); + for (int i = 0; i < t.length; i++) { + t[i] = (double) rweSound.sliceList[i] * binToT; + } + return t; } @Override diff --git a/src/RightWhaleEdgeDetector/RWEParameters.java b/src/RightWhaleEdgeDetector/RWEParameters.java index 8bb661a4..4b179378 100644 --- a/src/RightWhaleEdgeDetector/RWEParameters.java +++ b/src/RightWhaleEdgeDetector/RWEParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class RWEParameters implements Serializable, Cloneable, ManagedParameters { @@ -41,7 +42,7 @@ public class RWEParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/RightWhaleEdgeDetector/RWEProcess.java b/src/RightWhaleEdgeDetector/RWEProcess.java index ccc766bb..081489c9 100644 --- a/src/RightWhaleEdgeDetector/RWEProcess.java +++ b/src/RightWhaleEdgeDetector/RWEProcess.java @@ -42,6 +42,10 @@ public class RWEProcess extends PamProcess { private FFTDataBlock sourceDataBlock; private RWEDataBlock rweDataBlock; + public RWEDataBlock getRweDataBlock() { + return rweDataBlock; + } + private Hashtable bearingLocalisers; private StandardSymbolManager symbolManager; /** @@ -212,7 +216,7 @@ public class RWEProcess extends PamProcess { // System.out.println(String.format("Detected sound type %d on channel %d", // soundType, this.iChannel)); duration = sourceDataBlock.getFftHop() * aSound.duration; - rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, + rweDataUnit = new RWEDataUnit(RWEProcess.this, aSound.timeMilliseconds, 1< { + + private RWSpeciesTypes rwSpeciesTypes = new RWSpeciesTypes(); + + public RWSpeciesManager(PamDataBlock dataBlock) { + super(dataBlock); + setDefaultDefaultSpecies(new SpeciesMapItem(RWSpeciesTypes.eubalaena, RWSpeciesTypes.onlyType, RWSpeciesTypes.defaultName)); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + return null; + } + + @Override + public String getSpeciesCode(RWEDataUnit dataUnit) { + return RWSpeciesTypes.defaultName; + } + +} diff --git a/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java b/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java new file mode 100644 index 00000000..654fe24c --- /dev/null +++ b/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java @@ -0,0 +1,17 @@ +package RightWhaleEdgeDetector.species; + +import tethys.species.DataBlockSpeciesCodes; + +public class RWSpeciesTypes extends DataBlockSpeciesCodes { + + public static final String onlyType = "Up call"; + + public static final int eubalaena = 180536; + + public static final String defaultName = "Right Whale"; + + public RWSpeciesTypes() { + super(eubalaena, defaultName, onlyType); + } + +} diff --git a/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java b/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java new file mode 100644 index 00000000..3577bd12 --- /dev/null +++ b/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java @@ -0,0 +1,37 @@ +package RightWhaleEdgeDetector.species; + +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamDataUnit; +import RightWhaleEdgeDetector.RWEDataUnit; +import nilus.Detection; +import nilus.Detection.Parameters; +import tethys.TethysControl; +import tethys.output.StreamExportParams; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; + +public class RWTethysDataProvider extends AutoTethysProvider { + + public RWTethysDataProvider(TethysControl tethysControl, PamDataBlock pamDataBlock) { + super(tethysControl, pamDataBlock); + } + + @Override + public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams, + StreamExportParams streamExportParams) { + Detection detection = super.createDetection(dataUnit, tethysExportParams, streamExportParams); + if (detection == null) { + return null; + } + + RWEDataUnit rweDataUnit = (RWEDataUnit) dataUnit; + + Parameters parameters = detection.getParameters(); + parameters.setScore((double) rweDataUnit.rweSound.soundType); + double snr = 20.*Math.log10(rweDataUnit.rweSound.signal/rweDataUnit.rweSound.noise); + parameters.setSNRDB(snr); + + return detection; + } + +} diff --git a/src/SoundRecorder/RecorderSettings.java b/src/SoundRecorder/RecorderSettings.java index 72c9576d..4fcd6eec 100644 --- a/src/SoundRecorder/RecorderSettings.java +++ b/src/SoundRecorder/RecorderSettings.java @@ -16,6 +16,7 @@ import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamguardMVC.PamRawDataBlock; import SoundRecorder.trigger.RecorderTrigger; @@ -443,7 +444,7 @@ public class RecorderSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("channelBitmap"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/SoundRecorder/trigger/RecorderTriggerData.java b/src/SoundRecorder/trigger/RecorderTriggerData.java index 2192afc9..9b0cb32c 100644 --- a/src/SoundRecorder/trigger/RecorderTriggerData.java +++ b/src/SoundRecorder/trigger/RecorderTriggerData.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Information for triggered recordings to tell each recorder how long @@ -271,7 +272,7 @@ public class RecorderTriggerData implements Serializable, Cloneable, ManagedPara */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("lastTriggerStart"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Spectrogram/SpectrogramDisplay.java b/src/Spectrogram/SpectrogramDisplay.java index 5c86913a..08a7bf2d 100644 --- a/src/Spectrogram/SpectrogramDisplay.java +++ b/src/Spectrogram/SpectrogramDisplay.java @@ -1652,6 +1652,9 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett return; } long t1 = dataUnit.getTimeMilliseconds()-viewerScroller.getValueMillis(); + if (timeAxis == null) { + return; + } int x1 = (int) Math.floor(timeAxis.getPosition(t1/1000)); int x2 = x1; if (dataUnit.getDurationInMilliseconds() != null) { diff --git a/src/alarm/AlarmParameters.java b/src/alarm/AlarmParameters.java index df89b940..0694adfc 100644 --- a/src/alarm/AlarmParameters.java +++ b/src/alarm/AlarmParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class AlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -103,7 +104,7 @@ public class AlarmParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("hadHold"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/alarm/actions/email/SendEmailSettings.java b/src/alarm/actions/email/SendEmailSettings.java index dcd4dc0b..da558c85 100644 --- a/src/alarm/actions/email/SendEmailSettings.java +++ b/src/alarm/actions/email/SendEmailSettings.java @@ -28,6 +28,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import alarm.actions.serial.AlarmSerialSettings; /** @@ -158,7 +159,7 @@ public class SendEmailSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/serial/AlarmSerialSettings.java b/src/alarm/actions/serial/AlarmSerialSettings.java index b14e785c..801cc765 100644 --- a/src/alarm/actions/serial/AlarmSerialSettings.java +++ b/src/alarm/actions/serial/AlarmSerialSettings.java @@ -8,6 +8,7 @@ import com.fazecast.jSerialComm.SerialPort; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import serialComms.SerialPortConstants; import serialComms.jserialcomm.PJSerialComm; @@ -68,7 +69,7 @@ public class AlarmSerialSettings implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/sound/PlaySoundParams.java b/src/alarm/actions/sound/PlaySoundParams.java index c9f97970..6481e41d 100644 --- a/src/alarm/actions/sound/PlaySoundParams.java +++ b/src/alarm/actions/sound/PlaySoundParams.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import alarm.AlarmParameters; public class PlaySoundParams implements Cloneable, Serializable, ManagedParameters { @@ -33,7 +34,7 @@ public class PlaySoundParams implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/udp/AlarmUDPParams.java b/src/alarm/actions/udp/AlarmUDPParams.java index 10728bb2..7a7bfa61 100644 --- a/src/alarm/actions/udp/AlarmUDPParams.java +++ b/src/alarm/actions/udp/AlarmUDPParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AlarmUDPParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class AlarmUDPParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/amplifier/AmpParameters.java b/src/amplifier/AmpParameters.java index 98e52a63..89aac38c 100644 --- a/src/amplifier/AmpParameters.java +++ b/src/amplifier/AmpParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -41,7 +42,7 @@ public class AmpParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("rawDataSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/analogarraysensor/ArraySensorLogging.java b/src/analogarraysensor/ArraySensorLogging.java index e4eba2e9..ca13752a 100644 --- a/src/analogarraysensor/ArraySensorLogging.java +++ b/src/analogarraysensor/ArraySensorLogging.java @@ -56,7 +56,8 @@ public class ArraySensorLogging extends SQLLogging { AnalogSensorData aData = new AnalogSensorData(rawValue, calValue); sensorData[i] = aData; } - int chanMap = getTableDefinition().getChannelBitmap().getIntegerValue(); + PamTableDefinition pamTableDef = (PamTableDefinition) getTableDefinition(); + int chanMap = pamTableDef.getChannelBitmap().getIntegerValue(); int streamer = PamUtils.getSingleChannel(chanMap); if (streamer < 0) streamer = 0; AnalogArraySensorDataUnit asdu = new AnalogArraySensorDataUnit(timeMilliseconds, streamer, sensorData); diff --git a/src/analogarraysensor/ArraySensorParams.java b/src/analogarraysensor/ArraySensorParams.java index c59d31eb..b84081a6 100644 --- a/src/analogarraysensor/ArraySensorParams.java +++ b/src/analogarraysensor/ArraySensorParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Array.sensors.ArrayDisplayParameters; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ArraySensorParams implements Serializable, Cloneable, ManagedParameters { @@ -47,7 +48,7 @@ public class ArraySensorParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/analoginput/AnalogDeviceParams.java b/src/analoginput/AnalogDeviceParams.java index 1b43c7b9..cae97232 100644 --- a/src/analoginput/AnalogDeviceParams.java +++ b/src/analoginput/AnalogDeviceParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import analoginput.calibration.CalibrationData; @@ -63,7 +64,7 @@ public class AnalogDeviceParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("calibrationTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/analoginput/AnalogInputParams.java b/src/analoginput/AnalogInputParams.java index acd041e4..a64d51ba 100644 --- a/src/analoginput/AnalogInputParams.java +++ b/src/analoginput/AnalogInputParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AnalogInputParams implements Serializable, Cloneable, ManagedParameters { @@ -13,7 +14,7 @@ public class AnalogInputParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/analoginput/AnalogRangeData.java b/src/analoginput/AnalogRangeData.java index 00043994..7a7d7109 100644 --- a/src/analoginput/AnalogRangeData.java +++ b/src/analoginput/AnalogRangeData.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AnalogRangeData implements Serializable, Cloneable, Comparable, ManagedParameters { @@ -119,7 +120,7 @@ public class AnalogRangeData implements Serializable, Cloneable, Comparable 0) { diff --git a/src/annotation/timestamp/TimestampSQLLogging.java b/src/annotation/timestamp/TimestampSQLLogging.java index fd1d7be6..2f6b0728 100644 --- a/src/annotation/timestamp/TimestampSQLLogging.java +++ b/src/annotation/timestamp/TimestampSQLLogging.java @@ -3,6 +3,7 @@ package annotation.timestamp; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -22,12 +23,12 @@ public class TimestampSQLLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(timestamp); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { TimestampAnnotation timestampAnnotation = (TimestampAnnotation) pamDataUnit.findDataAnnotation(TimestampAnnotation.class, timestampAnnotationType.getAnnotationName()); if (timestampAnnotation == null) { @@ -40,7 +41,7 @@ public class TimestampSQLLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { try { TimestampAnnotation timestampAnnotation = new TimestampAnnotation(timestampAnnotationType); Long note = sqlTypes.millisFromTimeStamp(timestamp.getValue()); diff --git a/src/annotation/userforms/UserFormSQLAddon.java b/src/annotation/userforms/UserFormSQLAddon.java index fb5a20f0..8156bfda 100644 --- a/src/annotation/userforms/UserFormSQLAddon.java +++ b/src/annotation/userforms/UserFormSQLAddon.java @@ -3,6 +3,7 @@ package annotation.userforms; import java.util.ArrayList; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -32,7 +33,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { loggerTableItems.clear(); FormDescription formDescription = userFormAnnotationType.findFormDescription(); if (formDescription == null) { @@ -58,7 +59,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { if (pamDataUnit == null) { clearTableItems(); return false; @@ -103,7 +104,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { FormDescription formDescription = userFormAnnotationType.findFormDescription(); if (formDescription == null) { return false; diff --git a/src/annotationMark/spectrogram/SpectrogramMarkParams.java b/src/annotationMark/spectrogram/SpectrogramMarkParams.java index 0d65e6e4..89540c01 100644 --- a/src/annotationMark/spectrogram/SpectrogramMarkParams.java +++ b/src/annotationMark/spectrogram/SpectrogramMarkParams.java @@ -5,6 +5,7 @@ import java.util.List; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import annotation.DataAnnotationType; import annotation.handler.AnnotationChoices; @@ -31,7 +32,7 @@ public class SpectrogramMarkParams implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/backupmanager/FileLocation.java b/src/backupmanager/FileLocation.java index 1508125a..6557821d 100644 --- a/src/backupmanager/FileLocation.java +++ b/src/backupmanager/FileLocation.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Information on a file path or folder path that can be used with the @@ -42,7 +43,7 @@ public class FileLocation implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/backupmanager/settings/BackupSettings.java b/src/backupmanager/settings/BackupSettings.java index 71b90fda..bc9ac14c 100644 --- a/src/backupmanager/settings/BackupSettings.java +++ b/src/backupmanager/settings/BackupSettings.java @@ -6,6 +6,7 @@ import java.util.List; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public abstract class BackupSettings implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public abstract class BackupSettings implements Serializable, Cloneable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/beamformer/BeamAlgorithmParams.java b/src/beamformer/BeamAlgorithmParams.java index 7cde91b4..eabdb943 100644 --- a/src/beamformer/BeamAlgorithmParams.java +++ b/src/beamformer/BeamAlgorithmParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import beamformer.algorithms.basicFreqDomain.BasicFreqDomParams; /* @@ -336,7 +337,7 @@ public abstract class BeamAlgorithmParams implements Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/beamformer/BeamFormerParams.java b/src/beamformer/BeamFormerParams.java index f5cc3f5d..d6082a1d 100644 --- a/src/beamformer/BeamFormerParams.java +++ b/src/beamformer/BeamFormerParams.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.HashMap; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.DeepCloner; import PamView.GroupedSourceParameters; @@ -325,7 +326,7 @@ public class BeamFormerParams implements Cloneable, Serializable, ManagedParamet */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmParamsTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/beamformer/annotation/BFAnnotationLogging.java b/src/beamformer/annotation/BFAnnotationLogging.java index 83d7641a..ba9bed54 100644 --- a/src/beamformer/annotation/BFAnnotationLogging.java +++ b/src/beamformer/annotation/BFAnnotationLogging.java @@ -6,6 +6,7 @@ import PamDetection.LocContents; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import beamformer.loc.BeamFormerLocalisation; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -29,7 +30,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(bfPhones); pamTableDefinition.addTableItem(bfArrayType); pamTableDefinition.addTableItem(bfContents); @@ -38,7 +39,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { bfPhones.setValue(null); bfArrayType.setValue(null); bfContents.setValue(null); @@ -64,7 +65,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Float[] Angles = new Float[2]; for (int i = 0; i < 2; i++) { Angles[i] = (Float) angle[i].getFloatValue(); diff --git a/src/bearinglocaliser/BearingLocaliserParams.java b/src/bearinglocaliser/BearingLocaliserParams.java index 277c8e5d..d697781c 100644 --- a/src/bearinglocaliser/BearingLocaliserParams.java +++ b/src/bearinglocaliser/BearingLocaliserParams.java @@ -8,6 +8,7 @@ import java.util.HashMap; import Localiser.controls.RawOrFFTParamsInterface; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import bearinglocaliser.algorithms.BearingAlgorithmParams; @@ -188,7 +189,7 @@ public class BearingLocaliserParams implements Serializable, Cloneable, RawOrFFT @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmParamsTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java b/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java index 3b6c0bed..cea3e25f 100644 --- a/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java +++ b/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class BearingAlgorithmParams implements Serializable, Cloneable, ManagedParameters { @@ -60,7 +61,7 @@ public class BearingAlgorithmParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/bearinglocaliser/annotation/BearingAnnotationSQL.java b/src/bearinglocaliser/annotation/BearingAnnotationSQL.java index bc4b88bb..d56e8be7 100644 --- a/src/bearinglocaliser/annotation/BearingAnnotationSQL.java +++ b/src/bearinglocaliser/annotation/BearingAnnotationSQL.java @@ -4,6 +4,7 @@ import java.sql.Types; import PamguardMVC.PamDataUnit; import bearinglocaliser.BearingLocalisation; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -34,7 +35,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(algoName); pamTableDefinition.addTableItem(bfPhones); pamTableDefinition.addTableItem(bfArrayType); @@ -48,7 +49,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { algoName.setValue(null); bfPhones.setValue(null); bfArrayType.setValue(null); @@ -96,7 +97,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Float[] Angles = new Float[2]; int nNans = 0; for (int i = 0; i < 2; i++) { diff --git a/src/binaryFileStorage/BinaryFooter.java b/src/binaryFileStorage/BinaryFooter.java index 98142a16..f410998b 100644 --- a/src/binaryFileStorage/BinaryFooter.java +++ b/src/binaryFileStorage/BinaryFooter.java @@ -7,6 +7,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class BinaryFooter implements Serializable, ManagedParameters { @@ -230,7 +231,7 @@ public class BinaryFooter implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/binaryFileStorage/BinaryHeader.java b/src/binaryFileStorage/BinaryHeader.java index b27652ec..b1d7a986 100644 --- a/src/binaryFileStorage/BinaryHeader.java +++ b/src/binaryFileStorage/BinaryHeader.java @@ -9,6 +9,7 @@ import java.lang.reflect.Field; import PamController.PamguardVersionInfo; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.PamCalendar; @@ -289,7 +290,7 @@ public class BinaryHeader implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("pamguard"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/binaryFileStorage/BinarySettingsStorage.java b/src/binaryFileStorage/BinarySettingsStorage.java index 48278c1d..c59992d8 100644 --- a/src/binaryFileStorage/BinarySettingsStorage.java +++ b/src/binaryFileStorage/BinarySettingsStorage.java @@ -110,6 +110,12 @@ public class BinarySettingsStorage implements PamSettingsSource { return false;*/ } + @Override + public boolean saveEndSettings(long timeNow) { + // do nothing at the end of a run with binary store. + return true; + } + // private boolean writeData(DataOutputStream dos, int objectId, byte[] data) { // int totalLen = data.length + 16; // int dataLen = data.length; diff --git a/src/binaryFileStorage/BinaryStore.java b/src/binaryFileStorage/BinaryStore.java index 3db5fd66..e01cc9b4 100644 --- a/src/binaryFileStorage/BinaryStore.java +++ b/src/binaryFileStorage/BinaryStore.java @@ -561,6 +561,12 @@ PamSettingsSource, DataOutputStore { return binarySettingsStorage.saveStartSettings(timeNow); } + @Override + public boolean saveEndSettings(long timeNow) { + // TODO Auto-generated method stub + return false; + } + @Override public int getNumSettings() { if (binarySettingsStorage == null) { @@ -2583,5 +2589,9 @@ PamSettingsSource, DataOutputStore { } return state; } + + public String getDataLocation() { + return binaryStoreSettings.getStoreLocation(); + } } diff --git a/src/binaryFileStorage/BinaryStoreSettings.java b/src/binaryFileStorage/BinaryStoreSettings.java index 441baddd..78c42e99 100644 --- a/src/binaryFileStorage/BinaryStoreSettings.java +++ b/src/binaryFileStorage/BinaryStoreSettings.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamController.PamFolders; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class BinaryStoreSettings implements Serializable, Cloneable, ManagedParameters { @@ -90,7 +91,7 @@ public class BinaryStoreSettings implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/cepstrum/CepstrumParams.java b/src/cepstrum/CepstrumParams.java index a24fab3a..59f6fbb9 100644 --- a/src/cepstrum/CepstrumParams.java +++ b/src/cepstrum/CepstrumParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class CepstrumParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class CepstrumParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/clickDetector/BTDisplayParameters.java b/src/clickDetector/BTDisplayParameters.java index 143b3eab..bf9604f7 100644 --- a/src/clickDetector/BTDisplayParameters.java +++ b/src/clickDetector/BTDisplayParameters.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import clickDetector.tdPlots.ClickSymbolOptions; @@ -137,7 +138,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("showSpeciesList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/BasicClickIdParameters.java b/src/clickDetector/BasicClickIdParameters.java index feeefb67..6cc5925c 100644 --- a/src/clickDetector/BasicClickIdParameters.java +++ b/src/clickDetector/BasicClickIdParameters.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; @@ -83,7 +84,7 @@ public class BasicClickIdParameters implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/ClickAlarm.java b/src/clickDetector/ClickAlarm.java index f9459296..515945ab 100644 --- a/src/clickDetector/ClickAlarm.java +++ b/src/clickDetector/ClickAlarm.java @@ -33,6 +33,7 @@ import javax.sound.sampled.Clip; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -209,7 +210,7 @@ public class ClickAlarm implements Comparable, Serializable, Cloneab @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fileIsLoaded"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickBinaryModuleFooter.java b/src/clickDetector/ClickBinaryModuleFooter.java index 35718e17..f24ed53c 100644 --- a/src/clickDetector/ClickBinaryModuleFooter.java +++ b/src/clickDetector/ClickBinaryModuleFooter.java @@ -12,6 +12,7 @@ import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleFooter; @@ -128,7 +129,7 @@ public class ClickBinaryModuleFooter extends ModuleFooter implements ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("clickDetectorName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickBinaryModuleHeader.java b/src/clickDetector/ClickBinaryModuleHeader.java index 1cb7f8d8..f36f7854 100644 --- a/src/clickDetector/ClickBinaryModuleHeader.java +++ b/src/clickDetector/ClickBinaryModuleHeader.java @@ -2,6 +2,7 @@ package clickDetector; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleHeader; @@ -28,7 +29,7 @@ public class ClickBinaryModuleHeader extends ModuleHeader implements ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java b/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java new file mode 100644 index 00000000..89812008 --- /dev/null +++ b/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java @@ -0,0 +1,52 @@ +package clickDetector.ClickClassifiers; + +import clickDetector.ClickControl; +import clickDetector.ClickDataBlock; +import clickDetector.ClickDetection; +import tethys.species.DataBlockSpeciesManager; +import tethys.species.DataBlockSpeciesCodes; +import tethys.species.ITISTypes; +import tethys.species.SpeciesMapItem; + +public class ClickBlockSpeciesManager extends DataBlockSpeciesManager { + + private ClickControl clickControl; + + public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) { + super(clickDataBlock); + this.clickControl = clickControl; + setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.UNKNOWN, "Unknown", "Unknown")); + setDefaultSpeciesCode("Unknown"); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + ClickTypeMasterManager masterManager = clickControl.getClickTypeMasterManager(); + if (masterManager == null) { + return null; + } + String[] speciesList = masterManager.getSpeciesList(); + // add the default + String[] fullList = new String[speciesList.length+1]; + fullList[0] = getDefaultSpeciesCode(); + for (int i = 0; i < speciesList.length; i++) { + fullList[i+1] = speciesList[i]; + } + + return new DataBlockSpeciesCodes("Click", fullList); + } + + @Override + public String getSpeciesCode(ClickDetection dataUnit) { + ClickTypeMasterManager masterManager = clickControl.getClickTypeMasterManager(); + if (masterManager == null) { + return null; + } + int listIndex = masterManager.codeToListIndex(dataUnit.getClickType()); + if (listIndex < 0) { + return null; + } + return masterManager.getSpeciesList()[listIndex]; + } + +} diff --git a/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java b/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java index d937b164..78b56316 100644 --- a/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java +++ b/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java @@ -28,6 +28,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Superclass for click parameters, including the ClickTypeParms and @@ -191,7 +192,7 @@ abstract public class ClickTypeCommonParams implements Cloneable, Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java b/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java index baa057ac..840d2086 100644 --- a/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java +++ b/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java @@ -3,6 +3,7 @@ package clickDetector.ClickClassifiers.annotation; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -33,12 +34,12 @@ public class ClickAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(classifierSetTable); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { ClickClassifierAnnotation clickAnnotation = (ClickClassifierAnnotation) pamDataUnit.findDataAnnotation(ClickClassificationType.class); //create a comma delimited string @@ -53,7 +54,7 @@ public class ClickAnnotationSQL implements SQLLoggingAddon { @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { String array = classifierSetTable.getDeblankedStringValue(); //read in the classification set. This a list of all the classifiers the clicks passed. diff --git a/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java b/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java index 9c925607..6cc4f1b5 100644 --- a/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java +++ b/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java @@ -7,6 +7,7 @@ import java.util.Vector; import PamModel.SMRUEnable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class SweepClassifierParameters implements Serializable, Cloneable, ManagedParameters { @@ -72,7 +73,7 @@ public class SweepClassifierParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("classifierSets"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickControl.java b/src/clickDetector/ClickControl.java index e03b73a7..9787c59f 100644 --- a/src/clickDetector/ClickControl.java +++ b/src/clickDetector/ClickControl.java @@ -26,6 +26,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.Serializable; import java.util.ArrayList; +import java.util.List; import java.util.ListIterator; import javax.swing.JMenu; @@ -1071,7 +1072,7 @@ public class ClickControl extends PamControlledUnit implements PamSettings { subDet.removeSuperDetection(event); } } - clickDetector.getOfflineEventDataBlock().remove(event); + clickDetector.getOfflineEventDataBlock().remove(event, true); } @Override @@ -1168,6 +1169,31 @@ public class ClickControl extends PamControlledUnit implements PamSettings { return targetMotionLocaliser; } + /** + * Remove clicks from existing events, if they have any. They may not. + * This is called whenever clicks are assigned to a new event to make + * sure that they don't end up in two events. + * @param markedClicks + */ + public void removeFromEvents(List markedClicks) { + if (markedClicks == null) { + return; + } + for (PamDataUnit dataUnit : markedClicks) { + OfflineEventDataUnit anEvent = (OfflineEventDataUnit) dataUnit.getSuperDetection(OfflineEventDataUnit.class); + if (anEvent == null) { + continue; + } + anEvent.removeSubDetection(dataUnit); + if (anEvent.getSubDetectionsCount() == 0) { + deleteEvent(anEvent); + } + else { + anEvent.updateDataUnit(System.currentTimeMillis()); + } + } + + } /** * Reassign all the clicks on one event to a different event @@ -1199,7 +1225,7 @@ public class ClickControl extends PamControlledUnit implements PamSettings { } clickEvent.setComment(clickEvent.getComment() + " Clicks reassigned to event " + reassignEvent.getEventId()); offlineEventDataBlock.updatePamData(clickEvent, PamCalendar.getTimeInMillis()); - offlineEventDataBlock.remove(clickEvent); + offlineEventDataBlock.remove(clickEvent, true); reassignEvent.sortSubDetections(); offlineEventDataBlock.updatePamData(reassignEvent, now); if (ClickTrainDetection.class.isAssignableFrom(reassignEvent.getClass())) { diff --git a/src/clickDetector/ClickDataBlock.java b/src/clickDetector/ClickDataBlock.java index 3e650b85..5536aa79 100644 --- a/src/clickDetector/ClickDataBlock.java +++ b/src/clickDetector/ClickDataBlock.java @@ -3,6 +3,9 @@ package clickDetector; import java.util.ListIterator; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; //import staticLocaliser.StaticLocaliserControl; //import staticLocaliser.StaticLocaliserProvider; //import staticLocaliser.panels.AbstractLocaliserControl; @@ -10,8 +13,10 @@ import pamScrollSystem.ViewLoadObserver; import alarm.AlarmCounterProvider; import alarm.AlarmDataSource; import binaryFileStorage.BinaryStore; +import clickDetector.ClickClassifiers.ClickBlockSpeciesManager; import clickDetector.dataSelector.ClickDataSelectCreator; import clickDetector.offlineFuncs.OfflineClickLogging; +import clickDetector.tethys.ClickTethysDataProvider; import clickDetector.toad.ClickTOADCalculator; import dataMap.OfflineDataMap; import fftManager.fftorganiser.FFTDataOrganiser; @@ -24,6 +29,8 @@ import PamUtils.PamUtils; import PamView.GroupedDataSource; import PamView.GroupedSourceParameters; import PamguardMVC.AcousticDataBlock; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.FFTDataHolderBlock; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; @@ -41,6 +48,8 @@ public class ClickDataBlock extends AcousticDataBlock implement private boolean isViewer; + private ClickBlockSpeciesManager clickBlockSpeciesManager; + public ClickDataBlock(ClickControl clickControl, PamProcess parentProcess, int channelMap) { @@ -65,6 +74,8 @@ public class ClickDataBlock extends AcousticDataBlock implement private ClickTOADCalculator clickTOADCalculator; + private ClickTethysDataProvider clickTethysDataProvider; + /** * Click detector loading has to be a bit different to normal - first * data are loaded from the binary store, then a subset of these data @@ -304,5 +315,26 @@ public class ClickDataBlock extends AcousticDataBlock implement } } + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (clickBlockSpeciesManager == null) { + clickBlockSpeciesManager = new ClickBlockSpeciesManager(clickControl, this); + } + return clickBlockSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (clickTethysDataProvider == null) { + clickTethysDataProvider = new ClickTethysDataProvider(tethysControl, this); + } + return clickTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + } diff --git a/src/clickDetector/ClickDisplayManager.java b/src/clickDetector/ClickDisplayManager.java index f46aeca8..f992ef2d 100644 --- a/src/clickDetector/ClickDisplayManager.java +++ b/src/clickDetector/ClickDisplayManager.java @@ -28,6 +28,7 @@ import PamController.PamSettingManager; import PamController.PamSettings; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.MenuItemEnabler; @@ -302,7 +303,7 @@ public class ClickDisplayManager implements PamSettings { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("className"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickDisplayManagerParameters2.java b/src/clickDetector/ClickDisplayManagerParameters2.java index 86ccbca6..d8fd18cf 100644 --- a/src/clickDetector/ClickDisplayManagerParameters2.java +++ b/src/clickDetector/ClickDisplayManagerParameters2.java @@ -9,6 +9,7 @@ import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ClickDisplayManagerParameters2 implements Cloneable, Serializable, ManagedParameters { @@ -181,7 +182,7 @@ public class ClickDisplayManagerParameters2 implements Cloneable, Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("initialised"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickParameters.java b/src/clickDetector/ClickParameters.java index 3146b0e4..118eaf21 100644 --- a/src/clickDetector/ClickParameters.java +++ b/src/clickDetector/ClickParameters.java @@ -38,6 +38,7 @@ import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GroupedSourceParameters; import PamView.dialog.GroupedSourcePanel; import PamView.paneloverlay.overlaymark.MarkDataSelectorParams; @@ -441,7 +442,7 @@ public class ClickParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { PamParameterData param = ps.findParameterData("dbThreshold"); param.setShortName("Detection Threshold"); diff --git a/src/clickDetector/ClickSpectrumParams.java b/src/clickDetector/ClickSpectrumParams.java index 6784c9fa..d18927e3 100644 --- a/src/clickDetector/ClickSpectrumParams.java +++ b/src/clickDetector/ClickSpectrumParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ClickSpectrumParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class ClickSpectrumParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/ClickSpectrumTemplateParams.java b/src/clickDetector/ClickSpectrumTemplateParams.java index ff156b0e..caad2b6e 100644 --- a/src/clickDetector/ClickSpectrumTemplateParams.java +++ b/src/clickDetector/ClickSpectrumTemplateParams.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; @@ -39,7 +40,7 @@ public class ClickSpectrumTemplateParams implements Serializable, Cloneable, Man @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("clickTemplateArray"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ConcatenatedSpectParams.java b/src/clickDetector/ConcatenatedSpectParams.java index 6bf67108..db3f6a0b 100644 --- a/src/clickDetector/ConcatenatedSpectParams.java +++ b/src/clickDetector/ConcatenatedSpectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.ColourArray.ColourArrayType; public class ConcatenatedSpectParams implements Serializable, Cloneable, ManagedParameters { @@ -44,7 +45,7 @@ public class ConcatenatedSpectParams implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/IDI_DisplayParams.java b/src/clickDetector/IDI_DisplayParams.java index 0198fe92..e7641768 100644 --- a/src/clickDetector/IDI_DisplayParams.java +++ b/src/clickDetector/IDI_DisplayParams.java @@ -29,6 +29,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -270,7 +271,7 @@ public class IDI_DisplayParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("saveOutput"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/TrackedClickGroupLogging.java b/src/clickDetector/TrackedClickGroupLogging.java index 6016f704..90e7af9a 100644 --- a/src/clickDetector/TrackedClickGroupLogging.java +++ b/src/clickDetector/TrackedClickGroupLogging.java @@ -1,5 +1,6 @@ package clickDetector; +import generalDatabase.PamTableDefinition; import generalDatabase.SQLTypes; import PamguardMVC.PamDataUnit; import clickDetector.offlineFuncs.OfflineEventDataUnit; @@ -30,7 +31,8 @@ public class TrackedClickGroupLogging extends ClickGroupLogging { boolean isUpdate = true; // Timestamp ts = (Timestamp) getTableDefinition().getTimeStampItem().getValue(); // long t = PamCalendar.millisFromTimeStamp(ts); - int updateIndex = (Integer) getTableDefinition().getUpdateReference().getValue(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); + int updateIndex = (Integer) tableDef.getUpdateReference().getValue(); if (updateIndex > 0) { tcg = this.clickGroupDataBlock.findByDatabaseIndex(updateIndex); } diff --git a/src/clickDetector/WignerPlotOptions.java b/src/clickDetector/WignerPlotOptions.java index 0ef46f2e..e05640a6 100644 --- a/src/clickDetector/WignerPlotOptions.java +++ b/src/clickDetector/WignerPlotOptions.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class WignerPlotOptions implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class WignerPlotOptions implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/alarm/ClickAlarmParameters.java b/src/clickDetector/alarm/ClickAlarmParameters.java index 3cc714b2..8bed53c6 100644 --- a/src/clickDetector/alarm/ClickAlarmParameters.java +++ b/src/clickDetector/alarm/ClickAlarmParameters.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.dataSelector.DataSelectParams; @@ -127,7 +128,7 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("eventTypes"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/clicktrains/ClickTrainIdParams.java b/src/clickDetector/clicktrains/ClickTrainIdParams.java index 9f9b03c2..c6d4746f 100644 --- a/src/clickDetector/clicktrains/ClickTrainIdParams.java +++ b/src/clickDetector/clicktrains/ClickTrainIdParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -59,7 +60,7 @@ public class ClickTrainIdParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("dataVersion"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java b/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java index 668fec3e..a8cc198c 100644 --- a/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java +++ b/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java @@ -8,6 +8,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.dataSelector.DataSelectParams; @@ -91,7 +92,7 @@ public class ClickTrainDataSelect2Params extends DataSelectParams implements Clo @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("wantType"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/dataSelector/ClickTrainDataSelector2.java b/src/clickDetector/dataSelector/ClickTrainDataSelector2.java index 0520b4fb..9bde5123 100644 --- a/src/clickDetector/dataSelector/ClickTrainDataSelector2.java +++ b/src/clickDetector/dataSelector/ClickTrainDataSelector2.java @@ -82,7 +82,7 @@ public class ClickTrainDataSelector2 extends DataSelector { } SQLLogging logging = getPamDataBlock().getLogging(); if (logging == null) return null; //cannot happen! - PamTableDefinition tableDef = logging.getTableDefinition(); + EmptyTableDefinition tableDef = logging.getTableDefinition(); if (params.isIncludeUnclassified()) { return null; } diff --git a/src/clickDetector/dataSelector/ClickTrainSelectParameters.java b/src/clickDetector/dataSelector/ClickTrainSelectParameters.java index 3cfc5189..75462778 100644 --- a/src/clickDetector/dataSelector/ClickTrainSelectParameters.java +++ b/src/clickDetector/dataSelector/ClickTrainSelectParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; import clickDetector.ClickParameters; @@ -32,7 +33,7 @@ public class ClickTrainSelectParameters extends DataSelectParams implements Seri @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/echoDetection/JamieEchoParams.java b/src/clickDetector/echoDetection/JamieEchoParams.java index ec00df42..e3cbadb5 100644 --- a/src/clickDetector/echoDetection/JamieEchoParams.java +++ b/src/clickDetector/echoDetection/JamieEchoParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class JamieEchoParams implements Serializable, Cloneable, ManagedParameters { @@ -31,7 +32,7 @@ public static final long serialVersionUID = 3L; @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/echoDetection/SimpleEchoParams.java b/src/clickDetector/echoDetection/SimpleEchoParams.java index fe5eae8e..eb6095a1 100644 --- a/src/clickDetector/echoDetection/SimpleEchoParams.java +++ b/src/clickDetector/echoDetection/SimpleEchoParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SimpleEchoParams implements Serializable, Cloneable, ManagedParameters { @@ -26,7 +27,7 @@ public class SimpleEchoParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java index e11aec29..a86f27f5 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java @@ -1628,8 +1628,6 @@ public class SweepClassifierSetPaneFX extends SettingsPane { p.setLayout(new GridBagLayout()); GridBagConstraints c = new PamGridBagContraints(); - - // c.gridx = 0; // addComponent(p, enableBearings, c); // c.gridx += c.gridwidth; @@ -1736,7 +1734,6 @@ public class SweepClassifierSetPaneFX extends SettingsPane { // } // } // } -// else multiChan = true; // Debug.out.println("Check multi-channel: " + multiChan); return multiChan; diff --git a/src/clickDetector/localisation/ClickLocParams.java b/src/clickDetector/localisation/ClickLocParams.java index fcfaaff6..6a597258 100644 --- a/src/clickDetector/localisation/ClickLocParams.java +++ b/src/clickDetector/localisation/ClickLocParams.java @@ -7,6 +7,7 @@ import java.util.Arrays; import Localiser.detectionGroupLocaliser.DetectionGroupOptions; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class ClickLocParams implements Serializable, Cloneable, DetectionGroupOptions, ManagedParameters { @@ -110,7 +111,7 @@ public class ClickLocParams implements Serializable, Cloneable, DetectionGroupOp @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("internalVersion"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/offlineFuncs/ClicksOffline.java b/src/clickDetector/offlineFuncs/ClicksOffline.java index 4423c721..6b72da91 100644 --- a/src/clickDetector/offlineFuncs/ClicksOffline.java +++ b/src/clickDetector/offlineFuncs/ClicksOffline.java @@ -632,6 +632,7 @@ public class ClicksOffline { OfflineEventDataUnit newUnit = new OfflineEventDataUnit(null, getNextEventColourIndex(), null); newUnit = OfflineEventDialog.showDialog(win, clickControl, newUnit); if (newUnit != null) { + clickControl.removeFromEvents(markedClicks); newUnit.addSubDetections(markedClicks); offlineEventDataBlock.addPamData(newUnit); clickControl.setLatestOfflineEvent(newUnit); diff --git a/src/clickDetector/offlineFuncs/DatabaseChecks.java b/src/clickDetector/offlineFuncs/DatabaseChecks.java index 38bfe6a5..585bbf50 100644 --- a/src/clickDetector/offlineFuncs/DatabaseChecks.java +++ b/src/clickDetector/offlineFuncs/DatabaseChecks.java @@ -102,16 +102,17 @@ public class DatabaseChecks { long resultTime; long firstTime = Long.MAX_VALUE; long lastTime = Long.MIN_VALUE; + PamTableDefinition pamTableDef = (PamTableDefinition) clickLogging.getTableDefinition(); try { Statement stmt = con.getConnection().createStatement(); ResultSet result = stmt.executeQuery(sqlStr); while (result.next()) { nClicks++; clickLogging.transferDataFromResult(sqlTypes, result); - ts = clickLogging.getTableDefinition().getTimeStampItem().getValue(); + ts = pamTableDef.getTimeStampItem().getValue(); resultTime = sqlTypes.millisFromTimeStamp(ts); if (resultTime%1000 == 0) { - resultTime += clickLogging.getTableDefinition().getTimeStampMillis().getIntegerValue(); + resultTime += pamTableDef.getTimeStampMillis().getIntegerValue(); } firstTime = Math.min(firstTime, resultTime); lastTime = Math.max(lastTime, resultTime); @@ -188,7 +189,7 @@ public class DatabaseChecks { eventDataBlock.addPamData(event); PamConnection con = DBControlUnit.findConnection(); // now find a cursor and save it. - PamTableDefinition eventTableDef = eventDataBlock.getLogging().getTableDefinition(); + PamTableDefinition eventTableDef = (PamTableDefinition) eventDataBlock.getLogging().getTableDefinition(); PamCursor cursor = eventDataBlock.getLogging().getViewerCursorFinder().getCursor(con, eventTableDef); cursor.immediateInsert(con); int newId = event.getDatabaseIndex(); diff --git a/src/clickDetector/offlineFuncs/LabelClicksDialog.java b/src/clickDetector/offlineFuncs/LabelClicksDialog.java index 0e25b495..113f7864 100644 --- a/src/clickDetector/offlineFuncs/LabelClicksDialog.java +++ b/src/clickDetector/offlineFuncs/LabelClicksDialog.java @@ -146,6 +146,7 @@ public class LabelClicksDialog extends PamDialog { * @param thenClose option to close dialog */ private void addClicksToEvent(OfflineEventDataUnit event, boolean thenClose) { + removeFromOldEvent(markedClicks); event.addSubDetections(markedClicks); offlineEventListPanel.tableDataChanged(); clickControl.setLatestOfflineEvent(event); @@ -154,6 +155,15 @@ public class LabelClicksDialog extends PamDialog { } } + /** + * clicks may have already been part of an event, so need to remove them from that + * event first, and if there is nothing left in that event, delete the event. + * @param markedClicks2 + */ + private void removeFromOldEvent(List markedClicks) { + clickControl.removeFromEvents(markedClicks); + } + @Override public void restoreDefaultSettings() { // TODO Auto-generated method stub diff --git a/src/clickDetector/offlineFuncs/OfflineClickLogging.java b/src/clickDetector/offlineFuncs/OfflineClickLogging.java index a75897f7..43a73fea 100644 --- a/src/clickDetector/offlineFuncs/OfflineClickLogging.java +++ b/src/clickDetector/offlineFuncs/OfflineClickLogging.java @@ -51,7 +51,7 @@ public class OfflineClickLogging extends SQLLogging { tableDef.addTableItem(clickNumber = new PamTableItem("ClickNo", Types.INTEGER)); tableDef.addTableItem(amplitude = new PamTableItem("Amplitude", Types.DOUBLE)); tableDef.addTableItem(channelNumbers = new PamTableItem("Channels", Types.INTEGER)); - tableDef.setUseCheatIndexing(true); + tableDef.setUseCheatIndexing(false); setTableDefinition(tableDef); } @@ -277,13 +277,14 @@ public class OfflineClickLogging extends SQLLogging { Integer millis; Object ts; SQLTypes sqlTypes = dbControl.getConnection().getSqlTypes(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); try { while (resultSet.next()) { transferDataFromResult(sqlTypes, resultSet); - ts = getTableDefinition().getTimeStampItem().getValue(); + ts = tableDef.getTimeStampItem().getValue(); long m = SQLTypes.millisFromTimeStamp(ts); if (m%1000 == 0) { - millis = (Integer) getTableDefinition().getTimeStampMillis().getValue(); + millis = (Integer) tableDef.getTimeStampMillis().getValue(); if (millis != null) { m += millis; } diff --git a/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java b/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java index 4af5872b..afc60ec7 100644 --- a/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java +++ b/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java @@ -16,6 +16,10 @@ import PamController.PamViewParameters; import PamUtils.PamCalendar; import PamView.symbol.StandardSymbolManager; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; +import clickDetector.ClickDetection; //import staticLocaliser.StaticLocaliserControl; //import staticLocaliser.StaticLocaliserProvider; //import staticLocaliser.panels.AbstractLocaliserControl; @@ -23,7 +27,12 @@ import pamScrollSystem.ViewLoadObserver; import clickDetector.ClickDetector; import clickDetector.ClickTrainDetection; import clickDetector.dataSelector.ClickTrainDataSelectorCreator; +import clickDetector.tethys.ClickEventSpeciesManager; +import clickDetector.tethys.ClickEventTethysDataProvider; +import clickDetector.tethys.ClickTethysDataProvider; import dataMap.OfflineDataMap; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.dataOffline.OfflineDataLoadInfo; @@ -49,6 +58,8 @@ public class OfflineEventDataBlock extends SuperDetDataBlock getDatablockSpeciesManager() { + if (eventSpeciesManager == null) { + eventSpeciesManager = new ClickEventSpeciesManager(clickDetector, this); + } + return eventSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (eventTethysDataProvider == null) { + eventTethysDataProvider = new ClickEventTethysDataProvider(tethysControl, this); + } + return eventTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.MANUALANDAUTOMATIC); + } + } diff --git a/src/clickDetector/offlineFuncs/OfflineParameters.java b/src/clickDetector/offlineFuncs/OfflineParameters.java index 2ab82962..0c4b2c71 100644 --- a/src/clickDetector/offlineFuncs/OfflineParameters.java +++ b/src/clickDetector/offlineFuncs/OfflineParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OfflineParameters implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class OfflineParameters implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java b/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java index d4fb6fb2..0b9b0996 100644 --- a/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java +++ b/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java @@ -148,7 +148,7 @@ public class RainbowDatabseConverter { ClickDataBlock clickDataBlock = clickControl.getClickDataBlock(); clickLogging = new ClickImportLogging(clickControl); - PamTableDefinition tableDef = clickLogging.getTableDefinition(); + PamTableDefinition tableDef = (PamTableDefinition) clickLogging.getTableDefinition(); boolean ok = checkTable(pamConnection, tableDef); if (!ok) { System.out.println("Error in Pamguard clicks table"); @@ -156,7 +156,7 @@ public class RainbowDatabseConverter { } eventLogging = new OfflineEventLogging(clickControl, clickControl.getClickDetector().getOfflineEventDataBlock()); - tableDef = eventLogging.getTableDefinition(); + tableDef = (PamTableDefinition) eventLogging.getTableDefinition(); ok = checkTable(pamConnection, tableDef); if (!ok) { System.out.println("Error in Pamguard events table"); diff --git a/src/clickDetector/tethys/ClickEventSpeciesManager.java b/src/clickDetector/tethys/ClickEventSpeciesManager.java new file mode 100644 index 00000000..c0ee92fd --- /dev/null +++ b/src/clickDetector/tethys/ClickEventSpeciesManager.java @@ -0,0 +1,57 @@ +package clickDetector.tethys; + +import java.util.Vector; + +import PamguardMVC.PamDataUnit; +import clickDetector.ClickControl; +import clickDetector.ClickDetector; +import clickDetector.offlineFuncs.ClicksOffline; +import clickDetector.offlineFuncs.OfflineEventDataBlock; +import clickDetector.offlineFuncs.OfflineEventDataUnit; +import generalDatabase.lookupTables.LookUpTables; +import generalDatabase.lookupTables.LookupItem; +import generalDatabase.lookupTables.LookupList; +import tethys.species.DataBlockSpeciesCodes; +import tethys.species.DataBlockSpeciesManager; + +public class ClickEventSpeciesManager extends DataBlockSpeciesManager { + + private OfflineEventDataBlock eventDataBlock; + private ClickDetector clickDetector; + private ClickControl clickControl; + private ClicksOffline clicksOffline; + + public ClickEventSpeciesManager(ClickDetector clickDetector, OfflineEventDataBlock eventDataBlock) { + super(eventDataBlock); + this.clickDetector = clickDetector; + this.eventDataBlock = eventDataBlock; + clickControl = clickDetector.getClickControl(); + clicksOffline = clickControl.getClicksOffline(); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + LookupList lutList = LookUpTables.getLookUpTables().getLookupList(ClicksOffline.ClickTypeLookupName); + if (lutList == null || lutList.getLutList().size() == 0) { + return new DataBlockSpeciesCodes("Unknown"); + } + Vector spList = lutList.getLutList(); + String[] spNames = new String[spList.size()]; + int i = 0; + for (LookupItem lItem : spList) { + spNames[i++] = lItem.getCode(); + } + return new DataBlockSpeciesCodes("Unknown", spNames); + } + + @Override + public String getSpeciesCode(PamDataUnit dataUnit) { + OfflineEventDataUnit eventDataUnit = (OfflineEventDataUnit) dataUnit; + String eventType = eventDataUnit.getEventType(); + if (eventType == null) { + eventType = "Unknown"; + } + return eventType; + } + +} diff --git a/src/clickDetector/tethys/ClickEventTethysDataProvider.java b/src/clickDetector/tethys/ClickEventTethysDataProvider.java new file mode 100644 index 00000000..bbc5d1fd --- /dev/null +++ b/src/clickDetector/tethys/ClickEventTethysDataProvider.java @@ -0,0 +1,72 @@ +package clickDetector.tethys; + +import java.math.BigInteger; + +import PamguardMVC.PamDataUnit; +import clickDetector.offlineFuncs.OfflineEventDataBlock; +import clickDetector.offlineFuncs.OfflineEventDataUnit; +import nilus.Detection; +import nilus.GranularityEnumType; +import nilus.Detection.Parameters; +import nilus.Detection.Parameters.UserDefined; +import tethys.TethysControl; +import tethys.output.StreamExportParams; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; +import tethys.swing.export.ExportWizardCard; +import tethys.swing.export.GranularityCard; + +public class ClickEventTethysDataProvider extends AutoTethysProvider { + + private OfflineEventDataBlock eventDataBlock; + + public ClickEventTethysDataProvider(TethysControl tethysControl, OfflineEventDataBlock eventDataBlock) { + super(tethysControl, eventDataBlock); + this.eventDataBlock = eventDataBlock; + } + + @Override + public GranularityEnumType[] getAllowedGranularities() { + GranularityEnumType[] allowed = {GranularityEnumType.GROUPED}; + return allowed; + } + @Override + public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams, + StreamExportParams streamExportParams) { + Detection detection = super.createDetection(dataUnit, tethysExportParams, streamExportParams); + if (detection == null) { + return null; + } + OfflineEventDataUnit eventDataUnit = (OfflineEventDataUnit) dataUnit; + detection.setCount(BigInteger.valueOf(eventDataUnit.getSubDetectionsCount())); + String comment = eventDataUnit.getComment(); + if (comment != null && comment.length() > 0) { + detection.setComment(comment); + } + Parameters params = detection.getParameters(); + addUserNumber(params, "MinNumber", eventDataUnit.getMinNumber()); + addUserNumber(params, "BestNumber", eventDataUnit.getBestNumber()); + addUserNumber(params, "MaxNumber", eventDataUnit.getMaxNumber()); + + + return detection; + } + + private void addUserNumber(Parameters params, String numName, Short number) { + if (number == null) { + return; + } + addUserDefined(params, numName, number.toString()); + } + + @Override + public boolean wantExportDialogCard(ExportWizardCard wizPanel) { + if (wizPanel.getClass() == GranularityCard.class) { + return false; + } + else { + return true; + } + } + +} diff --git a/src/clickDetector/tethys/ClickTethysDataProvider.java b/src/clickDetector/tethys/ClickTethysDataProvider.java new file mode 100644 index 00000000..44e1c8c8 --- /dev/null +++ b/src/clickDetector/tethys/ClickTethysDataProvider.java @@ -0,0 +1,22 @@ +package clickDetector.tethys; + +import clickDetector.ClickDataBlock; +import nilus.GranularityEnumType; +import tethys.TethysControl; +import tethys.pamdata.AutoTethysProvider; + +public class ClickTethysDataProvider extends AutoTethysProvider { + + private ClickDataBlock clickDataBlock; + + public ClickTethysDataProvider(TethysControl tethysControl, ClickDataBlock clickDataBlock) { + super(tethysControl, clickDataBlock); + this.clickDataBlock = clickDataBlock; + } + + @Override + public GranularityEnumType[] getAllowedGranularities() { + return GranularityEnumType.values(); // everything ! + } + +} diff --git a/src/clickTrainDetector/ClickTrainParams.java b/src/clickTrainDetector/ClickTrainParams.java index 1200883d..0a3663b9 100644 --- a/src/clickTrainDetector/ClickTrainParams.java +++ b/src/clickTrainDetector/ClickTrainParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import clickTrainDetector.classification.CTClassifierParams; import clickTrainDetector.classification.simplechi2classifier.Chi2ThresholdParams; @@ -127,7 +128,7 @@ public class ClickTrainParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/classification/CTClassifierParams.java b/src/clickTrainDetector/classification/CTClassifierParams.java index 91d4e8a7..64fa96e9 100644 --- a/src/clickTrainDetector/classification/CTClassifierParams.java +++ b/src/clickTrainDetector/classification/CTClassifierParams.java @@ -5,6 +5,7 @@ import java.util.UUID; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; @@ -68,7 +69,7 @@ public class CTClassifierParams implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java b/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java index 83a326c8..b3e26d12 100644 --- a/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java +++ b/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -53,7 +54,7 @@ public class SpectrumTemplateParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java index 499fee9f..046c6478 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters class must extend this. @@ -38,7 +39,7 @@ public class MHTChi2Params implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java index 964073dc..d40d95e0 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Options for the MHT algorithm @@ -63,7 +64,7 @@ public class MHTKernelParams implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java index 06f6e6f4..cd75fc67 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters for the MHT algorithm, contains two serializable parameter @@ -47,7 +48,7 @@ public class MHTParams implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java index 6a6c3611..8773e368 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -29,7 +30,7 @@ public class SimpleElectricalNoiseParams implements Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java index 94a578df..01b877d5 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters class for a simple chi2 variable. Contains the expected error in the @@ -194,7 +195,7 @@ public class SimpleChi2VarParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/dataselector/CTSelectParams.java b/src/clickTrainDetector/dataselector/CTSelectParams.java index 5343f020..fa6f26dd 100644 --- a/src/clickTrainDetector/dataselector/CTSelectParams.java +++ b/src/clickTrainDetector/dataselector/CTSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; import clickDetector.dataSelector.ClickTrainSelectParameters; @@ -93,7 +94,7 @@ public class CTSelectParams extends DataSelectParams implements Serializable, Cl @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clipgenerator/ClipGenSetting.java b/src/clipgenerator/ClipGenSetting.java index ee834658..eb0dd0e0 100644 --- a/src/clipgenerator/ClipGenSetting.java +++ b/src/clipgenerator/ClipGenSetting.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -115,7 +116,7 @@ public class ClipGenSetting implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("hadMapLine"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clipgenerator/ClipSettings.java b/src/clipgenerator/ClipSettings.java index 8636600a..aada971c 100644 --- a/src/clipgenerator/ClipSettings.java +++ b/src/clipgenerator/ClipSettings.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -135,7 +136,7 @@ public class ClipSettings implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("clipGenSettings"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clipgenerator/clipDisplay/ClipDisplayParameters.java b/src/clipgenerator/clipDisplay/ClipDisplayParameters.java index 15571e2d..15858716 100644 --- a/src/clipgenerator/clipDisplay/ClipDisplayParameters.java +++ b/src/clipgenerator/clipDisplay/ClipDisplayParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.ColourArray.ColourArrayType; @@ -88,7 +89,7 @@ public class ClipDisplayParameters implements Cloneable, Serializable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("maxClips"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/crossedbearinglocaliser/CBLocaliserSettngs.java b/src/crossedbearinglocaliser/CBLocaliserSettngs.java index e296f276..a323eee3 100644 --- a/src/crossedbearinglocaliser/CBLocaliserSettngs.java +++ b/src/crossedbearinglocaliser/CBLocaliserSettngs.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamDataBlock; import annotation.localise.targetmotion.TMAnnotationOptions; @@ -78,7 +79,7 @@ public class CBLocaliserSettngs implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/d3/D3DataMapPoint.java b/src/d3/D3DataMapPoint.java index c42595f2..78962aa1 100644 --- a/src/d3/D3DataMapPoint.java +++ b/src/d3/D3DataMapPoint.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import fileOfflineData.OfflineFileMapPoint; @@ -30,7 +31,7 @@ public class D3DataMapPoint extends OfflineFileMapPoint implements ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fileOffsetStart"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataGram/Datagram.java b/src/dataGram/Datagram.java index 33b72d42..eaafcf3f 100644 --- a/src/dataGram/Datagram.java +++ b/src/dataGram/Datagram.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryTypes; import dataMap.OfflineDataMapPoint; @@ -175,7 +176,7 @@ public class Datagram implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataGram/DatagramDataPoint.java b/src/dataGram/DatagramDataPoint.java index 92da4033..dc27f4c6 100644 --- a/src/dataGram/DatagramDataPoint.java +++ b/src/dataGram/DatagramDataPoint.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DatagramDataPoint implements Serializable, ManagedParameters { @@ -89,7 +90,7 @@ public class DatagramDataPoint implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nDataUnits"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataGram/DatagramSettings.java b/src/dataGram/DatagramSettings.java index e466d55d..a3b5a4df 100644 --- a/src/dataGram/DatagramSettings.java +++ b/src/dataGram/DatagramSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DatagramSettings implements Serializable, Cloneable, ManagedParameters { @@ -33,7 +34,7 @@ public class DatagramSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataMap/DataMapParameters.java b/src/dataMap/DataMapParameters.java index 22eed747..cd714199 100644 --- a/src/dataMap/DataMapParameters.java +++ b/src/dataMap/DataMapParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataMapParameters implements Cloneable, Serializable, ManagedParameters { @@ -36,7 +37,7 @@ public class DataMapParameters implements Cloneable, Serializable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataMap/DataStreamPanel.java b/src/dataMap/DataStreamPanel.java index 957eadfd..275be1f5 100644 --- a/src/dataMap/DataStreamPanel.java +++ b/src/dataMap/DataStreamPanel.java @@ -747,11 +747,20 @@ public class DataStreamPanel extends JPanel implements DataMapObserver { String tipText; if (startTimeArrow != null && startTimeArrow.contains(me.getPoint())) { - tipText = "Data Start: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataStart(), true); + tipText = "Data Start: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataStart(), false); } else if (endTimeArrow != null && endTimeArrow.contains(me.getPoint())) { - tipText = "Data End: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataEnd(), true); + tipText = "Data End: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataEnd(), false); } else { - tipText = "Cursor: " + PamCalendar.formatDateTime(tm, true); + OfflineDataMap dMap = dataBlock.getPrimaryDataMap(); + if (dMap != null) { + tipText = String.format("%s Data from

    %s to %s

    Cursor: %s", dataBlock.getDataName(), + PamCalendar.formatDateTime(dMap.getFirstDataTime(), false), + PamCalendar.formatDateTime(dMap.getLastDataTime(), false), + PamCalendar.formatDateTime(tm, true)); + } + else { + tipText = "Cursor: " + PamCalendar.formatDateTime(tm, true); + } } // tipText += "
    Panel height = " + getHeight(); diff --git a/src/dataMap/OfflineDataMap.java b/src/dataMap/OfflineDataMap.java index 2295af01..d51ee120 100644 --- a/src/dataMap/OfflineDataMap.java +++ b/src/dataMap/OfflineDataMap.java @@ -84,6 +84,8 @@ abstract public class OfflineDataMap { public static final int POINT_END = 0x8; // 8 public static final int IN_DATA = 0x10; // 16 public static final int NO_DATA = 0x20; // 32 + + private static final long oneDayInMillis = 3600L*24L*1000L; public OfflineDataMap(OfflineDataStore offlineDataStore, PamDataBlock parentDataBlock) { super(); @@ -145,10 +147,10 @@ abstract public class OfflineDataMap { */ synchronized public void addDataPoint(TmapPoint mapPoint) { boolean first = (mapPoints.size() == 0); - if (mapPoint.getStartTime() > 0) { + if (mapPoint.getStartTime() > oneDayInMillis) { firstDataTime = Math.min(firstDataTime, mapPoint.getStartTime()); } - if (mapPoint.getEndTime() > 0) { + if (mapPoint.getEndTime() > oneDayInMillis) { lastDataTime = Math.max(lastDataTime, mapPoint.getEndTime()); // if (mapPoint.getEndTime() > System.currentTimeMillis()) { // System.out.println("Stupid large data time in " + mapPoint.getName()); @@ -273,10 +275,10 @@ abstract public class OfflineDataMap { while (it.hasNext()) { aPoint = it.next(); - if (aPoint.getStartTime() > 0) { + if (aPoint.getStartTime() > oneDayInMillis) { firstDataTime = Math.min(firstDataTime, aPoint.getStartTime()); } - if (aPoint.getEndTime() > 0) { + if (aPoint.getEndTime() > oneDayInMillis) { lastDataTime = Math.max(lastDataTime, aPoint.getEndTime()); } n = aPoint.getNDatas(); @@ -361,6 +363,28 @@ abstract public class OfflineDataMap { } } + /** + * Get the start time of the first datamap point or Long.minval + * @return + */ + public long getMapStartTime() { + if (mapPoints == null || mapPoints.size() == 0) { + return Long.MIN_VALUE; + } + return mapPoints.get(0).getStartTime(); + } + + /** + * Get the start time of the first datamap point or Long.minval + * @return + */ + public long getMapEndTime() { + if (mapPoints == null || mapPoints.size() == 0) { + return Long.MIN_VALUE; + } + return mapPoints.get(mapPoints.size()-1).getEndTime(); + } + /** * @return the lowestPoint */ diff --git a/src/dataMap/OfflineDataMapPoint.java b/src/dataMap/OfflineDataMapPoint.java index af9e1910..d1e8917c 100644 --- a/src/dataMap/OfflineDataMapPoint.java +++ b/src/dataMap/OfflineDataMapPoint.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; /** @@ -251,7 +252,7 @@ abstract public class OfflineDataMapPoint implements Comparable impl // TODO Auto-generated method stub return "Sound Files"; } + + @Override + public String getDataLocation() { + getOfflineFileParameters(); + return offlineFileParameters.folderName; + } public TmapPoint findFirstMapPoint(Iterator mapIterator, long startMillis, long endMillis) { TmapPoint mapPoint, prevMapPoint = null; diff --git a/src/dataPlots/TDParameters.java b/src/dataPlots/TDParameters.java index 80d67871..bb7f14db 100644 --- a/src/dataPlots/TDParameters.java +++ b/src/dataPlots/TDParameters.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlots.layout.GraphParameters; import pamScrollSystem.PamScroller; @@ -45,7 +46,7 @@ public class TDParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlots/layout/DataListInfo.java b/src/dataPlots/layout/DataListInfo.java index 05edd3f8..d506fe64 100644 --- a/src/dataPlots/layout/DataListInfo.java +++ b/src/dataPlots/layout/DataListInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * TDDataInfo objects can't be serialised since they contain @@ -44,7 +45,7 @@ public class DataListInfo implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlots/layout/GraphParameters.java b/src/dataPlots/layout/GraphParameters.java index f505422e..5fc3fe2a 100644 --- a/src/dataPlots/layout/GraphParameters.java +++ b/src/dataPlots/layout/GraphParameters.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import dataPlots.data.TDDataInfo; @@ -41,7 +42,7 @@ public class GraphParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("dataListInfos"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/TDGraphParametersFX.java b/src/dataPlotsFX/TDGraphParametersFX.java index c4d6de46..f3f6c691 100644 --- a/src/dataPlotsFX/TDGraphParametersFX.java +++ b/src/dataPlotsFX/TDGraphParametersFX.java @@ -8,6 +8,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GeneralProjector.ParameterType; import PamView.GeneralProjector.ParameterUnits; import javafx.scene.paint.Color; @@ -137,7 +138,7 @@ public class TDGraphParametersFX implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("channels"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/TDParametersFX.java b/src/dataPlotsFX/TDParametersFX.java index c87320bc..8b614dcc 100644 --- a/src/dataPlotsFX/TDParametersFX.java +++ b/src/dataPlotsFX/TDParametersFX.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.geometry.Orientation; import userDisplayFX.UserDisplayNodeParams; @@ -122,7 +123,7 @@ public class TDParametersFX implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/data/TDScaleInfoData.java b/src/dataPlotsFX/data/TDScaleInfoData.java index a0d54dba..9cd2ea3c 100644 --- a/src/dataPlotsFX/data/TDScaleInfoData.java +++ b/src/dataPlotsFX/data/TDScaleInfoData.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -105,7 +106,7 @@ public class TDScaleInfoData implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("autoDivisor"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java b/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java index 388ea462..ec6a1030 100644 --- a/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java +++ b/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -48,7 +49,7 @@ public class FFTPlotSettings implements ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java b/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java index c39aeb96..de80f049 100644 --- a/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java +++ b/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlotsFX.scrollingPlot2D.StandardPlot2DColours; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -55,7 +56,7 @@ public class TDAcousticScrollerParams implements Cloneable, Serializable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java b/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java index 159fa2ad..40aed7c7 100644 --- a/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java +++ b/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.scene.paint.Color; @@ -156,7 +157,7 @@ public class PlotParams2D implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java b/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java index 7aafc8ad..a8f2faa2 100644 --- a/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java +++ b/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlotsFX.scrollingPlot2D.PlotParams2D; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; import javafx.beans.property.DoubleProperty; @@ -125,7 +126,7 @@ public class SpectrogramParamsFX extends PlotParams2D implements Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dbht/DbHtDisplayParams.java b/src/dbht/DbHtDisplayParams.java index 61e8386c..fb7cab16 100644 --- a/src/dbht/DbHtDisplayParams.java +++ b/src/dbht/DbHtDisplayParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DbHtDisplayParams implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public class DbHtDisplayParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dbht/DbHtParameters.java b/src/dbht/DbHtParameters.java index 7ef321f7..2e32bb3e 100644 --- a/src/dbht/DbHtParameters.java +++ b/src/dbht/DbHtParameters.java @@ -9,6 +9,7 @@ import PamModel.parametermanager.FieldNotFoundException; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DbHtParameters implements Serializable, Cloneable, ManagedParameters { @@ -186,7 +187,7 @@ public class DbHtParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("frequencyPoints"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dbht/alarm/DbHtAlarmParameters.java b/src/dbht/alarm/DbHtAlarmParameters.java index beb98589..5023e1ae 100644 --- a/src/dbht/alarm/DbHtAlarmParameters.java +++ b/src/dbht/alarm/DbHtAlarmParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DbHtAlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class DbHtAlarmParameters implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("returnedMeasure"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dbht/offline/DbHtSummaryParams.java b/src/dbht/offline/DbHtSummaryParams.java index b77adf17..34c4951a 100644 --- a/src/dbht/offline/DbHtSummaryParams.java +++ b/src/dbht/offline/DbHtSummaryParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DbHtSummaryParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class DbHtSummaryParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/decimator/DecimatorControl.java b/src/decimator/DecimatorControl.java index 7bf9f8ac..1b7d2758 100644 --- a/src/decimator/DecimatorControl.java +++ b/src/decimator/DecimatorControl.java @@ -193,6 +193,15 @@ public class DecimatorControl extends PamControlledUnit implements PamSettings, } return offlineFileServer.getDataSourceName(); } + + @Override + public String getDataLocation() { + if (offlineFileServer == null) { + return getUnitName(); + } + return offlineFileServer.getDataLocation(); + } + @Override public boolean loadData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) { if (offlineFileServer == null) { diff --git a/src/decimator/DecimatorParams.java b/src/decimator/DecimatorParams.java index 8fe72caf..472d758a 100644 --- a/src/decimator/DecimatorParams.java +++ b/src/decimator/DecimatorParams.java @@ -26,6 +26,7 @@ import Filters.FilterBand; import Filters.FilterParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DecimatorParams implements Serializable, Cloneable, ManagedParameters { @@ -102,7 +103,7 @@ public class DecimatorParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/depthReadout/DepthParameters.java b/src/depthReadout/DepthParameters.java index 1e40df4e..99dcdd25 100644 --- a/src/depthReadout/DepthParameters.java +++ b/src/depthReadout/DepthParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DepthParameters implements Serializable, Cloneable, ManagedParameters { @@ -37,7 +38,7 @@ public class DepthParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/depthReadout/MccDepthParameters.java b/src/depthReadout/MccDepthParameters.java index 7859a1a7..d027670a 100644 --- a/src/depthReadout/MccDepthParameters.java +++ b/src/depthReadout/MccDepthParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import mcc.MccJniInterface; import mcc.mccjna.MCCConstants; @@ -44,7 +45,7 @@ public class MccDepthParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } @@ -62,7 +63,7 @@ public class MccDepthParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("mccSensorParameters"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/detectionPlotFX/plots/FFTPlotParams.java b/src/detectionPlotFX/plots/FFTPlotParams.java index 483f9051..3b8a428d 100644 --- a/src/detectionPlotFX/plots/FFTPlotParams.java +++ b/src/detectionPlotFX/plots/FFTPlotParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; public class FFTPlotParams implements Serializable, Cloneable, ManagedParameters { @@ -98,7 +99,7 @@ public class FFTPlotParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/SpectrumPlotParams.java b/src/detectionPlotFX/plots/SpectrumPlotParams.java index 36d1807e..c0790a9a 100644 --- a/src/detectionPlotFX/plots/SpectrumPlotParams.java +++ b/src/detectionPlotFX/plots/SpectrumPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SpectrumPlotParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class SpectrumPlotParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/WaveformPlotParams.java b/src/detectionPlotFX/plots/WaveformPlotParams.java index 0c631272..fefc68b5 100644 --- a/src/detectionPlotFX/plots/WaveformPlotParams.java +++ b/src/detectionPlotFX/plots/WaveformPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import depthReadout.DepthParameters; import fftFilter.FFTFilterParams; @@ -63,7 +64,7 @@ public class WaveformPlotParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/WignerPlotParams.java b/src/detectionPlotFX/plots/WignerPlotParams.java index 0dece899..15f38498 100644 --- a/src/detectionPlotFX/plots/WignerPlotParams.java +++ b/src/detectionPlotFX/plots/WignerPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -51,7 +52,7 @@ public class WignerPlotParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectiongrouplocaliser/DetectionGroupSettings.java b/src/detectiongrouplocaliser/DetectionGroupSettings.java index 318d2b8c..3bc28816 100644 --- a/src/detectiongrouplocaliser/DetectionGroupSettings.java +++ b/src/detectiongrouplocaliser/DetectionGroupSettings.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.paneloverlay.overlaymark.OverlayMarkDataInfo; import annotation.handler.AnnotationChoices; @@ -109,7 +110,7 @@ public class DetectionGroupSettings implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("overlayMarkInfo"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/difar/DifarParameters.java b/src/difar/DifarParameters.java index c54774e9..b8b8dc8c 100644 --- a/src/difar/DifarParameters.java +++ b/src/difar/DifarParameters.java @@ -15,6 +15,7 @@ import Filters.FilterType; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.PamCalendar; import PamView.PamGui; @@ -588,7 +589,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } @@ -659,7 +660,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } @@ -773,7 +774,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("groupList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/difar/beamforming/BeamformControl.java b/src/difar/beamforming/BeamformControl.java index edf3507b..bf04ea05 100644 --- a/src/difar/beamforming/BeamformControl.java +++ b/src/difar/beamforming/BeamformControl.java @@ -88,6 +88,16 @@ public class BeamformControl extends PamControlledUnit implements PamSettings, O return DifarParameters.serialVersionUID; } + @Override + public String getDataLocation() { + if (offlineFileServer != null) { + return offlineFileServer.getDataLocation(); + } + else { + return null; + } + } + @Override public boolean restoreSettings( PamControlledUnitSettings pamControlledUnitSettings) { diff --git a/src/difar/beamforming/BeamformParameters.java b/src/difar/beamforming/BeamformParameters.java index 6688d309..2d65e576 100644 --- a/src/difar/beamforming/BeamformParameters.java +++ b/src/difar/beamforming/BeamformParameters.java @@ -5,6 +5,8 @@ import Filters.FilterParams; import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; +import PamUtils.DeepCloner; import PamUtils.PamUtils; public class BeamformParameters implements Serializable, Cloneable, ManagedParameters { @@ -110,7 +112,7 @@ public class BeamformParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/dataSelector/DifarSelectParameters.java b/src/difar/dataSelector/DifarSelectParameters.java index bc9814ad..af1c703e 100644 --- a/src/difar/dataSelector/DifarSelectParameters.java +++ b/src/difar/dataSelector/DifarSelectParameters.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamguardMVC.dataSelector.DataSelectParams; @@ -61,7 +62,7 @@ public class DifarSelectParameters extends DataSelectParams implements Cloneable @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/demux/GreenridgeParams.java b/src/difar/demux/GreenridgeParams.java index d86fa2da..470357df 100644 --- a/src/difar/demux/GreenridgeParams.java +++ b/src/difar/demux/GreenridgeParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GreenridgeParams implements Serializable, Cloneable, ManagedParameters { @@ -144,7 +145,7 @@ public class GreenridgeParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/trackedGroups/TrackedGroupSqlLogging.java b/src/difar/trackedGroups/TrackedGroupSqlLogging.java index 54bd708b..e3b8b15b 100644 --- a/src/difar/trackedGroups/TrackedGroupSqlLogging.java +++ b/src/difar/trackedGroups/TrackedGroupSqlLogging.java @@ -125,7 +125,7 @@ public class TrackedGroupSqlLogging extends SQLLogging { */ protected void updateData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { - PamTableDefinition tableDef = getTableDefinition(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); PamTableItem tableItem; tableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); diff --git a/src/effortmonitor/EffortParams.java b/src/effortmonitor/EffortParams.java index fcd5bcb5..d19d3e36 100644 --- a/src/effortmonitor/EffortParams.java +++ b/src/effortmonitor/EffortParams.java @@ -5,6 +5,7 @@ import java.util.LinkedList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EffortParams implements Cloneable, Serializable, ManagedParameters { @@ -100,7 +101,7 @@ public class EffortParams implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/effortmonitor/swing/EffortDialog.java b/src/effortmonitor/swing/EffortDialog.java index 4f4d8b7f..6850415f 100644 --- a/src/effortmonitor/swing/EffortDialog.java +++ b/src/effortmonitor/swing/EffortDialog.java @@ -43,7 +43,7 @@ public class EffortDialog extends PamDialog { mainPanel.add(new JLabel("Observer name or initials"), c); c.gridx++; mainPanel.add(observer = new JComboBox(), c); - outerOnly = new JRadioButton("Log uter scroll only"); + outerOnly = new JRadioButton("Log outer scroll only"); allActions = new JRadioButton("Log all scroll actions"); ButtonGroup bg = new ButtonGroup(); bg.add(allActions); diff --git a/src/envelopeTracer/EnvelopeParams.java b/src/envelopeTracer/EnvelopeParams.java index 09b427f9..6076deb9 100644 --- a/src/envelopeTracer/EnvelopeParams.java +++ b/src/envelopeTracer/EnvelopeParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Filters.FilterParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EnvelopeParams implements Serializable, Cloneable, ManagedParameters { @@ -34,7 +35,7 @@ public class EnvelopeParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/fftFilter/FFTFilterParams.java b/src/fftFilter/FFTFilterParams.java index dd4d8ab0..bae3a3b6 100644 --- a/src/fftFilter/FFTFilterParams.java +++ b/src/fftFilter/FFTFilterParams.java @@ -8,6 +8,7 @@ import org.w3c.dom.Element; import Filters.FilterBand; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.FrequencyFormat; public class FFTFilterParams implements Serializable, Cloneable, ManagedParameters { @@ -62,7 +63,7 @@ public class FFTFilterParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/fftManager/Complex.java b/src/fftManager/Complex.java index 25b53edd..e2e13ded 100644 --- a/src/fftManager/Complex.java +++ b/src/fftManager/Complex.java @@ -25,6 +25,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class definition for a Complex number type. @@ -349,7 +350,7 @@ public class Complex implements Cloneable, Serializable, Comparable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/fftManager/FFTDataBlock.java b/src/fftManager/FFTDataBlock.java index db04f8d6..3bf0b7b1 100644 --- a/src/fftManager/FFTDataBlock.java +++ b/src/fftManager/FFTDataBlock.java @@ -4,6 +4,9 @@ import java.util.List; import java.util.ListIterator; import java.util.Vector; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import PamView.GeneralProjector.ParameterType; import PamView.GeneralProjector.ParameterUnits; import PamguardMVC.DataBlock2D; @@ -186,6 +189,13 @@ public class FFTDataBlock extends DataBlock2D { public DataTypeInfo getScaleInfo() { return dataTypeInfo; } + @Override + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + el.setAttribute("FFTLength", String.format("%d", getFftLength())); + el.setAttribute("FFTHop", String.format("%d", getFftHop())); + return el; + } diff --git a/src/fftManager/FFTDataDisplayOptions.java b/src/fftManager/FFTDataDisplayOptions.java index a6d17619..969a7a81 100644 --- a/src/fftManager/FFTDataDisplayOptions.java +++ b/src/fftManager/FFTDataDisplayOptions.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class FFTDataDisplayOptions implements Serializable, Cloneable, ManagedParameters { @@ -45,7 +46,7 @@ public class FFTDataDisplayOptions implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("maxVal"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/fileOfflineData/OfflineFileControl.java b/src/fileOfflineData/OfflineFileControl.java index cb408652..45998aaf 100644 --- a/src/fileOfflineData/OfflineFileControl.java +++ b/src/fileOfflineData/OfflineFileControl.java @@ -54,6 +54,11 @@ public abstract class OfflineFileControl extends PamControlledUnit implements Of } + @Override + public String getDataLocation() { + return fileParams.offlineFolder; + } + /* (non-Javadoc) * @see PamController.PamControlledUnit#notifyModelChanged(int) */ diff --git a/src/fileOfflineData/OfflineFileParams.java b/src/fileOfflineData/OfflineFileParams.java index b31d547b..82e4d61a 100644 --- a/src/fileOfflineData/OfflineFileParams.java +++ b/src/fileOfflineData/OfflineFileParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OfflineFileParams implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class OfflineFileParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/generalDatabase/DBControl.java b/src/generalDatabase/DBControl.java index fa49abac..70e0d549 100644 --- a/src/generalDatabase/DBControl.java +++ b/src/generalDatabase/DBControl.java @@ -578,10 +578,16 @@ PamSettingsSource { */ @Override public boolean saveStartSettings(long timeNow) { - return dbProcess.saveStartSettings(); + return dbProcess.saveStartSettings(timeNow); } + @Override + public boolean saveEndSettings(long timeNow) { + // TODO Auto-generated method stub + return true; + } + @Override public int getNumSettings() { if (dbSettingsStore == null) { diff --git a/src/generalDatabase/DBControlUnit.java b/src/generalDatabase/DBControlUnit.java index e3f9e625..0b4239b8 100644 --- a/src/generalDatabase/DBControlUnit.java +++ b/src/generalDatabase/DBControlUnit.java @@ -411,6 +411,11 @@ public class DBControlUnit extends DBControl implements DataOutputStore { return getUnitName(); } + @Override + public String getDataLocation() { + return getDatabaseName(); + } + @Override public boolean loadData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) { SQLLogging logging = dataBlock.getLogging(); diff --git a/src/generalDatabase/DBParameters.java b/src/generalDatabase/DBParameters.java index ce8103d7..ab06c212 100644 --- a/src/generalDatabase/DBParameters.java +++ b/src/generalDatabase/DBParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DBParameters implements Cloneable, Serializable, ManagedParameters { @@ -75,7 +76,7 @@ public class DBParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); if (databaseName != null) { try { Field field = this.getClass().getDeclaredField("databaseName"); diff --git a/src/generalDatabase/DBProcess.java b/src/generalDatabase/DBProcess.java index 167d49f5..597b1a10 100644 --- a/src/generalDatabase/DBProcess.java +++ b/src/generalDatabase/DBProcess.java @@ -102,6 +102,8 @@ public class DBProcess extends PamProcess { dbSpecials.add(logSettings = new LogSettings(databaseControll, "Pamguard Settings", false)); dbSpecials.add(logLastSettings = new LogSettings(databaseControll, "Pamguard Settings Last", true)); dbSpecials.add(logViewerSettings = new LogSettings(databaseControll, "Pamguard Settings Viewer", true)); + + dbSpecials.add(new LogXMLSettings(databaseControll)); } @@ -113,9 +115,13 @@ public class DBProcess extends PamProcess { } } - protected boolean saveStartSettings() { + protected boolean saveStartSettings(long timeNow) { PamConnection con = databaseControll.getConnection(); if (con != null) { + /** + * This first one is the 'old' pre 2022 method which saves a serialised lump of all + * the settings in the database. It ain't broke, so not fixing it. + */ for (int i = 0; i < dbSpecials.size(); i++) { dbSpecials.get(i).pamStart(con); } @@ -124,6 +130,11 @@ public class DBProcess extends PamProcess { return false; } + protected boolean saveEndSettings(long timeNow) { + + return true; + } + @Override public void pamStop() { PamConnection con = databaseControll.getConnection(); @@ -212,7 +223,7 @@ public class DBProcess extends PamProcess { } dataBlocks = PamController.getInstance().getDataBlocks(); - PamTableDefinition tableDefinition; + EmptyTableDefinition tableDefinition; SQLLogging logging; // for each datablock, check that the process can log (ignoring GPS process) diff --git a/src/generalDatabase/DBSchemaWriter.java b/src/generalDatabase/DBSchemaWriter.java index f602ad5c..a29a90b5 100644 --- a/src/generalDatabase/DBSchemaWriter.java +++ b/src/generalDatabase/DBSchemaWriter.java @@ -48,7 +48,7 @@ public class DBSchemaWriter { } - PamTableDefinition tableDef = logging.getTableDefinition(); + EmptyTableDefinition tableDef = logging.getTableDefinition(); tableDef = logging.getBaseTableDefinition(); if (tableDef instanceof PamTableDefinition) { @@ -63,13 +63,14 @@ public class DBSchemaWriter { return true; } - private void exportDatabaseSchema(File outputFolder, PamDataBlock dataBlock, SQLLogging logging, PamTableDefinition tableDef) { - - /** - * write a parent item, e.g. if tableDef is a sub class of PamTableDefinition - */ - // String parentName = writeParentTableSchema(outputFolder, dataBlock, tableDef); - + /** + * Generate an xml schema for a datablock. + * @param dataBlock + * @param logging + * @param tableDef + * @return + */ + public Document generateDatabaseSchema(PamDataBlock dataBlock, SQLLogging logging, EmptyTableDefinition tableDef) { String tableName = tableDef.getTableName(); Document doc = PamUtils.XMLUtils.createBlankDoc(); Element schemaEl = doc.createElement("xs:schema"); @@ -95,7 +96,20 @@ public class DBSchemaWriter { } } } + return doc; + } + + private void exportDatabaseSchema(File outputFolder, PamDataBlock dataBlock, SQLLogging logging, EmptyTableDefinition tableDef) { + /** + * write a parent item, e.g. if tableDef is a sub class of PamTableDefinition + */ + // String parentName = writeParentTableSchema(outputFolder, dataBlock, tableDef); + + Document doc = generateDatabaseSchema(dataBlock, logging, tableDef); + + String tableName = tableDef.getTableName(); + try { File outputFile = new File(outputFolder, tableName+".xsd"); XMLUtils.writeToFile(doc, outputFile); diff --git a/src/generalDatabase/DbSpecial.java b/src/generalDatabase/DbSpecial.java index 05400f7a..401eac1a 100644 --- a/src/generalDatabase/DbSpecial.java +++ b/src/generalDatabase/DbSpecial.java @@ -9,7 +9,7 @@ import PamguardMVC.PamDataUnit; * @author Doug Gillespie * */ -abstract public class DbSpecial extends SQLLogging{ +abstract public class DbSpecial extends SQLLogging { private DBControl dbControl; diff --git a/src/generalDatabase/EmptyTableDefinition.java b/src/generalDatabase/EmptyTableDefinition.java index 9e10753e..53cfd1fb 100644 --- a/src/generalDatabase/EmptyTableDefinition.java +++ b/src/generalDatabase/EmptyTableDefinition.java @@ -300,7 +300,7 @@ public class EmptyTableDefinition implements Cloneable { * @param tableName * @return reference to the database deinition if it exists, or null */ - static PamTableDefinition findTableDefinition(String tableName) { + static EmptyTableDefinition findTableDefinition(String tableName) { String searchName = EmptyTableDefinition.deblankString(tableName); SQLLogging log = SQLLogging.findLogger(searchName); if (log == null) return null; @@ -389,6 +389,15 @@ public class EmptyTableDefinition implements Cloneable { this.updatePolicy = updatePolicy; } + public PamConnection getCheckedConnection() { + return checkedConnection; + } + + public void setCheckedConnection(PamConnection checkedConnection) { + this.checkedConnection = checkedConnection; + } + + @Override protected EmptyTableDefinition clone() { try { diff --git a/src/generalDatabase/LogSettings.java b/src/generalDatabase/LogSettings.java index af5305e9..23b713be 100644 --- a/src/generalDatabase/LogSettings.java +++ b/src/generalDatabase/LogSettings.java @@ -23,7 +23,7 @@ import PamUtils.PamCalendar; import PamguardMVC.PamDataUnit; /** - * Functions for writing Pamguard Settings into any database as character data + * Functions for writing serialised Pamguard Settings into any database as character data * Runs at DAQ start, goes through the settings manager list and for each * set of settings, it serialises the settings data into a binary array, this * is then converted from binary data to 6 bit ascii data (using the character set @@ -185,6 +185,7 @@ public class LogSettings extends DbSpecial { DeserialisationWarning dsWarning = new DeserialisationWarning(getDbControl().getDatabaseName()); SQLTypes sqlTypes = con.getSqlTypes(); + boolean haveData; if (result != null) try { haveData = result.next(); @@ -193,7 +194,7 @@ public class LogSettings extends DbSpecial { // transfer data back into the tableItems store. transferDataFromResult(sqlTypes, result); - tableItem = getTableDefinition().getTimeStampItem(); + tableItem = tableDef.getTimeStampItem(); // timestamp = (Timestamp) tableItem.getTimestampValue(); timeMillis = sqlTypes.millisFromTimeStamp(tableItem.getValue()); diff --git a/src/generalDatabase/LogXMLDataUnit.java b/src/generalDatabase/LogXMLDataUnit.java new file mode 100644 index 00000000..63189784 --- /dev/null +++ b/src/generalDatabase/LogXMLDataUnit.java @@ -0,0 +1,75 @@ +package generalDatabase; + +import PamController.PamSettings; +import PamguardMVC.PamDataUnit; + +/** + * simple data unit for use with the LogXMLSettings class + * @author dg50 + * + */ +public class LogXMLDataUnit extends PamDataUnit { + + private long processTime; + private PamSettings pamSettings; + private String xml; + private Long dataEnd, processEnd; + + public LogXMLDataUnit(long timeMilliseconds, long processTime, PamSettings pamSettings, String xml) { + super(timeMilliseconds); + this.processTime = processTime; + this.pamSettings = pamSettings; + this.xml = xml; + } + + /** + * @return the dataEnd + */ + public Long getDataEnd() { + return dataEnd; + } + + /** + * @param dataEnd the dataEnd to set + */ + public void setDataEnd(Long dataEnd) { + this.dataEnd = dataEnd; + } + + /** + * @return the processEnd + */ + public Long getProcessEnd() { + return processEnd; + } + + /** + * @param processEnd the processEnd to set + */ + public void setProcessEnd(Long processEnd) { + this.processEnd = processEnd; + } + + /** + * @return the processTime + */ + public long getProcessTime() { + return processTime; + } + + /** + * @return the pamSettings + */ + public PamSettings getPamSettings() { + return pamSettings; + } + + /** + * @return the xml + */ + public String getXml() { + return xml; + } + + +} diff --git a/src/generalDatabase/LogXMLSettings.java b/src/generalDatabase/LogXMLSettings.java new file mode 100644 index 00000000..3f33c188 --- /dev/null +++ b/src/generalDatabase/LogXMLSettings.java @@ -0,0 +1,123 @@ +package generalDatabase; + +import java.io.Serializable; +import java.util.HashMap; + +import org.w3c.dom.Document; + +import PamController.PamControlledUnit; +import PamController.PamController; +import PamController.PamSettings; +import PamController.PamguardVersionInfo; +import PamController.settings.output.xml.PamguardXMLWriter; +import PamUtils.PamCalendar; +import PamguardMVC.PamDataUnit; +/** + * 2022 Additional way of saving settings for each module into the database in more human readable + * XML format.

    + * In other ways, similar to LogSettings which saves serialised Java. This will write a line + * per module. A main difference is that on pamStop it will update the end time for each line, so + * that we have a record of analysis effort for each module. Will therefore need to store the last + * index of the entry for each module, so that we can update the appropriate row. + * @author dg50 + * + */ +public class LogXMLSettings extends DbSpecial { + + private XMLSettingsTableDefinition xmlTableDef; + + private HashMap moduleRows; + + private PamguardXMLWriter xmlWriter; + + public LogXMLSettings(DBControl dbControl) { + super(dbControl); + xmlTableDef = new XMLSettingsTableDefinition("Module Effort"); + setTableDefinition(xmlTableDef); + moduleRows = new HashMap<>(); + xmlWriter = PamguardXMLWriter.getXMLWriter(); + } + + @Override + public void pamStart(PamConnection con) { + long time = PamCalendar.getTimeInMillis(); + saveModuleSettings(con, time); + } + + @Override + public void pamStop(PamConnection con) { + long time = PamCalendar.getTimeInMillis(); + updateModuleSettings(con, time); + } + + private void saveModuleSettings(PamConnection con, long dataTime) { + int n = PamController.getInstance().getNumControlledUnits(); + long now = System.currentTimeMillis(); + for (int i = 0; i < n; i++) { + saveModuleSettings(con, dataTime, now, PamController.getInstance().getControlledUnit(i)); + } + + } + + private void saveModuleSettings(PamConnection con, long dataTime, long now, PamControlledUnit controlledUnit) { + if (controlledUnit instanceof PamSettings == false) { + return; + } + PamSettings pamSettings = (PamSettings) controlledUnit; + Serializable settings = pamSettings.getSettingsReference(); + Document doc = xmlWriter.writeOneModule(pamSettings, dataTime); + String xmlString = xmlWriter.getAsString(doc, true); + LogXMLDataUnit logXMLDataUnit = new LogXMLDataUnit(dataTime, now, pamSettings, xmlString); + + logData(logXMLDataUnit); + int dbIndex = logXMLDataUnit.getDatabaseIndex(); + moduleRows.put(getModuleHash(pamSettings), logXMLDataUnit); + } + + private void updateModuleSettings(PamConnection con, long dataTime) { + int n = PamController.getInstance().getNumControlledUnits(); + long now = System.currentTimeMillis(); + for (int i = 0; i < n; i++) { + updateModuleSettings(con, dataTime, now, PamController.getInstance().getControlledUnit(i)); + } + + } + + private void updateModuleSettings(PamConnection con, long dataTime, long now, PamControlledUnit controlledUnit) { + if (controlledUnit instanceof PamSettings == false) { + return; + } + PamSettings pamSettings = (PamSettings) controlledUnit; + LogXMLDataUnit logXMLDataUnit = moduleRows.get(getModuleHash(pamSettings)); + if (logXMLDataUnit == null) { + return; + } + logXMLDataUnit.setDataEnd(dataTime); + logXMLDataUnit.setProcessEnd(now); + reLogData(con, logXMLDataUnit); + } + + private String getModuleHash(PamSettings pamSettings) { + if (pamSettings == null) { + return null; + } + return pamSettings.getUnitName()+pamSettings.getUnitType(); + } + + @Override + public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { + LogXMLDataUnit logXMLDataUnit = (LogXMLDataUnit) pamDataUnit; + PamSettings pamSettings = logXMLDataUnit.getPamSettings(); + + xmlTableDef.getDataStart().setValue(sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); + xmlTableDef.getDataEnd().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getDataEnd())); + xmlTableDef.getProcessStart().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getProcessTime())); + xmlTableDef.getProcessEnd().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getProcessEnd())); + xmlTableDef.getName().setValue(pamSettings.getUnitName()); + xmlTableDef.getType().setValue(pamSettings.getUnitType()); + xmlTableDef.getPamGuardVersion().setValue(PamguardVersionInfo.version); + xmlTableDef.getSettingsVersion().setValue(pamSettings.getSettingsVersion()); + xmlTableDef.getXmlSettings().setValue(logXMLDataUnit.getXml()); + } + +} diff --git a/src/generalDatabase/MySQLParameters.java b/src/generalDatabase/MySQLParameters.java index 9491a6da..cadd498f 100644 --- a/src/generalDatabase/MySQLParameters.java +++ b/src/generalDatabase/MySQLParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MySQLParameters implements Cloneable, Serializable, ManagedParameters { @@ -37,7 +38,7 @@ public class MySQLParameters implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("databaseName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/generalDatabase/PamSubtableDefinition.java b/src/generalDatabase/PamSubtableDefinition.java index 0aa20215..ec3780b0 100644 --- a/src/generalDatabase/PamSubtableDefinition.java +++ b/src/generalDatabase/PamSubtableDefinition.java @@ -51,6 +51,7 @@ public class PamSubtableDefinition extends PamTableDefinition { addTableItem(parentUID = new PamTableItem(PARENTUIDNAME, Types.BIGINT)); addTableItem(longName = new PamTableItem(LONGDATANAME, Types.CHAR, DATANAME_LENGTH)); addTableItem(binaryFilename = new PamTableItem(BINARYFILE, Types.CHAR, BINARY_FILE_NAME_LENGTH)); + setUseCheatIndexing(false); } public PamTableItem getParentID() { diff --git a/src/generalDatabase/PamTableDefinition.java b/src/generalDatabase/PamTableDefinition.java index e8a2b5dc..8424b683 100644 --- a/src/generalDatabase/PamTableDefinition.java +++ b/src/generalDatabase/PamTableDefinition.java @@ -192,14 +192,7 @@ public class PamTableDefinition extends EmptyTableDefinition implements Cloneabl public PamTableItem getUidItem() { return uid; } - public PamConnection getCheckedConnection() { - return checkedConnection; - } - - public void setCheckedConnection(PamConnection checkedConnection) { - this.checkedConnection = checkedConnection; - } - + public PamTableItem getUpdateReference() { return updateReference; } diff --git a/src/generalDatabase/PamTableItem.java b/src/generalDatabase/PamTableItem.java index 2a046623..e73772e8 100644 --- a/src/generalDatabase/PamTableItem.java +++ b/src/generalDatabase/PamTableItem.java @@ -377,7 +377,7 @@ public class PamTableItem implements Cloneable { * column for use in cross referencing. */ public static PamTableItem findTableItem(String tableName, String columnName) { - PamTableDefinition tableDef = EmptyTableDefinition. + EmptyTableDefinition tableDef = EmptyTableDefinition. findTableDefinition(EmptyTableDefinition.deblankString(tableName)); if (tableDef == null) return null; return tableDef.findTableItem(EmptyTableDefinition.deblankString(columnName)); diff --git a/src/generalDatabase/SQLLogging.java b/src/generalDatabase/SQLLogging.java index e9c094ed..8f8b9f84 100644 --- a/src/generalDatabase/SQLLogging.java +++ b/src/generalDatabase/SQLLogging.java @@ -190,7 +190,7 @@ public abstract class SQLLogging { ArrayList blockList = PamController.getInstance() .getDataBlocks(); SQLLogging logger; - PamTableDefinition tableDef; + EmptyTableDefinition tableDef; for (int i = 0; i < blockList.size(); i++) { if ((logger = blockList.get(i).getLogging()) != null) { tableDef = logger.getTableDefinition(); @@ -293,37 +293,42 @@ public abstract class SQLLogging { * @param superDetection */ protected void fillTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit, PamDataUnit superDetection) { + + EmptyTableDefinition emptyTableDef = getTableDefinition(); - PamTableDefinition tableDef = getTableDefinition(); PamTableItem tableItem; - tableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); - /* - * All tables have a timestamp near the front of the table. And all data - * units have a time in milliseconds, so always fill this in ! - */ - tableDef.getTimeStampItem().setValue( - sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); + emptyTableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); + + if (emptyTableDef instanceof PamTableDefinition) { + PamTableDefinition tableDef = (PamTableDefinition) emptyTableDef; + /* + * All tables have a timestamp near the front of the table. And all data + * units have a time in milliseconds, so always fill this in ! + */ + tableDef.getTimeStampItem().setValue( + sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); - tableDef.getTimeStampMillis().setValue((int) (pamDataUnit.getTimeMilliseconds()%1000)); + tableDef.getTimeStampMillis().setValue((int) (pamDataUnit.getTimeMilliseconds()%1000)); - tableDef.getLocalTimeItem().setValue(sqlTypes.getLocalTimeStamp(pamDataUnit.getTimeMilliseconds())); + tableDef.getLocalTimeItem().setValue(sqlTypes.getLocalTimeStamp(pamDataUnit.getTimeMilliseconds())); - tableDef.getPCTimeItem().setValue(sqlTypes.getTimeStamp(System.currentTimeMillis())); + tableDef.getPCTimeItem().setValue(sqlTypes.getTimeStamp(System.currentTimeMillis())); - tableDef.getUidItem().setValue(pamDataUnit.getUID()); + tableDef.getUidItem().setValue(pamDataUnit.getUID()); - tableDef.getChannelBitmap().setValue(pamDataUnit.getChannelBitmap()); + tableDef.getChannelBitmap().setValue(pamDataUnit.getChannelBitmap()); - tableDef.getSequenceBitmap().setValue(pamDataUnit.getSequenceBitmapObject()); + tableDef.getSequenceBitmap().setValue(pamDataUnit.getSequenceBitmapObject()); - if (tableDef.getUpdateReference() != null) { - tableDef.getUpdateReference().setValue(pamDataUnit.getDatabaseIndex()); + if (tableDef.getUpdateReference() != null) { + tableDef.getUpdateReference().setValue(pamDataUnit.getDatabaseIndex()); + } } - for (int i = 0; i < tableDef.getTableItemCount(); i++) { + for (int i = 0; i < emptyTableDef.getTableItemCount(); i++) { - tableItem = tableDef.getTableItem(i); + tableItem = emptyTableDef.getTableItem(i); // if (tableItem.isCounter()) { // tableItem.setValue(1); // } @@ -333,8 +338,8 @@ public abstract class SQLLogging { } } - if (tableDef instanceof PamSubtableDefinition) { - PamSubtableDefinition subTableDef = (PamSubtableDefinition) tableDef; + if (emptyTableDef instanceof PamSubtableDefinition) { + PamSubtableDefinition subTableDef = (PamSubtableDefinition) emptyTableDef; fillSubTableData(subTableDef, pamDataUnit, superDetection); } @@ -525,7 +530,7 @@ public abstract class SQLLogging { } // now put some sql into the statement // if (resultSet == null) { - PamTableDefinition tableDef = getTableDefinition(); + EmptyTableDefinition tableDef = getTableDefinition(); String sqlString = tableDef.getSQLSelectString(con.getSqlTypes()); // sqlString = "select \"comment\" from userinput"; try { @@ -546,6 +551,71 @@ public abstract class SQLLogging { // } return resultSet; } + + /** + * Find the data point which is closest in time to that given, or null + * returning whatever type of data unit this deals with. + * @param timeMillis + * @return + */ + public PamDataUnit findClosestDataPoint(PamConnection con, long timeMillis) { + + PamCursor pamCursor = loggingCursorFinder.getCursor(con, pamTableDefinition); + + // can't really do any math with the string based dates, so will have to query from + // a few s before the time we want. + PamDataUnit[] beforeNafter = new PamDataUnit[2]; + + SQLTypes sqlTypes = con.getSqlTypes(); + + for (int i = 0; i < 2; i++) { + String clause; + + if (i == 0) { + clause = String.format("WHERE UTC <= %s ORDER BY UTC DESC", sqlTypes.formatDBDateTimeQueryString(timeMillis)); + } + else { + clause = String.format("WHERE UTC >= %s ORDER BY UTC ASC", sqlTypes.formatDBDateTimeQueryString(timeMillis)); + } + + ResultSet result = pamCursor.openReadOnlyCursor(con, clause); + if (result==null) { + return null; + } + + PamTableItem tableItem; + try { + if (result.next()) { + // for (int i = 0; i < pamTableDefinition.getTableItemCount(); i++) { + // tableItem = pamTableDefinition.getTableItem(i); + // tableItem.setValue(result.getObject(i + 1)); + // } + // return true; + boolean ok = transferDataFromResult(con.getSqlTypes(), result); + result.close(); + beforeNafter[i] = createDataUnit(sqlTypes, lastTime, lastLoadIndex); + } + } catch (SQLException ex) { + ex.printStackTrace(); + continue; + } + } + // now pick the closest + if (beforeNafter[0] == null) { + return beforeNafter[1]; + } + if (beforeNafter[1] == null) { + return beforeNafter[0]; + } + long t1 = timeMillis-beforeNafter[0].getTimeMilliseconds(); + long t2 = beforeNafter[1].getTimeMilliseconds()-timeMillis; + if (t1 < t2) { + return beforeNafter[0]; + } + else { + return beforeNafter[1]; + } + } /** * Called when a new database is connected to read the last values back in @@ -1079,7 +1149,7 @@ public abstract class SQLLogging { public boolean transferDataFromResult(SQLTypes sqlTypes, ResultSet resultSet) { - PamTableDefinition tableDef = getTableDefinition(); + EmptyTableDefinition tableDef = getTableDefinition(); PamTableItem tableItem; try { for (int i = 0; i < tableDef.getTableItemCount(); i++) { @@ -1090,17 +1160,20 @@ public abstract class SQLLogging { // Timestamp ts = (Timestamp) getTableDefinition().getTimeStampItem().getValue(); // Timestamp ts = getTableDefinition().getTimeStampItem().getTimestampValue(); // lastTime = sqlTypes.millisFromTimeStamp(ts); - lastTime = sqlTypes.millisFromTimeStamp(getTableDefinition().getTimeStampItem().getValue()); - if (lastTime%1000 == 0) { - // some databases may have stored the milliseconds, in which - // case this next bit is redundant. - lastTime += getTableDefinition().getTimeStampMillis().getIntegerValue(); - } - lastLoadIndex = getTableDefinition().getIndexItem().getIntegerValue(); - lastLoadUID = getTableDefinition().getUidItem().getLongObject(); - lastChannelBitmap = getTableDefinition().getChannelBitmap().getIntegerValue(); - lastSequenceBitmap = getTableDefinition().getSequenceBitmap().getIntegerObject(); + if (tableDef instanceof PamTableDefinition) { + PamTableDefinition pamTableDef = (PamTableDefinition) tableDef; + lastTime = sqlTypes.millisFromTimeStamp(pamTableDef.getTimeStampItem().getValue()); + if (lastTime%1000 == 0) { + // some databases may have stored the milliseconds, in which + // case this next bit is redundant. + lastTime += pamTableDef.getTimeStampMillis().getIntegerValue(); + } + + lastLoadUID = pamTableDef.getUidItem().getLongObject(); + lastChannelBitmap = pamTableDef.getChannelBitmap().getIntegerValue(); + lastSequenceBitmap = pamTableDef.getSequenceBitmap().getIntegerObject(); + } return true; } catch (SQLException ex) { diff --git a/src/generalDatabase/SQLLoggingAddon.java b/src/generalDatabase/SQLLoggingAddon.java index 6d347fb4..ff8bd561 100644 --- a/src/generalDatabase/SQLLoggingAddon.java +++ b/src/generalDatabase/SQLLoggingAddon.java @@ -15,7 +15,7 @@ public interface SQLLoggingAddon { * Add a load of columns to an existing table definition * @param pamTableDefinition */ - public void addTableItems(PamTableDefinition pamTableDefinition); + public void addTableItems(EmptyTableDefinition pamTableDefinition); /** * Save data - that is transfer data from the pamDataUnit to the data objects @@ -24,7 +24,7 @@ public interface SQLLoggingAddon { * @param pamDataUnit data unit * @return true if successful */ - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); /** * Load data - that is read data from the table definition and turn it into something sensible @@ -33,7 +33,7 @@ public interface SQLLoggingAddon { * @param pamDataUnit data unit * @return true if successful */ - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); /** * Get a name for the SQLLogging Addon. this is used diff --git a/src/generalDatabase/SQLTypes.java b/src/generalDatabase/SQLTypes.java index a81edd89..fd8ccb56 100644 --- a/src/generalDatabase/SQLTypes.java +++ b/src/generalDatabase/SQLTypes.java @@ -387,6 +387,7 @@ public class SQLTypes { return timestamp.getTime() + tz.getOffset(timestamp.getTime()); } else if (timeValue instanceof String) { + timeValue = ((String) timeValue).replace("'", ""); return PamCalendar.millisFromDateString((String) timeValue, false); } if (timeValue instanceof Long) { diff --git a/src/generalDatabase/XMLSettingsTableDefinition.java b/src/generalDatabase/XMLSettingsTableDefinition.java new file mode 100644 index 00000000..8d40bc55 --- /dev/null +++ b/src/generalDatabase/XMLSettingsTableDefinition.java @@ -0,0 +1,94 @@ +package generalDatabase; + +import java.sql.Types; + +import PamguardMVC.PamConstants; + +public class XMLSettingsTableDefinition extends PamTableDefinition { + + private PamTableItem dataStart, dataEnd, processStart, processEnd, type, name, pamGuardVersion, settingsVersion, xmlSettings; + + public XMLSettingsTableDefinition(String tableName) { + super(tableName, SQLLogging.UPDATE_POLICY_WRITENEW); + pamTableItems.add(dataStart = new PamTableItem("Data Start", Types.TIMESTAMP, "Data start time")); + pamTableItems.add(dataEnd = new PamTableItem("Data End", Types.TIMESTAMP, "Data end time")); + pamTableItems.add(processStart = new PamTableItem("Process Start", Types.TIMESTAMP, "Process start time")); + pamTableItems.add(processEnd = new PamTableItem("Process End", Types.TIMESTAMP, "Process end time")); + addTableItem(type = new PamTableItem("unitType", Types.CHAR, PamConstants.MAX_ITEM_NAME_LENGTH)); + addTableItem(name = new PamTableItem("unitName", Types.CHAR, PamConstants.MAX_ITEM_NAME_LENGTH)); + addTableItem(pamGuardVersion = new PamTableItem("PAMGuardVersion", Types.INTEGER)); + addTableItem(settingsVersion = new PamTableItem("SettingsVersion", Types.INTEGER)); + addTableItem(xmlSettings = new PamTableItem("XMLSettings", Types.VARCHAR)); + setUseCheatIndexing(false); + } + + + /** + * @return the dataStart + */ + public PamTableItem getDataStart() { + return dataStart; + } + + + /** + * @return the dataEnd + */ + public PamTableItem getDataEnd() { + return dataEnd; + } + + + /** + * @return the processStart + */ + public PamTableItem getProcessStart() { + return processStart; + } + + + /** + * @return the processEnd + */ + public PamTableItem getProcessEnd() { + return processEnd; + } + + + /** + * @return the type + */ + public PamTableItem getType() { + return type; + } + + /** + * @return the name + */ + public PamTableItem getName() { + return name; + } + + /** + * @return the pamGuardVersion + */ + public PamTableItem getPamGuardVersion() { + return pamGuardVersion; + } + + /** + * @return the settingsVersion + */ + public PamTableItem getSettingsVersion() { + return settingsVersion; + } + + /** + * @return the xmlSettings + */ + public PamTableItem getXmlSettings() { + return xmlSettings; + } + + +} diff --git a/src/generalDatabase/dataExport/ValueFilterParams.java b/src/generalDatabase/dataExport/ValueFilterParams.java index 15ffdfbd..52c57cfd 100644 --- a/src/generalDatabase/dataExport/ValueFilterParams.java +++ b/src/generalDatabase/dataExport/ValueFilterParams.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Abstract class for ValueFilters for filtering database data tables. @@ -110,7 +111,7 @@ public abstract class ValueFilterParams implements Cloneable, Serializable, Mana @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/generalDatabase/lookupTables/LookupItem.java b/src/generalDatabase/lookupTables/LookupItem.java index 7115406e..9ee05094 100644 --- a/src/generalDatabase/lookupTables/LookupItem.java +++ b/src/generalDatabase/lookupTables/LookupItem.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamSymbol; import PamView.PamSymbolType; @@ -232,7 +233,7 @@ public class LookupItem implements Cloneable, Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/generalDatabase/lookupTables/LookupList.java b/src/generalDatabase/lookupTables/LookupList.java index 8e0a0e0c..7714cdd3 100644 --- a/src/generalDatabase/lookupTables/LookupList.java +++ b/src/generalDatabase/lookupTables/LookupList.java @@ -7,6 +7,7 @@ import java.util.Vector; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Handles information for a single list from the look up table @@ -253,7 +254,7 @@ public class LookupList implements Cloneable, Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/generalDatabase/parameterstore/ParameterDatabaseStore.java b/src/generalDatabase/parameterstore/ParameterDatabaseStore.java new file mode 100644 index 00000000..29c740eb --- /dev/null +++ b/src/generalDatabase/parameterstore/ParameterDatabaseStore.java @@ -0,0 +1,187 @@ +package generalDatabase.parameterstore; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.util.Arrays; +import java.util.Collection; + +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterData; +import PamModel.parametermanager.PamParameterSet; +import generalDatabase.DBControlUnit; +import generalDatabase.EmptyTableDefinition; +import generalDatabase.PamConnection; +import generalDatabase.PamTableItem; +import generalDatabase.SQLTypes; + +/** + * Store parameters from a managed parameter set in the PAMGuard database. These go into a dead simple table, which has + * two columns. The first is a name, the second a string value. Each parameter can only appear once. + * This works with ManagedParameters using the same names and field names that go into the xml output. + * @author dg50 + * + */ +public class ParameterDatabaseStore { + + + private EmptyTableDefinition tableDef; + private PamTableItem nameItem, dataItem; + + public ParameterDatabaseStore(String tableName) { + tableDef = new EmptyTableDefinition(tableName); + tableDef.addTableItem(nameItem = new PamTableItem("ParameterName", Types.VARCHAR)); + tableDef.addTableItem(dataItem = new PamTableItem("Value", Types.VARCHAR)); + } + + public boolean saveParameterSet(ManagedParameters managedParameters) { + if (managedParameters == null) { + return false; + } + return saveParameterSet(managedParameters.getClass().getSimpleName(), managedParameters); + } + + private boolean saveParameterSet(String name, ManagedParameters managedParameters) { + DBControlUnit dbControl = DBControlUnit.findDatabaseControl(); + if (dbControl == null) { + return false; + } + PamConnection con = dbControl.getConnection(); + if (checkTable(con) == false) { + return false; + } + + String prefix; + if (name == null) { + prefix = ""; + } + else { + prefix = name + "."; + } + PamParameterSet paramSet = managedParameters.getParameterSet(); + Collection params = paramSet.getParameterCollection(); + for (PamParameterData paramData : params) { + String paramName = paramData.getFieldName(); + paramName = prefix + paramName; + Object data = null; + try { + data = paramData.getData();// .getField().get(managedParameters); + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } +// System.out.printf("Store param \"%s\" as \"%s\"\n", paramName, data); + saveToDatabase(con, paramName, data); + } + dbControl.commitChanges(); + + return true; + } + + private boolean saveToDatabase(PamConnection con, String name, Object data) { + int[] existing = findExistingRows(con, name); + boolean ok = true; + if (existing == null || existing.length == 0) { + ok |= newRecord(con, name, data); + } + else { + ok |= updateRecord(con, existing[0], name, data); + if (existing.length > 1) { + for (int i = 1; i < existing.length; i++) { + ok |= deleteDuplicateRow(con, existing[i]); + } + } + } + return true; + } + + private int[] findExistingRows(PamConnection con, String name) { + /** + * Find existing rows with that name. + */ + int[] rows = new int[0]; + if (con == null) { + return rows; + } + String qStr = String.format("SELECT Id FROM %s WHERE %s='%s'", tableDef.getTableName(), nameItem.getName(), name); + try { + Statement stmt = con.getConnection().createStatement(); + ResultSet res = stmt.executeQuery(qStr); + while (res.next()) { + int rowId = res.getInt(1); + rows = Arrays.copyOf(rows, rows.length+1); + rows[rows.length-1] = rowId; + } + res.close(); + stmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return rows; + } + + private boolean newRecord(PamConnection con, String name, Object data) { + + String insertStr = tableDef.getSQLInsertString(con.getSqlTypes()); + try { + PreparedStatement stmt = con.getConnection().prepareStatement(insertStr); + stmt.setString(1, name); + if (data == null) { + stmt.setNull(2, Types.VARCHAR); + } + else { + stmt.setString(2, data.toString()); + } + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private boolean updateRecord(PamConnection con, int iRow, String name, Object data) { + SQLTypes st = con.getSqlTypes(); + String updateString = String.format("UPDATE %s SET %s = '%s' WHERE Id = %d", tableDef.getTableName(), + st.formatColumnName(dataItem.getName()), data, iRow); + + try { + PreparedStatement stmt = con.getConnection().prepareStatement(updateString); + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private boolean deleteDuplicateRow(PamConnection con, int rowId) { + + String delStr = String.format("DELETE FROM %s WHERE Id=%d", tableDef.getTableName(), rowId); + + try { + PreparedStatement stmt = con.getConnection().prepareStatement(delStr); + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + private boolean checkTable(PamConnection con) { + DBControlUnit dbControl = DBControlUnit.findDatabaseControl(); + if (dbControl == null) { + return false; + } + dbControl.commitChanges(); + return dbControl.getDbProcess().checkTable(tableDef); + } + +} diff --git a/src/generalDatabase/sqlite/SqliteSQLTypes.java b/src/generalDatabase/sqlite/SqliteSQLTypes.java index 580c8c5e..4f2baf73 100644 --- a/src/generalDatabase/sqlite/SqliteSQLTypes.java +++ b/src/generalDatabase/sqlite/SqliteSQLTypes.java @@ -10,7 +10,7 @@ import PamUtils.PamCalendar; public class SqliteSQLTypes extends SQLTypes { - protected static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT; + public static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT; @Override public String typeToString(int sqlType, int length, boolean counter) { diff --git a/src/gpl/GPLParameters.java b/src/gpl/GPLParameters.java index 666c559e..fcda34d9 100644 --- a/src/gpl/GPLParameters.java +++ b/src/gpl/GPLParameters.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.FieldNotFoundException; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.blockprocess.PamBlockParams; import gpl.contour.ContourMerge; @@ -198,7 +199,7 @@ public class GPLParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { ps.findParameterData("minPeakGap").setInfo("Minimum gap", "bins", "Minimum gap between peaks (FFT time bins)"); ps.findParameterData("minCallLengthSeconds").setInfo("Minimum length", "bins", "Minimum length of a detection in seconds"); diff --git a/src/gpl/io/GPLLogging.java b/src/gpl/io/GPLLogging.java index d8817bdc..c407193f 100644 --- a/src/gpl/io/GPLLogging.java +++ b/src/gpl/io/GPLLogging.java @@ -5,6 +5,7 @@ import java.sql.Types; import PamDetection.AcousticSQLLogging; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLTypes; @@ -22,7 +23,7 @@ public class GPLLogging extends AcousticSQLLogging { super(gplDetectionBlock, gplControlledUnit.getUnitName() + " Detections"); this.gplControlledUnit = gplControlledUnit; - PamTableDefinition pamTable = getTableDefinition(); + EmptyTableDefinition pamTable = getTableDefinition(); pamTable.addTableItem(peakValue = new PamTableItem("PeakValue", Types.REAL)); pamTable.addTableItem(contourArea = new PamTableItem("ContourArea", Types.REAL)); } diff --git a/src/group3dlocaliser/Group3DParams.java b/src/group3dlocaliser/Group3DParams.java index fbf75743..6467a9ad 100644 --- a/src/group3dlocaliser/Group3DParams.java +++ b/src/group3dlocaliser/Group3DParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import group3dlocaliser.algorithm.LocaliserAlgorithm3D; @@ -126,7 +127,7 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmSpecificParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java b/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java index 7f7e1371..735d70f1 100644 --- a/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java +++ b/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class MFPGridSearchParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class MFPGridSearchParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftLength"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java b/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java index 6f2a0fb2..8c845ffe 100644 --- a/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java +++ b/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import group3dlocaliser.grids.SphericalGrid; import pamMaths.PamVector; @@ -49,7 +50,7 @@ public class TOADGridParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("gridType"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java b/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java index 1aa70f8a..b0e11190 100644 --- a/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java +++ b/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters that apply to all TOAD based localisers. @@ -117,7 +118,7 @@ public class TOADBaseParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java b/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java index 879eae8b..86e2397d 100644 --- a/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java +++ b/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; public class Group3DDataSelectParams extends DataSelectParams implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class Group3DDataSelectParams extends DataSelectParams implements Seriali @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/grids/SphericalGridParams.java b/src/group3dlocaliser/grids/SphericalGridParams.java index f323ee53..5ece7b39 100644 --- a/src/group3dlocaliser/grids/SphericalGridParams.java +++ b/src/group3dlocaliser/grids/SphericalGridParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SphericalGridParams implements Serializable, Cloneable, ManagedParameters { @@ -88,7 +89,7 @@ public class SphericalGridParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/grouper/DetectionGrouperParams.java b/src/group3dlocaliser/grouper/DetectionGrouperParams.java index 5d92afd1..d789b054 100644 --- a/src/group3dlocaliser/grouper/DetectionGrouperParams.java +++ b/src/group3dlocaliser/grouper/DetectionGrouperParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DetectionGrouperParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class DetectionGrouperParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/help/JavaHelpSearch/DOCS b/src/help/JavaHelpSearch/DOCS index aece1f43..aa2227fe 100644 Binary files a/src/help/JavaHelpSearch/DOCS and b/src/help/JavaHelpSearch/DOCS differ diff --git a/src/help/JavaHelpSearch/DOCS.TAB b/src/help/JavaHelpSearch/DOCS.TAB index fcb0be96..ad72b66e 100644 Binary files a/src/help/JavaHelpSearch/DOCS.TAB and b/src/help/JavaHelpSearch/DOCS.TAB differ diff --git a/src/help/JavaHelpSearch/OFFSETS b/src/help/JavaHelpSearch/OFFSETS index 7aeaea18..8a7b9b88 100644 Binary files a/src/help/JavaHelpSearch/OFFSETS and b/src/help/JavaHelpSearch/OFFSETS differ diff --git a/src/help/JavaHelpSearch/POSITIONS b/src/help/JavaHelpSearch/POSITIONS index 168a00c2..91375b46 100644 Binary files a/src/help/JavaHelpSearch/POSITIONS and b/src/help/JavaHelpSearch/POSITIONS differ diff --git a/src/help/JavaHelpSearch/SCHEMA b/src/help/JavaHelpSearch/SCHEMA index f1bcbb62..0de6873b 100644 --- a/src/help/JavaHelpSearch/SCHEMA +++ b/src/help/JavaHelpSearch/SCHEMA @@ -1,2 +1,2 @@ JavaSearch 1.0 -TMAP bs=2048 rt=1 fl=-1 id1=6700 id2=1 +TMAP bs=2048 rt=1 fl=-1 id1=6709 id2=1 diff --git a/src/help/JavaHelpSearch/TMAP b/src/help/JavaHelpSearch/TMAP index 0f4d546b..a083f8e0 100644 Binary files a/src/help/JavaHelpSearch/TMAP and b/src/help/JavaHelpSearch/TMAP differ diff --git a/src/help/Map.jhm b/src/help/Map.jhm index 176022cb..a3886c8c 100644 --- a/src/help/Map.jhm +++ b/src/help/Map.jhm @@ -528,6 +528,8 @@ + + @@ -644,6 +646,8 @@ + + diff --git a/src/help/PAMGUARDHelpProject.xml b/src/help/PAMGUARDHelpProject.xml index 69b52d84..fe06f32b 100644 --- a/src/help/PAMGUARDHelpProject.xml +++ b/src/help/PAMGUARDHelpProject.xml @@ -6,7 +6,7 @@ PAMGUARD - C:\Users\dg50\source\repos\PAMGuardDG\src\help + C:\Users\dg50\source\repos\PAMGuardDG_2\src\help index.html diff --git a/src/help/PAMGUARDIndex.xml b/src/help/PAMGUARDIndex.xml index 18d93123..c9cf5489 100644 --- a/src/help/PAMGUARDIndex.xml +++ b/src/help/PAMGUARDIndex.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/help/PAMGUARDTOC.xml b/src/help/PAMGUARDTOC.xml index 73590bca..e1eeb6dc 100644 --- a/src/help/PAMGUARDTOC.xml +++ b/src/help/PAMGUARDTOC.xml @@ -195,6 +195,12 @@ + + + + + + diff --git a/src/help/pamHelpStylesheet.css b/src/help/pamHelpStylesheet.css index e2174daf..d2d474b9 100644 --- a/src/help/pamHelpStylesheet.css +++ b/src/help/pamHelpStylesheet.css @@ -52,7 +52,9 @@ ol { FONT-SIZE: 14; } + img.wrap {float: left} +img.wrapright {float: right} table, th, td { border: 1px solid black; diff --git a/src/help/utilities/tethys/docs/images/Tethys-200.png b/src/help/utilities/tethys/docs/images/Tethys-200.png new file mode 100644 index 00000000..19e3c48f Binary files /dev/null and b/src/help/utilities/tethys/docs/images/Tethys-200.png differ diff --git a/src/help/utilities/tethys/docs/tethys_overview.html b/src/help/utilities/tethys/docs/tethys_overview.html new file mode 100644 index 00000000..da30d095 --- /dev/null +++ b/src/help/utilities/tethys/docs/tethys_overview.html @@ -0,0 +1,70 @@ + + + + + +Tethys Module Overview + + + +

    Tethys Interface

    +

    Overview

    + +

    + Tethys mosaic +

    +

    + + Tethys is a freely + available open source temporal-spatial database for metadata related + to acoustic recordings. The database is intended to house the metadata + from marine mammal detection and localization studies, allowing the + user to perform meta analyses or to aggregate data from many + experimental efforts based on a common attribute. This resulting + database can then be queried based on time, space, or any desired + attribute and the results can be integrated with external datasets + such as NASA's Ocean Color, lunar illumination, etc. in a consistent + manner. While Tethys is designed primarily for acoustic metadata from + marine mammals, the design is general enough to permit use in other + areas as well. + +

    +

    PAMGuard is compatible with Tethys 3.0, released early in 2024.

    +

    The Tethys database is not a replacement for the existing + + PAMGuard Database. + Where the PAMGuard database only contains data from a single instrument or cruise, the Tethys + database contains data from many cruises and projects and can be used to hold a summary of all data + from a lab or organisation. +

    + +

    Before using the module in PAMGuard, you should install the Tethys Server, which runs under + Windows. + Instructions for installing the Tethys Server can be found here.

    + + +

    + + + Next: Configuring the Tethys + Module +

    +
    +
    +
    + + diff --git a/src/help/utilities/tethys/docs/tethys_server.html b/src/help/utilities/tethys/docs/tethys_server.html new file mode 100644 index 00000000..50a61a06 --- /dev/null +++ b/src/help/utilities/tethys/docs/tethys_server.html @@ -0,0 +1,34 @@ + + + + + + + + Tethys Module Overview + + +

    Tethys Interface

    +

    Tethys Server

    +

    + Tethys is ... +

    + +
    +
    + +
    +
    +
    + + diff --git a/src/landMarks/LandmarkData.java b/src/landMarks/LandmarkData.java index 2be20e55..ef0cb561 100644 --- a/src/landMarks/LandmarkData.java +++ b/src/landMarks/LandmarkData.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.masterReference.MasterReferencePoint; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; import PamView.PamSymbol; @@ -49,7 +50,7 @@ public class LandmarkData extends Object implements Serializable, Cloneable, Man @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/landMarks/LandmarkDatas.java b/src/landMarks/LandmarkDatas.java index d4cd386d..73fb4785 100644 --- a/src/landMarks/LandmarkDatas.java +++ b/src/landMarks/LandmarkDatas.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LandmarkDatas implements Serializable, Cloneable, ManagedParameters { @@ -76,7 +77,7 @@ public class LandmarkDatas implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/levelMeter/LevelMeterParams.java b/src/levelMeter/LevelMeterParams.java index dd1b6752..c25860dc 100644 --- a/src/levelMeter/LevelMeterParams.java +++ b/src/levelMeter/LevelMeterParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LevelMeterParams implements Cloneable, Serializable, ManagedParameters { @@ -35,7 +36,7 @@ public class LevelMeterParams implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/AcquisitionSettings.java b/src/likelihoodDetectionModule/AcquisitionSettings.java index abf61481..10033395 100644 --- a/src/likelihoodDetectionModule/AcquisitionSettings.java +++ b/src/likelihoodDetectionModule/AcquisitionSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The AcquisitionSettings class provides a module-local storage object for holding @@ -48,7 +49,7 @@ public class AcquisitionSettings implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/ConfigurationDialogSettings.java b/src/likelihoodDetectionModule/ConfigurationDialogSettings.java index 6856e501..9011ffbd 100644 --- a/src/likelihoodDetectionModule/ConfigurationDialogSettings.java +++ b/src/likelihoodDetectionModule/ConfigurationDialogSettings.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The Class ConfigurationDialogSettings holds parameters about the @@ -28,7 +29,7 @@ public class ConfigurationDialogSettings implements Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("expandedState"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/likelihoodDetectionModule/GuardBand.java b/src/likelihoodDetectionModule/GuardBand.java index ccd9a6c0..cb07df7b 100644 --- a/src/likelihoodDetectionModule/GuardBand.java +++ b/src/likelihoodDetectionModule/GuardBand.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Represents the parameters that make up a guard band, used as @@ -106,7 +107,7 @@ public class GuardBand implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java b/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java index 9c405cdd..9481c26c 100644 --- a/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java +++ b/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java @@ -11,6 +11,7 @@ import java.util.Iterator; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The Class LikelihoodDetectionParameters provides the standard PamGuard @@ -271,7 +272,7 @@ public class LikelihoodDetectionParameters implements Serializable, Cloneable, M @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/LikelihoodFFTParameters.java b/src/likelihoodDetectionModule/LikelihoodFFTParameters.java index e90e51c8..13b85fda 100644 --- a/src/likelihoodDetectionModule/LikelihoodFFTParameters.java +++ b/src/likelihoodDetectionModule/LikelihoodFFTParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import fftManager.FFTParameters; import Spectrogram.WindowFunction; @@ -270,7 +271,7 @@ public class LikelihoodFFTParameters implements Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("sourceNumber"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/likelihoodDetectionModule/SignalBand.java b/src/likelihoodDetectionModule/SignalBand.java index 00e7af96..3b3150d6 100644 --- a/src/likelihoodDetectionModule/SignalBand.java +++ b/src/likelihoodDetectionModule/SignalBand.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Represents the parameters that make up a signal band, used as @@ -151,7 +152,7 @@ public class SignalBand implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/likelihoodDetectionModule/TargetConfiguration.java b/src/likelihoodDetectionModule/TargetConfiguration.java index 29c82890..0cc0e398 100644 --- a/src/likelihoodDetectionModule/TargetConfiguration.java +++ b/src/likelihoodDetectionModule/TargetConfiguration.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import likelihoodDetectionModule.normalizer.NormalizerProcess.NormalizerAlgorithm; /** @@ -453,7 +454,7 @@ public class TargetConfiguration implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/loc3d_Thode/TowedArray3DSQLLogging.java b/src/loc3d_Thode/TowedArray3DSQLLogging.java index c5a8b1f7..95bc98e6 100644 --- a/src/loc3d_Thode/TowedArray3DSQLLogging.java +++ b/src/loc3d_Thode/TowedArray3DSQLLogging.java @@ -1,5 +1,6 @@ package loc3d_Thode; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamDetectionLogging; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; @@ -17,7 +18,6 @@ public class TowedArray3DSQLLogging extends PamDetectionLogging { TowedArray3DController towedArray3DController; - PamTableDefinition tableDefinition; PamTableItem dateItem, range_boat_Item, range_f_Item, range_r_Item, depthItem, azi_boat_Item,azi_f_Item, azi_r_Item, tdd_Item, bearing_f_Item,bearing_r_Item, tds_f_Item, tds_r_Item, za_f_Item, za_r_Item; @@ -34,7 +34,7 @@ public class TowedArray3DSQLLogging extends PamDetectionLogging { this.towedArray3DController = towedArray3DController; // create the table definition. - tableDefinition = createTableDefinition(); + PamTableDefinition tableDefinition = createTableDefinition(); } public PamTableDefinition createTableDefinition() { diff --git a/src/loggerForms/FormPlotOptions.java b/src/loggerForms/FormPlotOptions.java index 8f55f828..9763d8ba 100644 --- a/src/loggerForms/FormPlotOptions.java +++ b/src/loggerForms/FormPlotOptions.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -95,7 +96,7 @@ public class FormPlotOptions implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("controlChoices"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/loggerForms/FormSettings.java b/src/loggerForms/FormSettings.java index 199edfe4..f7553e13 100644 --- a/src/loggerForms/FormSettings.java +++ b/src/loggerForms/FormSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Manage a bit of persistent data for a single Logger form description.

    @@ -32,7 +33,7 @@ public class FormSettings implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/loggerForms/FormsDataDisplayTable.java b/src/loggerForms/FormsDataDisplayTable.java index 26e2f5b3..1300fc79 100644 --- a/src/loggerForms/FormsDataDisplayTable.java +++ b/src/loggerForms/FormsDataDisplayTable.java @@ -261,6 +261,7 @@ public class FormsDataDisplayTable { + /** * Called when data have changed in the datablock. */ diff --git a/src/loggerForms/monitor/FormsSelectorParams.java b/src/loggerForms/monitor/FormsSelectorParams.java index d691af0c..d1797798 100644 --- a/src/loggerForms/monitor/FormsSelectorParams.java +++ b/src/loggerForms/monitor/FormsSelectorParams.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; public class FormsSelectorParams extends DataSelectParams implements Cloneable, Serializable, ManagedParameters { @@ -30,7 +31,7 @@ public class FormsSelectorParams extends DataSelectParams implements Cloneable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("formSelection"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/ltsa/LtsaModuleHeader.java b/src/ltsa/LtsaModuleHeader.java index 0b5d888e..50c1034d 100644 --- a/src/ltsa/LtsaModuleHeader.java +++ b/src/ltsa/LtsaModuleHeader.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleHeader; @@ -37,7 +38,7 @@ public class LtsaModuleHeader extends ModuleHeader implements ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftLength"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/ltsa/LtsaParameters.java b/src/ltsa/LtsaParameters.java index 2dfd9a62..dbf62ec0 100644 --- a/src/ltsa/LtsaParameters.java +++ b/src/ltsa/LtsaParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LtsaParameters implements Cloneable, Serializable, ManagedParameters { @@ -35,7 +36,7 @@ public class LtsaParameters implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/mapgrouplocaliser/MapGrouperSettings.java b/src/mapgrouplocaliser/MapGrouperSettings.java index 955542dc..440700b7 100644 --- a/src/mapgrouplocaliser/MapGrouperSettings.java +++ b/src/mapgrouplocaliser/MapGrouperSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.paneloverlay.OverlayDataInfo; import PamView.paneloverlay.overlaymark.MarkDataSelectorParams; import PamView.paneloverlay.overlaymark.OverlayMarkDataInfo; @@ -64,7 +65,7 @@ public class MapGrouperSettings implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("markDataSelectorParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/MTClassifier.java b/src/matchedTemplateClassifer/MTClassifier.java index ddde2bc7..9065daac 100644 --- a/src/matchedTemplateClassifer/MTClassifier.java +++ b/src/matchedTemplateClassifer/MTClassifier.java @@ -15,6 +15,7 @@ import Localiser.DelayMeasurementParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamArrayUtils; import PamUtils.PamInterp; import PamUtils.complex.ComplexArray; @@ -629,7 +630,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("inteprWaveformReject"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/MatchTemplate.java b/src/matchedTemplateClassifer/MatchTemplate.java index 7f758ddf..0990a22d 100644 --- a/src/matchedTemplateClassifer/MatchTemplate.java +++ b/src/matchedTemplateClassifer/MatchTemplate.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.RawDataHolder; import PamguardMVC.RawDataTransforms; @@ -51,7 +52,7 @@ public class MatchTemplate implements RawDataHolder, Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/matchedTemplateClassifer/MatchedTemplateParams.java b/src/matchedTemplateClassifer/MatchedTemplateParams.java index 05f8b107..edd2b912 100644 --- a/src/matchedTemplateClassifer/MatchedTemplateParams.java +++ b/src/matchedTemplateClassifer/MatchedTemplateParams.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamSymbolType; import PamView.symbol.SymbolData; import fftFilter.FFTFilterParams; @@ -150,7 +151,7 @@ public class MatchedTemplateParams implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftFilterParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java b/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java index acf38f67..3b248ea9 100644 --- a/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java +++ b/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java @@ -7,6 +7,7 @@ import java.util.List; import PamUtils.PamArrayUtils; import PamguardMVC.PamDataUnit; import PamguardMVC.debug.Debug; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -49,7 +50,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(typeTable); pamTableDefinition.addTableItem(mtThresholdsTable); pamTableDefinition.addTableItem(mtMatchCorrsTable); @@ -58,7 +59,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { MatchedClickAnnotation clickAnnotation = (MatchedClickAnnotation) pamDataUnit.findDataAnnotation(MatchedClickAnnotation.class); @@ -95,7 +96,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { String threshold = mtThresholdsTable.getDeblankedStringValue(); String mtMatchCorrs = mtMatchCorrsTable.getDeblankedStringValue(); diff --git a/src/mcc/mccacquisition/MCCDaqParams.java b/src/mcc/mccacquisition/MCCDaqParams.java index f1fc3450..ba44c99e 100644 --- a/src/mcc/mccacquisition/MCCDaqParams.java +++ b/src/mcc/mccacquisition/MCCDaqParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Acquisition.DaqSystemXMLManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import analoginput.AnalogRangeData; import simulatedAcquisition.SimProcess; @@ -51,7 +52,7 @@ public class MCCDaqParams implements Serializable, Cloneable, ManagedParameters return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/metadata/MetaDataContol.java b/src/metadata/MetaDataContol.java new file mode 100644 index 00000000..98093b08 --- /dev/null +++ b/src/metadata/MetaDataContol.java @@ -0,0 +1,114 @@ +package metadata; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JFrame; +import javax.swing.JMenuItem; + +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamController.PamSettingManager; +import PamController.PamSettings; +import metadata.swing.MetaDataDialog; + +/** + * Class to handle Project MetaData. Am making this a PAMControlledUnit, but may never + * register it with the model ? Will see what advantages and disadvantages there are. + * @author dg50 + * + */ +public class MetaDataContol extends PamControlledUnit implements PamSettings { + + public static final String unitType = "Meta Data"; + + private static MetaDataContol singleInstance; + + private PamguardMetaData pamguardMetaData = new PamguardMetaData(); + +// private ParameterSetManager deploymentSetManager; + + + private MetaDataContol(String unitName) { + super(unitType, unitName); +// deploymentSetManager = new ParameterSetManager(deploymentData, "Deployment Data"); + PamSettingManager.getInstance().registerSettings(this); + } + + /** + * Easy getter for singleton MetaData controller. + * @return meta data controller + */ + public static MetaDataContol getMetaDataControl() { + if (singleInstance == null) { + singleInstance = new MetaDataContol(unitType); + // add this line to add it to the main modules list. Then it will get menu's, etc. + PamController.getInstance().addControlledUnit(singleInstance); + } + return singleInstance; + } + + /** + * Get PAMGuard Metadata. This contains a nilus Deployment object wrapped up + * so that it can be serialised into other PAMGuard settings. + * @return PAMGuard meta data + */ + public PamguardMetaData getMetaData() { + return pamguardMetaData; + } + + /** + * Set the meta data object. + * @param metaData + */ + public void setMetaData(PamguardMetaData metaData) { + this.pamguardMetaData = metaData; + } + + @Override + public Serializable getSettingsReference() { + pamguardMetaData.checkSerialisation(); + return pamguardMetaData; + } + + @Override + public long getSettingsVersion() { + return PamguardMetaData.serialVersionUID; + } + + @Override + public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { + Object obj = pamControlledUnitSettings.getSettings(); + if (obj instanceof PamguardMetaData) { + pamguardMetaData = (PamguardMetaData) obj; + return true; + } + return false; + } + +// @Override + public JMenuItem createMenu(JFrame parentFrame) { + JMenuItem menuItem = new JMenuItem("Project information ..."); + menuItem.setToolTipText("General project objectives, region, etc."); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showDialog(parentFrame); + } + }); + return menuItem; + } + + protected void showDialog(JFrame parentFrame) { + PamguardMetaData newData = MetaDataDialog.showDialog(parentFrame, pamguardMetaData); + if (newData != null) { + this.pamguardMetaData = newData; + // send around a notification ? + } + } + + + +} diff --git a/src/metadata/PamguardMetaData.java b/src/metadata/PamguardMetaData.java new file mode 100644 index 00000000..ae4064ab --- /dev/null +++ b/src/metadata/PamguardMetaData.java @@ -0,0 +1,111 @@ +package metadata; + +import java.io.Serializable; + +import PamUtils.LatLong; +import nilus.ContactInfo; +import nilus.Deployment; +import nilus.DeploymentRecoveryDetails; +import nilus.DescriptionType; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.ResponsibleParty; +import tethys.niluswraps.NilusSettingsWrapper; + +/** + * Meta data for a PAMGuard data set. This is based around serialisable versions of + * nilus classes to be compliant with both Tethys and PAMGuard settings files. May only + * need a Deployment object, but scope for adding others / other fields if it's useful. + * @author dg50 + * + */ +public class PamguardMetaData implements Serializable { + + public static final long serialVersionUID = 1L; + + private NilusSettingsWrapper deploymentWrapper; + + public boolean useAudioForDeploymentTimes = true; + +// /** +// * Deployment time (used if different +// */ +// private Long deploymentMillis; +// +// private Long recoverMillis; +// +// private LatLong recoverLatLong; + + /** + * Get the deployment data + * @return nilus deployment + */ + public Deployment getDeployment() { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + Deployment deployment = deploymentWrapper.getNilusObject(Deployment.class); + if (deployment == null) { + deployment = new Deployment(); + try { + Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + deploymentWrapper.setNilusObject(deployment); + } + // check some fields we know we'll need that the Helper may not have managed. + if (deployment.getDescription() == null) { + deployment.setDescription(new DescriptionType()); + } + if (deployment.getMetadataInfo() == null) { + deployment.setMetadataInfo(new MetadataInfo()); + } + if (deployment.getMetadataInfo().getContact() == null) { + deployment.getMetadataInfo().setContact(new ResponsibleParty()); + } + if (deployment.getMetadataInfo().getContact().getContactInfo() == null) { + deployment.getMetadataInfo().getContact().setContactInfo(new ContactInfo()); + } + + if (deployment.getDeploymentDetails() == null) { + deployment.setDeploymentDetails(new DeploymentRecoveryDetails()); + } + if (deployment.getRecoveryDetails() == null) { + deployment.setRecoveryDetails(new DeploymentRecoveryDetails()); + } + return deployment; + } + + /** + * Set the deployment data. + * @param deployment nilus deployment + */ + public void setDeployment(Deployment deployment) { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + deploymentWrapper.setNilusObject(deployment); + } + + /** + * @return the deploymentWrapper + */ + public NilusSettingsWrapper getDeploymentWrapper() { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + return deploymentWrapper; + } + + public void checkSerialisation() { + // check that all wrappers have their xml up to date. + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + deploymentWrapper.reSerialise(); + } + + + +} diff --git a/src/metadata/swing/MetaDataDialog.java b/src/metadata/swing/MetaDataDialog.java new file mode 100644 index 00000000..9f744391 --- /dev/null +++ b/src/metadata/swing/MetaDataDialog.java @@ -0,0 +1,121 @@ +package metadata.swing; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Window; + +import javax.swing.BoxLayout; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.border.TitledBorder; + +import PamController.PamController; +import PamView.dialog.PamDialog; +import PamView.panel.PamNorthPanel; +import PamView.panel.WestAlignedPanel; +import metadata.PamguardMetaData; +import nilus.Deployment; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysState.StateType; +import tethys.deployment.swing.ProjectInformationPanel; +import tethys.swing.export.DeploymentPeriodPanel; +import tethys.swing.export.DescriptionTypePanel; +import tethys.swing.export.ResponsiblePartyPanel; + +public class MetaDataDialog extends PamDialog { + + private static MetaDataDialog singleInstance; + + private PamguardMetaData pamguardMetaData; + + private DescriptionTypePanel descriptionPanel; + + private ProjectInformationPanel projectInformationPanel; + + private DeploymentPeriodPanel deploymentPeriodPanel; + + private ResponsiblePartyPanel responsiblePanel; + + private TethysControl tethysControl; + + private MetaDataDialog(Window parentFrame) { + super(parentFrame, "Project information", false); + + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + JTabbedPane tabbedPane = new JTabbedPane(); + + tethysControl = (TethysControl) PamController.getInstance().findControlledUnit(TethysControl.unitType); + + projectInformationPanel = new ProjectInformationPanel(parentFrame, null); + descriptionPanel = new DescriptionTypePanel(null, false, false, false); + deploymentPeriodPanel = new DeploymentPeriodPanel(parentFrame); + descriptionPanel.getMainPanel().setPreferredSize(new Dimension(400,300)); + + responsiblePanel = new ResponsiblePartyPanel(); + JPanel northPanel = new JPanel(); + WestAlignedPanel wp; + northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS)); + + northPanel.add(wp = new WestAlignedPanel(projectInformationPanel.getMainPanel())); + wp.setBorder(new TitledBorder("General project information")); + northPanel.add(wp = new WestAlignedPanel(responsiblePanel.getMainPanel())); + wp.setBorder(new TitledBorder("Contact information")); + + JPanel dpPanel = new WestAlignedPanel(deploymentPeriodPanel.getMainPanel()); + dpPanel.setBorder(new TitledBorder("Deployment period")); + + mainPanel.add(tabbedPane, BorderLayout.CENTER); + tabbedPane.add(northPanel, "General"); + tabbedPane.add(descriptionPanel.getMainPanel(), "Description"); + tabbedPane.add(dpPanel, "Deployment"); + + setResizable(true); + + setDialogComponent(mainPanel); + } + + + + + public static PamguardMetaData showDialog(Window frame, PamguardMetaData pamguardMetaData) { + singleInstance = new MetaDataDialog(frame); + singleInstance.setParams(pamguardMetaData); + singleInstance.setVisible(true); + return singleInstance.pamguardMetaData; + } + + private void setParams(PamguardMetaData pamguardMetaData) { + this.pamguardMetaData = pamguardMetaData; + Deployment deployment = pamguardMetaData.getDeployment(); + projectInformationPanel.setParams(deployment); + descriptionPanel.setParams(deployment.getDescription()); + responsiblePanel.setParams(deployment.getMetadataInfo().getContact()); + deploymentPeriodPanel.setParams(pamguardMetaData); + } + + @Override + public boolean getParams() { + Deployment deployment = pamguardMetaData.getDeployment(); + boolean ok = descriptionPanel.getParams(deployment.getDescription()); + ok &= responsiblePanel.getParams(deployment.getMetadataInfo().getContact()); + ok &= deploymentPeriodPanel.getParams(pamguardMetaData); + + if (tethysControl != null) { + tethysControl.sendStateUpdate(new TethysState(StateType.NEWPROJECTSELECTION)); + } + return ok; + } + + @Override + public void cancelButtonPressed() { + pamguardMetaData = null; + } + + @Override + public void restoreDefaultSettings() { + + } + +} diff --git a/src/networkTransfer/emulator/EmulatorParams.java b/src/networkTransfer/emulator/EmulatorParams.java index e4fe0f74..3f38266a 100644 --- a/src/networkTransfer/emulator/EmulatorParams.java +++ b/src/networkTransfer/emulator/EmulatorParams.java @@ -8,6 +8,7 @@ import PamController.PamControlledUnitSettings; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; public class EmulatorParams implements Cloneable, Serializable, ManagedParameters { @@ -50,7 +51,7 @@ public class EmulatorParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("circleRadius"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/networkTransfer/receive/BuoyStatusData.java b/src/networkTransfer/receive/BuoyStatusData.java index 6b17a6ad..8138f4bf 100644 --- a/src/networkTransfer/receive/BuoyStatusData.java +++ b/src/networkTransfer/receive/BuoyStatusData.java @@ -5,6 +5,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; /** @@ -140,7 +141,7 @@ public class BuoyStatusData implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/receive/BuoyStatusValue.java b/src/networkTransfer/receive/BuoyStatusValue.java index d73a5acd..a42ea7ff 100644 --- a/src/networkTransfer/receive/BuoyStatusValue.java +++ b/src/networkTransfer/receive/BuoyStatusValue.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class BuoyStatusValue implements Serializable, ManagedParameters { @@ -53,7 +54,7 @@ public class BuoyStatusValue implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/receive/NetworkReceiveParams.java b/src/networkTransfer/receive/NetworkReceiveParams.java index f067c789..488899c5 100644 --- a/src/networkTransfer/receive/NetworkReceiveParams.java +++ b/src/networkTransfer/receive/NetworkReceiveParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NetworkReceiveParams implements Cloneable, Serializable, ManagedParameters { @@ -40,7 +41,7 @@ public class NetworkReceiveParams implements Cloneable, Serializable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/send/NetworkSendParams.java b/src/networkTransfer/send/NetworkSendParams.java index 9e0024d8..87e25b0c 100644 --- a/src/networkTransfer/send/NetworkSendParams.java +++ b/src/networkTransfer/send/NetworkSendParams.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamDataBlock; public class NetworkSendParams implements Serializable, Cloneable, ManagedParameters { @@ -108,7 +109,7 @@ public class NetworkSendParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("selectedDataBlocks"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/nidaqdev/networkdaq/NIDaqLogging.java b/src/nidaqdev/networkdaq/NIDaqLogging.java index dc12309b..75022e5c 100644 --- a/src/nidaqdev/networkdaq/NIDaqLogging.java +++ b/src/nidaqdev/networkdaq/NIDaqLogging.java @@ -3,6 +3,7 @@ package nidaqdev.networkdaq; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -20,12 +21,12 @@ public class NIDaqLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(crioTemperature); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Double lastTemp = niNetworkDaq.getLastTemperature(); if (lastTemp == null) { crioTemperature.setValue(null); @@ -38,7 +39,7 @@ public class NIDaqLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } diff --git a/src/nidaqdev/networkdaq/NINetworkDaqParams.java b/src/nidaqdev/networkdaq/NINetworkDaqParams.java index 7458739e..a7f67845 100644 --- a/src/nidaqdev/networkdaq/NINetworkDaqParams.java +++ b/src/nidaqdev/networkdaq/NINetworkDaqParams.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import Acquisition.DaqSystemXMLManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NINetworkDaqParams implements Serializable, Cloneable, ManagedParameters { @@ -169,7 +170,7 @@ public class NINetworkDaqParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { if (DaqSystemXMLManager.isSelected(NINetworkDaq.systemName)) { - return PamParameterSet.autoGenerate(this); + return PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); } return null; } diff --git a/src/nmeaEmulator/NMEAEmulatorParams.java b/src/nmeaEmulator/NMEAEmulatorParams.java index 1889ca17..d7b89529 100644 --- a/src/nmeaEmulator/NMEAEmulatorParams.java +++ b/src/nmeaEmulator/NMEAEmulatorParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NMEAEmulatorParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class NMEAEmulatorParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/noiseBandMonitor/NoiseBandSettings.java b/src/noiseBandMonitor/NoiseBandSettings.java index d905c536..8f00571c 100644 --- a/src/noiseBandMonitor/NoiseBandSettings.java +++ b/src/noiseBandMonitor/NoiseBandSettings.java @@ -7,6 +7,7 @@ import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NoiseBandSettings implements Serializable, Cloneable, ManagedParameters { @@ -59,7 +60,7 @@ public class NoiseBandSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("showStandard"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseMonitor/NoiseDataBlock.java b/src/noiseMonitor/NoiseDataBlock.java index b5e7f628..effbd591 100644 --- a/src/noiseMonitor/NoiseDataBlock.java +++ b/src/noiseMonitor/NoiseDataBlock.java @@ -2,11 +2,18 @@ package noiseMonitor; import noiseMonitor.alarm.NoiseAlarmCounter; import noiseMonitor.alarm.NoiseAlarmProvider; +import noiseMonitor.species.TethysNoiseDataProvider; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; +import tethys.species.FixedSpeciesManager; import alarm.AlarmCounter; import alarm.AlarmCounterProvider; import alarm.AlarmDataSource; import PamUtils.FrequencyFormat; import PamUtils.PamUtils; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamDataBlock; import PamguardMVC.PamProcess; @@ -32,13 +39,15 @@ public class NoiseDataBlock extends PamDataBlock implements Alarm private NoiseAlarmProvider noiseAlarmCounter; /** - * These are the names used in the database columns, so dont' change them on pain of + * These are the names used in the database columns, so don't change them on pain of * nothing ever working ever again ! */ public static final String[] measureNames = {"mean", "median", "low95", "high95", "Min", "Max", "Peak"}; public static final String[] displayNames = {"Mean", "Median", "Lower 95%", "Upper 95%", "Minimum", "Maximim", "Peak"}; private int statisticTypes; + private TethysNoiseDataProvider tethysNoiseDataProvider; + private FixedSpeciesManager fixedSpeciesManager; public NoiseDataBlock(String dataName, PamProcess parentProcess, int channelMap) { @@ -244,6 +253,27 @@ public class NoiseDataBlock extends PamDataBlock implements Alarm } return noiseAlarmCounter; } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (tethysNoiseDataProvider == null) { + tethysNoiseDataProvider = new TethysNoiseDataProvider(tethysControl, this); + } + return tethysNoiseDataProvider; + } + + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (fixedSpeciesManager == null) { + fixedSpeciesManager = new FixedSpeciesManager(this, -10, "anthropogenic", "noise"); + } + return fixedSpeciesManager; + } } diff --git a/src/noiseMonitor/NoiseDisplaySettings.java b/src/noiseMonitor/NoiseDisplaySettings.java index 7ef4f5de..b70db3ac 100644 --- a/src/noiseMonitor/NoiseDisplaySettings.java +++ b/src/noiseMonitor/NoiseDisplaySettings.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class NoiseDisplaySettings implements Serializable, Cloneable, ManagedParameters { @@ -70,7 +71,7 @@ public class NoiseDisplaySettings implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("displayLengthSeconds"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseMonitor/NoiseLogging.java b/src/noiseMonitor/NoiseLogging.java index 4bbc0cfd..a3a62d61 100644 --- a/src/noiseMonitor/NoiseLogging.java +++ b/src/noiseMonitor/NoiseLogging.java @@ -116,5 +116,27 @@ public class NoiseLogging extends SQLLogging { } } } + + private long lastTime; + + @Override + protected PamDataUnit createDataUnit(SQLTypes sqlTypes, long timeMilliseconds, int databaseIndex) { + int chan = channelNumber.getIntegerValue(); + int nBands = noiseDataBlock.getBandLoEdges().length; + int nMeasures = noiseDataBlock.getUsedMeasureNames().length; + if (nMeasures * nBands != bandItems.length) { + return null; + } + double[][] bandData = new double[nBands][nMeasures]; + for (int iBand = 0, iCol = 0; iBand < nBands; iBand++) { + for (int iMeasure = 0; iMeasure < nMeasures; iMeasure++, iCol++) { + bandData[iBand][iMeasure] = bandItems[iCol].getDoubleValue(); + } + } + + NoiseDataUnit noiseDataUnit = new NoiseDataUnit(timeMilliseconds, 1< measurements = params.getFrequencyMeasurementsDB(); + double[][] noiseData = noiseDataUnit.getNoiseBandData(); + int meanIndex = -1; + for (int i = 0; i < nTypes; i++) { + int type = PamUtils.getNthChannel(i, statTypes); + String name = noiseDataBlock.getMeasureName(type); + if (1< effortKinds, + StreamExportParams exportParams) { + super.getEffortKinds(pDeployment, effortKinds, exportParams); + DetectionEffortKind kind = effortKinds.get(0); + nilus.DetectionEffortKind.Parameters params = kind.getParameters(); + if (params == null) { + params = new nilus.DetectionEffortKind.Parameters(); + try { + Helper.createRequiredElements(params); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + kind.setParameters(params); + } + List fMeasures = params.getFrequencyMeasurementsHz(); + double[] loEdges = noiseDataBlock.getBandLoEdges(); + double[] hiEdges = noiseDataBlock.getBandHiEdges(); + // put lot mean into the array + for (int i = 0; i < loEdges.length; i++) { + fMeasures.add(roundSignificantFigures(Math.sqrt(loEdges[i]*hiEdges[i]), 4)); + } + } + + @Override + public boolean wantExportDialogCard(ExportWizardCard wizPanel) { + if (wizPanel.getClass() == GranularityCard.class) { + return false; + } + return super.wantExportDialogCard(wizPanel); + } + +} diff --git a/src/noiseOneBand/OneBandAlarmParameters.java b/src/noiseOneBand/OneBandAlarmParameters.java index 90a1659c..3e4e5a69 100644 --- a/src/noiseOneBand/OneBandAlarmParameters.java +++ b/src/noiseOneBand/OneBandAlarmParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandAlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -37,7 +38,7 @@ public class OneBandAlarmParameters implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/noiseOneBand/OneBandDisplayParams.java b/src/noiseOneBand/OneBandDisplayParams.java index 04cf01d7..fe9b7a82 100644 --- a/src/noiseOneBand/OneBandDisplayParams.java +++ b/src/noiseOneBand/OneBandDisplayParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class OneBandDisplayParams implements Serializable, Cloneable, ManagedParameters { @@ -61,7 +62,7 @@ public class OneBandDisplayParams implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("displayChannels"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseOneBand/OneBandParameters.java b/src/noiseOneBand/OneBandParameters.java index b35e4f68..ea2f3320 100644 --- a/src/noiseOneBand/OneBandParameters.java +++ b/src/noiseOneBand/OneBandParameters.java @@ -10,6 +10,7 @@ import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandParameters implements Serializable, Cloneable, ManagedParameters { @@ -235,7 +236,7 @@ public class OneBandParameters implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("filterParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseOneBand/offline/OneBandSummaryParams.java b/src/noiseOneBand/offline/OneBandSummaryParams.java index 7565c6e7..14e71708 100644 --- a/src/noiseOneBand/offline/OneBandSummaryParams.java +++ b/src/noiseOneBand/offline/OneBandSummaryParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandSummaryParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class OneBandSummaryParams implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/offlineProcessing/TaskGroupParams.java b/src/offlineProcessing/TaskGroupParams.java index 25497c24..c04a88cc 100644 --- a/src/offlineProcessing/TaskGroupParams.java +++ b/src/offlineProcessing/TaskGroupParams.java @@ -8,6 +8,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameter control for offline task groups. @@ -137,7 +138,7 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("taskSelection"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/pamMaths/PamVector.java b/src/pamMaths/PamVector.java index 910e0bc9..d491f01e 100644 --- a/src/pamMaths/PamVector.java +++ b/src/pamMaths/PamVector.java @@ -382,7 +382,7 @@ public class PamVector implements Serializable, Cloneable, PamCoordinate, Manage * @return magnitude of those dimensions only. */ public double norm(int nDim) { - return Math.sqrt(normSquared(2)); + return Math.sqrt(normSquared(nDim)); } /** * diff --git a/src/pamguard/Pamguard.java b/src/pamguard/Pamguard.java index 0a6da447..33009522 100644 --- a/src/pamguard/Pamguard.java +++ b/src/pamguard/Pamguard.java @@ -731,6 +731,47 @@ public class Pamguard { } } } + /* + * Some bits that need added to Maven POM. + * + + + org.eclipse.persistence + org.eclipse.persistence.moxy + 2.5.0 + + + javax.xml.bind + jaxb-api + 2.4.0-b180830.0359 + + + org.glassfish.jaxb + jaxb-runtime + 2.4.0-b180830.0438 + + + org.glassfish.jaxb + jaxb-xjc + 2.4.0-b180830.0438 + + + + */ } diff --git a/src/quickAnnotation/QuickAnnotationParameters.java b/src/quickAnnotation/QuickAnnotationParameters.java index fd8ed2a7..65e3b05b 100644 --- a/src/quickAnnotation/QuickAnnotationParameters.java +++ b/src/quickAnnotation/QuickAnnotationParameters.java @@ -9,6 +9,7 @@ import PamController.PamSettingManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import difar.DifarControl; import difar.DifarParameters; import generalDatabase.lookupTables.LookupItem; @@ -96,7 +97,7 @@ public class QuickAnnotationParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("exportClips"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java b/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java index 7ad1ffb9..41ef495e 100644 --- a/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java @@ -3,6 +3,7 @@ package rawDeepLearningClassifier.dataPlotFX; import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.scene.paint.Color; /** @@ -25,7 +26,7 @@ public class DLPredDisplayParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java b/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java index 72761199..b046b27b 100644 --- a/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java +++ b/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java @@ -1,6 +1,7 @@ package rawDeepLearningClassifier.logging; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.SQLLoggingAddon; import generalDatabase.SQLTypes; @@ -12,19 +13,19 @@ public class DLAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { // TODO Auto-generated method stub } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } diff --git a/src/rocca/RoccaParameters.java b/src/rocca/RoccaParameters.java index bec1fecb..c7db4aae 100644 --- a/src/rocca/RoccaParameters.java +++ b/src/rocca/RoccaParameters.java @@ -30,6 +30,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters for Rocca
    @@ -856,7 +857,7 @@ public class RoccaParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("runAncCalcs4Clicks"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/seismicVeto/VetoParameters.java b/src/seismicVeto/VetoParameters.java index 0ca08357..e41907f7 100644 --- a/src/seismicVeto/VetoParameters.java +++ b/src/seismicVeto/VetoParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class VetoParameters implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public class VetoParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("backgroundConstant"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/serialComms/SerialPortParameters.java b/src/serialComms/SerialPortParameters.java index bb9d699c..373852fd 100644 --- a/src/serialComms/SerialPortParameters.java +++ b/src/serialComms/SerialPortParameters.java @@ -29,6 +29,7 @@ import com.fazecast.jSerialComm.SerialPort; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @author David McLaren, Paul Redmond @@ -166,7 +167,7 @@ public class SerialPortParameters implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/simulatedAcquisition/SimObject.java b/src/simulatedAcquisition/SimObject.java index 053c8a9b..335139fb 100644 --- a/src/simulatedAcquisition/SimObject.java +++ b/src/simulatedAcquisition/SimObject.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import simulatedAcquisition.movement.MovementModel; import simulatedAcquisition.movement.MovementModels; @@ -150,7 +151,7 @@ public class SimObject implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("depth"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/simulatedAcquisition/movement/CircularMovementParams.java b/src/simulatedAcquisition/movement/CircularMovementParams.java index 4fe63e95..c956209e 100644 --- a/src/simulatedAcquisition/movement/CircularMovementParams.java +++ b/src/simulatedAcquisition/movement/CircularMovementParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class CircularMovementParams implements Serializable, Cloneable, ManagedParameters { @@ -84,7 +85,7 @@ public class CircularMovementParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/simulatedAcquisition/movement/GridMovementParams.java b/src/simulatedAcquisition/movement/GridMovementParams.java index 210ac943..72ae6cb2 100644 --- a/src/simulatedAcquisition/movement/GridMovementParams.java +++ b/src/simulatedAcquisition/movement/GridMovementParams.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GridMovementParams implements Serializable, Cloneable, ManagedParameters { @@ -42,7 +43,7 @@ public class GridMovementParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("distRangeMetres"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/soundPlayback/PlaybackParameters.java b/src/soundPlayback/PlaybackParameters.java index 08c1e56a..2d7d22d1 100644 --- a/src/soundPlayback/PlaybackParameters.java +++ b/src/soundPlayback/PlaybackParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters controlling sound playback @@ -165,7 +166,7 @@ public class PlaybackParameters implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/soundPlayback/preprocess/EnvelopeParams.java b/src/soundPlayback/preprocess/EnvelopeParams.java index b3e0587c..7dd143e9 100644 --- a/src/soundPlayback/preprocess/EnvelopeParams.java +++ b/src/soundPlayback/preprocess/EnvelopeParams.java @@ -7,6 +7,7 @@ import Filters.FilterParams; import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EnvelopeParams implements Cloneable, Serializable, ManagedParameters { @@ -87,7 +88,7 @@ public class EnvelopeParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/soundtrap/STClickControl.java b/src/soundtrap/STClickControl.java index 203357fe..8e7ca7b0 100644 --- a/src/soundtrap/STClickControl.java +++ b/src/soundtrap/STClickControl.java @@ -37,6 +37,7 @@ import javax.swing.JSeparator; import org.pamguard.x3.sud.SUDClickDetectorInfo; import Acquisition.AcquisitionControl; +import PamController.PamSensor; import PamController.PamControlledUnitSettings; import PamController.PamController; import PamController.PamSettingManager; @@ -54,7 +55,7 @@ import soundtrap.sud.SudFileDWVHandler; * @author mo55 * */ -public class STClickControl extends ClickControl { +public class STClickControl extends ClickControl implements PamSensor { private SUDClickDetectorInfo sudClickDetectorInfo; @@ -229,6 +230,17 @@ public class STClickControl extends ClickControl { public void setSudClickDetectorInfo(SUDClickDetectorInfo sudClickDetectorInfo) { this.sudClickDetectorInfo = sudClickDetectorInfo; } + + @Override + public String getSensorDescription() { + String desc = String.format("SoundTrap Click Detector at %dHz", (int) getClickDataBlock().getSampleRate()); + return desc; + } + + @Override + public String getSensorId() { + return null; + } /** * Class to handle SoundTrap click detector settings without messing up diff --git a/src/soundtrap/STToolsParams.java b/src/soundtrap/STToolsParams.java index 722c6fb6..514b96d6 100644 --- a/src/soundtrap/STToolsParams.java +++ b/src/soundtrap/STToolsParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class STToolsParams implements Serializable, Cloneable, ManagedParameters { @@ -62,7 +63,7 @@ public class STToolsParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java b/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java index 0931c963..9cfa3765 100644 --- a/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java +++ b/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SpectrogramNoiseSettings implements Serializable, Cloneable, ManagedParameters { @@ -79,7 +80,7 @@ public class SpectrogramNoiseSettings implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("runMethod"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java b/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java index 23e9f1f7..18f1811e 100644 --- a/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java +++ b/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AverageSubtractionParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class AverageSubtractionParameters implements Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java b/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java index fe91beba..c24aed99 100644 --- a/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java +++ b/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MedianFilterParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class MedianFilterParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/threshold/ThresholdParams.java b/src/spectrogramNoiseReduction/threshold/ThresholdParams.java index 8842e6e0..5674d577 100644 --- a/src/spectrogramNoiseReduction/threshold/ThresholdParams.java +++ b/src/spectrogramNoiseReduction/threshold/ThresholdParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ThresholdParams implements Serializable, Cloneable, ManagedParameters { @@ -27,7 +28,7 @@ public class ThresholdParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/targetMotionOld/TargetMotionSQLLogging.java b/src/targetMotionOld/TargetMotionSQLLogging.java index 6017a12b..4f4f133e 100644 --- a/src/targetMotionOld/TargetMotionSQLLogging.java +++ b/src/targetMotionOld/TargetMotionSQLLogging.java @@ -15,6 +15,7 @@ import PamDetection.AbstractLocalisation; import PamDetection.LocContents; import PamUtils.LatLong; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -119,7 +120,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(modelName); @@ -146,7 +147,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { AbstractLocalisation tmResult = pamDataUnit.getLocalisation(); clearEverything(); @@ -218,7 +219,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private boolean saveGroupLocalisation(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private boolean saveGroupLocalisation(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, GroupLocalisation groupLocalisation) { int nAmbiguities = groupLocalisation.getAmbiguityCount(); @@ -239,7 +240,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private boolean saveGroupLocalisation(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private boolean saveGroupLocalisation(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, int resultIndex, GroupLocResult tmResult) { @@ -323,7 +324,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { GroupLocalisation tml = new GroupLocalisation(pamDataUnit, null); @@ -341,7 +342,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private GroupLocResult loadLocResult(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private GroupLocResult loadLocResult(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, GroupLocalisation tml, int resultIndex) { double latVal, longVal; diff --git a/src/tethys/Collection.java b/src/tethys/Collection.java new file mode 100644 index 00000000..93a6acb2 --- /dev/null +++ b/src/tethys/Collection.java @@ -0,0 +1,136 @@ +package tethys; + +/** + * Names of Tethys Collections. These are the plural names, though contain functionality + * to get the document names, which are generally the singular of the enum + * @author dg50 + * + */ +public enum Collection { + + Deployments, Detections, Calibrations, Localizations, SpeciesAbbreviations, Ensembles, SourceMaps, ITIS, ITIS_ranks, OTHER; + + /** + * A list of the main collections in the database, i.e. ones the user will + * possibly want to interract with through the GUI. + * @return list of main collections. + */ + public static Collection[] mainList() { + Collection[] cs = {Deployments, Detections, Calibrations, Localizations, SpeciesAbbreviations, Ensembles}; + return cs; + } + /** + * Get the name of a document in this collection, this is generally the singular + * of the collection name. + * @return Document name, e.g. Detection for Detections + */ + public String documentName() { + switch (this) { + case Calibrations: + return "Calibration"; + case Deployments: + return "Deployment"; + case Detections: + return "Detections"; // this one is plural ! + case Localizations: + return "Localize"; + case SpeciesAbbreviations: + return "SpeciesAbbreviation"; + case Ensembles: + return "Ensemble"; + default: + break; + } + return null; + } + + public String collectionName() { + return this.toString(); + } + + /** + * Find a collection for the given name. This does + * a bit more than the simple 'valueof' since it also + * allows the user to input a documentname in place, which + * is just the collection name without the plural 's' on the end + * @param name Collection name. + * @return Collection or null. + */ + public static Collection fromName(String name) { + Collection c = Collection.valueOf(name); + if (c != null) { + return c; + } + /** + * Otherwise, may need to do a longer search to see if the user has passed + * the singular document name. + */ + if (name.endsWith("s") == false) { + c = Collection.valueOf(name+"s"); + if (c != null) { + return c; + } + } + return null; + } + /** + * get Tethys collection name from nilus collection objects + * @param className nilus object Class Name + * @return name of Tethys collection + */ + public static Collection fromClass(Class nilusClass) { + String className = nilusClass.getName(); + switch(className) { + case "nilus.Deployment": + return Deployments; + case "nilus.Detections": + return Detections; + case "nilus.Calibration": + return Calibrations; + case "nilus.Ensemble": + return Ensembles; + case "nilus.Localization": + return Localizations; + case "nilus.SpeciesAbbreviation": + return SpeciesAbbreviations; + case "nilus.SourceMap": + return SourceMaps; + case "nilus.ITIS": + return ITIS; + case "nilus.ranks": + return ITIS_ranks; + default: + return null; + } + } +// /** +// * get Tethys collection name from nilus collection objects +// * @param className nilus object Class Name +// * @return name of Tethys collection +// */ +// public static String getCollection(Class nilusClass) { +// String className = nilusClass.getName(); +// switch(className) { +// case "nilus.Deployment": +// return "Deployments"; +// case "nilus.Detections": +// return "Detections"; +// case "nilus.Calibration": +// return "Calibrations"; +// case "nilus.Ensemble": +// return "Ensembles"; +// case "nilus.Localization": +// return "Localizations"; +// case "nilus.SpeciesAbbreviation": +// return "SpeciesAbbreviations"; +// case "nilus.SourceMap": +// return "SourceMaps"; +// case "nilus.ITIS": +// return "ITIS"; +// case "nilus.ranks": +// return "ITIS_ranks"; +// default: +// return ""; +// } +// } +} diff --git a/src/tethys/DocumentInfo.java b/src/tethys/DocumentInfo.java new file mode 100644 index 00000000..7ad2d750 --- /dev/null +++ b/src/tethys/DocumentInfo.java @@ -0,0 +1,49 @@ +package tethys; + +/** + * Basic information about a document that can be used to + * make document lists. + * @author dg50 + * + */ +public class DocumentInfo implements Comparable { + + private Collection collection; + private String documentName; + private String documentId; + + /** + * @param collection + * @param documentName + * @param documentId + */ + public DocumentInfo(Collection collection, String documentName, String documentId) { + this.collection = collection; + this.documentName = documentName; + this.documentId = documentId; + } + @Override + public int compareTo(DocumentInfo o) { + return this.documentName.compareTo(o.documentName); + } + /** + * @return the collection + */ + public Collection getCollection() { + return collection; + } + /** + * @return the documentName + */ + public String getDocumentName() { + return documentName; + } + /** + * @return the documentId + */ + public String getDocumentId() { + return documentId; + } + + +} diff --git a/src/tethys/DocumentNilusObject.java b/src/tethys/DocumentNilusObject.java new file mode 100644 index 00000000..c6b5a402 --- /dev/null +++ b/src/tethys/DocumentNilusObject.java @@ -0,0 +1,32 @@ +package tethys; + +/** + * information about a document AND the nilus object to go with it. + * @author dg50 + * + * @param + */ +public class DocumentNilusObject extends DocumentInfo { + + private T nilusObject; + + public DocumentNilusObject(Collection collection, String documentName, String documentId, T nilusObject) { + super(collection, documentName, documentId); + this.nilusObject = nilusObject; + } + + /** + * @return the nilusObject + */ + public T getNilusObject() { + return nilusObject; + } + + /** + * @param nilusObject the nilusObject to set + */ + public void setNilusObject(T nilusObject) { + this.nilusObject = nilusObject; + } + +} diff --git a/src/tethys/TethysControl.java b/src/tethys/TethysControl.java new file mode 100644 index 00000000..446face1 --- /dev/null +++ b/src/tethys/TethysControl.java @@ -0,0 +1,703 @@ +package tethys; + +import java.awt.Desktop; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.Timer; + +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamController.PamControllerInterface; +import PamController.PamFolders; +import PamController.PamSettingManager; +import PamController.PamSettings; +import PamUtils.PamFileChooser; +import PamUtils.PamFileFilter; +import PamView.PamTabPanel; +import PamView.dialog.warn.WarnOnce; +import PamguardMVC.PamDataBlock; +import metadata.MetaDataContol; +import metadata.PamguardMetaData; +import nilus.Deployment; +import tethys.TethysState.StateType; +import tethys.calibration.CalibrationHandler; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.DBXMLQueries; +import tethys.dbxml.ServerStatus; +import tethys.dbxml.TethysException; +import tethys.dbxml.TethysQueryException; +import tethys.deployment.DeploymentHandler; +import tethys.detection.DetectionsHandler; +import tethys.niluswraps.PDeployment; +import tethys.output.DatablockSynchInfo; +import tethys.output.TethysExportParams; +import tethys.species.ITISFunctions; +import tethys.species.SpeciesMapManager; +import tethys.swing.ProjectDeploymentsDialog; +import tethys.swing.TethysTabPanel; +import tethys.swing.XMLStringView; +import tethys.swing.documents.TethysDocumentsFrame; + +/** + * Quick play with a simple system for outputting data to Tethys. At it's start + * this is simply going to offer a dialog and have a few functions which show how + * to access data within PAMGuard. + * @author dg50 + * + */ +public class TethysControl extends PamControlledUnit implements PamSettings, TethysStateObserver { + + public static final String unitType = "Tethys Interface"; + public static String defaultName = "Tethys"; + public static String xmlNameSpace = "http://tethys.sdsu.edu/schema/1.0"; + + private TethysExportParams tethysExportParams = new TethysExportParams(); + + private DBXMLConnect dbxmlConnect; + + private TethysTabPanel tethysTabPanel; + + private DBXMLQueries dbxmlQueries; + + private ArrayList stateObservers; + + private Timer serverCheckTimer; + + private ServerStatus lastServerStatus; + + private ArrayList dataBlockSynchInfos; + + private DeploymentHandler deploymentHandler; + private DetectionsHandler detectionsHandler; + private CalibrationHandler calibrationHandler; + + private ITISFunctions itisFunctions; + + public TethysControl(String unitName) { + super(unitType, unitName); + stateObservers = new ArrayList(); + dbxmlConnect = new DBXMLConnect(this); + dbxmlQueries = new DBXMLQueries(this, dbxmlConnect); + deploymentHandler = new DeploymentHandler(this); + detectionsHandler = new DetectionsHandler(this); + calibrationHandler = new CalibrationHandler(this); + + serverCheckTimer = new Timer(10000, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + checkServer(); + } + }); + serverCheckTimer.setInitialDelay(0); + PamSettingManager.getInstance().registerSettings(this); + addStateObserver(this); + + if (PamController.getInstance().isInitializationComplete()) { + // must be adding module later on ... + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + initializationStuff(); + } + }); + } + } + + /** + * Get DBXML Connector. This class contains all the functions that are needed + * to talk to the database. + * @return DBXML functions. + */ + public DBXMLConnect getDbxmlConnect() { + return dbxmlConnect; + } + @Override + public JMenuItem createDetectionMenu(Frame parentFrame) { + return createTethysMenu(parentFrame); + } + + @Override + public JMenuItem createFileMenu(JFrame parentFrame) { + // TODO Auto-generated method stub + return super.createFileMenu(parentFrame); + } + + /** + * Make a menu. Can go either in File or Settings. TBD. + * @param parentFrame + * @return + */ + public JMenuItem createTethysMenu(Frame parentFrame) { + JMenu tethysMenu = new JMenu("Tethys"); +// JMenuItem tethysExport = new JMenuItem("Export ..."); +// tethysMenu.add(tethysExport); +// tethysExport.addActionListener(new ActionListener() { +// @Override +// public void actionPerformed(ActionEvent e) { +// tethysExport(parentFrame); +// } +// }); + JMenuItem menuItem; + menuItem = new JMenuItem("Open client in browser"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTethysClient(); + } + }); + + tethysMenu.add(menuItem); + menuItem = new JMenuItem("Open temp document folder"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTempDocuments(); + } + }); + tethysMenu.add(menuItem); + + + JMenuItem collections = new JMenu("Collections"); + Collection[] mainCollections = Collection.mainList(); + for (int i = 0; i < mainCollections.length; i++) { + Collection col = mainCollections[i]; + menuItem = new JMenuItem("Open " + col.collectionName() + " collection in browser"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTethysCollection(col); + } + }); + collections.add(menuItem); + } + + tethysMenu.add(collections); + tethysMenu.addSeparator(); + JMenuItem showDeps = new JMenuItem("Show project deployments"); + showDeps.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showProjectDeploymentsDialog(); + } + }); + tethysMenu.add(showDeps); + + JMenuItem cals = new JMenuItem("Export calibrations"); + cals.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + calibrationHandler.exportAllCalibrations(); + } + }); + tethysMenu.add(cals); + + tethysMenu.addSeparator(); + JMenuItem mapItem = new JMenuItem("Export species maps ..."); + mapItem.setToolTipText("Export all species maps (PAMGuard codes to ITIS codes to file for import into other configurations"); + mapItem.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame)); + tethysMenu.add(mapItem); + + mapItem = new JMenuItem("Import species maps ..."); + mapItem.setToolTipText("Import species maps (PAMGuard codes to ITIS codes to file for import into other configurations"); + mapItem.addActionListener(SpeciesMapManager.getInstance().getImportAction(parentFrame)); + tethysMenu.add(mapItem); + + return tethysMenu; + } + + protected void openTempDocuments() { + File tempFolder = dbxmlConnect.checkTempFolder(); + if (tempFolder == null) { + WarnOnce.showWarning("Tethys Error", "Unable to obtain a temporary folder name", WarnOnce.WARNING_MESSAGE); + return; + } + try { +// String cmd = "explorer.exe /select," + tempFolder.getAbsolutePath() + File.separator; +// Runtime.getRuntime().exec(cmd); + Desktop.getDesktop().open(tempFolder); + } + catch(Exception e) { + e.printStackTrace(); + } + } + + public void showProjectDeploymentsDialog() { + ProjectDeploymentsDialog.showDialog(getGuiFrame(), this); + } + + public ArrayList getExportableDataBlocks() { + ArrayList sets = new ArrayList<>(); + ArrayList allDataBlocks = PamController.getInstance().getDataBlocks(); + for (PamDataBlock aDataBlock : allDataBlocks) { + if (aDataBlock.getTethysDataProvider(this) != null) { + sets.add(aDataBlock); + } + } + return sets; + } + + /** + * Get the synchronisation info for all datablocks. + * This list should be static, but check it in case something has been + * added or removed. + * @return + */ + public ArrayList getSynchronisationInfos() { + if (dataBlockSynchInfos == null) { + dataBlockSynchInfos = new ArrayList<>(); + } + ArrayList dataBlocks = getExportableDataBlocks(); + // check all datablocks are in there ... + for (PamDataBlock aBlock : dataBlocks) { + if (findDatablockSynchInfo(aBlock) == null) { + dataBlockSynchInfos.add(new DatablockSynchInfo(this, aBlock)); + } + } + // and remove any which are no longer there. + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { + if (!dataBlocks.contains(synchInfo.getDataBlock())) { + dataBlockSynchInfos.remove(synchInfo); + } + } + + return dataBlockSynchInfos; + } + + public DatablockSynchInfo findDatablockSynchInfo(PamDataBlock dataBlock) { + if (dataBlockSynchInfos == null) { + return null; + } + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { + if (synchInfo.getDataBlock() == dataBlock) { + return synchInfo; + } + } + return null; + } + + /** + * open client in the default web browser + */ + public void openTethysClient() { +// String urlString = tethysExportParams.getFullServerName() + "/Client"; +// System.out.println("Opening url " + urlString); +// URL url = null; +// try { +// url = new URL(urlString); +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } +// if (url == null) { +// return; +// } +// try { +// Desktop.getDesktop().browse(url.toURI()); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (URISyntaxException e) { +// e.printStackTrace(); +// } + openCollectionInBrowser("Client"); + } + /** + * open client in the default web browser + */ + public void openTethysCollection(Collection collection) { + if (collection == null) { + return; + } + if (getTethysExportParams().listDocsInPamguard) { + openCollectionInPAMGuard(collection); + } + else { + openCollectionInBrowser(collection.collectionName()); + } + } + public void openCollectionInPAMGuard(Collection collection) { + TethysDocumentsFrame.showTable(getGuiFrame(), this, collection); + } + + public void openCollectionInBrowser(String collectionName) { + String urlString = tethysExportParams.getFullServerName() + "/" + collectionName; +// System.out.println("Opening url " + urlString); + URL url = null; + try { + url = new URL(urlString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + if (url == null) { + return; + } + try { + Desktop.getDesktop().browse(url.toURI()); + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + @Override + public PamTabPanel getTabPanel() { + if (tethysTabPanel == null) { + tethysTabPanel = new TethysTabPanel(this); + } + return tethysTabPanel; + } + + /** + * @return the tethysExportParams + */ + public TethysExportParams getTethysExportParams() { + return tethysExportParams; + } + +// /** +// * We'll probably want to +// * @param parentFrame +// */ +// protected void tethysExport(JFrame parentFrame) { +// TethysExportParams newExportParams = TethysExportDialog.showDialog(parentFrame, this); +// if (newExportParams != null) { +// // dialog returns null if cancel was pressed. +// tethysExportParams = newExportParams; +// exportTethysData(tethysExportParams); +// } +// } +// +// /** +// * We'll arrive here if the dialog has been opened and we want to export Tethys data. +// * @param tethysExportParams2 +// */ +// private void exportTethysData(TethysExportParams tethysExportParams) { +// TethysExporter tethysExporter = new TethysExporter(this, tethysExportParams); +// tethysExporter.doExport(); +// +// sendStateUpdate(new TethysState(StateType.TRANSFERDATA)); +// countProjectDetections(); +// sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION)); +// } + + /** + * Get global deployment data. This is a bit of a mess, trying to use a separate module + * so that the rest of PAMGuard can use it, but creating the + * @return + */ + public Deployment getGlobalDeplopymentData() { + + MetaDataContol metaControl = MetaDataContol.getMetaDataControl(); + PamguardMetaData metaData = metaControl.getMetaData(); + return metaData.getDeployment(); +// Deployment deploymentData = metaControl != null ? metaData.getDeployment() : getTethysProjectData(); +// +//// deploymentData.setProject("thisIsAProject"); +////// deploymentData.setPlatform("Yay a platform"); +//// deploymentData.setCruise("cruisey"); +//// deploymentData.setDeploymentId(142536); +////// deploymentData.setInstrumentId("super instrument"); +//// deploymentData.setSite("in the ocean somewhere"); +//// deploymentData.setRegion("ocean water"); +////// deploymentData.setInstrumentType("sensor of sorts"); +// +// return deploymentData; + } + + /** + * Add a new state observer. + * @param stateObserver + */ + public void addStateObserver(TethysStateObserver stateObserver) { + stateObservers.add(stateObserver); + } + + /** + * Remove a state observer. + * @param stateObserver + * @return true if it existed. + */ + public boolean removeStateObserver(TethysStateObserver stateObserver) { + return stateObservers.remove(stateObserver); + } + + /** + * Send state updates around to all state observers. + * @param tethysState + */ + public void sendStateUpdate(TethysState tethysState) { + for (TethysStateObserver stateObserver : this.stateObservers) { + stateObserver.updateState(tethysState); + } + } + /** + * A name for any deta selectors. + * @return + */ + public String getDataSelectName() { + return getUnitName(); + } + + public DBXMLQueries getDbxmlQueries() { + return dbxmlQueries; + } + + @Override + public void notifyModelChanged(int changeType) { + super.notifyModelChanged(changeType); + switch (changeType) { + case PamControllerInterface.INITIALIZE_LOADDATA: +// case PamControllerInterface.INITIALIZATION_COMPLETE: + initializationStuff(); + break; + } + } + + /** + * Stuff to do on initial load (initialization complete or addition of + * a Tethys module after initialisation). + */ + private void initializationStuff() { + deploymentHandler.createPamguardOverview(); + serverCheckTimer.start(); + sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION)); + } + + /** + * Check the server. This will send around a notification if the state + * has changed since the last call to this function, so it's unlikely you'll + * need to use the return value + * @return server status. + */ + public ServerStatus checkServer() { + ServerStatus serverState = dbxmlConnect.pingServer(); + if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) { + sendStateUpdate(new TethysState(StateType.UPDATESERVER)); + } + lastServerStatus = serverState; + return serverState; + } + + @Override + public Serializable getSettingsReference() { + return tethysExportParams; + } + + @Override + public long getSettingsVersion() { + return TethysExportParams.serialVersionUID; + } + + @Override + public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { + tethysExportParams = (TethysExportParams) pamControlledUnitSettings.getSettings(); + return true; + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case NEWPROJECTSELECTION: + case EXPORTRDATA: + case DELETEDATA: + countProjectDetections(); + break; + } + } + + private void countProjectDetections() { + if (dataBlockSynchInfos == null) { + return; + } + Deployment deplData = getGlobalDeplopymentData(); + String[] dataPrefixes = new String[dataBlockSynchInfos.size()]; + int i = 0; + ArrayList matchedDeployments = deploymentHandler.getMatchedDeployments(); + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { +// dataPrefixes[i] = DetectionsHandler.getDetectionsDocIdPrefix(deplData.getProject(), synchInfo.getDataBlock()); + int detectionCount = 0; + int documentCount = 0; + for (PDeployment pDepl : matchedDeployments) { + detectionCount += dbxmlQueries.countData(synchInfo.getDataBlock(), pDepl.deployment.getId()); + ArrayList detectionsNames = getDbxmlQueries().getDetectionsDocuments(synchInfo.getDataBlock(), pDepl.deployment.getId()); + if (detectionsNames != null) { + documentCount += detectionsNames.size(); + } + } + synchInfo.setDataCount(detectionCount); + synchInfo.setDetectionDocumentCount(documentCount); + + i++; + } +// int[] counts = dbxmlQueries.countDataForProject(deplData.getProject(), dataPrefixes); +// if (counts != null) { +// for ( i = 0; i < counts.length; i++ ) { +// dataBlockSynchInfos.get(i).setDataCount(counts[i]); +// } +// } + } + + /** + * One stop place to get Deployment information. Will provide + * both information on record periods in PAMGuard and also Deployment docs in Tethys. + * @return set of functions for handling deployments. + */ + public DeploymentHandler getDeploymentHandler() { + return deploymentHandler; + } + + public DetectionsHandler getDetectionsHandler() { + return detectionsHandler; + } + + public void showException(TethysException tethysException) { + String title = tethysException.getMessage(); + StackTraceElement[] stack = tethysException.getStackTrace(); + String msg = ""; + if (stack != null) { + msg = "Caused in"; + for (int i = 0; i < Math.min(stack.length, 3); i++) { + msg += "
    " + stack[i].getClassName() + "." + stack[i].getMethodName(); + } + } + if (tethysException instanceof TethysQueryException) { + TethysQueryException tqe = (TethysQueryException) tethysException; +// msg += tqe. + } + + String xml = tethysException.getXmlError(); + if (xml != null) { + /** + * html can't handle the < and > in xml without getting very confused + * but it seems to work fine if they are replaced with their html codes. + */ + xml = xml.replace("<", "<"); + xml = xml.replace(">", ">"); + xml = xml.replace("\n", "
    "); + msg += "

    "+xml+"
    "; + } + WarnOnce.showWarning(title, msg, WarnOnce.WARNING_MESSAGE); + } + + public void displayDocument(DocumentInfo docInfo) { + String collectionName = docInfo.getCollection().collectionName(); + String docId = docInfo.getDocumentName(); + displayDocument(collectionName, docId); + } + /** + * Load a document from the database and display it in a popup window + * @param collection + * @param documentId + */ + public void displayDocument(String collection, String documentId) { + String doc = getDbxmlQueries().getDocument(collection, documentId); + if (doc == null | doc.length() == 0) { + doc = String.format("Unable to retrieve document %s/%s from database\n", collection, documentId); + + } + XMLStringView.showDialog(getGuiFrame(), collection, documentId, doc); + } + + /** + * Load a document from the database and write to a file selected by the user + * @param collection + * @param documentId + */ + public void exportDocument(String collection, String documentId) { + String doc = getDbxmlQueries().getDocument(collection, documentId); + if (doc == null | doc.length() == 0) { + String msg = String.format("Unable to retrieve document %s/%s from database\n", collection, documentId); + WarnOnce.showWarning("Error", msg, WarnOnce.WARNING_MESSAGE); + } + + PamFileFilter fileFilter = new PamFileFilter("XML documents", ".xml"); +// fileFilter + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(fileFilter); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + // make a default name based on the document id and the dataset directory. + String defFolder = PamFolders.getDefaultProjectFolder(); + File defFile = null; + if (defFolder != null) { + defFolder = String.format("%s%s%s_%s.xml", defFolder,File.separator,collection,documentId); + defFile = new File(defFolder); + fileChooser.setAcceptAllFileFilterUsed(true); + fileChooser.setSelectedFile(defFile); + +// fileChooser.setSelectedFile(new File(String.format("%s.xml", documentId))); +// fileChooser.set + } + int state = fileChooser.showSaveDialog(getGuiFrame()); + if (state != JFileChooser.APPROVE_OPTION) return; + File newFile = fileChooser.getSelectedFile(); + if (newFile == null) return; + newFile = PamFileFilter.checkFileEnd(newFile, "xml", true); + if (newFile == null) { + return; + } + if (newFile.exists()) { + int ans2 = WarnOnce.showWarning(newFile.getAbsolutePath(), + "The file already exists. Do you want to overwrite it ?", WarnOnce.OK_CANCEL_OPTION); + if (ans2 == WarnOnce.CANCEL_OPTION) { + return; + } + } + try { + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); + bos.write(doc.getBytes()); + bos.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * @return the itisFunctions + */ + public ITISFunctions getItisFunctions() { + if (itisFunctions == null) { + itisFunctions = new ITISFunctions(this); + } + return itisFunctions; + } + + /** + * Called when a detections document has been exported. + * @param dataBlock + */ + public void exportedDetections(PamDataBlock dataBlock) { + sendStateUpdate(new TethysState(StateType.EXPORTRDATA, Collection.Detections)); + countProjectDetections(); + sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION, Collection.Detections)); + } + + /** + * @return the calibrationHandler + */ + public CalibrationHandler getCalibrationHandler() { + return calibrationHandler; + } + + +} diff --git a/src/tethys/TethysLocationFuncs.java b/src/tethys/TethysLocationFuncs.java new file mode 100644 index 00000000..dbfa68d8 --- /dev/null +++ b/src/tethys/TethysLocationFuncs.java @@ -0,0 +1,83 @@ +package tethys; + +import Array.ArrayManager; +import Array.HydrophoneLocator; +import Array.PamArray; +import Array.Streamer; +import GPS.GPSControl; +import GPS.GpsDataUnit; +import PamUtils.LatLong; +import PamUtils.PamUtils; +import generalDatabase.DBControlUnit; +import generalDatabase.PamConnection; +import nilus.Deployment; +import nilus.DeploymentRecoveryDetails; + +/** + * Function(s) to get location information for Tethys in the required format. + * @author dg50 + * + */ +public class TethysLocationFuncs { + + + /** + * Get everything we need for a deployment document including the track # + * and the deployment / recovery information. Basically this means we + * have to load the GPS data, then potentially filter it. Slight risk this + * may all be too much for memory, but give it a go by loading GPS data for + * the deployment times. + * @param deployment + */ + public static void getTrackAndPositionData(Deployment deployment) { + long start = TethysTimeFuncs.millisFromGregorianXML(deployment.getDeploymentDetails().getAudioTimeStamp()); + long end = TethysTimeFuncs.millisFromGregorianXML(deployment.getRecoveryDetails().getAudioTimeStamp()); + /* + * Need to load data for GPS, Hydrophones and Streamers datablocks for this time period. Can then use + * the snapshot geomentry classes to do the rest from the array manager ? + */ + boolean ok = true; + ok &= addPositionData(deployment.getDeploymentDetails()); + ok &= addPositionData(deployment.getRecoveryDetails()); + + } + + /** + * Add position data to DeploymentRecoveryDetails. + * @param drd + * @return + */ + public static boolean addPositionData(DeploymentRecoveryDetails drd) { + long timeMillis = TethysTimeFuncs.millisFromGregorianXML(drd.getAudioTimeStamp()); + LatLong pos = getLatLongData(timeMillis); + if (pos == null) { + return false; + } + drd.setLongitude(PamUtils.constrainedAngle(pos.getLongitude(), 360)); + drd.setLatitude(pos.getLatitude()); + drd.setElevationInstrumentM(pos.getHeight()); + drd.setDepthInstrumentM(-pos.getHeight()); + return true; + } + + public static LatLong getLatLongData(long timeMillis) { + // check the array time. + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + Streamer aStreamer = array.getStreamer(0); + GPSControl gpsControl = GPSControl.getGpsControl(); + PamConnection con = DBControlUnit.findConnection(); + if (gpsControl != null) { +// check GPS data are loaded for times around this. + GpsDataUnit gpsData = (GpsDataUnit) gpsControl.getGpsDataBlock().getLogging().findClosestDataPoint(con, timeMillis); + if (gpsData != null) { + return gpsData.getGpsData(); + } + } + HydrophoneLocator hydrophoneLocator = aStreamer.getHydrophoneLocator(); + if (hydrophoneLocator == null) { + return null; + } + return hydrophoneLocator.getStreamerLatLong(timeMillis); + } + +} diff --git a/src/tethys/TethysMenuActions.java b/src/tethys/TethysMenuActions.java new file mode 100644 index 00000000..625096a9 --- /dev/null +++ b/src/tethys/TethysMenuActions.java @@ -0,0 +1,70 @@ +package tethys; + + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +import tethys.dbxml.TethysException; +import tethys.niluswraps.PDeployment; + +/* + * Some standard meny dirven functions which we may want to call from + * a few different places. + */ +public class TethysMenuActions { + + private TethysControl tethysControl; + + public TethysMenuActions(TethysControl tethysControl) { + super(); + this.tethysControl = tethysControl; + } + + public void deploymentMouseActions(MouseEvent e, PDeployment pDeployment) { + ArrayList detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(pDeployment.deployment.getId()); +// System.out.println("Detections for deployment " + pDeployment.deployment.getId()); +// for (String detName : detDocNames) { +// System.out.println(detName); +// } + JPopupMenu menu = new JPopupMenu(); + if (detDocNames.size() == 0) { + JMenuItem menuItem = new JMenuItem("Delete deployment " + pDeployment.deployment.getId()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + deleteDeployment(pDeployment); + } catch (TethysException e1) { + tethysControl.showException(e1); + } + } + }); + menu.add(menuItem); + } + else { + String str = String.format("Delete deployment %s and %d Detections documents", pDeployment.deployment.getId(), detDocNames.size()); + JMenuItem menuItem = new JMenuItem(str); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + deleteDeployment(pDeployment); + } catch (TethysException e1) { + tethysControl.showException(e1); + } + } + }); + menu.add(menuItem); + } + menu.show(e.getComponent(), e.getX(), e.getY()); + } + + protected void deleteDeployment(PDeployment pDeployment) throws TethysException { + tethysControl.getDbxmlConnect().deleteDeployment(pDeployment.deployment.getId()); + } +} diff --git a/src/tethys/TethysState.java b/src/tethys/TethysState.java new file mode 100644 index 00000000..ea2f2746 --- /dev/null +++ b/src/tethys/TethysState.java @@ -0,0 +1,54 @@ +package tethys; + +/** + * Basis for a message system which will get passed around whenever something happens in + * Tethys, whether it be a new connection, progress during data output, etc. + * @author dg50 + * + */ +public class TethysState { + + public enum StateType {UPDATESERVER, // Server connection or status has changed + EXPORTRDATA, // data have been transferred from PAMGuard to Tethys + NEWPROJECTSELECTION, // a new Tethys project has been selected in the GUI + NEWPAMGUARDSELECTION, // new PAMGuard data are available (called once on first load) + UPDATEMETADATA, // META Data being prepared for output have changed (so may be able to enable output!) + EXPORTING, // currently exporting data. may be a while ... + DELETEDATA // data were deleted + } + + public StateType stateType; + + public Collection collection; + + public TethysState(StateType stateType) { + super(); + this.stateType = stateType; + collection = Collection.OTHER; + } + + public TethysState(StateType stateType, Collection collection) { + this.stateType = stateType; + this.collection = collection; + if (this.collection == null) { + this.collection = Collection.OTHER; + } + } + + /** + * @return the collection associated with this notification. Note that there is + * an OTHER category in Collections which is used for server / project updates, making + * it easier to switch on the collection type when notifications are received. + */ + public Collection getCollection() { + return collection; + } + + /** + * @return the stateType + */ + public StateType getStateType() { + return stateType; + } + +} diff --git a/src/tethys/TethysStateObserver.java b/src/tethys/TethysStateObserver.java new file mode 100644 index 00000000..33a9de5c --- /dev/null +++ b/src/tethys/TethysStateObserver.java @@ -0,0 +1,13 @@ +package tethys; + +public interface TethysStateObserver { + + /** + * Receive state updates when Tethys has done something (made a connection, moved some data, etc.)
    + * Note that this is for RECEIVING state updates, not for sending them. To avoid infinite notifications + * loops, use tethysControl.sendStateUpdate(TethysState) to send out state notifications. + * @param tethysState + */ + public void updateState(TethysState tethysState); + +} diff --git a/src/tethys/TethysTimeFuncs.java b/src/tethys/TethysTimeFuncs.java new file mode 100644 index 00000000..70d11704 --- /dev/null +++ b/src/tethys/TethysTimeFuncs.java @@ -0,0 +1,90 @@ +package tethys; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import PamUtils.PamCalendar; + +public class TethysTimeFuncs { + + private static TimeZone timeZone = TimeZone.getTimeZone("UTC"); + + /* + * Copied from http://www.java2s.com/Code/Java/Development-Class/ConvertsagiventimeinmillisecondsintoaXMLGregorianCalendarobject.htm + */ + public static XMLGregorianCalendar xmlGregCalFromMillis(long millis) { + try { + final GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTimeZone(timeZone); + calendar.setTimeInMillis(millis); + return DatatypeFactory.newInstance().newXMLGregorianCalendar( + calendar); + } + catch (final DatatypeConfigurationException ex) { + System.out.println("Unable to convert date '%s' to an XMLGregorianCalendar object"); + return null; + } + } + + /** + * Convert a Gregorian calendar value back to milliseconds. + * @param xmlGregorian + * @return + */ + public static Long millisFromGregorianXML(XMLGregorianCalendar xmlGregorian) { + if (xmlGregorian == null) { + return null; + } + GregorianCalendar gc2 = xmlGregorian.toGregorianCalendar(); + gc2.setTimeZone(timeZone); + return gc2.getTimeInMillis(); + } + + /** + * Make a Gregorian calendar object from a returned XML string. + * @param gregorianString + * @return + */ + public static XMLGregorianCalendar fromGregorianXML(String gregorianString) { + // typical string is 2018-10-20T00:00:00Z + if (gregorianString == null) { + return null; + } +// GregorianCalendar gCal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + gregorianString = gregorianString.replace("T", " "); + gregorianString = gregorianString.replace("Z", ""); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + Date date = null; + try { + date = df.parse(gregorianString); + } catch (ParseException e) { + System.out.printf("Unparsable date string:\"%s\"", gregorianString); + e.printStackTrace(); + return null; + } + return xmlGregCalFromMillis(date.getTime()); +// gCal.setTimeInMillis(date.getTime()); +//// gCal.se +// return gCal; + } + + public static String formatGregorianTime(XMLGregorianCalendar gregCal) { + if (gregCal == null) { + return null; + } + Long millis = millisFromGregorianXML(gregCal); + if (millis == null) { + return gregCal.toString(); + } + return PamCalendar.formatDBDateTime(millis); + } +} diff --git a/src/tethys/calibration/CalibrationHandler.java b/src/tethys/calibration/CalibrationHandler.java new file mode 100644 index 00000000..15f3ece4 --- /dev/null +++ b/src/tethys/calibration/CalibrationHandler.java @@ -0,0 +1,545 @@ +package tethys.calibration; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBException; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; + +import Acquisition.AcquisitionControl; +import Acquisition.AcquisitionParameters; +import Acquisition.AcquisitionProcess; +import Array.ArrayManager; +import Array.Hydrophone; +import Array.PamArray; +import Array.Preamplifier; +import PamController.PamController; +import PamController.soundMedium.GlobalMedium; +import PamController.soundMedium.GlobalMedium.SoundMedium; +import PamUtils.PamCalendar; +import PamView.dialog.warn.WarnOnce; +import dbxml.Queries; +import PamController.soundMedium.GlobalMediumManager; +import nilus.AlgorithmType.Parameters; +import nilus.Calibration; +import nilus.Calibration.FrequencyResponse; +import nilus.Calibration.QualityAssurance; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.QualityValueBasic; +import nilus.ResponsibleParty; +import tethys.Collection; +import tethys.DocumentInfo; +import tethys.DocumentNilusObject; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysStateObserver; +import tethys.TethysTimeFuncs; +import tethys.calibration.swing.CalibrationsExportWizard; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.TethysException; +import tethys.niluswraps.NilusSettingsWrapper; +import tethys.niluswraps.NilusUnpacker; +import tethys.pamdata.AutoTethysProvider; + +public class CalibrationHandler implements TethysStateObserver { + + private TethysControl tethysControl; + + private ArrayList> calibrationsList; + + public static final String[] updateOptions = {"as-needed", "unplanned", "yearly"}; + + public static final String[] calibrationMethods = {"Reference hydrophone", "Manufacturers specification", "Piston phone", "Other calibrated source", "Unknown"}; + + public static final String[] qaTypes = {"unverified", "valid", "invalid"}; + + private Helper nilusHelper; + /** + * @param tethysControl + */ + public CalibrationHandler(TethysControl tethysControl) { + this.tethysControl = tethysControl; + calibrationsList = new ArrayList(); + tethysControl.addStateObserver(this); try { + nilusHelper = new Helper(); + } catch (JAXBException e) { + e.printStackTrace(); + } + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case EXPORTING: + break; + case NEWPAMGUARDSELECTION: + case NEWPROJECTSELECTION: + case EXPORTRDATA: + case DELETEDATA: + case UPDATEMETADATA: + case UPDATESERVER: + if (isWantedState(tethysState)) { + updateDocumentsList(); + } + default: + break; + + } + } + + /** + * Is it a state notification we want to respond to + * @param state + * @return true if worth it. + */ + protected boolean isWantedState(TethysState state) { + if (state.collection == null) { + return true; + } + switch (state.collection) { + case OTHER: + case Calibrations: + return true; + } + return false; + } + + /** + * Update the list of documents associated with the selected instrument. + */ + private void updateDocumentsList() { + + calibrationsList.clear(); + + ArrayList docsList = getArrayCalibrations(); + // now immediately read the calibrations in again. + if (docsList == null) { + return; + } + NilusUnpacker unpacker = new NilusUnpacker(); + for (DocumentInfo aDoc : docsList) { + Queries queries = tethysControl.getDbxmlConnect().getTethysQueries(); + String result = null; + Calibration calObj = null; + try { + result = queries.getDocument(Collection.Calibrations.toString(), aDoc.getDocumentName()); + if (result != null) { + // create a document and convert it into a Nilus calibrations document. + Document doc = tethysControl.getDbxmlQueries().convertStringToXMLDocument(result); + if (doc == null) { + System.out.println("Unable to convert Calibration result to Document\n " + result); + continue; + } + calObj = (Calibration) unpacker.unpackDocument(doc, Calibration.class); + if (calObj == null) { + System.out.println("Unable to convert Calibration document to nilus object\n " + result); + continue; + } + } + long t = System.currentTimeMillis(); + try { + XMLGregorianCalendar gt = calObj.getMetadataInfo().getDate(); + if (gt != null) { + t = TethysTimeFuncs.millisFromGregorianXML(gt); + } + } + catch (Exception e) { + + } + DocumentNilusObject calDataUnit = new DocumentNilusObject(Collection.Calibrations, aDoc.getDocumentName(), calObj.getId(), calObj); + calibrationsList.add(calDataUnit); +// System.out.println(result); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public int exportAllCalibrations() { + + Calibration sampleCal = new Calibration(); + try { + Helper.createRequiredElements(sampleCal); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e1) { + e1.printStackTrace(); + } + sampleCal = CalibrationsExportWizard.showWizard(tethysControl.getGuiFrame(), sampleCal); + if (sampleCal == null) { + return 0; + } + + NilusSettingsWrapper wrappedSample = new NilusSettingsWrapper(); + wrappedSample.setNilusObject(sampleCal); + + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nPhone = array.getHydrophoneCount(); + DBXMLConnect dbxml = tethysControl.getDbxmlConnect(); + int nExport = 0; + boolean overwrite = false; + boolean exists; + for (int i = 0; i < nPhone; i++) { +// String docName = getHydrophoneId(i); + NilusSettingsWrapper clonedWrap = wrappedSample.clone(); + sampleCal = clonedWrap.getNilusObject(Calibration.class); + Calibration calDoc = createCalibrationDocument(i); + if (sampleCal != null) { + calDoc.setMetadataInfo(sampleCal.getMetadataInfo()); + calDoc.setProcess(sampleCal.getProcess()); + calDoc.setQualityAssurance(sampleCal.getQualityAssurance()); + calDoc.setResponsibleParty(sampleCal.getResponsibleParty()); + calDoc.setTimeStamp(sampleCal.getTimeStamp()); + } + + addParameterDetails(calDoc, i); + + String calDocName = createDocumentName(calDoc, i); + exists = calDocumentExists(calDocName); + if (exists && overwrite == false) { + String msg = String.format("Calibration document %s already exists. Do you want to overwrite it and other documents from this date?", calDocName); + int ans = WarnOnce.showWarning("Calibration Export", msg, WarnOnce.OK_CANCEL_OPTION); + if (ans == WarnOnce.OK_OPTION) { + overwrite = true; + } + else { + return nExport; + } + } + boolean ok = false; + if (exists == true && overwrite == false) { + continue; + } + try { + if (exists) { + ok = dbxml.removeDocument(Collection.Calibrations, calDocName); + } + ok = dbxml.postAndLog(calDoc, calDocName); + } catch (TethysException e) { + e.printStackTrace(); + tethysControl.showException(e); + ok = false; + break; + } + if (ok) { + nExport++; + } + } + tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.EXPORTRDATA, Collection.Calibrations)); + return nExport; + } + + /** + * Add the separate pamguard parameters to the document which are used + * to make up the overall calibration. + * @param calDoc + * @param i hydrophone number + */ + private void addParameterDetails(Calibration calDoc, int i) { + Parameters params = calDoc.getProcess().getParameters(); + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType); + AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); + Hydrophone phone = array.getHydrophoneArray().get(i); + try { + nilusHelper.AddAnyElement(params.getAny(), "HydrophoneType", phone.getType()); + nilusHelper.AddAnyElement(params.getAny(), "Sensitivity", String.format("%3.1f", phone.getSensitivity())); + nilusHelper.AddAnyElement(params.getAny(), "PreampGain", String.format("%3.1f", phone.getPreampGain())); + nilusHelper.AddAnyElement(params.getAny(), "ADCp-p", String.format("%3.2fV", daqParams.getVoltsPeak2Peak())); + Preamplifier preamp = daqParams.preamplifier; + if (preamp != null) { + nilusHelper.AddAnyElement(params.getAny(), "ADCAmplifier", String.format("%3.2fdB", preamp.getGain())); + } + } catch (JAXBException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + + } + + /** + * Format the data in the dd MMMM yyyy format + * @param timeInMillis time in milliseconds + * @return formatted string. + */ + public static String formatDate(long timeInMillis) { + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(timeInMillis); + c.setTimeZone(PamCalendar.defaultTimeZone); + DateFormat df = new SimpleDateFormat("yyMMdd"); + df.setTimeZone(PamCalendar.defaultTimeZone); + Date d = c.getTime(); + return df.format(d); + } + + + /** + * Get a name for the document, which is a bit like the id within + * the document, but also contain a yymmdd data string. + * @param calDoc + * @param i channel + * @return document name + */ + private String createDocumentName(Calibration calDoc, int iChan) { + long docDate = System.currentTimeMillis(); + XMLGregorianCalendar date = calDoc.getMetadataInfo().getDate(); + if (date != null) { + docDate = TethysTimeFuncs.millisFromGregorianXML(date); + } + String dateStr = formatDate(docDate); + String name = String.format("%s_%s_ch%d", createCalibrationDocumentRoot(), dateStr, iChan); + return name; + } + + /** + * Get a start of name for a calibration document. This will be used in the document name + * with a date and a channel, and the document Id just of the root and the channel. + * @return root string for document names and document id's. + */ + public String createCalibrationDocumentRoot() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + String root = String.format("%s %s", array.getInstrumentType(), array.getInstrumentId()); + root = root.replace(" ", "_"); + return root; + } + + /** + * Create a calibration document for a single hydrophone channel. + * @param pDeployment deployment, for cross referencing. + * @param channelIndex channel id. One document per channel for a multi hydrophone array. + * @return Calibration document. + */ + public Calibration createCalibrationDocument(int channelIndex) { + AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType); + return createCalibrationDocument(daqControl, channelIndex); + } + + /** + * Create a calibration document for a single hydrophone channel. + * @param pDeployment deployment, for cross referencing. + * @param soundAcquisition Daq information - needed to get the ADC calibration information. + * @param channelIndex channel id. One document per channel for a multi hydrophone array. + * @return Calibration document. + */ + public Calibration createCalibrationDocument(AcquisitionControl soundAcquisition, int channelIndex) { + /** + * Calibrations document id and cross referencing to Deploymnet documents: + * Identifier of instrument, preamplifier, or hydrophone. + * Corresponds to elements in Deployment: + * Deployment/Instrument/Id, + * Deployment/Sensors/Audio/HydrophoneId, + * Deployment/Sensors/Audio[i]/PreampId. + * As instruments may be calibrated multiple times, it is not an error for duplicate Id values to appear. + * It is recommended that the three different types of identifiers (instrument, hydrophone, preamp) be distinct, + * but the Type element may be used to distinguish them if they are not. + */ + + /* + * very remote possibility that DAQ doesn't exist. What to do in this case ? It's also possible that some configurations may + * have to have >1 DAQ's ? + */ + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + if (channelIndex < 0 || channelIndex >= array.getHydrophoneCount()) { + return null; + } +// ArrayManager.getArrayManager().get +// hydrophones = array. + Hydrophone hydrophone = array.getHydrophoneArray().get(channelIndex); + double hSens = hydrophone.getSensitivity(); + double preampGain = hydrophone.getPreampGain(); + + GlobalMediumManager mediumManager = PamController.getInstance().getGlobalMediumManager(); + SoundMedium currentMedium = mediumManager.getCurrentMedium(); + double dbRef = GlobalMedium.getdBreference(currentMedium); // probably in Pa, so multiply by 1e6. 20 (air) or 0 (water) + + /** + * The calibration id can be a bit tricky, it will need to be cross referenced from the + * Deployment document, and it is likely that a deployment document will have to reference several + * calibration documents for different channels. + * Make the name from the Array name (new), the array Instrument Id (unique to the array) + * and the channel number. These will then all have to go into the Deployment document in + * the list of audio devices, cross referenced as the SensorId field. + * + */ + + Calibration calibration = new Calibration(); + + try { + Helper.createRequiredElements(calibration); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + String id = getHydrophoneId(channelIndex); +// id = String.format("%d", channelIndex); + calibration.setId(id); + calibration.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); +// calibration.setType(GlobalMedium.getRecieverString(currentMedium, false, false)); + calibration.setType("end-to-end"); + calibration.setIntensityReferenceUPa(AutoTethysProvider.roundSignificantFigures(dbRef*1e6,3)); +// String sensRef = GlobalMedium.getdBRefString(currentMedium); + // it doesn't like this since it has a unicode character. Leave it or change the micro to 'u' +// calibration.setSensitivityReference(sensRef); + calibration.setSensitivityDBV(hSens+preampGain); + if (soundAcquisition != null) { + AcquisitionProcess daqProcess = soundAcquisition.getAcquisitionProcess(); + double fullScale = daqProcess.rawAmplitude2dB(1, channelIndex, false); + calibration.setSensitivityDBFS(fullScale); + } + FrequencyResponse frs = calibration.getFrequencyResponse(); + List hz = frs.getHz(); + List db = frs.getDB(); + hz.add(Double.valueOf(0)); + db.add(Double.valueOf(hSens+preampGain)); + + MetadataInfo metaInf = calibration.getMetadataInfo(); + if (metaInf == null) { + metaInf = new MetadataInfo(); + calibration.setMetadataInfo(metaInf); + } + metaInf.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + metaInf.setUpdateFrequency("as-needed"); + ResponsibleParty contact = metaInf.getContact(); + if (contact == null) { + contact = new ResponsibleParty(); + metaInf.setContact(contact); + } + contact.setIndividualName("Unknown"); + contact.setOrganizationName("unknown"); + + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa == null) { + qa = new QualityAssurance(); + calibration.setQualityAssurance(qa); + } + qa.setQuality(QualityValueBasic.VALID); + qa.setComment("Unknown calibration"); + + + return calibration; + } + + /** + * See if a document already exists. This should only occur if you + * try to export the same document twice with the same calibration date. + * @param documentName + * @return true if a document already exists. + */ + public boolean calDocumentExists(String documentName) { + if (calibrationsList == null) { + return false; + } + for (int i = 0; i < calibrationsList.size(); i++) { + if (calibrationsList.get(i).getDocumentName().equalsIgnoreCase(documentName)) { + return true; + } + } + return false; + } + + /** + * Return if we have at least one document for every channel. + * @return true if all cal documents exist. + */ + public boolean haveAllChannelCalibrations() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nPhone = array.getHydrophoneCount(); + for (int i = 0; i < nPhone; i++) { + if (haveChannelCalibration(i) == false) { + return false; + } + } + return true; + } + + /** + * Find whether we have a document for this instrument and channel. + * @param iChan + * @return true if we have an appropriate doc. + */ + public boolean haveChannelCalibration(int iChan) { + if (calibrationsList == null) { + return false; + } + String seachPattern = makeChannelNamePart(iChan); + for (int i = 0; i < calibrationsList.size(); i++) { + String docName = calibrationsList.get(i).getDocumentName(); + if (docName.endsWith(seachPattern)) { + return true; + } + } + + return false; + } + + /** + * Get an id based on the instrument identifiers and channel number. + * This is the internal id of the document, not the document name which + * includes an additional date part in the name. + * @param channelIndex + * @return id string - instrument type + instrument id + channel + */ + public String getHydrophoneId(int channelIndex) { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + String id = String.format("%s_%s", createCalibrationDocumentRoot(), makeChannelNamePart(channelIndex)); + id = id.replace(" ", "_"); + return id; + } + + /** + * Make the final part of the document name / id which is the channel number. + * @param channelIndex channel index + * @return string in the form ch%02d (e.g. ch03) + */ + public String makeChannelNamePart(int channelIndex) { + return String.format("ch%02d", channelIndex); + } + + /** + * @return the calibrationDataBlock + */ + public ArrayList> getCalibrationDataList() { + return calibrationsList; + } + + /** + * Make a list of document names associated with this instrument. + * @return list of calibration documents using this instrument, based on the start of the document name. + */ + private ArrayList getArrayCalibrations() { + ArrayList allCals = null; + try { + allCals = tethysControl.getDbxmlQueries().getCollectionDocumentList(Collection.Calibrations); + } + catch (Exception e) { + + } + if (allCals == null) { + return null; + } + String prefix = createCalibrationDocumentRoot(); // find doc names that have that root. + ArrayList theseCals = new ArrayList<>(); + for (DocumentInfo aDoc : allCals) { + if (aDoc.getDocumentName().startsWith(prefix)) { + theseCals.add(aDoc); + } + } + return theseCals; + } +} diff --git a/src/tethys/calibration/swing/CalibrationProcessCard.java b/src/tethys/calibration/swing/CalibrationProcessCard.java new file mode 100644 index 00000000..30e37ba7 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationProcessCard.java @@ -0,0 +1,170 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.List; + +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; +import PamView.wizard.PamWizard; +import nilus.AlgorithmType; +import nilus.AlgorithmType.Parameters; +import nilus.AlgorithmType.SupportSoftware; +import nilus.Calibration; +import nilus.Calibration.QualityAssurance; +import nilus.QualityValueBasic; +import tethys.calibration.CalibrationHandler; + +public class CalibrationProcessCard extends CalibrationsCard { + + private JPanel processPanel; + + private JComboBox calMethod; + + private JTextArea software; + + private JTextField version; + + private JComboBox qaQuality; + + private JTextField qaComment; + + public CalibrationProcessCard(PamWizard pamWizard) { + super(pamWizard, "Calibration Process"); + this.setLayout(new BorderLayout()); + processPanel = new JPanel(new GridBagLayout()); + WestAlignedPanel wp; + this.add(BorderLayout.NORTH, wp = new WestAlignedPanel(processPanel)); + wp.setBorder(new TitledBorder("Calibration Process")); + + GridBagConstraints c = new PamGridBagContraints(); + + calMethod = new JComboBox(); + String[] meths = CalibrationHandler.calibrationMethods; + for (int i = 0; i < meths.length; i++) { + calMethod.addItem(meths[i]); + } + + qaQuality = new JComboBox<>(); + String[] vals = CalibrationHandler.qaTypes; + for (int i = 0; i < vals.length; i++) { + qaQuality.addItem(vals[i]); + } + + software = new JTextArea(5, 25); + software.setLineWrap(true); + software.setWrapStyleWord(true); + software.setToolTipText("Details of calibration method and software used"); + + version = new JTextField(20); + version.setToolTipText("Serial number of calibration device"); + + qaComment = new JTextField(20); + qaComment.setToolTipText("Comment on calibration quality"); + + processPanel.add(new JLabel("Method ", JLabel.RIGHT), c); + c.gridx++; + processPanel.add(calMethod, c); + c.gridx = 0; + c.gridy++; + c.gridwidth = 1; + processPanel.add(new JLabel("Serial number ", JLabel.RIGHT), c); + c.gridx++; + c.gridwidth = 2; + processPanel.add(version, c); + c.gridx = 0; + c.gridy++; + c.gridwidth = 1; + processPanel.add(new JLabel("Quality ", JLabel.RIGHT), c); + c.gridx++; + processPanel.add(qaQuality, c); + c.gridx = 0; + c.gridy++; + processPanel.add(new JLabel("QA Comment ", JLabel.RIGHT), c); + c.gridx++; + c.gridwidth = 2; + processPanel.add(qaComment, c); + + this.add(BorderLayout.CENTER, makeScrollablePanel(software, "Calibration method")); + + } + + private JScrollPane makeScrollablePanel(JTextArea textArea, String title) { + // TODO Auto-generated method stub +// mainPanel.add(new Label(title, JLabel.LEFT)); +// textArea.setMinimumSize(new Dimension(200, 200)); + JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(new TitledBorder(title)); + scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().height/2, 0)); + return scrollPane; + } + + + @Override + public boolean getParams(Calibration calibration) { + if (calibration == null) { + return false; + } + AlgorithmType process = calibration.getProcess(); + if (process == null) { + process = new AlgorithmType(); + calibration.setProcess(process); + } + process.setMethod((String) calMethod.getSelectedItem()); + process.setVersion(version.getText()); + process.setSoftware(software.getText()); + if (software.getText() == null) { + getPamWizard().showWarning("You must specify the calibratin method used"); + } + + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa == null) { + qa = new QualityAssurance(); + calibration.setQualityAssurance(qa); + } + qa.setComment(qaComment.getText()); + qa.setQuality(QualityValueBasic.fromValue((String) qaQuality.getSelectedItem())); + + // need to add a few fixed things for this to work... +// List supportSoftware = process.getSupportSoftware(); + Parameters params = process.getParameters(); + if (params == null) { + params = new Parameters(); + process.setParameters(params); + } + + return true; + } + + @Override + public void setParams(Calibration calibration) { + if (calibration == null) { + return; + } + AlgorithmType process = calibration.getProcess(); + if (process != null) { + calMethod.setSelectedItem(process.getMethod()); + version.setText(process.getVersion()); + software.setText(process.getSoftware()); + } + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa != null) { + QualityValueBasic qb = qa.getQuality(); + if (qb != null) { + qaQuality.setSelectedItem(qb.value()); + } + qaComment.setText(qa.getComment()); + } + } +} diff --git a/src/tethys/calibration/swing/CalibrationsCard.java b/src/tethys/calibration/swing/CalibrationsCard.java new file mode 100644 index 00000000..b97221d3 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsCard.java @@ -0,0 +1,13 @@ +package tethys.calibration.swing; + +import PamView.wizard.PamWizard; +import PamView.wizard.PamWizardCard; +import nilus.Calibration; + +abstract public class CalibrationsCard extends PamWizardCard { + + public CalibrationsCard(PamWizard pamWizard, String title) { + super(pamWizard, title); + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsContactCard.java b/src/tethys/calibration/swing/CalibrationsContactCard.java new file mode 100644 index 00000000..3adc9f33 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsContactCard.java @@ -0,0 +1,198 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Date; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.jdesktop.swingx.JXDatePicker; + +import PamView.dialog.PamDialog; +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; +import PamView.wizard.PamWizard; +import nilus.Calibration; +import nilus.ContactInfo; +import nilus.MetadataInfo; +import nilus.ResponsibleParty; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.swing.export.ResponsiblePartyPanel; + +public class CalibrationsContactCard extends CalibrationsCard { + + private JXDatePicker datePicker; + + private ResponsiblePartyPanel calibrator, dataManager; + + private JComboBox updateInterval; + + private MetadataInfo metaData; + + private JButton copyDown, copyUp; + + public CalibrationsContactCard(PamWizard pamWizard) { + super(pamWizard, "Contact Details"); + // TODO Auto-generated constructor stub +// setBorder(new TitledBorder("Contact")); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + updateInterval = new JComboBox<>(); + String[] vals = CalibrationHandler.updateOptions; + for (int i = 0; i < vals.length; i++) { + updateInterval.addItem(vals[i]); + } + + JPanel datePanel = new JPanel(new GridBagLayout()); + JPanel lp = new WestAlignedPanel(datePanel); + lp.setBorder(new TitledBorder("Calibration date")); + GridBagConstraints c = new PamGridBagContraints(); + datePanel.add(new JLabel("Calibration date: ", JLabel.RIGHT), c); + datePicker = new JXDatePicker(); + c.gridx++; + datePanel.add(datePicker, c); + c.gridx = 0; + c.gridy++; + datePanel.add(new JLabel("Update Frequency", JLabel.RIGHT), c); + c.gridx++; + datePanel.add(updateInterval, c); + + calibrator = new ResponsiblePartyPanel("Technical Person"); + dataManager = new ResponsiblePartyPanel("Data Manager"); + + JPanel copyPanel = new JPanel(new GridBagLayout()); + c = new PamGridBagContraints(); + copyPanel.add(copyDown = new JButton("Copy down"),c); + c.gridx++; + copyPanel.add(copyUp = new JButton("Copy up"), c); + + add(lp); + add(calibrator.getMainPanel()); + add(copyPanel); + add(dataManager.getMainPanel()); + + copyDown.setToolTipText("Copy technical person to data manager"); + copyUp.setToolTipText("Copy data manager to technical person"); + copyDown.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyRPDown(); + } + }); + copyUp.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyRPUp(); + } + + }); + } + + protected void copyRPDown() { + copyRPData(calibrator, dataManager); + } + private void copyRPUp() { + copyRPData(dataManager, calibrator); + } + + private void copyRPData(ResponsiblePartyPanel rFrom, ResponsiblePartyPanel rTo) { + ResponsibleParty rp = checkRPChildren(null); + rFrom.getParams(rp); + rTo.setParams(rp); + } + + @Override + public boolean getParams(Calibration cardParams) { + ResponsibleParty rp = checkRPChildren(cardParams.getResponsibleParty()); + cardParams.setResponsibleParty(rp); + calibrator.getParams(rp); + + metaData = cardParams.getMetadataInfo(); + if (metaData == null) { + metaData = new MetadataInfo(); + cardParams.setMetadataInfo(metaData); + } + metaData.setContact(checkRPChildren(metaData.getContact())); + dataManager.getParams(metaData.getContact()); + + metaData.setUpdateFrequency((String) updateInterval.getSelectedItem()); + metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + + Date date = datePicker.getDate(); + if (date == null) { + return getPamWizard().showWarning("You must specify the data of the calibration"); + } + long millis = date.getTime(); + cardParams.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(millis)); + + return true; + } + + private ResponsibleParty checkRPChildren(ResponsibleParty rp) { + if (rp == null) { + rp = new ResponsibleParty(); + } + if (rp.getContactInfo() == null) { + rp.setContactInfo(new ContactInfo()); + } + if (rp.getContactInfo().getAddress() == null) { +// rp.getContactInfo().setAddress(new Address()); + } + return rp; + } + + private ResponsibleParty findResponsibleParty(Calibration cal) { + if (cal == null) { + return null; + } + MetadataInfo metaInfo = cal.getMetadataInfo(); + if (metaInfo != null) { + ResponsibleParty resp = metaInfo.getContact(); + if (resp != null && resp.getIndividualName() != null) { + return resp; + } + } + return cal.getResponsibleParty(); + + } + + @Override + public void setParams(Calibration cardParams) { + // fill in as much as possible from the existing Calibration + ResponsibleParty resp = cardParams.getResponsibleParty(); + if (resp != null) { + calibrator.setParams(resp); + } + + MetadataInfo metaInf = cardParams.getMetadataInfo(); + if (metaInf != null) { + resp = metaInf.getContact(); + if (resp != null) { + dataManager.getParams(resp); + } + String uf = metaInf.getUpdateFrequency(); + if (uf != null) { + updateInterval.setSelectedItem(uf); + } + } + + XMLGregorianCalendar ts = cardParams.getTimeStamp(); + if (ts != null) { + datePicker.setDate(new Date(TethysTimeFuncs.millisFromGregorianXML(ts))); + } + + + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsExportWizard.java b/src/tethys/calibration/swing/CalibrationsExportWizard.java new file mode 100644 index 00000000..74bb356a --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsExportWizard.java @@ -0,0 +1,42 @@ +package tethys.calibration.swing; + +import java.awt.Window; + +import PamView.wizard.PamWizard; +import PamView.wizard.PamWizardCard; +import nilus.Calibration; + +public class CalibrationsExportWizard extends PamWizard { + + private Calibration sampleDocument; + + private CalibrationsExportWizard(Window parentFrame, Calibration sampleDocument) { + super(parentFrame, "Calibrations Export"); + this.sampleDocument = sampleDocument; + addCard(new CalibrationProcessCard(this)); + addCard(new CalibrationsContactCard(this)); + } + + public static Calibration showWizard(Window parentFrame, Calibration sampleDocument) { + CalibrationsExportWizard wiz = new CalibrationsExportWizard(parentFrame, sampleDocument); + wiz.setParams(); + wiz.setVisible(true); + return wiz.sampleDocument; + } + + @Override + public void setCardParams(PamWizardCard wizardCard) { + wizardCard.setParams(sampleDocument); + } + + @Override + public boolean getCardParams(PamWizardCard wizardCard) { + return wizardCard.getParams(sampleDocument); + } + + @Override + public void cancelButtonPressed() { + sampleDocument = null; + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsMainPanel.java b/src/tethys/calibration/swing/CalibrationsMainPanel.java new file mode 100644 index 00000000..385ca9ef --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsMainPanel.java @@ -0,0 +1,66 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.TitledBorder; + + +import PamView.panel.PamPanel; +import tethys.TethysControl; +import tethys.calibration.CalibrationHandler; +import tethys.swing.TethysGUIPanel; + +public class CalibrationsMainPanel extends TethysGUIPanel { + + private CalibrationHandler calibrationHandler; + + private CalibrationsTable calibrationsTable; + + private JPanel mainPanel; + + private JPanel ctrlPanel; + + private JButton exportButton; + + private JLabel warning; + + public CalibrationsMainPanel(TethysControl tethysControl, CalibrationHandler calibrationHandler) { + super(tethysControl); + this.calibrationHandler = calibrationHandler; + mainPanel = new PamPanel(new BorderLayout()); + mainPanel.setBorder(new TitledBorder("Instrument calibration information")); + + calibrationsTable = new CalibrationsTable(tethysControl, calibrationHandler); + mainPanel.add(BorderLayout.CENTER, calibrationsTable.getComponent()); + + ctrlPanel = new PamPanel(new BorderLayout()); + exportButton = new JButton("Export ..."); + ctrlPanel.add(BorderLayout.WEST, exportButton); + warning = new JLabel(); + ctrlPanel.add(BorderLayout.CENTER, warning); + mainPanel.add(BorderLayout.NORTH, ctrlPanel); + exportButton.setToolTipText("Export calibration data to database"); + exportButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + exportCalibrations(); + } + }); + } + + protected void exportCalibrations() { + calibrationHandler.exportAllCalibrations(); + } + + @Override + public JComponent getComponent() { + return mainPanel; + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsTable.java b/src/tethys/calibration/swing/CalibrationsTable.java new file mode 100644 index 00000000..45b91f18 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsTable.java @@ -0,0 +1,285 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.border.TitledBorder; +import javax.swing.table.AbstractTableModel; +import javax.xml.datatype.XMLGregorianCalendar; + +import PamController.PamController; +import PamController.soundMedium.GlobalMedium; +import PamController.soundMedium.GlobalMediumManager; +import PamUtils.PamCalendar; +import PamView.dialog.warn.WarnOnce; +import PamView.panel.PamPanel; +import PamView.tables.SwingTableColumnWidths; +import nilus.Calibration; +import tethys.Collection; +import tethys.DocumentNilusObject; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysState.StateType; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.dbxml.TethysException; +import tethys.swing.TethysGUIPanel; + +public class CalibrationsTable extends TethysGUIPanel { + + private CalibrationHandler calibrationHandler; + + private CalibrationsTableModel calTableModel; + + private JPanel mainPanel; + + private JTable calTable; + + private TethysControl tethysControl; + + /** + * @param calibrationHandler + */ + public CalibrationsTable(TethysControl tethysControl, CalibrationHandler calibrationHandler) { + super(tethysControl); + this.tethysControl = tethysControl; + this.calibrationHandler = calibrationHandler; + calTableModel = new CalibrationsTableModel(); + calTable = new JTable(calTableModel); + calTable.setRowSelectionAllowed(true); + calTable.addMouseListener(new TableMouse()); + + JScrollPane scrollPane = new JScrollPane(calTable); + + mainPanel = new PamPanel(new BorderLayout()); + mainPanel.add(BorderLayout.CENTER, scrollPane); + + calTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + new SwingTableColumnWidths(tethysControl.getUnitName()+"CalibrationsTable", calTable); + + } + + + @Override + public JComponent getComponent() { + return mainPanel; + } + + + @Override + public void updateState(TethysState tethysState) { + super.updateState(tethysState); + calTableModel.fireTableDataChanged(); + } + + private class TableMouse extends MouseAdapter { + + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopupMenu(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopupMenu(e); + } + } + + } + + public void showPopupMenu(MouseEvent e) { + int[] rows = calTable.getSelectedRows(); + if (rows == null || rows.length == 0) { + return; + } + int n = rows.length; + DocumentNilusObject doc = calibrationHandler.getCalibrationDataList().get(rows[0]); + + JPopupMenu popMenu = new JPopupMenu(); + JMenuItem menuItem; + if (n == 1) { + menuItem = new JMenuItem("Show document " + doc.getDocumentName()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showCalibration(doc); + } + }); + popMenu.add(menuItem); + } + if (n > 1) { + menuItem = new JMenuItem("Delete selected documents"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deleteCalibrations(rows); + } + }); + popMenu.add(menuItem); + } + else { + menuItem = new JMenuItem("Delete document " + doc.getDocumentName()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deleteCalibration(doc); + } + }); + popMenu.add(menuItem); + } + popMenu.show(e.getComponent(), e.getX(), e.getY()); + } + + protected void deleteCalibration(DocumentNilusObject doc) { + String docName = doc.getDocumentName(); + int ans = WarnOnce.showNamedWarning("delete doc " + Collection.Calibrations.collectionName(), + PamController.getMainFrame(), "Delete document", + "Are you sure you want to delete the document " + docName, WarnOnce.OK_CANCEL_OPTION); + if (ans == WarnOnce.OK_OPTION) { + try { + tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations.collectionName(), docName); + } catch (TethysException e) { + System.out.println("Failed to delete " + docName); + System.out.println(e.getMessage()); + } + } + updateEverything(); + calTableModel.fireTableDataChanged(); + } + + + protected void showCalibration(DocumentNilusObject docInfo) { + tethysControl.displayDocument(docInfo); + + } + + + protected void deleteCalibrations(int[] rows) { + String msg = String.format("Are you sure you want to delete %d calibrations documents ?", rows.length); + int ans = WarnOnce.showNamedWarning("Deletemanycalibrations", PamController.getMainFrame(), "Delete multiple documents", msg, WarnOnce.OK_CANCEL_OPTION); + if (ans != WarnOnce.OK_OPTION) { + return; + } + for (int i = 0; i < rows.length; i++) { + String docName = null; + try { + DocumentNilusObject doc = calibrationHandler.getCalibrationDataList().get(rows[i]); + docName = doc.getDocumentName(); + tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations, docName); + } catch (TethysException e) { + System.out.println("Failed to delete " + docName); + System.out.println(e.getMessage()); + } + } + + updateEverything(); + + } + + private void updateEverything() { + getTethysControl().sendStateUpdate(new TethysState(StateType.DELETEDATA, Collection.Calibrations)); + } + + class CalibrationsTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + + private String[] columnNames = {"Document", "Id", "Date", "End to End", "Hydrophone"}; + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + DocumentNilusObject dataUnit = null; + try { + dataUnit = calibrationHandler.getCalibrationDataList().get(rowIndex); + } + catch (Exception e) { + return null; + } + if (dataUnit == null) { + return null; + } + Calibration cal = dataUnit.getNilusObject(); + switch (columnIndex) { + case 0: + return dataUnit.getDocumentName(); + case 1: + return cal.getId(); + case 2: + XMLGregorianCalendar ts = cal.getTimeStamp(); + if (ts == null) { + return null; + } + long ms = TethysTimeFuncs.millisFromGregorianXML(ts); + return PamCalendar.formatDBDate(ms); + case 3: + return getFSString(cal); + case 4: + return getPhoneString(cal); +// return String.format("%3.1fdB %s", cal.getSensitivityV(), cal.getType()); + } + return null; + } + + @Override + public int getRowCount() { + return calibrationHandler.getCalibrationDataList().size(); + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public String getColumnName(int column) { + if (column == 4) { + return PamController.getInstance().getGlobalMediumManager().getRecieverString(); + } + else { + return columnNames[column]; + } + } + } + + public String getFSString(Calibration cal) { + Double fs = cal.getSensitivityDBFS(); + if (fs == null) { + return null; + } + double ir = cal.getIntensityReferenceUPa(); + String str = String.format("%3.1fdB", fs); + if (ir != 0) { + str += String.format(" re%.0f\u00B5Pa", ir); + } + return str; + } + + public Object getPhoneString(Calibration cal) { + Double dbV = cal.getSensitivityV(); + if (dbV == null) { + dbV = cal.getSensitivityDBV(); + } + if (dbV == null) { + return null; + } + double ir = cal.getIntensityReferenceUPa(); + String str = String.format("%3.1fdB", dbV); + if (ir != 0) { + str += String.format(" re%.0fV/\u00B5Pa", ir); + } + return str; + } +} diff --git a/src/tethys/database/TethysActions.java b/src/tethys/database/TethysActions.java new file mode 100644 index 00000000..0c9ece36 --- /dev/null +++ b/src/tethys/database/TethysActions.java @@ -0,0 +1,27 @@ +package tethys.database; + +/** + * Possible document actions + * @author dg50 + * + */ +public enum TethysActions { + + ADDDOCUMENT, DELETEDOCUMENT, UPDATEDOCUMENT; + +// @Override +// public String toString() { +// switch (this) { +// case ADDDOCUMENT: +// return "Add document"; +// case DELETEDOCUMENT: +// return "Delete document"; +// case UPDATEDOCUMENT: +// return "Update document"; +// default: +// return null; +// } +// } + + +} diff --git a/src/tethys/database/TethysLogDataBlock.java b/src/tethys/database/TethysLogDataBlock.java new file mode 100644 index 00000000..7a3639d6 --- /dev/null +++ b/src/tethys/database/TethysLogDataBlock.java @@ -0,0 +1,16 @@ +package tethys.database; + +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamProcess; +import tethys.TethysControl; + +public class TethysLogDataBlock extends PamDataBlock { + + private TethysControl tethysControl; + + public TethysLogDataBlock(TethysControl tethysControl) { + super(TethysLogDataUnit.class, "Tethys Log", null, 0); + this.tethysControl = tethysControl; + } + +} diff --git a/src/tethys/database/TethysLogDataUnit.java b/src/tethys/database/TethysLogDataUnit.java new file mode 100644 index 00000000..e1998c2b --- /dev/null +++ b/src/tethys/database/TethysLogDataUnit.java @@ -0,0 +1,59 @@ +package tethys.database; + +import PamguardMVC.PamDataUnit; + +public class TethysLogDataUnit extends PamDataUnit { + + private String collection; + private String documentId; + private TethysActions action; + private String comment; + private boolean success; + + public TethysLogDataUnit(long timeMilliseconds, String collection, String documentId, TethysActions action, boolean success, String comment) { + super(timeMilliseconds); + this.collection = collection; + this.documentId = documentId; + this.action = action; + this.success = success; + this.comment = comment; + + } + + /** + * @return the collection + */ + public String getCollection() { + return collection; + } + + /** + * @return the documentId + */ + public String getDocumentId() { + return documentId; + } + + /** + * @return the action + */ + public TethysActions getAction() { + return action; + } + + /** + * @return the comment + */ + public String getComment() { + return comment; + } + + /** + * @return the success + */ + public boolean isSuccess() { + return success; + } + + +} diff --git a/src/tethys/database/TethysLogger.java b/src/tethys/database/TethysLogger.java new file mode 100644 index 00000000..9e7ae2ad --- /dev/null +++ b/src/tethys/database/TethysLogger.java @@ -0,0 +1,128 @@ +package tethys.database; + +import java.sql.Types; + +import PamguardMVC.PamDataUnit; +import generalDatabase.DBControlUnit; +import generalDatabase.DBProcess; +import generalDatabase.PamConnection; +import generalDatabase.PamTableDefinition; +import generalDatabase.PamTableItem; +import generalDatabase.SQLLogging; +import generalDatabase.SQLTypes; +import tethys.TethysControl; + +/** + * Logging everything we put into Tethys in our own database. + * @author dg50 + * + */ +public class TethysLogger extends SQLLogging { + + private static TethysLogger tethysLogger; + + private TethysControl tethysControl; + + private TethysLogDataBlock logDataBlock; + + private PamTableDefinition tableDefinition; + + private PamTableItem collection, documentId, action, status, comment; + + private boolean tableChecked = false; + + private TethysLogger(TethysControl tethysControl, TethysLogDataBlock pamDataBlock) { + super(pamDataBlock); + this.tethysControl = tethysControl; + this.logDataBlock = pamDataBlock; + tableDefinition = new PamTableDefinition("TethysLog"); + tableDefinition.addTableItem(collection = new PamTableItem("Collection", Types.VARCHAR)); + tableDefinition.addTableItem(documentId = new PamTableItem("DocumentId", Types.VARCHAR)); + tableDefinition.addTableItem(action = new PamTableItem("Action", Types.VARCHAR)); + tableDefinition.addTableItem(status = new PamTableItem("Status", Types.VARCHAR)); + tableDefinition.addTableItem(comment = new PamTableItem("Comment", Types.VARCHAR)); + tableDefinition.setUpdatePolicy(UPDATE_POLICY_OVERWRITE); + setTableDefinition(tableDefinition); + } + + public static TethysLogger getTethysLogger(TethysControl tethysControl) { + if (tethysLogger == null) { + tethysLogger = createTethysLogger(tethysControl); + } + return tethysLogger; + } + + private boolean checkTable() { + if (tableChecked == true) { + return true; + } + if (findDBProcess() == null) { + return false; + } + else { + tableChecked = findDBProcess().checkTable(tableDefinition); + } + return tableChecked; + } + + public boolean logAction(String collection, String documentId, TethysActions action, boolean success, String comment) { + PamConnection con = findDBConnection(); + if (con == null) { + return false; + } + if (checkTable() == false) { + return false; + } + + TethysLogDataUnit dataUnit = new TethysLogDataUnit(System.currentTimeMillis(), collection, documentId, action, success, comment); + return this.logData(con, dataUnit); + } + + private PamConnection findDBConnection() { + return DBControlUnit.findConnection(); + } + + /** + * Find the database controlled unit.
    Must exist in viewer mode surely, but perhaps + * created after the Tethys module if the user is really crafty ! + * @return the DB controlled unit. + */ + private DBControlUnit findDBControl() { + return DBControlUnit.findDatabaseControl(); + } + + /** + * Fine the database process. Should exist. + * @return + */ + private DBProcess findDBProcess() { + DBControlUnit dbControl = findDBControl(); + if (dbControl == null) { + return null; + } + return dbControl.getDbProcess(); + } + + private static TethysLogger createTethysLogger(TethysControl tethysControl) { + TethysLogDataBlock datablock = new TethysLogDataBlock(tethysControl); + TethysLogger newLogger = new TethysLogger(tethysControl, datablock); + return newLogger; + } + + + @Override + public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { + TethysLogDataUnit tldu = (TethysLogDataUnit) pamDataUnit; + collection.setValue(tldu.getCollection()); + documentId.setValue(tldu.getDocumentId()); + action.setValue(tldu.getAction().toString()); + status.setValue(tldu.isSuccess() ? "Success" : "Fail"); + comment.setValue(tldu.getComment()); + } + +// public TethysLogger(TethysControl tethysControl) { +// this.tethysControl = tethysControl; +// } + + +} diff --git a/src/tethys/dbxml/DBQueryResult.java b/src/tethys/dbxml/DBQueryResult.java new file mode 100644 index 00000000..80a27246 --- /dev/null +++ b/src/tethys/dbxml/DBQueryResult.java @@ -0,0 +1,62 @@ +package tethys.dbxml; + +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class DBQueryResult { + + public long queryTimeMillis; + + public String queryResult; + + public String schemaPlan; + + public Exception queryException; + + public DBQueryResult(long queryTimeMillis, String queryResult, String schemaPlan) { + super(); + this.queryTimeMillis = queryTimeMillis; + this.queryResult = queryResult; + this.schemaPlan = schemaPlan; + } + + public DBQueryResult(long queryTimeMillis, Exception queryException) { + super(); + this.queryTimeMillis = queryTimeMillis; + this.queryException = queryException; + } + + /** + * Get the result as an XML document. + * @return XML document + * @throws ParserConfigurationException + * @throws SAXException + * @throws IOException + */ + public Document getDocument() throws ParserConfigurationException, SAXException, IOException { + if (queryResult == null) { + return null; + } + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(queryResult))); + return doc; + } + +} diff --git a/src/tethys/dbxml/DBXMLConnect.java b/src/tethys/dbxml/DBXMLConnect.java new file mode 100644 index 00000000..e13b05fd --- /dev/null +++ b/src/tethys/dbxml/DBXMLConnect.java @@ -0,0 +1,546 @@ +package tethys.dbxml; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.util.ArrayList; + +import javax.xml.bind.JAXBException; + +import dbxml.JerseyClient; +import dbxml.Queries; +import dbxml.uploader.Importer; +import nilus.MarshalXML; +import tethys.Collection; +import tethys.TethysControl; +import tethys.database.TethysActions; +import tethys.database.TethysLogger; +import tethys.output.TethysExportParams; + +/** + * Class containing functions for managing the database connection. Opening, closing, + * writing, keeping track of performance, etc. + * @author Doug Gillespie, Katie O'Laughlin + * + */ +public class DBXMLConnect { + + private TethysControl tethysControl; + private File tempDirectory; + + private JerseyClient jerseyClient; + + private Queries queries; + + private String currentSiteURL; + +// public static String[] collections = {"Deployments", "Detections", "Localizations", "Calibrations", "SpeciesAbbreviations"}; + + public DBXMLConnect(TethysControl tethysControl) { + this.tethysControl = tethysControl; + + checkTempFolder(); + } + + /** + * Check the jersey client and the queries. Need to recreate + * if the url has changed. + * @return + */ + private boolean checkClient() { + if (jerseyClient == null || queries == null || currentSiteURL == null) { + return false; + } + TethysExportParams params = tethysControl.getTethysExportParams(); + if (!currentSiteURL.equalsIgnoreCase(params.getFullServerName())) { + return false; + } + return true; + } + + + /** + * Get the client. The client will only be recreated if the url changes + * @return Jersy client + */ + public synchronized JerseyClient getJerseyClient() { + if (!checkClient()) { + openConnections(); + } + return jerseyClient; + } + + /** + * Get the Queries object. This will only be recreated if the client changes. + * @return + */ + public synchronized Queries getTethysQueries() { + if (!checkClient()) { + openConnections(); + } + return queries; + } + + /** + * Convert a nilus Object into a file + * @param nilusObject nilus object + * @param file file (should not exist) + * @return file (will be the same as input file) + * @throws TethysException + */ + public File createXMLDocument(Object nilusObject, File file) throws TethysException { + Class objClass = nilusObject.getClass(); + try { + MarshalXML marshal = new MarshalXML(); + marshal.createInstance(objClass); + marshal.marshal(nilusObject, file.toString()); + } catch(IllegalArgumentException e) { + throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null); + } catch (IOException e) { + throw new TethysException("IOException posting to Tethys: " + e.getMessage(), null); + } catch (JAXBException e) { + throw new TethysException("JAXBException posting to Tethys: " + e.getMessage(), null); + } + return file; + } + + /** + * Create a temporary nilus file. + * @param nilusObject + * @return + * @throws TethysException + */ + public File createTempXMLDocument(Object nilusObject) throws TethysException { + String tempName = getTempFileName(nilusObject); + tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml"; + File tempFile = new File(tempName); + File retFile = createXMLDocument(nilusObject, tempFile); + retFile.deleteOnExit(); + return retFile; + } + + + public boolean postAndLog(Object nilusObject) throws TethysException + { + return postAndLog(nilusObject, null); + } + + /** + * I don't think this should ever be used since everything goes a bit pear + * shaped if the documentName isn't the same as the Id. However, for Calibration + * documents this is no longer the case, since a Calibration can have multiple + * entries on different dates, so allow it ! + * @param nilusObject + * @param documentName + * @return + * @throws TethysException + */ + public boolean postAndLog(Object nilusObject, String documentName) throws TethysException + { + TethysException e = null; + boolean success = false; + try { + success = postToTethys(nilusObject, documentName); + } + catch (TethysException ex) { + e = ex; + } + TethysLogger logger = TethysLogger.getTethysLogger(tethysControl); + Class objClass = nilusObject.getClass(); + Collection collection = Collection.fromClass(objClass); + String documentId = getDocumentId(nilusObject); + logger.logAction(collection.collectionName(), documentId, TethysActions.ADDDOCUMENT, success, ""); + if (e != null) { + throw (e); + } + return success; + } + + /** + * take a nilus object loaded with PamGuard data and post it to the Tethys database + * + * @param pamGuardObjs a nilus object loaded with PamGuard data + * @return error string, null string means there are no errors + * @throws TethysException + */ + private boolean postToTethys(Object nilusObject, String documentName) throws TethysException + { + Class objClass = nilusObject.getClass(); + Collection collection = Collection.fromClass(nilusObject.getClass()); + TethysExportParams params = new TethysExportParams(); + String importReturn = null; + if (documentName == null) { + documentName = getTempFileName(nilusObject); + } + documentName = tempDirectory.getAbsolutePath() + File.separator + documentName + ".xml"; + File tempFile = new File(documentName); + String bodgeName = documentName;//"C:\\Users\\dg50\\AppData\\Local\\Temp\\PAMGuardTethys\\Meygen2022_10a.xml"; + try { + MarshalXML marshal = new MarshalXML(); + marshal.createInstance(objClass); + marshal.marshal(nilusObject, tempFile.toString()); + // tempFile = stripXMLHeader(tempFile); + importReturn = Importer.ImportFiles(params.getFullServerName(), collection.collectionName(), + new String[] { bodgeName }, "", "", false); + + + tempFile.deleteOnExit(); + } catch(IllegalArgumentException e) { + throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null); + } catch (IOException e) { + throw new TethysException("IOException posting to Tethys: " + e.getMessage(), null); + } catch (JAXBException e) { + throw new TethysException("JAXBException posting to Tethys: " + e.getMessage(), null); + } + + /* + * The returned string consists of the file name, then an XML report. + * Quite hard to see much common structure in this, so just look for + * two words, and + */ + boolean error = importReturn.contains(""); +// error = !success; might be a better options. + if (error) { + throw new TethysException("Error posting to Tethys", importReturn); + } + return success; + } + + /** + * Update a document within Tethys. We're assuming that a + * document with the same name in the same collection already + * exists. If it doesn't / has a different name, then use + * the removedocument function + * @param nilusDocument + * @return + * @throws TethysException + */ + public boolean updateDocument(Object nilusDocument) throws TethysException { + deleteDocument(nilusDocument); + return postToTethys(nilusDocument, null); + } + + /** + * Delete a nilus document from the database. The only field which + * needs to be populated here is the Id. The code also uses the object + * class to identify the correct collection. + * @param nilusDocument + * @return + * @throws TethysException + */ + public boolean deleteDocument(Object nilusDocument) throws TethysException { + + Class objClass = nilusDocument.getClass(); + Collection collection = Collection.fromClass(objClass); + String docId = getDocumentId(nilusDocument); + String result = null; + try { + result = jerseyClient.removeDocument(collection.collectionName(), docId ); + /** + * Return from a sucessful delete is something like + * + deployment = getTethysControl().getDeploymentHandler().createDeploymentDocument(freeId++, recordPeriod); + + ['ECoastNARW0'] + +An error will throw an exception. + */ + } + catch (Exception e) { +// System.out.printf("Error deleting %s %s: %s\n", collection, docId, e.getMessage()); + String msg = String.format("Error deleting %s:%s", collection, docId); + throw new TethysException(msg, e.getLocalizedMessage()); + } + // forceFlush(); + return true; + } + + /** + * Delete a Deploymnet and any contained Detections document. Doesn't work ! + * @param deploymentId + * @return + * @throws TethysException + */ + public boolean deleteDeployment(String deploymentId) throws TethysException { + ArrayList detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(deploymentId); + JerseyClient jerseyClient = getJerseyClient(); + Queries queries = null; + String result = null; + try { + result = jerseyClient.removeDocument("Deployments", deploymentId ); + } + catch (Exception e) { + throw new TethysException("Error deleting deployment document " + deploymentId, e.getMessage()); + } + return true; + } + + /** + * Remove a document based on a collection name and a cdocument Id. + * @param collection collection name. + * @param documentName document name (not the internal Document Id) + * @return + * @throws TethysException + */ + public boolean removeDocument(Collection collection, String documentName) throws TethysException { + return removeDocument(collection.collectionName(), documentName); + } + + /** + * Remove a document based on a collection name and a document namw. + * @param collectionName collection name. + * @param documentName document name (not the internal Document Id) + * @return + * @throws TethysException + */ + public boolean removeDocument(String collectionName, String documentName) throws TethysException { + try { + Object result = jerseyClient.removeDocument(collectionName, documentName ); + /** + * Return from a sucessful delete is something like + * + deployment = getTethysControl().getDeploymentHandler().createDeploymentDocument(freeId++, recordPeriod); + + ['ECoastNARW0'] + + An error will throw an exception. + */ + } + catch (Exception e) { + String msg = String.format("Error deleting %s:%s", collectionName, documentName); + throw new TethysException(msg, e.getLocalizedMessage()); + } + return true; + } + + /** + * check the return string from importFiles and if it's an + * error, throw an exception. Otherwise do nothing. + * @param fileError + */ + private void checkReturnString(String fileError) { + /** + * Example good string is + * +C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xml: 7360 bytes + + + added + + + 20080311_2DSimplex_0 + + + + +Example error (file not existing) +C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 bytes + + + C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot + does not exist + + + + + + */ + + + } + + /** + * Seems we have to get rid of the line + * which is being put there by the marshaller ? + * @param tempFile + */ + private File stripXMLHeader(File tempFile) { + // TODO Auto-generated method stub + + File tempTemp = new File(tempFile.getAbsolutePath().replace(".temp.xml", ".xml")); + try { + BufferedReader reader = new BufferedReader(new FileReader(tempFile)); + BufferedWriter writer = new BufferedWriter(new FileWriter(tempTemp)); + String line = reader.readLine(); + while (line != null) { + // see if the line has any unicode in it + int len = line.length(); + byte[] bytes = line.getBytes(); + if (len == bytes.length) { + System.out.println(line); + } + + if (line.startsWith(" getCollectionDocumentList(Collection collection) { + if (collection == null) { + return null; + } + + /** + * xQuery string based on examples in email from MR on 27/9/2023 + */ +// String baseQuery = " {\r\n" + String baseQuery = " {\r\n" + + " for $doc in collection(\"COLLECTIONAME\")/DOCUMENTNAME\r\n" + + " return\r\n" + + " {\r\n" + + " base-uri($doc), \r\n" + + " $doc/Id\r\n" + + " }\r\n" + + " \r\n" + + "} \r\n" + + ""; + String xQuery = baseQuery.replace("COLLECTIONAME", collection.collectionName()); + xQuery = xQuery.replace("DOCUMENTNAME", collection.documentName()); + + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.QueryTethys(xQuery); + } + catch (Exception e) { +// e.printStackTrace(); + } + if (result == null) { + return null; + } +// System.out.println(result); + ArrayList documentInfos = new ArrayList<>(); + + Document doc = convertStringToXMLDocument(result); + if (doc == null) { + return null; + } +// PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); +// System.out.println(pamXMLWriter.getAsString(doc)); + /** + * lots of elements along lines of + * dbxml:///Deployments/Meygen20229Meygen20229 + */ + NodeList returns = doc.getElementsByTagName("doc"); + int n = returns.getLength(); + String toStrip = "dbxml:///"+collection.collectionName()+"/"; + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + String nameStr = null; + String id = null; + NodeList kids = aNode.getChildNodes(); + for (int k = 0; k < kids.getLength(); k++) { + Node kidNode = kids.item(k); + String name = kidNode.getNodeName(); + String cont = kidNode.getTextContent(); + switch(name) { + case "#text": + nameStr = cont; + nameStr = nameStr.replaceFirst(toStrip, ""); + break; + case "Id": + id = kidNode.getTextContent(); + break; + default: + System.out.printf("Uknonwn node in Collection list %s item %d, Node %d name %s content %s\n", + collection, i, k, name, cont); + } + } +// if (i > 428) { +// System.out.println("MARU cal doc"); +// } + // this is the doc name with a load of stuff in front, + // e.g. dbxml:///Deployments/1705_Array-2017-09-261705_Array-2017-09-26 + if (nameStr == null) { + nameStr = aNode.getTextContent(); + nameStr = nameStr.replaceFirst(toStrip, ""); + } +// if (aNode instanceof Element) { + // nameStr = getElementData((Element) aNode, "#text"); + // } + + if (id == null) { + if (aNode instanceof Element) { + id = getElementData((Element) aNode, "Id"); + } + } + + DocumentInfo docInfo = new DocumentInfo(collection, nameStr, id); + documentInfos.add(docInfo); +// System.out.println(nameStr + " : " + id); + } + return documentInfos; + + + + // if (collection.endsWith("s")) { + // collection = collection.substring(0, collection.length()-1); + // } +// String baseQuery = "{\"return\":[\"COLLECTIONNAME/Id\"],\"select\":[],\"enclose\":1}"; +// baseQuery = baseQuery.replace("COLLECTIONNAME", collection); +// String tagName = "Id"; +// +// if (collection.equals("SpeciesAbbreviations")) { +// baseQuery = "{\"return\":[\"Abbreviations/Name\"],\"select\":[],\"enclose\":1}"; +// tagName = "Name"; +// } +// +// DBQueryResult result; +// try { +// result = executeQuery(baseQuery); +// } catch (TethysQueryException e) { +// System.out.println("Error with query: " + baseQuery); +// tethysControl.showException(e); +// return null; +// } +// +// if (result == null || result.queryResult == null) { +// return null; +// } +// Document doc = convertStringToXMLDocument(result.queryResult); +// if (doc == null) { +// return null; +// } +// NodeList returns = doc.getElementsByTagName(tagName); +// ArrayList docIds = new ArrayList<>(); +// int n = returns.getLength(); +// for (int i = 0; i < n; i++) { +// Node aNode = returns.item(i); +// String docId = aNode.getTextContent(); +// docIds.add(docId); +// } +// +// return docIds; + } + + /** + * Get a list of project names. + * @return + */ + public ArrayList getProjectNames() { + + String projectQuery = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + + DBQueryResult result; + try { + result = executeQuery(projectQuery); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + + if (result == null || result.queryResult == null) { + return null; + } + + // System.out.println("Project query execution time millis = " + result.queryTimeMillis); + + ArrayList projectNames = new ArrayList<>(); + // iterate through the document and make a list of names, then make them unique. + /* looking for elements like this: + * + * check out the jaxb unmarshaller ... + + + LJ + + + */ + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + NodeList returns = doc.getElementsByTagName("Project"); + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + String projName = aNode.getTextContent(); + if (projName != null) { + if (!projectNames.contains(projName)) { + projectNames.add(projName); + } + } + // } + // if (aNode instanceof Element) { + // Node depEl = ((Element) aNode).getFirstChild(); + // if (depEl == null) { + // continue; + // } + // if (depEl instanceof Element) { + // Element projEl = (Element) ((Element) depEl).getFirstChild(); + // String projName = projEl.getTextContent(); + // if (projName != null) { + // if (!projectNames.contains(projName)) { + // projectNames.add(projName); + // } + // } + // } + // } + } + + Collections.sort(projectNames); + + return projectNames; + } + + /** + * Get project deployments that use a specific instrument id. More use than the call without this + * extra clause since it can handle overlapping deployments. + * @param projectName + * @param instrumentId + * @return + */ + public ArrayList getProjectDeployments(String projectName, String instrumentId) { + if (projectName == null) { + return null; + } + String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"},{\"op\":\"=\"," + + "\"operands\":[\"Deployment/Instrument/InstrumentId\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String qStr = String.format(qBase, projectName, instrumentId); + + return runProjectDeploymentsQuery(projectName, qStr); + } + /** + * Get some basic (not all) data for deployments associated with a project. Note that + * this may include deployments which are NOT part of the current dataset. That requires + * a search on Instrument as well. + * @param projectName + * @return + */ + public ArrayList getProjectDeployments(String projectName) { + if (projectName == null) { + return null; + } + String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String qStr = String.format(qBase, projectName); + return runProjectDeploymentsQuery(projectName, qStr); + } + + /** + * Run the actual projects query from either of the two above functions. + * @param projectName + * @param qStr + * @return + */ + private ArrayList runProjectDeploymentsQuery(String projectName, String qStr) { + DBQueryResult result = null; + try { + result = executeQuery(qStr); + } catch (TethysQueryException e1) { + tethysControl.showException(e1); + } + if (result == null) { + return null; + } + // System.out.println("Deployment query execution time millis = " + result.queryTimeMillis); + + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + + // System.out.println(pamXMLWriter.getAsString(doc)); + + ArrayList deployments = new ArrayList<>(); + + NodeList returns = doc.getElementsByTagName("Deployment"); + // if (returns.getLength() == 0) { + // // try REsult instead ! + // returns = doc.getElementsByTagName("Result"); + // } + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + + // Queries queries = new Queries(null) + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + if (aNode instanceof Element) { + Element returnedEl = (Element) aNode; + + String Id = getElementData(returnedEl, "Id"); + String project = getElementData(returnedEl, "Project"); + String DeploymentId = getElementData(returnedEl, "DeploymentId"); + String instrType = getElementData(returnedEl, "Instrument.Type"); + String instrId = getElementData(returnedEl, "Instrument.InstrumentId"); + String geometry = getElementData(returnedEl, "Instrument.GeometryType"); + String audioStart = getElementData(returnedEl, "DeploymentDetails.AudioTimeStamp"); + String audioEnd = getElementData(returnedEl, "RecoveryDetails.AudioTimeStamp"); + String region = getElementData(returnedEl, "Region"); + Deployment deployment = new Deployment(); + try { + Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + deployment.setId(Id); + deployment.setProject(projectName); + deployment.setDeploymentId(Integer.valueOf(DeploymentId)); + XMLGregorianCalendar gcStart = TethysTimeFuncs.fromGregorianXML(audioStart); + XMLGregorianCalendar gcEnd = TethysTimeFuncs.fromGregorianXML(audioEnd); + // System.out.printf("Converted %s to %s\n", audioStart, + // PamCalendar.formatDBDateTime(TethysTimeFuncs.millisFromGregorianXML(gcStart), true)); + deployment.getDeploymentDetails().setAudioTimeStamp(gcStart); + if (deployment.getRecoveryDetails() == null) { + deployment.setRecoveryDetails(new DeploymentRecoveryDetails()); + } + deployment.getRecoveryDetails().setAudioTimeStamp(gcEnd); + if (instrType != null || instrId != null) { + Instrument instrument = new Instrument(); + instrument.setType(instrType); + instrument.setInstrumentId(instrId); + instrument.setGeometryType(geometry); + deployment.setInstrument(instrument); + } + deployment.setRegion(region); + deployments.add(deployment); + } + } + return deployments; + } + + /** + * Get a list of Detections documents which associate with a datablock and a deploymentId. + * @param dataBlock + * @param deploymentId can be null to get all docs for data block + * @return + */ + public ArrayList getDetectionsDocuments(PamDataBlock dataBlock, String deploymentId) { + /** + * first query for Detections documents associated with this deployment and datablock. + * updated May 23 + */ + String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String query; + if (deploymentId == null) { + query = queryNoDepl; + } + else { + query = queryWithDepl.replace("TheDeploymentId", deploymentId); + } + query = query.replace("LongDataName", dataBlock.getLongDataName()); + DBQueryResult queryResult = null; + try { + queryResult = executeQuery(query); + } catch (TethysQueryException e1) { + tethysControl.showException(e1); + return null; + } + if (queryResult ==null) { + return null; + } + Document doc; + try { + doc = queryResult.getDocument(); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + return null; + } + if (doc == null) { + return null; + } + ArrayList detectionsNames = new ArrayList(); + int count = 0; + NodeList returns = doc.getElementsByTagName("Detections"); + // if (returns.getLength() == 0) { + // returns = doc.getElementsByTagName("Result"); + // } + for (int i = 0; i < returns.getLength(); i++) { + Node aNode = returns.item(i); + String docName = aNode.getTextContent(); + detectionsNames.add(docName); + } + return detectionsNames; + } + + + /** + * Get the names of all detection documents for a given deployment for all data streams. + * @param deploymentId + * @return + */ + public ArrayList getDetectionsDocuments(String deploymentId) { + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryStr = queryBase.replace("SomeDeploymentId", deploymentId); + DBQueryResult queryResult = null; + try { + queryResult = executeQuery(queryStr); + } catch (TethysQueryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (queryResult == null || queryResult.queryException != null) { + return null; + } + + // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(queryResult.queryResult); + if (doc == null) { + return null; + } + + ArrayList detectionDocs = new ArrayList<>(); + + NodeList returns = doc.getElementsByTagName("Record"); + if (returns.getLength() == 0) { + returns = doc.getElementsByTagName("Record"); + } + for (int i = 0; i < returns.getLength(); i++) { + Node aNode = returns.item(i); + detectionDocs.add(aNode.getTextContent()); + } + return detectionDocs; + } + + public int countData(PamDataBlock dataBlock, String deploymentId) { + // /** + // * first query for Detections documents associated with this deployment and datablock. + // */ + // String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String query; + // if (deploymentId == null) { + // query = queryNoDepl; + // } + // else { + // query = queryWithDepl.replace("TheDeploymentId", deploymentId); + // } + // query = query.replace("LongDataName", dataBlock.getLongDataName()); + // DBQueryResult queryResult = executeQuery(query); + // if (queryResult ==null) { + // return 0; + // } + // Document doc; + // try { + // doc = queryResult.getDocument(); + // } catch (ParserConfigurationException | SAXException | IOException e) { + // e.printStackTrace(); + // return 0; + // } + // + // int count = 0; + // NodeList returns = doc.getElementsByTagName("Return"); + ArrayList documentNames = getDetectionsDocuments(dataBlock, deploymentId); + if (documentNames == null) { + return 0; + } + int count = 0; + for (String docName : documentNames) { + // System.out.println(aNode.getTextContent()); + int count2 = countDetections2(docName); + count += count2; //countDetecionsData(docName); + + } + return count; + } + + public String getDocument(String collection, String documentId) { + // String queryBase = "return:(collection(\"replaceCollectionName\")/Detections[Id=\"ReplaceDocumentId\"])"; + // queryBase = queryBase.replace("replaceCollectionName", collection); + // queryBase = queryBase.replace("ReplaceDocumentId", documentId); + // + // String result = null; + // try { + // Queries queries = dbXMLConnect.getTethysQueries(); + // result = queries.QueryTethys(queryBase); + //// System.out.println(result); + // } + // catch (Exception e) { + // System.out.println("Error executing " + queryBase); + //// e.printStackTrace(); + // return null; + // } + // return result; + + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.getDocument(collection, documentId); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return result; + + // String queryBase = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + } + + /** + * Find out if a document exists ? + * @param collection + * @param documentId + * @return + */ + public boolean documentExists(String collection, String documentId) { + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.getDocument(collection, documentId); + } catch (Exception e) { + return false; + } + if (result == null || result.length() == 0) { + return false; + } + + return result.contains(documentId); + } + + /** + * Count on effort detections in a Detections document + * @param docName + * @return + */ + public int countDetections2(String docName) { + TethysExportParams params = tethysControl.getTethysExportParams(); + String queryBase = "count(collection(\"Detections\")/Detections[Id=\"ReplaceDocumentId\"]/OnEffort/Detection)"; + String query = queryBase.replace("ReplaceDocumentId", docName); + + String result = null; + try { + Queries queries = dbXMLConnect.getTethysQueries(); + result = queries.QueryTethys(query); + // System.out.println(result); + } + catch (Exception e) { + System.out.println("Error executing " + query); + // e.printStackTrace(); + return -1; + } + int count = 0; + try { + count = Integer.valueOf(result); + } + catch (NumberFormatException e) { + System.out.println("Unable to interpret count data " + result); + return 0; + } + return count; + } + + // /** + // * Get a count of the detections in a detections document. + // * Only looking in onEffort so far. + // * @param deploymentId + // * @param detectionDocId + // * @param dataBlock + // * @return + // */ + // public int getDetectionsDetectionCount(String deploymentId, String detectionDocId, PamDataBlock dataBlock) { + // String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"SomeDetectionsId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String queryStr = queryBase.replace("SomeDetectionsId", detectionDocId); + // queryStr = queryStr.replace("SomeDeploymentId", deploymentId); + // DBQueryResult queryResult = executeQuery(queryStr); + // if (queryResult == null || queryResult.queryException != null) { + // return 0; + // } + //// System.out.println("Detections query time ms = " + queryResult.queryTimeMillis); + // + // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + // + // Document doc = convertStringToXMLDocument(queryResult.queryResult); + // if (doc == null) { + // return 0; + // } + // + //// System.out.println(pamXMLWriter.getAsString(doc)); + // + //// ArrayList detectionDocs = new ArrayList<>(); + // + // NodeList returns = doc.getElementsByTagName("Start"); + // int n = returns.getLength(); + // return n; + // } + + // /** + // * This is the quickest way of counting data in a project, but it will load the start + // * times for every detection in a project at once, so might use a lot of memory. Also + // * it wll probably get data for all deployments in a project, which may not be what we want. + // * @param projectName + // * @param dataPrefixes + // * @return + // */ + // public int[] countDataForProject(String projectName, String[] dataPrefixes) { + // int[] n = new int[dataPrefixes.length]; + // ArrayList matchedDeployments = tethysControl.getDeploymentHandler().getMatchedDeployments(); + //// ArrayList deployments = getProjectDeployments(projectName); + // if (matchedDeployments == null) { + // return null; + // } + // for (PDeployment aDeployment : matchedDeployments) { + //// ArrayList detectionsIds = getDetectionsDocsIds(aDeployment.getId()); + //// for (String detId : detectionsIds) { + //// n += getDetectionsDetectionCount(aDeployment.getId(), detId, dataBlock); + //// } + // int[] newN = countDataForDeployment(projectName, aDeployment.deployment.getId(), dataPrefixes); + // for (int i = 0; i < n.length; i++) { + // n[i] += newN[i]; + // } + // } + // return n; + // } + + /** + * Count data within a deployment document which is associated with a set of datablocks + * Since the detections all come back in one query, it's easier to count all datablocks at once so + * that it can all happen off a single query. + * @param id + * @param dataBlockPrefixes + * @return + */ + private int[] countDataForDeployment(String projectId, String deploymentId, String[] dataPrefixes) { + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"ReplaceDeploymentIdString\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryString = queryBase.replace("ReplaceDeploymentIdString", deploymentId); + DBQueryResult result; + try { + result = executeQuery(queryString); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + if (result == null || result.queryResult == null) { + return null; + } + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + + // System.out.println(pamXMLWriter.getAsString(doc)); + + NodeList detsDocs = doc.getElementsByTagName("Detections"); + int[] blockCounts = new int[dataPrefixes.length]; + + // String detDocPrefix = projectId + "_" + dataBlock.getDataName(); + + // int totalCalls = 0; + int detCount = 0; + int dataIndex; + for (int i = 0; i < detsDocs.getLength(); i++) { + Node detNode = detsDocs.item(i); + + NodeList childNodes = detNode.getChildNodes(); + detCount = childNodes.getLength()-1; + dataIndex = -1; + for (int n = 0; n < childNodes.getLength(); n++) { + Node aNode = childNodes.item(n); + if (aNode instanceof Element) { + Element el = (Element) aNode; + String nodeName = el.getNodeName(); + if (nodeName.equals("Id")) { + String id = el.getTextContent(); + for (int j = 0; j < dataPrefixes.length; j++) { + if (id != null && id.startsWith(dataPrefixes[j])) { + dataIndex = j; + } + } + // if (id != null && id.startsWith(detDocPrefix) == false) { + // detCount = 0; + // break; + // } + } + } + } + if (dataIndex >= 0) { + blockCounts[dataIndex] += detCount; + } + // System.out.printf("%d Added %d for new total %d\n",i, detCount, totalCalls); + } + + return blockCounts; + } + + public String getElementData(Element root, String elName) { + String[] tree = elName.split("\\."); + for (String element : tree) { + NodeList nodeList = root.getElementsByTagName(element); + // should only be one node for what we're unpacking. + if (nodeList == null || nodeList.getLength() == 0) { + return null; + } + int count = nodeList.getLength(); + for (int i = 0; i < count; i++) { + Node firstNode = nodeList.item(i); + if (firstNode instanceof Element) { + root = (Element) firstNode; + break; + } + } + } + return root.getTextContent(); + } + + + public String getElementAttribute(Element root, String elName, String attribute) { + String[] tree = elName.split("\\."); + for (String element : tree) { + NodeList nodeList = root.getElementsByTagName(element); + // should only be one node for what we're unpacking. + if (nodeList == null || nodeList.getLength() == 0) { + return null; + } + int count = nodeList.getLength(); + for (int i = 0; i < count; i++) { + Node firstNode = nodeList.item(i); + if (firstNode instanceof Element) { + root = (Element) firstNode; + break; + } + } + } + return root.getAttribute(attribute); + } + + public Document convertStringToXMLDocument(String xmlString) { + //Parser that produces DOM object trees from XML content + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + try { + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(xmlString))); + return doc; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get the basic information about a Detections document. This is basically everything apart from + * the actual detections themselves. + * @param aDoc + * @return + */ + public Detections getDetectionsDocInfo(String detectionsDocName) { +// String oldqueryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/Description\",\"Detections/DataSource\",\"Detections/Algorithm\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // updated May 23 + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\",\"Detections/Description\",\"Detections/DataSource\",\"Detections/Algorithm\",\"Detections/QualityAssurance\",\"Detections/UserId\",\"Detections/MetadataInfo\",\"Detections/Effort\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String query = queryBase.replace("DetectionsDocName", detectionsDocName); + DBQueryResult queryResult; + try { + queryResult = executeQuery(query); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + Document doc; + try { + doc = queryResult.getDocument(); + } catch (ParserConfigurationException | SAXException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + // System.out.println(queryResult.queryResult); + + Detections detections = new Detections(); + try { + Helper.createRequiredElements(detections); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + + NodeList returns = doc.getElementsByTagName("Result"); + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + if (n == 0) { + return null; + } + Element result = (Element) returns.item(0); + + DescriptionType description = detections.getDescription(); + if (description == null) { + description = new DescriptionType(); + detections.setDescription(description); + } + detections.setId(getElementData(result, "Id")); + description.setAbstract(getElementData(result, "Description.Abstract")); + description.setMethod(getElementData(result, "Description.Method")); + description.setObjectives(getElementData(result, "Description.Objectives")); + + String deployment = getElementData(result, "DataSource.DeploymentId"); + if (deployment != null) { + DataSourceType dataSource = detections.getDataSource(); + if (dataSource == null) { + dataSource = new DataSourceType(); + detections.setDataSource(dataSource); + } + dataSource.setDeploymentId(deployment); + } + + // get the effort start an end + String effStart = getElementData(result, "Effort.Start"); + String effEnd = getElementData(result, "Effort.End"); + detections.getEffort().setStart(TethysTimeFuncs.fromGregorianXML(effStart)); + detections.getEffort().setEnd(TethysTimeFuncs.fromGregorianXML(effEnd)); + // try to find the granularity. + String granularityString = getElementData(result, "Effort.Kind.Granularity"); + GranularityEnumType granularity = null; + if (granularityString != null) { + granularity = GranularityEnumType.fromValue(granularityString); + List kinds = detections.getEffort().getKind(); + DetectionEffortKind kind = new DetectionEffortKind(); + GranularityType granularityType = new GranularityType(); + granularityType.setValue(granularity); + kind.setGranularity(granularityType); + // try to find the rest of the granularity information. + String binSize_m = getElementAttribute(result, "Effort.Kind.Granularity", "BinSize_m"); + String encounterGap_m = getElementAttribute(result, "Effort.Kind.Granularity", "EncounterGap_m"); + String firstBinStart = getElementAttribute(result, "Effort.Kind.Granularity", "FirstBinStart"); + try { + granularityType.setBinSizeMin(Double.valueOf(binSize_m)); + } + catch (NumberFormatException e) { + } + try { + granularityType.setEncounterGapMin(Double.valueOf(encounterGap_m)); + } + catch (NumberFormatException e) { + } + + kinds.add(kind); + } + // String + + + + // TODO Auto-generated method stub + return detections; + } + +} diff --git a/src/tethys/dbxml/DMXMLQueryTest.java b/src/tethys/dbxml/DMXMLQueryTest.java new file mode 100644 index 00000000..e16e202a --- /dev/null +++ b/src/tethys/dbxml/DMXMLQueryTest.java @@ -0,0 +1,79 @@ +package tethys.dbxml; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import PamController.settings.output.xml.PamguardXMLWriter; +import dbxml.JerseyClient; +import tethys.output.TethysExportParams; + +public class DMXMLQueryTest { + + public static void main(String[] args) { + new DMXMLQueryTest().runTest(); + } + + private void runTest() { + TethysExportParams params = new TethysExportParams(); + + JerseyClient jerseyClient = new JerseyClient(params.getFullServerName()); + +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/DeploymentId\",\"Deployment/Site\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[],\"enclose\":1}"; +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"}],\"enclose\":1}"; + //String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"DCLDE2022\"],\"optype\":\"binary\"}],\"enclose\":1}"; +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\",\"Deployment/DeploymentId\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"DCLDE2022\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String testJson = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + // web browse to http://localhost:9779/Client + + String testResult = jerseyClient.queryJSON(testJson); + + Document doc = convertStringToXMLDocument(testResult); + + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + String formettedXML = pamXMLWriter.getAsString(doc, true); + + System.out.println(testResult); + System.out.println(formettedXML); +// try { +// Transformer serializer = SAXTransformerFactory.newInstance() +// .newTransformer(); +// Source source = new StreamSource(testResult); +// ByteArrayOutputStream bytes = new ByteArrayOutputStream(); +// StreamResult res = new StreamResult(bytes); +// serializer.transform(source, res); +// System.out.println(bytes.toString()); +// } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { +// e.printStackTrace(); +// } +// // System.err.println(testResult); +// catch (TransformerException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + } + + private Document convertStringToXMLDocument(String xmlString) { + //Parser that produces DOM object trees from XML content + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + try { + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(xmlString))); + return doc; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/tethys/dbxml/ServerStatus.java b/src/tethys/dbxml/ServerStatus.java new file mode 100644 index 00000000..25c9ebbf --- /dev/null +++ b/src/tethys/dbxml/ServerStatus.java @@ -0,0 +1,35 @@ +package tethys.dbxml; + +public class ServerStatus { + + public boolean ok; + + public Exception error; + + public ServerStatus(boolean ok, Exception error) { + super(); + this.ok = ok; + this.error = error; + } + + public String getFormatted() { + if (ok) { + return "Server OK"; + } + if (error == null) { + return "Unknown error"; + } + String msg = error.getLocalizedMessage(); + if (msg.startsWith("Exception")) { + msg.substring(9); + } + return msg; + } + + @Override + public String toString() { + return getFormatted(); + } + + +} diff --git a/src/tethys/dbxml/TethysException.java b/src/tethys/dbxml/TethysException.java new file mode 100644 index 00000000..034a1970 --- /dev/null +++ b/src/tethys/dbxml/TethysException.java @@ -0,0 +1,18 @@ +package tethys.dbxml; + +public class TethysException extends Exception { + + private static final long serialVersionUID = 1L; + + private String xmlError; + + public TethysException(String message, String xmlError) { + super(message); + this.xmlError = xmlError; + } + + public String getXmlError() { + return xmlError; + } + +} diff --git a/src/tethys/dbxml/TethysQueryException.java b/src/tethys/dbxml/TethysQueryException.java new file mode 100644 index 00000000..7f46d7bc --- /dev/null +++ b/src/tethys/dbxml/TethysQueryException.java @@ -0,0 +1,19 @@ +package tethys.dbxml; + +public class TethysQueryException extends TethysException { + + + private static final long serialVersionUID = 1L; + + private String queryString; + + public TethysQueryException(String message, String queryString) { + super(message, null); + this.queryString = queryString; + } + + public String getQueryString() { + return queryString; + } + +} diff --git a/src/tethys/deployment/DeploymentExportOpts.java b/src/tethys/deployment/DeploymentExportOpts.java new file mode 100644 index 00000000..18fa461f --- /dev/null +++ b/src/tethys/deployment/DeploymentExportOpts.java @@ -0,0 +1,43 @@ +package tethys.deployment; + +import java.io.Serializable; + +/** + * options for Deployment export collected by the export Wizard. + * @author dg50 + * + */ +public class DeploymentExportOpts implements Serializable, Cloneable { + + public static final long serialVersionUID = 1L; + + public boolean separateDeployments; + + /** + * Minimum number of seconds between GPS points in a track. + */ + public double trackPointInterval; + + /** + * Max gap before recording periods are separated, potentially into + * separate Deployment documents + */ + public int maxRecordingGapSeconds = 60; + + /** + * A recording section after joining with max gap parameter is too short + * to be worth keeping. + */ + public int minRecordingLengthSeconds = 10; + + @Override + protected DeploymentExportOpts clone() { + try { + return (DeploymentExportOpts) super.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } + } + +} diff --git a/src/tethys/deployment/DeploymentHandler.java b/src/tethys/deployment/DeploymentHandler.java new file mode 100644 index 00000000..85f834c3 --- /dev/null +++ b/src/tethys/deployment/DeploymentHandler.java @@ -0,0 +1,1270 @@ +package tethys.deployment; + +import java.awt.Window; +import java.io.Serializable; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; + +import javax.xml.bind.JAXBException; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.beanutils.converters.BigIntegerConverter; + +import Acquisition.AcquisitionControl; +import Acquisition.AcquisitionParameters; +import Acquisition.DaqStatusDataUnit; +import Acquisition.DaqSystem; +import Acquisition.FolderInputSystem; +import Array.ArrayManager; +import Array.Hydrophone; +import Array.HydrophoneLocator; +import Array.PamArray; +import Array.Streamer; +import Array.ThreadingHydrophoneLocator; +import GPS.GPSControl; +import GPS.GPSDataBlock; +import GPS.GpsData; +import GPS.GpsDataUnit; +import PamController.PamSensor; +import PamController.PamSettingManager; +import PamController.PamSettings; +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamUtils.PamUtils; +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamRawDataBlock; +import binaryFileStorage.BinaryStore; +import dataMap.OfflineDataMap; +import dataMap.OfflineDataMapPoint; +import generalDatabase.DBControlUnit; +import metadata.MetaDataContol; +import metadata.PamguardMetaData; +import nilus.Audio; +import nilus.ChannelInfo; +import nilus.ChannelInfo.DutyCycle; +import nilus.ChannelInfo.DutyCycle.Regimen.RecordingDurationS; +import nilus.ChannelInfo.DutyCycle.Regimen.RecordingIntervalS; +import nilus.ChannelInfo.Sampling; +import nilus.ChannelInfo.Sampling.Regimen; +import nilus.Deployment; +import nilus.Deployment.Data; +import nilus.Deployment.Data.Tracks; +import nilus.Deployment.Data.Tracks.Track; +import nilus.Deployment.Data.Tracks.Track.Point; +import nilus.Deployment.Data.Tracks.Track.Point.BearingDegN; +import nilus.Deployment.Instrument; +import nilus.Deployment.SamplingDetails; +import nilus.Deployment.Sensors; +import nilus.DeploymentRecoveryDetails; +import nilus.DescriptionType; +import nilus.GeometryTypeM; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.UnknownSensor; +import pamMaths.PamVector; +import pamMaths.STD; +import tethys.Collection; +import tethys.TethysControl; +import tethys.TethysLocationFuncs; +import tethys.TethysState; +import tethys.TethysStateObserver; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.TethysState.StateType; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.TethysException; +import tethys.deployment.swing.DeploymentWizard; +import tethys.deployment.swing.RecordingGapDialog; +import tethys.niluswraps.PDeployment; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; +import tethys.swing.DeploymentTableObserver; + +/** + * Functions to gather data for the deployment document from all around PAMGuard. + * There should be just one of these, available from TethysControl and it will try + * to sensible handle when and how it updates it's list of PAMGuard and Tethys information + *
    Any part of PAMGuard wanting information on Deployments should come here. + * @author dg50 + * + */ +public class DeploymentHandler implements TethysStateObserver, DeploymentTableObserver { + + private TethysControl tethysControl; + + /** + * @return the tethysControl + */ + public TethysControl getTethysControl() { + return tethysControl; + } + + private EffortFunctions effortFunctions; + + private DeploymentOverview deploymentOverview; + + private ArrayList projectDeployments; + + private Helper nilusHelper; + + private DeploymentExportOpts deploymentExportOptions = new DeploymentExportOpts(); + + public DeploymentHandler(TethysControl tethysControl) { + super(); + + this.tethysControl = tethysControl; + + this.effortFunctions = new EffortFunctions(tethysControl); + + tethysControl.addStateObserver(this); + try { + nilusHelper = new Helper(); + } catch (JAXBException e) { + e.printStackTrace(); + } + + PamSettingManager.getInstance().registerSettings(new SettingsHandler()); + } + + /** + * Gather up all track information both from the GPS module (if it exists) and + * the type of hydrophone array (or many!) + * @return + */ + public TrackInformation getTrackInformation() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nStreamers = array.getStreamerCount(); + HydrophoneLocator locator = null; + for (int i = 0; i < nStreamers; i++) { + Streamer aStreamer = array.getStreamer(i); + locator = aStreamer.getHydrophoneLocator(); +// locator.getLocatorSettings(). + } + // try to find a GPS datablock and see what's in it's datamap. + OfflineDataMap gpsDataMap = null; + GPSControl gpsControl = (GPSControl) PamController.getInstance().findControlledUnit(GPSControl.gpsUnitType); + if (gpsControl != null) { + GPSDataBlock gpsDataBlock = gpsControl.getGpsDataBlock(); + gpsDataMap = gpsDataBlock.getPrimaryDataMap(); + } + TrackInformation trackInformation = new TrackInformation(gpsDataMap, locator); + return trackInformation; + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case NEWPROJECTSELECTION: + updateProjectDeployments(); + break; + case EXPORTRDATA: + case DELETEDATA: + updateProjectDeployments(); + break; + case UPDATESERVER: + updateProjectDeployments(); + break; + default: + break; + } + } + + /** + * Update the list of Tethys deployments + * @return true if OK + */ + public boolean updateProjectDeployments() { + Deployment projData = tethysControl.getGlobalDeplopymentData(); + ArrayList tethysDocs = tethysControl.getDbxmlQueries().getProjectDeployments(projData.getProject(), getInstrumentId()); + if (tethysDocs == null) { + return false; + } + projectDeployments = new ArrayList<>(); + for (Deployment deployment : tethysDocs) { + projectDeployments.add(new PDeployment(deployment)); + } + matchPamguard2Tethys(deploymentOverview, projectDeployments); + tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.NEWPAMGUARDSELECTION)); + return true; + } + + /** + * Get a list of Tethys deployment docs. Note that this + * doesn't update the list, but uses the one currently in memory + * so call updateTethysDeployments() first if necessary. + * @return list of (wrapped) nilus Deployment objects. + */ + public ArrayList getProjectDeployments() { + if (projectDeployments == null) { + updateProjectDeployments(); + } + return projectDeployments; + } + +// /** +// * Get an overview of all the deployments. +// * @return +// */ +// public DeploymentOverview createPamguardOverview() { +// // first find an acquisition module. +// PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); +// if (!(aModule instanceof AcquisitionControl)) { +// // will return if it's null. Impossible for it to be the wrong type. +// // but it's good practice to check anyway before casting. +// return null; +// } +// // cast it to the right type. +// AcquisitionControl daqControl = (AcquisitionControl) aModule; +// AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); +// /** +// * The daqParams class has most of what we need about the set up in terms of sample rate, +// * number of channels, instrument type, ADC input range (part of calibration), etc. +// * It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers. +// * Realistically, this list is always 0,1,2,etc or it goes horribly wrong ! +// */ +// // so write functions here to get information from the daqParams. +//// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(), +//// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak); +// /** +// * then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map +// * but the datamap is a simple count of what's in the databasase which is not quite what we want. +// * we're going to have to query the database to get more detailed informatoin I think. +// * I'll do that here for now, but we may want to move this when we better organise the code. +// * It also seems that there are 'bad' dates in the database when it starts new files, which are the date +// * data were analysed at. So we really need to check the start and stop records only. +// */ +// PamDataBlock daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock(); +// // just load everything. Probably OK for the acqusition, but will bring down +// daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null); +// ArrayList allStatusData = daqInfoDataBlock.getDataCopy(); +// /** +// * Due to seird file overlaps we need to resort this by id if we can. +// * +// */ +// Collections.sort(allStatusData, new Comparator() { +// +// @Override +// public int compare(DaqStatusDataUnit o1, DaqStatusDataUnit o2) { +// if (o1.getDatabaseIndex() == 0) { +// return (int) (o1.getTimeMilliseconds()-o2.getTimeMilliseconds()); +// } +// return o1.getDatabaseIndex()-o2.getDatabaseIndex(); +// } +// }); +// +// ArrayList tempPeriods = null; +// +// if (allStatusData == null || allStatusData.size() == 0) { +// System.out.println("Data appear to have no logged recording periods. Try to extract from raw audio ..."); +// tempPeriods = extractTimesFromFiles(daqControl); +// } +// else { +// tempPeriods = extractTimesFromStatus(allStatusData); +// } +// if (tempPeriods == null || tempPeriods.size() == 0) { +// System.out.println("Data appear to have no logged recording periods available either from the database or the raw recordings."); +// tempPeriods = extractTimesFromOutputMaps(); +// } +// if (tempPeriods == null || tempPeriods.size() == 0) { +// System.out.println("Data appear to have no logged recording periods available either from the database or the raw recordings."); +// return null; +// } +// +// int nPeriods = tempPeriods.size(); +//// int i = 0; +//// for (RecordingPeriod aP : tempPeriods) { +//// System.out.printf("Pre merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()), +//// PamCalendar.formatDBDateTime(aP.getRecordStop())); +//// } +// // now go through those and merge into longer periods where there is no gap between files. +// ListIterator iterator = tempPeriods.listIterator(); +// RecordingPeriod prevPeriod = null; +// while (iterator.hasNext()) { +// RecordingPeriod nextPeriod = iterator.next(); +// long nextDur = nextPeriod.getRecordStop()-nextPeriod.getRecordStart(); +// if (nextDur == 0) { +// continue; +// } +// if (prevPeriod != null) { +// long gap = nextPeriod.getRecordStart() - prevPeriod.getRecordStop(); +// long prevDur = prevPeriod.getRecordStop()-prevPeriod.getRecordStart(); +// if (gap < exportOptions.maxGapSeconds*1000) { +// // ignoring up to 3s gap or a sample error < 2%.Dunno if this is sensible or not. +// prevPeriod.setRecordStop(nextPeriod.getRecordStop()); +// iterator.remove(); +// nextPeriod = prevPeriod; +// } +// } +// prevPeriod = nextPeriod; +// } +// // now remove ones which are too short even after merging. +// iterator = tempPeriods.listIterator(); +// while (iterator.hasNext()) { +// RecordingPeriod nextPeriod = iterator.next(); +// long duration = nextPeriod.getDuration(); +// if (duration < exportOptions.minLengthSeconds*1000L) { +// iterator.remove(); +// } +// } +//// i = 0; +//// for (RecordingPeriod aP : tempPeriods) { +//// System.out.printf("Post merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()), +//// PamCalendar.formatDBDateTime(aP.getRecordStop())); +//// } +//// System.out.printf("Data have %d distinct files, but only %d distinct recording periods\n", nPeriods, tempPeriods.size()); +// DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods); +// // if it's duty cycles, then we only want a single entry. +// ArrayList deploymentPeriods; +// if (dutyCycleinfo.isDutyCycled == false) { +// deploymentPeriods = tempPeriods; +// } +// else { +// deploymentPeriods = new ArrayList<>(); +// deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop())); +// } +// /* +// * do another sort of the deploymentPeriods. The start stops were in the order they went into the +// * database in the hope that pairs were the right way round. Now check all data are/ +// */ +// Collections.sort(deploymentPeriods, new Comparator() { +// @Override +// public int compare(RecordingPeriod o1, RecordingPeriod o2) { +// return (int) (o1.getRecordStart()-o2.getRecordStart()); +// } +// }); +// +// DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods); +// matchPamguard2Tethys(deploymentOverview, projectDeployments); +// this.deploymentOverview = deploymentOverview; +// return deploymentOverview; +// // find the number of times it started and stopped .... +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1); +// // now work out where there are genuine gaps and make up a revised list of recording periods. +// +// +// } + + public void showOptions(Window parent) { + if (parent == null) { + parent = tethysControl.getGuiFrame(); + } + DeploymentExportOpts newOpts = RecordingGapDialog.showDiloag(parent, deploymentExportOptions); + if (newOpts != null) { + deploymentExportOptions = newOpts; + createPamguardOverview(); + } + } + + public void createPamguardOverview() { + deploymentOverview = effortFunctions.makeRecordingOverview(); + updateProjectDeployments(); + matchPamguard2Tethys(deploymentOverview, projectDeployments); + } + + /** + * Export button pressed on GUI. Run wizard.... + */ + public void exportDeployments() { + Deployment deployment = MetaDataContol.getMetaDataControl().getMetaData().getDeployment(); + DeploymentExportOpts exportOptions = DeploymentWizard.showWizard(getTethysControl().getGuiFrame(), tethysControl, deployment, this.deploymentExportOptions); + if (exportOptions != null) { + this.deploymentExportOptions = exportOptions; + deploymentOverview = getDeploymentOverview(); + ArrayList allPeriods = deploymentOverview.getRecordingPeriods(); + exportDeployments(allPeriods); + } + } + + /** + * Export deployments docs. Playing with a couple of different ways of doing this. + * @param selectedDeployments + */ + public void exportDeployments(ArrayList selectedDeployments) { + if (deploymentExportOptions.separateDeployments) { + exportSeparateDeployments(selectedDeployments); + } + else { + exportOneDeploymnet(selectedDeployments); + } + } + + /** + * Make one big deployment document with all the recording periods in it. + */ + private void exportOneDeploymnet(ArrayList selectedDeployments) { + // do the lot, whatever ... + selectedDeployments = getDeploymentOverview().getRecordingPeriods(); + int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId(); + RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(), + selectedDeployments.get(selectedDeployments.size()-1).getRecordStop()); + TethysExportParams exportParams = tethysControl.getTethysExportParams(); + String id = String.format("%s_%s", exportParams.getDatasetName(), "all"); + Deployment deployment = createDeploymentDocument(freeId, onePeriod, id); + // fill in a few things from here + Deployment globalMeta = getTethysControl().getGlobalDeplopymentData(); + deployment.setCruise(globalMeta.getCruise()); + deployment.setSite(globalMeta.getSite()); + if (selectedDeployments.size() > 1) { + // now need to remove the + SamplingDetails samplingDetails = deployment.getSamplingDetails(); + samplingDetails.getChannel().clear(); + for (int i = 0; i < selectedDeployments.size(); i++) { + addSamplingDetails(deployment, selectedDeployments.get(i)); + } + } + DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect(); + PDeployment exDeploymnet = onePeriod.getMatchedTethysDeployment(); + try { + if (exDeploymnet != null) { + deployment.setId(exDeploymnet.deployment.getId()); + dbxmlConnect.updateDocument(deployment); + } + else { + dbxmlConnect.postAndLog(deployment); + } + } + catch (TethysException e) { + getTethysControl().showException(e); + } + getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER, Collection.Deployments)); + } + + /** + * Make a separate deployment document for every recording period. + */ + private void exportSeparateDeployments(ArrayList selectedDeployments) { + + int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId(); + // fill in a few things from here + Deployment globalMeta = getTethysControl().getGlobalDeplopymentData(); + TethysExportParams exportParams = tethysControl.getTethysExportParams(); + for (int i = 0; i < selectedDeployments.size(); i++) { + RecordingPeriod recordPeriod = selectedDeployments.get(i); + PDeployment exDeploymnet = recordPeriod.getMatchedTethysDeployment(); + Deployment deployment = null; + String id = String.format("%s_%d", exportParams.getDatasetName(), i); + if (exDeploymnet != null) { + deployment = createDeploymentDocument(freeId, recordPeriod, id); + deployment.setId(exDeploymnet.deployment.getId()); + } + if (deployment == null) { + deployment = createDeploymentDocument(freeId++, recordPeriod, id); + } + deployment.setCruise(globalMeta.getCruise()); + deployment.setSite(globalMeta.getSite()); + // also need to sort out track data here, etc. + DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect(); + try { + if (exDeploymnet != null) { + dbxmlConnect.updateDocument(deployment); + } + else { + dbxmlConnect.postAndLog(deployment); + } + } + catch (TethysException e) { + getTethysControl().showException(e); + } + } + getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER, Collection.Deployments)); + } + + + + public DeploymentOverview getDeploymentOverview() { + return deploymentOverview; + } + + /** + * Match what we think the PAMGuard deployment times are with Tethys Deployments read back + * from the database. + * @param deploymentOverview + * @param deployments + */ + private void matchPamguard2Tethys(DeploymentOverview deploymentOverview, ArrayList deployments) { + if (deployments == null || deploymentOverview == null) { + return; + } + ArrayList recordingPeriods = deploymentOverview.getRecordingPeriods(); + for (RecordingPeriod aPeriod : recordingPeriods) { + PDeployment closestDeployment = findClosestDeployment(aPeriod, deployments); + aPeriod.setMatchedTethysDeployment(closestDeployment); + if (closestDeployment != null) { + closestDeployment.setMatchedPAMGaurdPeriod(aPeriod); + } + } + } + + /** + * find the Tethys deployment that most closely matches the PAMGuard recording period. + * @param aPeriod + * @param deployments + * @return + */ + private PDeployment findClosestDeployment(RecordingPeriod aPeriod, ArrayList deployments) { + double overlap = -1; + PDeployment bestDeployment = null; + for (PDeployment aDeployment : deployments) { + double newOverlap = getDeploymentOverlap(aDeployment, aPeriod); + if (newOverlap > overlap) { + bestDeployment = aDeployment; + overlap = newOverlap; + } + } + return bestDeployment; + } + + /** + * Get the overlap in mills between a nilus Deployment and a PAMGuard recording period + * @param aDeployment nilus Deployment from Tethys + * @param aPeriod PAMGuard recording period + * @return overlap in milliseconds + */ + public long getDeploymentOverlap(PDeployment aDeployment, RecordingPeriod aPeriod) { + long start = aPeriod.getRecordStart(); // recording period. + long stop = aPeriod.getRecordStop(); + Long depStart = aDeployment.getAudioStart(); + Long depStop = aDeployment.getAudioEnd(); + if (depStart == null || depStop == null) { + return -1; + } + long overlap = (Math.min(stop, depStop)-Math.max(start, depStart)); + return overlap; + } + + + + + /** + * Get a list of Tethys Deployment docs that match the current PAMGuard data. Watch for repeats + * if a single deployment doc covers many perdiods. + * @return + */ + public ArrayList getMatchedDeployments() { + ArrayList matched = new ArrayList<>(); + if (deploymentOverview == null) { + return matched; + } + for (RecordingPeriod period : deploymentOverview.getRecordingPeriods()) { + PDeployment deployment = period.getMatchedTethysDeployment(); + if (deployment != null) { + if (matched.contains(deployment) == false) { + matched.add(period.getMatchedTethysDeployment()); + } + } + } + return matched; + } + + /** + * Get a list of instruments from the current project deployments. + * This may be a shorter list than the list of deployments. + * @return + */ + public ArrayList getProjectInstruments() { + if (projectDeployments == null) { + return null; + } + ArrayList instruments = new ArrayList<>(); + for (PDeployment aDepl : projectDeployments) { + Instrument intr = aDepl.deployment.getInstrument(); + if (intr == null) { + continue; + } + PInstrument pInstr = new PInstrument(intr.getType(), intr.getInstrumentId()); + if (instruments.contains(pInstr) == false) { + instruments.add(pInstr); + } + } + return instruments; + } + //in each channel +// public ArrayList getDeployments() { +// +// DeploymentOverview recordingOverview = this.deploymentOverview; +// +// // first find an acquisition module. +// PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); +// if (!(aModule instanceof AcquisitionControl)) { +// // will return if it's null. Impossible for it to be the wrong type. +// // but it's good practice to check anyway before casting. +// return null; +// } +// // cast it to the right type. +// AcquisitionControl daqControl = (AcquisitionControl) aModule; +// AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); +// /** +// * The daqParams class has most of what we need about the set up in terms of sample rate, +// * number of channels, instrument type, ADC input range (part of calibration), etc. +// * It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers. +// * Realistically, this list is always 0,1,2,etc or it goes horribly wrong ! +// */ +// // so write functions here to get information from the daqParams. +//// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(), +//// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak); +// /** +// * then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map +// * but the datamap is a simple count of what's in the databasase which is not quite what we want. +// * we're going to have to query the database to get more detailed informatoin I think. +// * I'll do that here for now, but we may want to move this when we better organise the code. +// * It also seems that there are 'bad' dates in the database when it starts new files, which are the date +// * data were analysed at. So we really need to check the start and stop records only. +// */ +// PamDataBlock daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock(); +// // just load everything. Probably OK for the acqusition, but will bring down +// daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null); +// ArrayList allStatusData = daqInfoDataBlock.getDataCopy(); +// long dataStart = Long.MAX_VALUE; +// long dataEnd = Long.MIN_VALUE; +// if (allStatusData != null && allStatusData.size() > 0) { +// // find the number of times it started and stopped .... +// int nStart = 0, nStop = 0, nFile=0; +// for (DaqStatusDataUnit daqStatus : allStatusData) { +// switch (daqStatus.getStatus()) { +// case "Start": +// nStart++; +// dataStart = Math.min(dataStart, daqStatus.getTimeMilliseconds()); +// break; +// case "Stop": +// nStop++; +// dataEnd = Math.max(dataEnd, daqStatus.getEndTimeInMilliseconds()); +// break; +// case "NextFile": +// nFile++; +// break; +// } +// } +// +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1); +// +// } +// +//// // and we find the datamap within that ... +//// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl()); +//// if (daqMap != null) { +//// // iterate through it. +//// long dataStart = daqMap.getFirstDataTime(); +//// long dataEnd = daqMap.getLastDataTime(); +//// List mapPoints = daqMap.getMapPoints(); +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d individual files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), mapPoints.size()); +//// /* +//// * clearly in the first database I've been looking at of Tinas data, this is NOT getting sensible start and +//// * end times. Print them out to see what's going on. +//// */ +////// for () +//// } +// DeploymentRecoveryPair pair = new DeploymentRecoveryPair(); +// DeploymentRecoveryDetails deployment = new DeploymentRecoveryDetails(); +// DeploymentRecoveryDetails recovery = new DeploymentRecoveryDetails(); +// pair.deploymentDetails = deployment; +// pair.recoveryDetails = recovery; +// +// deployment.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart)); +// deployment.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart)); +// recovery.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd)); +// recovery.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd)); +// +// ArrayList drPairs = new ArrayList<>(); +// drPairs.add(pair); +// return drPairs; +// +// } + + /** + * Get the first free deploymendId. This will get appended to + * the ProjectName to make and id for each Deployment document + * @return + */ + public int getFirstFreeDeploymentId() { + /** + * This is an integer used for the DeploymentId. Note that the String Id (currentl9) is just the Project name + * appended with this number. + */ + int firstFree = 0; + if (projectDeployments != null) { + for (PDeployment dep : projectDeployments) { + firstFree = Math.max(firstFree, dep.deployment.getDeploymentId()+1); + } + } + return firstFree; + } + + public Deployment createDeploymentDocument(int i, RecordingPeriod recordingPeriod, String deploymentId) { + Deployment deployment = new Deployment(); + try { + nilus.Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + PamguardMetaData pamguardMetaData = MetaDataContol.getMetaDataControl().getMetaData(); + Deployment templateDeployment = pamguardMetaData.getDeployment(); + +// Deployment globalDeplData = tethysControl.getGlobalDeplopymentData(); + deployment.setId(deploymentId); + deployment.setDeploymentId(i); + + DeploymentRecoveryDetails deploymentDetails = deployment.getDeploymentDetails(); + if (deploymentDetails == null) { + deploymentDetails = new DeploymentRecoveryDetails(); + } + DeploymentRecoveryDetails recoveryDetails = deployment.getRecoveryDetails(); + if (recoveryDetails == null) { + recoveryDetails = new DeploymentRecoveryDetails(); + } + + deploymentDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart())); + recoveryDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop())); + // handle situation where deployment and recovery times are not the same as the audio times. + if (pamguardMetaData.useAudioForDeploymentTimes == false) { + if (templateDeployment.getDeploymentDetails().getAudioTimeStamp() != null) { + deploymentDetails.setTimeStamp(templateDeployment.getDeploymentDetails().getAudioTimeStamp()); + } + if (templateDeployment.getRecoveryDetails().getAudioTimeStamp() != null) { + recoveryDetails.setTimeStamp(templateDeployment.getRecoveryDetails().getAudioTimeStamp()); + } + } + + deploymentDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart())); + recoveryDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop())); + + deployment.setDeploymentDetails(deploymentDetails); + deployment.setRecoveryDetails(recoveryDetails); + + getProjectData(deployment); + + TethysLocationFuncs.getTrackAndPositionData(deployment); + + getTrackDetails(deployment); + + /** + * Get some of the meta data from the centralised source. + */ + MetadataInfo metaData = templateDeployment.getMetadataInfo(); + metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + metaData.setUpdateFrequency("as-needed"); + deployment.setMetadataInfo(metaData); + + deployment.setDescription(templateDeployment.getDescription()); +// DescriptionType description = deployment.getDescription(); +// if (description == null ) { +// description = new DescriptionType(); +// deployment.setDescription(description); +// description.setAbstract("No abstract"); +// description.setMethod("no methods"); +// description.setObjectives("No objectives"); +// } +// description.set + + addSamplingDetails(deployment, recordingPeriod); + + getSensorDetails(deployment); + + getSensors(deployment); + + /** + * Stuff that may need to be put into the UI: + * Audio: can easily get current loc of raw and binary data, but may need to override these. I think + * this may be for the export UI ? + * Tracks: trackline information. General problem in PAMGUard. + */ + getDataDetails(deployment); + + + return deployment; + } + + /** + * Add the track to the deployment, if there is one (i.e. not for + * a fixed sensor). + * @param deployment + */ + private void getTrackDetails(Deployment deployment) { + TrackInformation trackInfo = getTrackInformation(); + if (trackInfo.haveGPSTrack() == false) { + return; + } + GPSDataBlock gpsDataBlock = (GPSDataBlock) trackInfo.getGpsDataMap().getParentDataBlock(); + if (gpsDataBlock == null) { + return; + } + /* + * should have some track information. Do a load from the + * database for the whole deployment. this may be the entire GPS record, but + * we should be able to cope with that. + */ + long trackStart = TethysTimeFuncs.millisFromGregorianXML(deployment.getDeploymentDetails().getTimeStamp()); + long trackEnd = TethysTimeFuncs.millisFromGregorianXML(deployment.getRecoveryDetails().getTimeStamp()); + long dataWin =(long) (Math.max(1./trackInfo.getGPSDataRate(), deploymentExportOptions.trackPointInterval)); + + // get the tracks object. + Tracks tracks = deployment.getData().getTracks(); + if (tracks == null) { + tracks = new Tracks(); + deployment.getData().setTracks(tracks); + } + List trackList = tracks.getTrack(); // lists are usually there. + + Track aTrack = new Track(); + trackList.add(aTrack); + List points = aTrack.getPoint(); + + gpsDataBlock.loadViewerData(trackStart-dataWin, trackEnd+dataWin, null); + long lastPointTime = 0; + ListIterator it = gpsDataBlock.getListIterator(0); + while (it.hasNext()) { + GpsDataUnit gpsDataUnit = it.next(); + if (gpsDataUnit.getTimeMilliseconds()-lastPointTime < deploymentExportOptions.trackPointInterval*1000) { + continue; + } + GpsData gpsData = gpsDataUnit.getGpsData(); + Point gpsPoint = new Point(); + gpsPoint.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(gpsDataUnit.getTimeMilliseconds())); + gpsPoint.setLatitude(gpsData.getLatitude()); + gpsPoint.setLongitude(PamUtils.constrainedAngle(gpsData.getLongitude())); + BearingDegN bdn = gpsPoint.getBearingDegN(); + if (bdn == null) { + bdn = new BearingDegN(); + gpsPoint.setBearingDegN(bdn); + } + bdn.setValue(AutoTethysProvider.roundDecimalPlaces(PamUtils.constrainedAngle(gpsData.getHeading()),1)); + gpsPoint.setSpeedKn(AutoTethysProvider.roundDecimalPlaces(gpsData.getSpeed(),2)); + + points.add(gpsPoint); + lastPointTime = gpsDataUnit.getTimeMilliseconds(); + } + } + + public String getBinaryDataURI() { + BinaryStore binStore = BinaryStore.findBinaryStoreControl(); + if (binStore != null) { + return binStore.getBinaryStoreSettings().getStoreLocation(); + } + return null; + } + + public String getDatabaseURI() { + DBControlUnit databaseControl = DBControlUnit.findDatabaseControl(); + if (databaseControl != null) { + return databaseControl.getLongDatabaseName(); + } + return null; + } + + public String getRawDataURI() { + try { + PamControlledUnit daq = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); + if (daq instanceof AcquisitionControl) { + AcquisitionControl daqCtrl = (AcquisitionControl) daq; + DaqSystem system = daqCtrl.findDaqSystem(null);// getAcquisitionProcess().getRunningSystem(); + if (system instanceof FolderInputSystem) { + FolderInputSystem fip = (FolderInputSystem) system; + return fip.getFolderInputParameters().recentFiles.get(0); + } + } + } + catch (Exception e) { + } + return "unknown"; + } + + private void getDataDetails(Deployment deployment) { + Data data = deployment.getData(); + if (data == null) { + data = new Data(); + deployment.setData(data); + } + nilus.Deployment.Data.Audio audio = data.getAudio(); + if (audio == null) { + audio = new nilus.Deployment.Data.Audio(); + data.setAudio(audio); + } + audio.setURI(getRawDataURI()); + String processed = "Database:"+getDatabaseURI(); + String binary = getBinaryDataURI(); + if (binary != null) { + binary += ";Binary:"+binary; + } + audio.setProcessed(processed); + + } + + /** + * Get sensor information. The Soundtrap CTD will count as a sensor. + * Modules that are sensors will have to implement a PAMSensor interface + * @param deployment + */ + private void getSensors(Deployment deployment) { + ArrayList sensorModules = PamController.getInstance().findControlledUnits(PamSensor.class, true); + if (sensorModules == null || sensorModules.size() == 0) { + return; + } + Sensors sensors = deployment.getSensors(); + if (sensors == null) { + sensors = new Sensors(); + deployment.setSensors(sensors); + } + List sensorList = sensors.getSensor(); + for (PamControlledUnit aUnit : sensorModules) { + PamSensor pamSensor = (PamSensor) aUnit; + UnknownSensor nilusSensor = new UnknownSensor(); + try { + Helper.createRequiredElements(nilusSensor); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +// nilusSensor.setName(pamSensor.getUnitName()); + nilusSensor.setType(pamSensor.getUnitType()); + nilusSensor.setNumber(BigInteger.ZERO); + nilusSensor.setDescription(pamSensor.getSensorDescription()); + nilusSensor.setSensorId(pamSensor.getUnitType()); + + sensorList.add(nilusSensor); + } + } + + /** + * Add project Metadata to a Deploymnet document. This is currently being + * made available in the MetaDataControl module which should be added to PAMGuard + * as well as the Tethys output module. + * @param deployment + */ + private boolean getProjectData(Deployment deployment) { +// PamControlledUnit aUnit = PamController.getInstance().findControlledUnit(MetaDataContol.class, null); +// if (aUnit instanceof MetaDataContol == false || true) { +// deployment.setProject("thisIsAProject"); +// deployment.setPlatform("Yay a platform"); +// Instrument instrument = new Instrument(); +// instrument.setType("machiney"); +// instrument.setInstrumentId("12345555"); +// deployment.setInstrument(instrument); +// return false; +// } +// +// MetaDataContol metaControl = (MetaDataContol) aUnit; + PamguardMetaData metaData = MetaDataContol.getMetaDataControl().getMetaData(); + Deployment deploymentData = tethysControl.getGlobalDeplopymentData(); + deployment.setProject(deploymentData.getProject()); + deployment.setDeploymentAlias(deploymentData.getDeploymentAlias()); + deployment.setSite(deploymentData.getSite()); + deployment.setCruise(deploymentData.getCruise()); + deployment.setPlatform(getPlatform()); + deployment.setRegion(deploymentData.getRegion()); + Instrument instrument = new Instrument(); + instrument.setType(getInstrumentType()); + instrument.setInstrumentId(getInstrumentId()); + // get the geometry type from the array manager. + String geomType = getGeometryType(); + instrument.setGeometryType(geomType); + deployment.setInstrument(instrument); + + // overwrite the default deployment and recovery times if there is non null data + XMLGregorianCalendar depTime = deploymentData.getDeploymentDetails().getTimeStamp(); + if (depTime != null) { + deployment.getDeploymentDetails().setTimeStamp(depTime); + } + if (deploymentData.getRecoveryDetails() != null) { + XMLGregorianCalendar recMillis = deploymentData.getRecoveryDetails().getTimeStamp(); + if (recMillis != null) { + deployment.getRecoveryDetails().setTimeStamp(recMillis); + } + double recLat = deploymentData.getRecoveryDetails().getLatitude(); + double recLong = deploymentData.getRecoveryDetails().getLongitude(); + if (recLat != 0 & recLong != 0.) { + deployment.getRecoveryDetails().setLatitude(recLat); + deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLong)); + } + } + + return true; + } + + /** + * Instrument identifier, e.g. serial number + * @return + */ + private String getInstrumentId() { + return ArrayManager.getArrayManager().getCurrentArray().getInstrumentId(); + } + + /** + * Test to see if it's possible to export Deployment documents. This is basically a test of + * various metadata fields that are required, such as instrument id's. + * @return null if OK, or a string describing the first encountered error + */ + public String canExportDeployments() { + + Deployment globalDeplData = tethysControl.getGlobalDeplopymentData(); + if (globalDeplData.getProject() == null) { + return "You must set a project name"; + } + + PInstrument arrayInstrument = getCurrentArrayInstrument(); + if (arrayInstrument == null) { + return "No 'Instrument' set. Goto array manager"; + } + return null; + } + + /** + * Get the Instrument info for the current array. + * @return + */ + public PInstrument getCurrentArrayInstrument() { + PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray(); + String currType = currentArray.getInstrumentType(); + String currId = currentArray.getInstrumentId(); + PInstrument currentInstrument = null; + if (currType != null || currId != null) { + currentInstrument = new PInstrument(currType, currId); + } + return currentInstrument; + } + + /** + * On what platform is the instrument deployed? (e.g. mooring, tag) + * @return + */ + private String getPlatform() { + return getGeometryType(); + } + /** + * Instrument type, e.g. HARP, EAR, Popup, DMON, Rock Hopper, etc. + * @return + */ + private String getInstrumentType() { + return ArrayManager.getArrayManager().getCurrentArray().getInstrumentType(); + } + + /** + * Get a geometry type string for Tethys based on information in the array manager. + * @return + */ + private String getGeometryType() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nStreamer = array.getStreamerCount(); + for (int i = 0; i < nStreamer; i++) { + Streamer streamer = array.getStreamer(i); + HydrophoneLocator locator = streamer.getHydrophoneLocator(); + if (locator == null) { + continue; + } + if (locator instanceof ThreadingHydrophoneLocator) { + return "cabled"; + } + else { + return "rigid"; + } + } + return "unknown"; + } + + private boolean getSensorDetails(Deployment deployment) { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + Sensors sensors = new Sensors(); + List