mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-25 16:42:27 +00:00
Merge from dev branch (#125)
* updating Tethys help * added help details server connection & calibration * Reporting outputs to user Use Pamguard WarnOnce system to show a message of success or failure after attempting to output to Tethys. * Removing empty fields Start of implementation of code that can remove empty fields from objects before they are written. * More help documentation Continued writing general export help. Added new css style Added image * Fix type in Deployment export * Prevent single deployment export For now, disable the option to export a single Deployment document for multiple recording periods. * System to search species codes Search the ITIS species codes in Tethys to find ITIS codes. Search can be on a common or scientific name. * Data blocks help + species codes More help documentation on exporting detections/localization as well as mapping detection species codes to TSNs. Includes supporting images * Improved dialog for finding species codes Now has a progress bar to block GUI while searching database. * Add species codes TOC in help * Documented new species search in help * Nilus Checker Can check a Nilus class to see if it's missing required objects and be used to remove empty fields (e.g. zero length strings) from an object. * fixed anchor html problem * Messing around with checking of required fields in nilus objects. * split Tethys help files into smaller chunks * Update button enablers And reinstate output of a single deployment document, with non-recording periods stores in the QA section And update help TOC for latest help documents. --------- Co-authored-by: Marie <marie.roch@sdsu.edu>
This commit is contained in:
parent
cb0d191c08
commit
5466914d4e
@ -1,7 +1,5 @@
|
|||||||
package PamView.wizard;
|
package PamView.wizard;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ public class ClickBlockSpeciesManager extends DataBlockSpeciesManager<ClickDetec
|
|||||||
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
|
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
|
||||||
super(clickDataBlock);
|
super(clickDataBlock);
|
||||||
this.clickControl = clickControl;
|
this.clickControl = clickControl;
|
||||||
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.UNKNOWN, "Unknown", "Unknown"));
|
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.OTHER, "Unknown", "Unknown"));
|
||||||
setDefaultSpeciesCode("Unknown");
|
setDefaultSpeciesCode("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,2 +1,2 @@
|
|||||||
JavaSearch 1.0
|
JavaSearch 1.0
|
||||||
TMAP bs=2048 rt=1 fl=-1 id1=6727 id2=1
|
TMAP bs=2048 rt=1 fl=-1 id1=6882 id2=1
|
||||||
|
Binary file not shown.
@ -54,6 +54,8 @@
|
|||||||
|
|
||||||
<mapID target="classifiers.whistleClassifierHelp.docs.whistleClassifier_Output" url="classifiers/whistleClassifierHelp/docs/whistleClassifier_Output.html"/>
|
<mapID target="classifiers.whistleClassifierHelp.docs.whistleClassifier_Output" url="classifiers/whistleClassifierHelp/docs/whistleClassifier_Output.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.calibrations" url="utilities/tethys/docs/calibrations.html"/>
|
||||||
|
|
||||||
<mapID target="utilities.hydrophoneArrayManagerHelp.docs.Array_Configuration_sec1" url="utilities/hydrophoneArrayManagerHelp/docs/Array_Configuration.html#sec1"/>
|
<mapID target="utilities.hydrophoneArrayManagerHelp.docs.Array_Configuration_sec1" url="utilities/hydrophoneArrayManagerHelp/docs/Array_Configuration.html#sec1"/>
|
||||||
|
|
||||||
<mapID target="sound_processing.fftManagerHelp.docs.noise_removal_medianfilter" url="sound_processing/fftManagerHelp/docs/noise_removal.html#medianfilter"/>
|
<mapID target="sound_processing.fftManagerHelp.docs.noise_removal_medianfilter" url="sound_processing/fftManagerHelp/docs/noise_removal.html#medianfilter"/>
|
||||||
@ -138,6 +140,8 @@
|
|||||||
|
|
||||||
<mapID target="sound_processing.NoiseBands.Docs.NoiseBands" url="sound_processing/NoiseBands/Docs/NoiseBands.html"/>
|
<mapID target="sound_processing.NoiseBands.Docs.NoiseBands" url="sound_processing/NoiseBands/Docs/NoiseBands.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.detect_localize" url="utilities/tethys/docs/detect_localize.html"/>
|
||||||
|
|
||||||
<mapID target="visual_methods.videoRangeHelp.docs.videoRange_Calibrating" url="visual_methods/videoRangeHelp/docs/videoRange_Calibrating.html"/>
|
<mapID target="visual_methods.videoRangeHelp.docs.videoRange_Calibrating" url="visual_methods/videoRangeHelp/docs/videoRange_Calibrating.html"/>
|
||||||
|
|
||||||
<mapID target="detectors.gpl.docs.detection" url="detectors/gpl/docs/detection.html"/>
|
<mapID target="detectors.gpl.docs.detection" url="detectors/gpl/docs/detection.html"/>
|
||||||
@ -198,6 +202,8 @@
|
|||||||
|
|
||||||
<mapID target="displays.userDisplayHelp.docs.userDisplayPanel" url="displays/userDisplayHelp/docs/userDisplayPanel.html"/>
|
<mapID target="displays.userDisplayHelp.docs.userDisplayPanel" url="displays/userDisplayHelp/docs/userDisplayPanel.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.tethys_speciescodes_TSNLookup" url="utilities/tethys/docs/tethys_speciescodes.html#TSNLookup"/>
|
||||||
|
|
||||||
<mapID target="classifiers.roccaHelp.docs.rocca_Configure_SchoolStats" url="classifiers/roccaHelp/docs/rocca_Configure.html#SchoolStats"/>
|
<mapID target="classifiers.roccaHelp.docs.rocca_Configure_SchoolStats" url="classifiers/roccaHelp/docs/rocca_Configure.html#SchoolStats"/>
|
||||||
|
|
||||||
<mapID target="visual_methods.loggerFormsHelp.docs.SUBTABS" url="visual_methods/loggerFormsHelp/docs/SUBTABS.html"/>
|
<mapID target="visual_methods.loggerFormsHelp.docs.SUBTABS" url="visual_methods/loggerFormsHelp/docs/SUBTABS.html"/>
|
||||||
@ -276,8 +282,6 @@
|
|||||||
|
|
||||||
<mapID target="detectors.clickDetectorHelp.docs.offline_Tools_AmplSel" url="detectors/clickDetectorHelp/docs/offline_Tools.html#AmplSel"/>
|
<mapID target="detectors.clickDetectorHelp.docs.offline_Tools_AmplSel" url="detectors/clickDetectorHelp/docs/offline_Tools.html#AmplSel"/>
|
||||||
|
|
||||||
<mapID target="utilities.tethys.docs.tethys_quickstart" url="utilities/tethys/docs/tethys_quickstart.html"/>
|
|
||||||
|
|
||||||
<mapID target="displays.spectrogramDisplayHelp.docs.UserDisplay_Spectrogram_Overlays" url="displays/spectrogramDisplayHelp/docs/UserDisplay_Spectrogram_Overlays.html"/>
|
<mapID target="displays.spectrogramDisplayHelp.docs.UserDisplay_Spectrogram_Overlays" url="displays/spectrogramDisplayHelp/docs/UserDisplay_Spectrogram_Overlays.html"/>
|
||||||
|
|
||||||
<mapID target="displays.radarDisplayHelp.docs.UserDisplay_Radar_Creating" url="displays/radarDisplayHelp/docs/UserDisplay_Radar_Creating.html"/>
|
<mapID target="displays.radarDisplayHelp.docs.UserDisplay_Radar_Creating" url="displays/radarDisplayHelp/docs/UserDisplay_Radar_Creating.html"/>
|
||||||
@ -290,6 +294,8 @@
|
|||||||
|
|
||||||
<mapID target="classifiers.roccaHelp.docs.rocca_Spectrogram_rocca_RecalcContour" url="classifiers/roccaHelp/docs/rocca_Spectrogram.html#rocca_RecalcContour"/>
|
<mapID target="classifiers.roccaHelp.docs.rocca_Spectrogram_rocca_RecalcContour" url="classifiers/roccaHelp/docs/rocca_Spectrogram.html#rocca_RecalcContour"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.tethys_speciescodes" url="utilities/tethys/docs/tethys_speciescodes.html"/>
|
||||||
|
|
||||||
<mapID target="overview.PamMasterHelp.docs.performanceTests" url="overview/PamMasterHelp/docs/performanceTests.html"/>
|
<mapID target="overview.PamMasterHelp.docs.performanceTests" url="overview/PamMasterHelp/docs/performanceTests.html"/>
|
||||||
|
|
||||||
<mapID target="overview.PamMasterHelp.docs.xmloutput" url="overview/PamMasterHelp/docs/xmloutput.html"/>
|
<mapID target="overview.PamMasterHelp.docs.xmloutput" url="overview/PamMasterHelp/docs/xmloutput.html"/>
|
||||||
@ -388,6 +394,8 @@
|
|||||||
|
|
||||||
<mapID target="localisation.group3d.docs.3dsimplex" url="localisation/group3d/docs/3dsimplex.html"/>
|
<mapID target="localisation.group3d.docs.3dsimplex" url="localisation/group3d/docs/3dsimplex.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.connection" url="utilities/tethys/docs/connection.html"/>
|
||||||
|
|
||||||
<mapID target="visual_methods.loggerFormsHelp.docs.NOCLEAR" url="visual_methods/loggerFormsHelp/docs/NOCLEAR.html"/>
|
<mapID target="visual_methods.loggerFormsHelp.docs.NOCLEAR" url="visual_methods/loggerFormsHelp/docs/NOCLEAR.html"/>
|
||||||
|
|
||||||
<mapID target="sound_processing.beamformer.docs.Beamformer_Settings_BF_SourceTab" url="sound_processing/beamformer/docs/Beamformer_Settings.html#BF_SourceTab"/>
|
<mapID target="sound_processing.beamformer.docs.Beamformer_Settings_BF_SourceTab" url="sound_processing/beamformer/docs/Beamformer_Settings.html#BF_SourceTab"/>
|
||||||
@ -456,6 +464,8 @@
|
|||||||
|
|
||||||
<mapID target="sound_processing.seismicveto.docs.veto_configuration" url="sound_processing/seismicveto/docs/veto_configuration.html"/>
|
<mapID target="sound_processing.seismicveto.docs.veto_configuration" url="sound_processing/seismicveto/docs/veto_configuration.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.deployments" url="utilities/tethys/docs/deployments.html"/>
|
||||||
|
|
||||||
<mapID target="detectors.whistleMoanHelp.docs.whistleMoan_ConfigNoise_averagesubtraction" url="detectors/whistleMoanHelp/docs/whistleMoan_ConfigNoise.html#averagesubtraction"/>
|
<mapID target="detectors.whistleMoanHelp.docs.whistleMoan_ConfigNoise_averagesubtraction" url="detectors/whistleMoanHelp/docs/whistleMoan_ConfigNoise.html#averagesubtraction"/>
|
||||||
|
|
||||||
<mapID target="localisation.largeAperture3D.docs.meal_exercise3_localise" url="localisation/largeAperture3D/docs/meal_exercise3_localise.html"/>
|
<mapID target="localisation.largeAperture3D.docs.meal_exercise3_localise" url="localisation/largeAperture3D/docs/meal_exercise3_localise.html"/>
|
||||||
@ -592,6 +602,8 @@
|
|||||||
|
|
||||||
<mapID target="detectors.gpl.docs.notes" url="detectors/gpl/docs/notes.html"/>
|
<mapID target="detectors.gpl.docs.notes" url="detectors/gpl/docs/notes.html"/>
|
||||||
|
|
||||||
|
<mapID target="utilities.tethys.docs.tethys_module" url="utilities/tethys/docs/tethys_module.html"/>
|
||||||
|
|
||||||
<mapID target="sound_processing.fftManagerHelp.docs.FFTEngine_Creating" url="sound_processing/fftManagerHelp/docs/FFTEngine_Creating.html"/>
|
<mapID target="sound_processing.fftManagerHelp.docs.FFTEngine_Creating" url="sound_processing/fftManagerHelp/docs/FFTEngine_Creating.html"/>
|
||||||
|
|
||||||
<mapID target="sound_processing.fftManagerHelp.docs.noise_removal_clickremoval" url="sound_processing/fftManagerHelp/docs/noise_removal.html#clickremoval"/>
|
<mapID target="sound_processing.fftManagerHelp.docs.noise_removal_clickremoval" url="sound_processing/fftManagerHelp/docs/noise_removal.html#clickremoval"/>
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 1.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd"><!--generated by JHelpDev Version: 0.63, 14 May 2008, see jhelpdev.sourceforge.net-->
|
<!DOCTYPE index PUBLIC "-//Sun Microsystems Inc.//DTD JavaHelp Index Version 1.0//EN" "http://java.sun.com/products/javahelp/index_2_0.dtd"><!--generated by JHelpDev Version: 0.63, 14 May 2008, see jhelpdev.sourceforge.net-->
|
||||||
|
|
||||||
<index version="1.0">
|
<index version="1.0">
|
||||||
|
<indexitem text="ITIS Species Codes " target="utilities.tethys.docs.tethys_speciescodes"/>
|
||||||
|
|
||||||
<indexitem text="Tethys server " target="utilities.tethys.docs.tethys_server"/>
|
<indexitem text="Tethys server " target="utilities.tethys.docs.tethys_server"/>
|
||||||
|
|
||||||
<indexitem text="Tethys database interface " target="utilities.tethys.docs.tethys_overview"/>
|
<indexitem text="Tethys database interface " target="utilities.tethys.docs.tethys_overview"/>
|
||||||
|
@ -198,10 +198,20 @@
|
|||||||
<tocitem text="Tethys Interface ">
|
<tocitem text="Tethys Interface ">
|
||||||
<tocitem text="Tethys Overview " target="utilities.tethys.docs.tethys_overview" image="topic"/>
|
<tocitem text="Tethys Overview " target="utilities.tethys.docs.tethys_overview" image="topic"/>
|
||||||
|
|
||||||
<tocitem text="Quick Start " target="utilities.tethys.docs.tethys_quickstart" image="topic"/>
|
<tocitem text="Tethys Module " target="utilities.tethys.docs.tethys_module" image="topic"/>
|
||||||
|
|
||||||
<tocitem text="Tethys Server " target="utilities.tethys.docs.tethys_server" image="topic"/>
|
<tocitem text="Tethys Server " target="utilities.tethys.docs.tethys_server" image="topic"/>
|
||||||
|
|
||||||
|
<tocitem text="Connecting to Tethys " target="utilities.tethys.docs.connection" image="topic"/>
|
||||||
|
|
||||||
|
<tocitem text="Instrument Calibrations " target="utilities.tethys.docs.calibrations" image="topic"/>
|
||||||
|
|
||||||
|
<tocitem text="Instrument Deployments " target="utilities.tethys.docs.deployments" image="topic"/>
|
||||||
|
|
||||||
|
<tocitem text="Detections and Localizations " target="utilities.tethys.docs.detect_localize" image="topic"/>
|
||||||
|
|
||||||
|
<tocitem text="ITIS Species Codes " target="utilities.tethys.docs.tethys_speciescodes" image="topic"/>
|
||||||
|
|
||||||
</tocitem>
|
</tocitem>
|
||||||
</tocitem>
|
</tocitem>
|
||||||
<tocitem text="Sensors ">
|
<tocitem text="Sensors ">
|
||||||
|
@ -55,6 +55,14 @@ ol {
|
|||||||
|
|
||||||
img.wrap {float: left}
|
img.wrap {float: left}
|
||||||
img.wrapright {float: right}
|
img.wrapright {float: right}
|
||||||
|
img.wrapcenter {float: center}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
table, th, td {
|
table, th, td {
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
|
147
src/help/utilities/tethys/docs/calibrations.html
Normal file
147
src/help/utilities/tethys/docs/calibrations.html
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<link href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Instrument Calibration Information</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img.wrap {
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
img.wrapright {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<h1>Instrument calibration information</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Most of the calibration data is taken from the array manager and
|
||||||
|
from the sound acquisition module. However, PAMGuard will ask a
|
||||||
|
few questions about HOW the instrument was calibrated, when it was
|
||||||
|
done and who is responsible.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
There are two dialogs associated with calibration. The first
|
||||||
|
asks for a calibration method and has the following fields:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Method: Must be one of the following options:
|
||||||
|
<ul>
|
||||||
|
<li>Reference hydrophone</li>
|
||||||
|
<li>Manufacturer’s specification</li>
|
||||||
|
<li>Piston phone</li>
|
||||||
|
<li>Other calibrated source</li>
|
||||||
|
<li>Unknown</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Serial number: Hydrophone serial number
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Quality: Quality assurance value:
|
||||||
|
<ul>
|
||||||
|
<li> unverified: The calibration has not been verified </li>
|
||||||
|
<li> valid: The calibration has been validated as per the quality assurance process </li>
|
||||||
|
<li> invalid: The calibration was found to be invalid during quality assurance </li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
QA Comment: Textual description of the quality assurance
|
||||||
|
process.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Calibration method: Textual description of the Method.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The second calibrations dialog asks for:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Calibration date: Date the calibration was performed.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Update frequency: Must be one of the following:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
as-needed: No updates are planned, but if a change is needed the calibration will be updated (defaul)t
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
unplanned: There are no plans to ever update the record.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
yearly: A yearly review will be conducted to ensure that the record is valid.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Technical Person / Data Manager: These two types of data have
|
||||||
|
the same fields and detail who was responsible for the
|
||||||
|
calibration and who is responsible for maintaining the record
|
||||||
|
of the calibration. In many cases, this may be the same
|
||||||
|
person and copy buttons allow the fields to be duplicated.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Name: Responsible party’s naem
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Organisation: Organisation to which the party reports
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Position: Responsible party’s title
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Email: Email contact information
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Fill in as much information as you can!
|
||||||
|
If the export is successful, a record will show for each
|
||||||
|
hydrophone (or sensor) in your instrument array in the
|
||||||
|
calibration information table:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="./images/calibration_information.png" class=".center"
|
||||||
|
alt="Panel with information about instrument calibration"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<p class="prevLink"><a href="tethys_module.html">Previous: Module overview
|
||||||
|
<p class="nextLink"><a href="deployments.html">Next: Instrument deployments
|
||||||
|
</a></p>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
121
src/help/utilities/tethys/docs/connection.html
Normal file
121
src/help/utilities/tethys/docs/connection.html
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<LINK href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Tethys Connection and Project Details </title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1> Connection and Project Details </h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Make sure you have a <a href = "tethys_server.html">Tethys Server</a> running. The PAMGuard interface will
|
||||||
|
only work with <a href="https://tethys.sdsu.edu/tethys3/">Tethys
|
||||||
|
3</a> or later. The section below specifies how to set the
|
||||||
|
address of Tethys server address as well as determine if
|
||||||
|
PAMGuard can communicate successfully with Tethys. (The top
|
||||||
|
panel will be orange if communication is not working.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Tethys Server</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Tethys Server field next to the picture of the goddess Tethys
|
||||||
|
indicates the address of the Tehtys server. To change this field,
|
||||||
|
click on the gear icon. You will be prompted to provide a computer
|
||||||
|
address (URL) and a port. The address should start with http://
|
||||||
|
followed by the machine name or internet protocol address unless
|
||||||
|
the Tethys server has been configured to use an encrypted
|
||||||
|
connection. In this case, start the address with https://.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
By default, PAMGuard will use http://localhost:9779 which
|
||||||
|
assumes that your Tethys server is running on the same computer as
|
||||||
|
PAMGuard and that it expects communication on port 9779, the
|
||||||
|
default port (administrators may change this).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If PAMGuard can communicate with the Tethys server, the
|
||||||
|
Connection and Project panel will be light grey. If
|
||||||
|
communication is not possible, the panel will be colored
|
||||||
|
orange. Likely causes for communication failure are:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
The server address or port is incorrect.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Tethys has not been started on the server machine. One of the
|
||||||
|
main reasons that we see this is when the administrator has
|
||||||
|
not configured Tethys to run automatically as a service. In
|
||||||
|
that case, when a machine reboots (e.g., for automatic
|
||||||
|
operaing system updates) the server will not start
|
||||||
|
automatically. The Tethys manual explains how to configure
|
||||||
|
Tethys as a service that starts automatically when the machine
|
||||||
|
boots.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Firewall rules do not permit traffic between the machine
|
||||||
|
executing PAMGuard and the one hosting Tethys on the selected
|
||||||
|
port. If you do not have adminstrative privileges, you will
|
||||||
|
need to contact your support team for help.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Project and Instrument Information</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Projects are names used by Tethys to help track work that should
|
||||||
|
be considered together, such as a series of deployments designed
|
||||||
|
to answer a specific question or funded under a specific
|
||||||
|
grant. If you do not already have a project defined in your
|
||||||
|
PAMGuard database, you can click the "New Project" button in the
|
||||||
|
"Connection and Project details" section of the Tethys
|
||||||
|
module. This will start a dialog that asks for a case-sensitive
|
||||||
|
project name and a geographic region. The geographic region is
|
||||||
|
for convenience, PAMGuard and Tethys track information by
|
||||||
|
longitude and latitude, but sometimes it is helpful to query for
|
||||||
|
information with respect to a geographic name such as Channel
|
||||||
|
|
||||||
|
Islands National Marine Sanctuary.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The array instrumentation is selected from a drop-down menu next
|
||||||
|
to the Instruments label. A dropdown menu next to the label
|
||||||
|
“Instruments” shows the list of hydrophone arrays. These are
|
||||||
|
likely to have been previously established prior to starting
|
||||||
|
analysis of your data by using the menu Settings -> Hydrophone
|
||||||
|
Array.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If you are a long-time user of PAMGuard, you will notice
|
||||||
|
additional fields are required for instrumentation: Instrument
|
||||||
|
Type and Instrument Id. The type indicates what type of
|
||||||
|
instrument is being used and may be generic such as a mooring or
|
||||||
|
array or denote a specific instrument such as a HARP, Rock
|
||||||
|
Hopper, SoundTrap, etc. The Id is a unique identifier for the
|
||||||
|
instrument such as a serial number. Note that if you are using
|
||||||
|
an older PAMGuard database, you may see a blank entry in the
|
||||||
|
instruments list as these new fields will not have been
|
||||||
|
populated. Press new/edit to access the instrument settings
|
||||||
|
from the Tethys module page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<p class="prevLink"><a href="tethys_module.html">Previous:
|
||||||
|
Tethys module</a></p>
|
||||||
|
<p class="nextLink"><a href="calibrations.html">Next: Instrument calibrations</a></p>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
</body>
|
143
src/help/utilities/tethys/docs/deployments.html
Normal file
143
src/help/utilities/tethys/docs/deployments.html
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<link href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Deployments</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img.wrap {
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
img.wrapright {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Deployments</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Tethys uses deployment records to register information about
|
||||||
|
when instruments have been deployed as well as their
|
||||||
|
characteristics. Examples of characteristics that are recorded
|
||||||
|
include sample rate and the number of quantization bits,
|
||||||
|
description of duty cycles (if applicable), hydrophone geometry,
|
||||||
|
and enough details to be able find calibration data for specific
|
||||||
|
hydrophones.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
PAMGuard will examine the
|
||||||
|
<a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard
|
||||||
|
database</a>
|
||||||
|
and <a href="../../BinaryStore/docs/binarystore_overview.html">
|
||||||
|
binary Store</a> to determine what records should be generated for
|
||||||
|
your instrumentation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Where data were collected continuously or on a regular duty
|
||||||
|
cycle, PAMGuard will create a single deployment record. If data
|
||||||
|
were collected on a more "ad-hoc" basis, where the instrument
|
||||||
|
has been deployed multiple times or has irregular recording,
|
||||||
|
PAMGuard will generate a deployment record for each period of
|
||||||
|
recording.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The figure below shows an example of ad-hoc recording periods
|
||||||
|
identified by PAMGuard:
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<img src="./images/deploymentspanel.png" class=".center"
|
||||||
|
alt="Panel showing recording times/deployments for this PAMGuard database"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Occasionally, there may be short recording periods (e.g. while
|
||||||
|
you were testing kit on deck) that you do not want to export. Use
|
||||||
|
the select checkbox to pick all of the rows that you wish to
|
||||||
|
export, or right click on the table and "Select All."
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When one or more deployment records are selected, the
|
||||||
|
"Export..." button will become available. Selecting the export
|
||||||
|
button will start a dialog that asks for additional information
|
||||||
|
about the deployments and then write records to Tethys.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The first page of the dialog asks for the project and geographic
|
||||||
|
region which will be automatically populated if they have been
|
||||||
|
previously specified. In addition, the following fields are
|
||||||
|
requested:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Cruise name - Optional name of the deployment cruise</li>
|
||||||
|
<li>Site - Case-sensitive name for the deployment site,
|
||||||
|
e.g. "Tanner Banks" or a letter designation "T". This can
|
||||||
|
provide a simple way to identify multiple deployments at the
|
||||||
|
same general location.
|
||||||
|
</li>
|
||||||
|
<li>Responsible Party - A set of fields describing who was
|
||||||
|
responsible for the deployment and how they may be
|
||||||
|
contacted.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The next page of the dialog asks whether you would like to
|
||||||
|
export a single deployment document or multiple deployments.
|
||||||
|
<strong>todo: add more detail here</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Finally, you are prompted to provide optional textual descriptions of:
|
||||||
|
<ul>
|
||||||
|
<li> Objectives - What were your objectives when deploying the
|
||||||
|
instrument? Example: Determine population estimates for
|
||||||
|
critically endangered populations of vaquita (<em>Phocoena
|
||||||
|
sinus</em>).
|
||||||
|
</li>
|
||||||
|
<li> Abstract - A textual description of the deployment.
|
||||||
|
Example: A set of high frequency recorders were deployed across the
|
||||||
|
northern portion of the Sea of Cortez in the historical range
|
||||||
|
of the vaquita (<em>Phocoena sinus</em>). These recordings will
|
||||||
|
support detection and density estimation efforts.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Method - A description of the methods used. Example:
|
||||||
|
Small boat deployment of bottom moored SoundTrap recorders
|
||||||
|
with acoustic releases.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
Press Finish to export the records. Once the
|
||||||
|
document(s) have been successuflly exported, the document name
|
||||||
|
associated with each recording period will be shown in the
|
||||||
|
Tethys Deployment column.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
|
||||||
|
<p class="prevLink">
|
||||||
|
<a href="calibrations.html">Previous: Calibrations</a>
|
||||||
|
</p>
|
||||||
|
<p class="nextLink">
|
||||||
|
<a href="detect_localize.html">Next: Detections & Localizations</a>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
161
src/help/utilities/tethys/docs/detect_localize.html
Normal file
161
src/help/utilities/tethys/docs/detect_localize.html
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<link href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Detections/Localizations</title>
|
||||||
|
<style type="text/css">
|
||||||
|
img.wrap {
|
||||||
|
float: left
|
||||||
|
}
|
||||||
|
|
||||||
|
img.wrapright {
|
||||||
|
float: right
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Exporting Detections/Localizations (PAMGuard data blocks)</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The bottom left panel of the Tethys module shows a list of
|
||||||
|
different types of PAMGuard data that can be exported. The data
|
||||||
|
in this list correspond to the various PAMGuard modules that have
|
||||||
|
been configured. See the
|
||||||
|
<a href="../../../overview/PamMasterHelp/docs/modelViewer.html">
|
||||||
|
data model viewer</a>
|
||||||
|
help for an example of how PAMGuard might be configured.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Species information</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some of these data represent detections of specific species or
|
||||||
|
phenomena that must be translated to Tethys. A context menu
|
||||||
|
(right-click on most computers) will show the option "Species
|
||||||
|
info..." that will allow you to specify the
|
||||||
|
<a href="./tethys_speciescodes.html">translation of events</a>
|
||||||
|
to species identifiers and call/sound types. If you try to export
|
||||||
|
without having done this, the species info dialog will be started
|
||||||
|
automatically prior to export.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Selecting data blocks for import</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In the sample data blocks below, four modules have been
|
||||||
|
configured, but only one of them has been run. Column "N Pam
|
||||||
|
Data" indicates the number of data records that have been
|
||||||
|
produced, and "PAMGuard Time" tells us when the data were
|
||||||
|
processed. "Tethys Documents" indicates how many Tethys records
|
||||||
|
have been produced, and should be 0 until the data are exported.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="./images/data_blocks.png" class=".center"
|
||||||
|
alt="List of results showing detections and other module processing events"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Select the data blocks to be exported by clicking on them.
|
||||||
|
Multiple lines can be selected by using keyboard modifiers such as
|
||||||
|
holding the shift while clicking to select all data blocks between
|
||||||
|
the last clicked block and where you click. Holding the alternate
|
||||||
|
(ALT) key will allow selection or de-selection of a single item
|
||||||
|
without affecting the selection state of other blocks.
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
SUGGESTION: It looks like we have to highlight these by clicking
|
||||||
|
on them. As we use select boxes for recording periods, we might
|
||||||
|
want to do the same thing here... We might want to rename
|
||||||
|
N PAM Datas to N PAM Data as data are already plural.
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2> Exporting data blocks </h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Once the data blocks have been selected, press export. A series
|
||||||
|
of dialogs will guide you through the export process. The first
|
||||||
|
set of dialogs simply display a summary of information about what
|
||||||
|
will be exported.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="./images/stream_algo_info.png" class=".center"
|
||||||
|
alt="List of details describing the mechanism, parameters, and version of modules used in processing"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
There is nothing to change in this summary. Press Next once you
|
||||||
|
have reviewed it. The second panel allows specification of your
|
||||||
|
objectives, abstract, and method. Many modules will have
|
||||||
|
pre-populated the method for you. While it is recommended to populate
|
||||||
|
the objectives and abstract, these fields are optional.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Press Next to proceed to the next step of the dialog. You will be asked
|
||||||
|
what details you wish to store within the parameters that were used to
|
||||||
|
produce these data. Your must select one of the following:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
None - Do not report any of parameters used to produce these
|
||||||
|
detections. This option is <strong>not recommended</strong> as
|
||||||
|
it severely limits your ability to reproduce your results at a
|
||||||
|
later date or know whether or not the results of different
|
||||||
|
studies can be used together.
|
||||||
|
</li>
|
||||||
|
<li> Data selector only - <strong>not sure what this is</strong> </li>
|
||||||
|
<li>
|
||||||
|
Module only - Report the parameters that were set with this
|
||||||
|
module. Only parameters associated with the specific module
|
||||||
|
will be reported. Examples include score and duration thresholds
|
||||||
|
as well as any other type of criterion used to determine whether
|
||||||
|
or not an event is associated with a specific phenomenon or species.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Full process chain (default) - This is the most verbose option. It includes the module
|
||||||
|
parameters as well as anything else that is part of the signal processing chain that leads
|
||||||
|
to the module. As an example, a module only setting would not report the parameters that were
|
||||||
|
used to generate a spectrogram that was presented to a module for classification, but the
|
||||||
|
full process chain would record these details as well. Use this option will dramatically
|
||||||
|
increase the potential to reproduce your results, but it will generate a large amount of data
|
||||||
|
about the signal processing chain, much of which might not be useful.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The final page of the dialog has an "Export data" button. Press
|
||||||
|
this to export the data. The system will begin generating the
|
||||||
|
Tethys document and the "Export data" button will be relabeled "Export complete"
|
||||||
|
once it is done. At this point, you can press "Finish" to close
|
||||||
|
the dialog.
|
||||||
|
|
||||||
|
<em>Would it make more sense to export when the user presses
|
||||||
|
Finish (or change the Finish button Export)?</em>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="prevLink">
|
||||||
|
<a href="deployments.html">Previous: Deployments</a>
|
||||||
|
</p>
|
||||||
|
<p class="nextLink">
|
||||||
|
<a href="./tethys_speciescodes.html">Translating species to
|
||||||
|
taxonomic serial numbers</a> (species encoding)
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
src/help/utilities/tethys/docs/images/data_blocks.png
Normal file
BIN
src/help/utilities/tethys/docs/images/data_blocks.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
src/help/utilities/tethys/docs/images/species_codes.png
Normal file
BIN
src/help/utilities/tethys/docs/images/species_codes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
src/help/utilities/tethys/docs/images/species_search.png
Normal file
BIN
src/help/utilities/tethys/docs/images/species_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
BIN
src/help/utilities/tethys/docs/images/stream_algo_info.png
Normal file
BIN
src/help/utilities/tethys/docs/images/stream_algo_info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
92
src/help/utilities/tethys/docs/tethys_module.html
Normal file
92
src/help/utilities/tethys/docs/tethys_module.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<LINK href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Tethys Module Overview</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Tethys Module Overview</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is assumed that you are familiar with PAMGuard and have some
|
||||||
|
knowledge about Tethys.
|
||||||
|
<a href="https://tethys.sdsu.edu/documentation">Documentation</a>
|
||||||
|
and <a href="https://tethys.sdsu.edu/tutorials/">tutorials</a>
|
||||||
|
are available at the Tethys
|
||||||
|
<a href="https://tethys.sdsu.edu">web site</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Launch PAMGuard in viewer mode</h1>
|
||||||
|
<p>
|
||||||
|
Tethys export is only available in
|
||||||
|
<a href="../../../overview/PamMasterHelp/docs/viewerMode.html">PAMGuard
|
||||||
|
Viewer mode</a>
|
||||||
|
and is used to archive project data to a centralised
|
||||||
|
database. It is NOT a replacement for the
|
||||||
|
existing <a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard
|
||||||
|
database</a>. Open the PAMGuard database that you wish to use
|
||||||
|
in viewer mode.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>PAMGuard Tethys Module</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Add a Tethys module to PAMGuard from the File / Add Modules /
|
||||||
|
Utilities menu. A new tab panel will show the Tethys interface
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src = "./images/TethysGUI_1.png" class=".center"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The tab shows a number of panes for the connection to the server
|
||||||
|
and the various types of data that will be output to the
|
||||||
|
database. Some of these panes summarize information on what's in
|
||||||
|
the current PAMGuard dataset (consisting of your PAMGuard
|
||||||
|
database and binary store), others may be empty until you start
|
||||||
|
to export to Tethys.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The Tethys module consists of several panels:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="connection.html">Connection and Project Details</a> -
|
||||||
|
Specifies the location of the Tethys server and metadata about
|
||||||
|
the project.
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
<li>Data Export - There are several panes that are responsible
|
||||||
|
for exporting information about instrument deployments, their
|
||||||
|
calibrations, and what they detected/localized.
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Instrument <a href="calibrations.html">calibration</a>
|
||||||
|
information
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
Recording periods
|
||||||
|
and <a href="deployments.html">deployments</a> information.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="detect_localize.html">Detections and
|
||||||
|
localizations</a>. A final panel next to this one lists
|
||||||
|
exported detection/localization documents.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<p class="prevLink"><a href="tethys_overview.html">Previous: Overview</a></p>
|
||||||
|
<p class="nextLink"><a href="connection.html">Next: Connection
|
||||||
|
& Project Details</a></p>
|
||||||
|
<br>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -21,48 +21,68 @@ img {
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Tethys Interface</h1>
|
<h1>Tethys Interface</h1>
|
||||||
<h2>Overview</h2>
|
<p></p>
|
||||||
|
<h2>Overview</h2>
|
||||||
|
|
||||||
<p align="right">
|
<div>
|
||||||
<img class="wrap" SRC="images/Tethys-200.png" alt="Tethys mosaic">
|
<img SRC="images/Tethys-200.png" alt="Tethys mosaic"
|
||||||
</p>
|
style="float: right; margin 10px;"/>
|
||||||
<p>
|
</div>
|
||||||
|
|
||||||
<a href="https://tethys.sdsu.edu/">Tethys</a> is a freely
|
<p>
|
||||||
available open source temporal-spatial database for metadata related
|
PAMGuard is compatible
|
||||||
to acoustic recordings. The database is intended to house the metadata
|
with <a href="https://tethys.sdsu.edu/tethys3/">Tethys 3.0</a> or
|
||||||
from marine mammal detection and localization studies, allowing the
|
later.
|
||||||
user to perform meta analyses or to aggregate data from many
|
<a href="https://tethys.sdsu.edu/">Tethys</a> is a freely
|
||||||
experimental efforts based on a common attribute. This resulting
|
available open source temporal-spatial database for metadata
|
||||||
database can then be queried based on time, space, or any desired
|
related to acoustic recordings. The database is intended to house
|
||||||
attribute and the results can be integrated with external datasets
|
the metadata from marine mammal detection and localization
|
||||||
such as NASA's Ocean Color, lunar illumination, etc. in a consistent
|
studies, allowing the user to perform meta analyses or to
|
||||||
manner. While Tethys is designed primarily for acoustic metadata from
|
aggregate data from many experimental efforts based on a common
|
||||||
marine mammals, the design is general enough to permit use in other
|
attribute. This resulting database can then be queried based on
|
||||||
areas as well.
|
time, space, or any desired attribute and the results can be
|
||||||
|
integrated with external datasets such as NASA's Ocean Color,
|
||||||
</p>
|
lunar illumination, etc. in a consistent manner. While Tethys is
|
||||||
<p>PAMGuard is compatible with <a href="https://tethys.sdsu.edu/tethys3/">Tethys 3.0</a> or above, released early in 2024. </p>
|
designed primarily for acoustic metadata from marine mammals, the
|
||||||
<p>The Tethys database is not a replacement for the existing
|
design is general enough to permit use in other areas as well.
|
||||||
<a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard Database.</a>
|
</p>
|
||||||
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.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>Before using the module in PAMGuard, you should install the Tethys Server, which runs under
|
|
||||||
Windows. <a href="https://tethys.sdsu.edu/install/">
|
|
||||||
Instructions for installing the Tethys Server can be found here.</a></p>
|
|
||||||
|
|
||||||
|
|
||||||
<br><br>
|
<p>
|
||||||
|
The Tethys database is not a replacement for the existing
|
||||||
|
<a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard
|
||||||
|
Database.</a> 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. PAMGuard's Tethys module
|
||||||
|
provides an interface for exporting detailed or summary
|
||||||
|
information about acoustic detections to the Tethys database.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Before using the module in PAMGuard, you should install the Tethys
|
||||||
|
Server. While clients that communicate with Tethys can run on a
|
||||||
|
variety of computer operating systems, there are a small number of
|
||||||
|
dependencies on Microsoft technologies that require the server to
|
||||||
|
be installed on a Microsoft Windows machine.
|
||||||
|
<a href="https://tethys.sdsu.edu/install/"> Instructions
|
||||||
|
for installing the Tethys Server can be found here.</a></p>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Module help:
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li> The <a href="tethys_module.html">Tethys module</a> (start here)</li>
|
||||||
|
<li> The <a href="connection.html">Connecting to Tethys</a> </li>
|
||||||
|
<li> The <a href="calibrations.html">Instrument calibrations</a> </li>
|
||||||
|
<li> The <a href="deployments.html">Instrument deployments</a> </li>
|
||||||
|
<li> The <a href="detect_localize.html">Detections & Localizations</a> </li>
|
||||||
|
<li> Guide to specifying <a href="tethys_speciescodes.html">species names</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
|
||||||
<a href="tethys_quickstart.html">Next: Quick Start</a>
|
|
||||||
</p>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<LINK href="../../../pamHelpStylesheet.css" type="text/css"
|
|
||||||
rel="STYLESHEET">
|
|
||||||
<title>Tethys</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Tethys Quick Start</h1>
|
|
||||||
|
|
||||||
<p>This 'Quick Start' guide is aimed at people who are already familiar with both Tethys and PAMGuard</p>
|
|
||||||
<p>The Tethys database is only used in
|
|
||||||
<a href="../../../overview/PamMasterHelp/docs/viewerMode.html">PAMGUard Viewer mode</a> and is only used to archive project data to a single
|
|
||||||
centralised database.
|
|
||||||
It is NOT a replacement for the existing <a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard database</a>.</p>
|
|
||||||
|
|
||||||
<h3>PAMGuard Tethys Module</h3>
|
|
||||||
<p>Launch PAMGuard in Viewer Mode with an existing set of data.</p>
|
|
||||||
<p>Add a Tethys module to PAMGuard from the File / Add Modules / Utilities menu. </p>
|
|
||||||
<p>A new tab panel will show the Tethys interface</p>
|
|
||||||
<center><img src = "./images/TethysGUI_1.png" width="100%" height="auto"></center>
|
|
||||||
<p>The tab shows a number of panels for the connection to the server and the various types
|
|
||||||
of data that will be output to the database. Some of these should summary information on what's in the
|
|
||||||
current PAMGuard dataset (consisting of your PAMGuard database and binary store), others may be empty until you start to
|
|
||||||
export to Tethys. </p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Tethys Server</h3>
|
|
||||||
<p>Make sure you have a <a href = "tethys_server.html">Tethys Server</a> running. The PAMGuard interface will
|
|
||||||
only work with <a href="https://tethys.sdsu.edu/tethys3/">Tethys 3.</a> </p>
|
|
||||||
<p>Check the server connection. If PAMGuard has correctly connected to the Tethys server, the top panel of the display will be a normal
|
|
||||||
grey colour. If the connection cannot be made, the panel will be orange.</p>
|
|
||||||
<p>If required, change the server settings using the "Select Sever" button</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h4>Project and Instrument Information</h4>
|
|
||||||
<p>Either select an existing "Project", or create a new one.</p>
|
|
||||||
<p>You also need to give Tethys more information about the instrument(s) or arrays you've deployed than in previous PAMGuard versions. Again, select an
|
|
||||||
existing instrument, or set up a new one. You'll notice that this information is held with the rest of the PAMGuard array management information.</p>
|
|
||||||
|
|
||||||
<h3>Data Export</h3>
|
|
||||||
<p>It's best to export data in the sequence the panels are laid out in on the PAMGuard display, i.e. Calibrations, then Deployments, and finally Detections.</p>
|
|
||||||
|
|
||||||
<h4>Calibrations</h4>
|
|
||||||
<p>To export the calibration data, press the "Export..." button at the top of the "Instrument Calibration Information" panel.
|
|
||||||
<p>Most of the calibration data is taken from the array manager and from the sound acquisition module. However, PAMGuard will ask a few questions about
|
|
||||||
HOW the instrument was calibrated, when it was done and who is responsible. Fill in as much information as you can!
|
|
||||||
IF the export is successful, a record will show for each hydrophone (or sensor) in your instrument array in the calibration information table:</p>
|
|
||||||
|
|
||||||
<center><img src="./images/calibration_information.png"></center>
|
|
||||||
|
|
||||||
<h4>Deployments</h4>
|
|
||||||
<p>PAMGuard will have done it's best to work out the temporal extent of your data by looking in the
|
|
||||||
<a href="../../generalDatabaseHelp/docs/database_database.html">PAMGuard database</a> and
|
|
||||||
<a href= "../../BinaryStore/docs/binarystore_overview.html">binary Store</a>. Where data were collected on a regular duty
|
|
||||||
cycle, or continuously, there should be a single record in the table of recording periods. If data were collected on a more
|
|
||||||
"ad-hoc" basis, for instance during a boat based survey, there might be many different records in the table.
|
|
||||||
Occasionally, there may be short recording periods (e.g. while you were testing kit on deck) that you don't want to export. Either select
|
|
||||||
individual rows that you want to export, or right click on the table and "Select All".</p>
|
|
||||||
|
|
||||||
<p>Press the "Export..." button and work through the questions to provide additional information about your data, why it was collected, etc. </p>
|
|
||||||
<p>Once the document(s) have been exported, the document names will be shown alongside each PAMGuard deployment period</p>
|
|
||||||
<center><img src="./images/deploymentspanel.png"></center>
|
|
||||||
|
|
||||||
<h4>Detections</h4>
|
|
||||||
<p>The bottom left panel shows a list of different types of PAMGuard data that can be exported and should also show the total numbers of each type of data that are available
|
|
||||||
within the PAMGuard storage systems. Select the datablock you want to export from and press "Export...". </p>
|
|
||||||
<p><strong>You really don't want to try to export zillions of data to Tethys</strong> , in the options that will appear you can opt to just export certain types of detections
|
|
||||||
or summary counts.</p>
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<p class="prevLink"><a href="tethys_overview.html">Previous: Overview</a></p>
|
|
||||||
<p class="nextLink"><a href="tethys_server.html">Next: Tethys Server</a></p>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
192
src/help/utilities/tethys/docs/tethys_speciescodes.html
Normal file
192
src/help/utilities/tethys/docs/tethys_speciescodes.html
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<LINK href="../../../pamHelpStylesheet.css" type="text/css"
|
||||||
|
rel="STYLESHEET">
|
||||||
|
<title>Species coding</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1> Species and Call Type Names </h1>
|
||||||
|
|
||||||
|
When exporting data from PAMGuard to Tethys, some PAMGuard records
|
||||||
|
will require additional information indicating what type of animal
|
||||||
|
or phenomena were detected. If a specific call-type was detected,
|
||||||
|
e.g. "Clicks" or "Whistles", these should be noted as well.
|
||||||
|
|
||||||
|
<h2> Species Names </h2>
|
||||||
|
<p>
|
||||||
|
Tethys uses the <a href="https:itis.gov">Integrated Taxonomic
|
||||||
|
Information System</a> (ITIS) to encode species names as taxonomic
|
||||||
|
serial numbers (TSNs), unique numeric identifiers for species.
|
||||||
|
These data conform with several international coding systems which
|
||||||
|
are described on the <a href="https://itis.gov/standard.html">ITIS
|
||||||
|
standards</a> page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is not uncommon to be unable to describe a call to the genus
|
||||||
|
level. In such cases, one can use a higher taxonomic level. For
|
||||||
|
example, beaked whale echolocation clicks are distinctive from the
|
||||||
|
clicks of other toothed whales as their pulses have a
|
||||||
|
frequency-modulated component. While they can frequently be
|
||||||
|
associated with the family Hyperodontidae, it is not always
|
||||||
|
possible to associate a click to a specific species as many of the
|
||||||
|
at least twenty-two species remain understudied. In such a case,
|
||||||
|
we would use the TSN for Hyperodontidae, 770799. While not
|
||||||
|
currently supported by PAMGuard, each species identifier has an
|
||||||
|
optional Group attribute that can be used in an ad-hoc manner to
|
||||||
|
provide additional information. This can be used to add
|
||||||
|
population markers, tentative genus groups, etc.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
ITIS does not describe abiotic sounds, Tethys records such sounds as follows:
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
For anthropogenic signals, the Tethys convention is to
|
||||||
|
use <em>Homo sapiens</em>, TSN 180092, for the species code
|
||||||
|
and describe the human-generated signal via a call type,
|
||||||
|
e.g. ship, mid-frequency active sonar, etc.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Tethys reserves the TSN -10 for geophonic signals.
|
||||||
|
The call type is used to describe the source. Examples
|
||||||
|
include ambient sound, earthquake, rain, etc. Note that negative TSNs
|
||||||
|
are not part of the ITIS standard.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Note that in general, you do not have to worry about remembering
|
||||||
|
TSNs. Tethys uses TSNs internally, but will translate TSNs to/from
|
||||||
|
Latin names or user-defined abbreviations both when querying and
|
||||||
|
presenting results.
|
||||||
|
|
||||||
|
<h2> Call types </h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some detectors identify specific call types. When this is the
|
||||||
|
case, users will need to specify the call type name. While
|
||||||
|
species names are standardized in Tethys, call names do not have a
|
||||||
|
well-defined standard and experts frequently use different names
|
||||||
|
for the same type of call. Consequently, Tethys does not provide a
|
||||||
|
standard coding for call types and users are free to choose the call
|
||||||
|
type names with which they feel most comfortable.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
That said, the authors of Tethys do however provide a list of recommend call
|
||||||
|
types for many species. These recommendations can be accessed in the
|
||||||
|
<a href="https://ars.els-cdn.com/content/image/1-s2.0-S1574954115001983-mmc1.docx">
|
||||||
|
supplemental information</a> of the open access article "Management of acoustic metadata
|
||||||
|
for bioacoustics," Roch et al. (2016),
|
||||||
|
(<a href="https://doi.org/10.1016/j.ecoinf.2015.12.002">DOI:10.1016/j.ecoinf.2015.12.002</a>).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
Export dialog
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
During export of records that are species-specific, a dialog will
|
||||||
|
appear that lists the types of events that were found by PAMGuard
|
||||||
|
modules. This dialog permits users to specify how the ad-hoc species
|
||||||
|
species/call encoding scheme used by PAMGuard modules can be systematically
|
||||||
|
translated to the TSNs and call types are stored in Tethys.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
PAMGuard events typically are a short name that represents the
|
||||||
|
species and/or potentially a call. Knowledge of the PAMGuard
|
||||||
|
modules that were run and the data on which they executed will let
|
||||||
|
a user infer what should be recorded.
|
||||||
|
|
||||||
|
The dialog below shows a sample set of events produced by one or more PAMGuard modules
|
||||||
|
using the names: HP, DO, SON, KW, UNK, and PHP:
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img src="./images/species_codes.png" class=".center"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The dialog above was produced from detections on data that were
|
||||||
|
recorded near the mouth of the River Tay in Scotland. Consequently,
|
||||||
|
we can infer that the harbour porpoise that is denoted by "HP" is
|
||||||
|
<em>Phocena phocena</em>, the only harbour porpoise endemic to
|
||||||
|
Scottish waters.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
An ITIS code and call/sound type can be associated with each event. The dialog lists:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Name - The ad-hoc name given by the PAMGuard module. This may not be changed.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
ITIS code -This is the ITIS TSN that is associated with PAMGuard
|
||||||
|
event code. Click on Find to inovke the TSN
|
||||||
|
search dialog whose behavior is described in the <a href="#TSNLookup">next
|
||||||
|
section</a>.
|
||||||
|
<p>
|
||||||
|
If you happen to know the TSN, you
|
||||||
|
can enter it directly. Pressing Find after typing the TNS will
|
||||||
|
populate the Latin and English vernauclar names so that you may
|
||||||
|
verify your TSN was entered correctly.
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li> Call / sound type - This will default to the code provided by
|
||||||
|
the module but should be updated to specify an appropriate call
|
||||||
|
type or left blank to indicate that the detection is not related
|
||||||
|
to a specific call type. In the case of a porpoise detector,
|
||||||
|
the likely call type would be "Clicks".
|
||||||
|
<strong>We should double check that no Call element is generated when this is blank.</strong>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Once all species names and call/sound types have been identified, press the Okay button.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a name="TSNLookup"></a>
|
||||||
|
<h2> Searching for ITIS Taxonomic Serial Numbers (TSNs) </h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
As noted above, pressing Find without typing a TSN will bring up a
|
||||||
|
search dialog:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<image src="./images/species_search.png" class=".center"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The top of this dialog has a search box where one can enter either
|
||||||
|
a Latin name or the common name for a species. The Tethys server
|
||||||
|
will search for all species that match the search-box contents.
|
||||||
|
For many species, there are common name entries in languages
|
||||||
|
other than English, and these are searched as well.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Once you press the search button, a list will appear with all
|
||||||
|
matches for your search term. If there are too many, a scroll bar
|
||||||
|
will permit you to look through the list. Select the entry that
|
||||||
|
you wish and press OK. The TSN on the species dialog will be
|
||||||
|
populated along with the Latin name and common names from the ITIS
|
||||||
|
database.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<br></br>
|
||||||
|
<br></br>
|
||||||
|
|
||||||
|
<p class="prevLink">
|
||||||
|
<a href="detect_localize.html">Previous: Detections & Localizations</a>
|
||||||
|
</p>
|
||||||
|
<p class="nextLink">
|
||||||
|
<a href="tethys_overview.html">Returrn to overview</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
@ -491,9 +491,10 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
|
|||||||
public ServerStatus checkServer() {
|
public ServerStatus checkServer() {
|
||||||
ServerStatus serverState = dbxmlConnect.pingServer();
|
ServerStatus serverState = dbxmlConnect.pingServer();
|
||||||
if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) {
|
if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) {
|
||||||
|
lastServerStatus = serverState; // set before sending notification!
|
||||||
sendStateUpdate(new TethysState(StateType.UPDATESERVER));
|
sendStateUpdate(new TethysState(StateType.UPDATESERVER));
|
||||||
}
|
}
|
||||||
lastServerStatus = serverState;
|
// lastServerStatus = serverState;
|
||||||
return serverState;
|
return serverState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,5 +700,23 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
|
|||||||
return calibrationHandler;
|
return calibrationHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastServerStatus
|
||||||
|
*/
|
||||||
|
public ServerStatus getLastServerStatus() {
|
||||||
|
return lastServerStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick way for any controls to see that the server is probably OK
|
||||||
|
* without actually pinging it.
|
||||||
|
* @return true if last ping of server was OK
|
||||||
|
*/
|
||||||
|
public boolean isServerOk() {
|
||||||
|
if (lastServerStatus == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return lastServerStatus.ok;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package tethys.calibration;
|
package tethys.calibration;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -45,9 +46,11 @@ import tethys.TethysTimeFuncs;
|
|||||||
import tethys.calibration.swing.CalibrationsExportWizard;
|
import tethys.calibration.swing.CalibrationsExportWizard;
|
||||||
import tethys.dbxml.DBXMLConnect;
|
import tethys.dbxml.DBXMLConnect;
|
||||||
import tethys.dbxml.TethysException;
|
import tethys.dbxml.TethysException;
|
||||||
|
import tethys.niluswraps.NilusChecker;
|
||||||
import tethys.niluswraps.NilusSettingsWrapper;
|
import tethys.niluswraps.NilusSettingsWrapper;
|
||||||
import tethys.niluswraps.NilusUnpacker;
|
import tethys.niluswraps.NilusUnpacker;
|
||||||
import tethys.pamdata.AutoTethysProvider;
|
import tethys.pamdata.AutoTethysProvider;
|
||||||
|
import tethys.reporter.TethysReporter;
|
||||||
|
|
||||||
public class CalibrationHandler implements TethysStateObserver {
|
public class CalibrationHandler implements TethysStateObserver {
|
||||||
|
|
||||||
@ -186,6 +189,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
|||||||
int nExport = 0;
|
int nExport = 0;
|
||||||
boolean overwrite = false;
|
boolean overwrite = false;
|
||||||
boolean exists;
|
boolean exists;
|
||||||
|
TethysReporter.getTethysReporter().clear();
|
||||||
for (int i = 0; i < nPhone; i++) {
|
for (int i = 0; i < nPhone; i++) {
|
||||||
// String docName = getHydrophoneId(i);
|
// String docName = getHydrophoneId(i);
|
||||||
NilusSettingsWrapper<Calibration> clonedWrap = wrappedSample.clone();
|
NilusSettingsWrapper<Calibration> clonedWrap = wrappedSample.clone();
|
||||||
@ -195,11 +199,24 @@ public class CalibrationHandler implements TethysStateObserver {
|
|||||||
calDoc.setMetadataInfo(sampleCal.getMetadataInfo());
|
calDoc.setMetadataInfo(sampleCal.getMetadataInfo());
|
||||||
calDoc.setProcess(sampleCal.getProcess());
|
calDoc.setProcess(sampleCal.getProcess());
|
||||||
calDoc.setQualityAssurance(sampleCal.getQualityAssurance());
|
calDoc.setQualityAssurance(sampleCal.getQualityAssurance());
|
||||||
calDoc.setResponsibleParty(sampleCal.getResponsibleParty());
|
if (NilusChecker.isEmpty(sampleCal.getResponsibleParty()) == false) {
|
||||||
|
calDoc.setResponsibleParty(sampleCal.getResponsibleParty());
|
||||||
|
}
|
||||||
calDoc.setTimeStamp(sampleCal.getTimeStamp());
|
calDoc.setTimeStamp(sampleCal.getTimeStamp());
|
||||||
}
|
}
|
||||||
|
// check the contact info in the metadata.
|
||||||
|
// can't so because it's required.
|
||||||
|
// MetadataInfo metaData = calDoc.getMetadataInfo();
|
||||||
|
// if (metaData != null) {
|
||||||
|
// if (NilusChecker.isEmpty(metaData.getContact())) {
|
||||||
|
// metaData.setContact(null);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
addParameterDetails(calDoc, i);
|
addParameterDetails(calDoc, i);
|
||||||
|
// run some checks of completeness of the data
|
||||||
|
NilusChecker.removeEmptyFields(calDoc);
|
||||||
|
// ArrayList<Field> emptyFields = NilusChecker.checkEmptyFields(calDoc);
|
||||||
|
|
||||||
String calDocName = createDocumentName(calDoc, i);
|
String calDocName = createDocumentName(calDoc, i);
|
||||||
exists = calDocumentExists(calDocName);
|
exists = calDocumentExists(calDocName);
|
||||||
@ -233,6 +250,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.EXPORTRDATA, Collection.Calibrations));
|
tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.EXPORTRDATA, Collection.Calibrations));
|
||||||
|
TethysReporter.getTethysReporter().showReport(true);
|
||||||
return nExport;
|
return nExport;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,6 +423,10 @@ public class CalibrationHandler implements TethysStateObserver {
|
|||||||
hz.add(Double.valueOf(0));
|
hz.add(Double.valueOf(0));
|
||||||
db.add(Double.valueOf(hSens+preampGain));
|
db.add(Double.valueOf(hSens+preampGain));
|
||||||
|
|
||||||
|
if (NilusChecker.isEmpty(calibration.getResponsibleParty())) {
|
||||||
|
calibration.setResponsibleParty(null);
|
||||||
|
}
|
||||||
|
|
||||||
MetadataInfo metaInf = calibration.getMetadataInfo();
|
MetadataInfo metaInf = calibration.getMetadataInfo();
|
||||||
if (metaInf == null) {
|
if (metaInf == null) {
|
||||||
metaInf = new MetadataInfo();
|
metaInf = new MetadataInfo();
|
||||||
@ -417,6 +439,12 @@ public class CalibrationHandler implements TethysStateObserver {
|
|||||||
contact = new ResponsibleParty();
|
contact = new ResponsibleParty();
|
||||||
metaInf.setContact(contact);
|
metaInf.setContact(contact);
|
||||||
}
|
}
|
||||||
|
if (NilusChecker.isEmpty(metaInf.getContact())) {
|
||||||
|
metaInf.setContact(null);
|
||||||
|
}
|
||||||
|
if (NilusChecker.isEmpty(metaInf)) {
|
||||||
|
calibration.setMetadataInfo(null);
|
||||||
|
}
|
||||||
contact.setIndividualName("Unknown");
|
contact.setIndividualName("Unknown");
|
||||||
contact.setOrganizationName("unknown");
|
contact.setOrganizationName("unknown");
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import java.awt.BorderLayout;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
@ -15,6 +17,7 @@ import javax.swing.JTextArea;
|
|||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
|
import PamView.dialog.PamDialog;
|
||||||
import PamView.dialog.PamGridBagContraints;
|
import PamView.dialog.PamGridBagContraints;
|
||||||
import PamView.panel.WestAlignedPanel;
|
import PamView.panel.WestAlignedPanel;
|
||||||
import PamView.wizard.PamWizard;
|
import PamView.wizard.PamWizard;
|
||||||
@ -23,9 +26,17 @@ import nilus.AlgorithmType.Parameters;
|
|||||||
import nilus.AlgorithmType.SupportSoftware;
|
import nilus.AlgorithmType.SupportSoftware;
|
||||||
import nilus.Calibration;
|
import nilus.Calibration;
|
||||||
import nilus.Calibration.QualityAssurance;
|
import nilus.Calibration.QualityAssurance;
|
||||||
|
import nilus.Helper;
|
||||||
import nilus.QualityValueBasic;
|
import nilus.QualityValueBasic;
|
||||||
import tethys.calibration.CalibrationHandler;
|
import tethys.calibration.CalibrationHandler;
|
||||||
|
import tethys.niluswraps.NilusChecker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calibrations Process card attempts to fill in the
|
||||||
|
* calibration data for the Quality Assurance and Process fields.
|
||||||
|
* @author dg50
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CalibrationProcessCard extends CalibrationsCard {
|
public class CalibrationProcessCard extends CalibrationsCard {
|
||||||
|
|
||||||
private JPanel processPanel;
|
private JPanel processPanel;
|
||||||
@ -123,9 +134,13 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
|||||||
}
|
}
|
||||||
process.setMethod((String) calMethod.getSelectedItem());
|
process.setMethod((String) calMethod.getSelectedItem());
|
||||||
process.setVersion(version.getText());
|
process.setVersion(version.getText());
|
||||||
process.setSoftware(software.getText());
|
String soft = warnNotNull(getPamWizard(), software, "Calibration Method");
|
||||||
|
if (soft == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
process.setSoftware(soft);
|
||||||
if (software.getText() == null) {
|
if (software.getText() == null) {
|
||||||
getPamWizard().showWarning("You must specify the calibratin method used");
|
getPamWizard().showWarning("You must specify the calibration method used");
|
||||||
}
|
}
|
||||||
|
|
||||||
QualityAssurance qa = calibration.getQualityAssurance();
|
QualityAssurance qa = calibration.getQualityAssurance();
|
||||||
@ -133,7 +148,11 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
|||||||
qa = new QualityAssurance();
|
qa = new QualityAssurance();
|
||||||
calibration.setQualityAssurance(qa);
|
calibration.setQualityAssurance(qa);
|
||||||
}
|
}
|
||||||
qa.setComment(qaComment.getText());
|
String t = warnNotNull(getPamWizard(), qaComment, "QA Comment");
|
||||||
|
if (t == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
qa.setComment(t);
|
||||||
qa.setQuality(QualityValueBasic.fromValue((String) qaQuality.getSelectedItem()));
|
qa.setQuality(QualityValueBasic.fromValue((String) qaQuality.getSelectedItem()));
|
||||||
|
|
||||||
// need to add a few fixed things for this to work...
|
// need to add a few fixed things for this to work...
|
||||||
@ -142,11 +161,27 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
|||||||
if (params == null) {
|
if (params == null) {
|
||||||
params = new Parameters();
|
params = new Parameters();
|
||||||
process.setParameters(params);
|
process.setParameters(params);
|
||||||
|
// params.getAny().
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
Helper.createRequiredElements(params);
|
||||||
|
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (checkEmptyFields(qa) == false) {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// if (checkEmptyFields(process) == false) {
|
||||||
|
//// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setParams(Calibration calibration) {
|
public void setParams(Calibration calibration) {
|
||||||
if (calibration == null) {
|
if (calibration == null) {
|
||||||
|
@ -3,8 +3,9 @@ package tethys.calibration.swing;
|
|||||||
import PamView.wizard.PamWizard;
|
import PamView.wizard.PamWizard;
|
||||||
import PamView.wizard.PamWizardCard;
|
import PamView.wizard.PamWizardCard;
|
||||||
import nilus.Calibration;
|
import nilus.Calibration;
|
||||||
|
import tethys.swing.TethysWizardCard;
|
||||||
|
|
||||||
abstract public class CalibrationsCard extends PamWizardCard<Calibration> {
|
abstract public class CalibrationsCard extends TethysWizardCard<Calibration> {
|
||||||
|
|
||||||
public CalibrationsCard(PamWizard pamWizard, String title) {
|
public CalibrationsCard(PamWizard pamWizard, String title) {
|
||||||
super(pamWizard, title);
|
super(pamWizard, title);
|
||||||
|
@ -28,6 +28,7 @@ import nilus.MetadataInfo;
|
|||||||
import nilus.ResponsibleParty;
|
import nilus.ResponsibleParty;
|
||||||
import tethys.TethysTimeFuncs;
|
import tethys.TethysTimeFuncs;
|
||||||
import tethys.calibration.CalibrationHandler;
|
import tethys.calibration.CalibrationHandler;
|
||||||
|
import tethys.niluswraps.NilusChecker;
|
||||||
import tethys.swing.export.ResponsiblePartyPanel;
|
import tethys.swing.export.ResponsiblePartyPanel;
|
||||||
|
|
||||||
public class CalibrationsContactCard extends CalibrationsCard {
|
public class CalibrationsContactCard extends CalibrationsCard {
|
||||||
@ -125,6 +126,11 @@ public class CalibrationsContactCard extends CalibrationsCard {
|
|||||||
}
|
}
|
||||||
metaData.setContact(checkRPChildren(metaData.getContact()));
|
metaData.setContact(checkRPChildren(metaData.getContact()));
|
||||||
dataManager.getParams(metaData.getContact());
|
dataManager.getParams(metaData.getContact());
|
||||||
|
ResponsibleParty metaContact = metaData.getContact();
|
||||||
|
NilusChecker.removeEmptyFields(metaData);
|
||||||
|
if (metaData.getContact() == null) {
|
||||||
|
return PamDialog.showWarning(getPamWizard(), "Missing data", "The Data Manager fields must be completed");
|
||||||
|
}
|
||||||
|
|
||||||
metaData.setUpdateFrequency((String) updateInterval.getSelectedItem());
|
metaData.setUpdateFrequency((String) updateInterval.getSelectedItem());
|
||||||
metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis()));
|
metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis()));
|
||||||
@ -136,6 +142,10 @@ public class CalibrationsContactCard extends CalibrationsCard {
|
|||||||
long millis = date.getTime();
|
long millis = date.getTime();
|
||||||
cardParams.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(millis));
|
cardParams.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(millis));
|
||||||
|
|
||||||
|
|
||||||
|
checkEmptyFields(rp);
|
||||||
|
checkEmptyFields(metaData);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import javax.swing.border.TitledBorder;
|
|||||||
|
|
||||||
import PamView.panel.PamPanel;
|
import PamView.panel.PamPanel;
|
||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
|
import tethys.TethysState;
|
||||||
import tethys.calibration.CalibrationHandler;
|
import tethys.calibration.CalibrationHandler;
|
||||||
import tethys.swing.TethysGUIPanel;
|
import tethys.swing.TethysGUIPanel;
|
||||||
|
|
||||||
@ -63,4 +64,14 @@ public class CalibrationsMainPanel extends TethysGUIPanel {
|
|||||||
return mainPanel;
|
return mainPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(TethysState tethysState) {
|
||||||
|
super.updateState(tethysState);
|
||||||
|
enableControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableControls() {
|
||||||
|
exportButton.setEnabled(getTethysControl().isServerOk());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,10 @@ import tethys.Collection;
|
|||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
import tethys.database.TethysActions;
|
import tethys.database.TethysActions;
|
||||||
import tethys.database.TethysLogger;
|
import tethys.database.TethysLogger;
|
||||||
|
import tethys.niluswraps.NilusChecker;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
|
import tethys.reporter.TethysReport;
|
||||||
|
import tethys.reporter.TethysReporter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class containing functions for managing the database connection. Opening, closing,
|
* Class containing functions for managing the database connection. Opening, closing,
|
||||||
@ -144,6 +147,9 @@ public class DBXMLConnect {
|
|||||||
*/
|
*/
|
||||||
public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
|
public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
|
||||||
{
|
{
|
||||||
|
boolean ok = NilusChecker.warnEmptyFields(tethysControl.getGuiFrame(), nilusObject);
|
||||||
|
|
||||||
|
|
||||||
TethysException e = null;
|
TethysException e = null;
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
@ -207,6 +213,8 @@ public class DBXMLConnect {
|
|||||||
*/
|
*/
|
||||||
boolean error = importReturn.contains("<Error");
|
boolean error = importReturn.contains("<Error");
|
||||||
boolean success = importReturn.contains("<Success>");
|
boolean success = importReturn.contains("<Success>");
|
||||||
|
String name = tempFile.getName();
|
||||||
|
TethysReporter.getTethysReporter().addReport(new TethysReport(success, collection, name, name));
|
||||||
// error = !success; might be a better options.
|
// error = !success; might be a better options.
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new TethysException("Error posting to Tethys", importReturn);
|
throw new TethysException("Error posting to Tethys", importReturn);
|
||||||
|
@ -45,6 +45,9 @@ import dataMap.OfflineDataMapPoint;
|
|||||||
import generalDatabase.DBControlUnit;
|
import generalDatabase.DBControlUnit;
|
||||||
import metadata.MetaDataContol;
|
import metadata.MetaDataContol;
|
||||||
import metadata.PamguardMetaData;
|
import metadata.PamguardMetaData;
|
||||||
|
import nilus.AcousticDataQAType;
|
||||||
|
import nilus.AcousticDataQAType.Quality;
|
||||||
|
import nilus.AcousticDataQAType.Quality.FrequencyRange;
|
||||||
import nilus.Audio;
|
import nilus.Audio;
|
||||||
import nilus.ChannelInfo;
|
import nilus.ChannelInfo;
|
||||||
import nilus.ChannelInfo.DutyCycle;
|
import nilus.ChannelInfo.DutyCycle;
|
||||||
@ -84,6 +87,7 @@ import tethys.deployment.swing.RecordingGapDialog;
|
|||||||
import tethys.niluswraps.PDeployment;
|
import tethys.niluswraps.PDeployment;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
import tethys.pamdata.AutoTethysProvider;
|
import tethys.pamdata.AutoTethysProvider;
|
||||||
|
import tethys.reporter.TethysReporter;
|
||||||
import tethys.swing.DeploymentTableObserver;
|
import tethys.swing.DeploymentTableObserver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -387,12 +391,14 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
|||||||
* @param selectedDeployments
|
* @param selectedDeployments
|
||||||
*/
|
*/
|
||||||
public void exportDeployments(ArrayList<RecordingPeriod> selectedDeployments) {
|
public void exportDeployments(ArrayList<RecordingPeriod> selectedDeployments) {
|
||||||
|
TethysReporter.getTethysReporter().clear();
|
||||||
if (deploymentExportOptions.separateDeployments) {
|
if (deploymentExportOptions.separateDeployments) {
|
||||||
exportSeparateDeployments(selectedDeployments);
|
exportSeparateDeployments(selectedDeployments);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exportOneDeploymnet(selectedDeployments);
|
exportOneDeploymnet(selectedDeployments);
|
||||||
}
|
}
|
||||||
|
TethysReporter.getTethysReporter().showReport(tethysControl.getGuiFrame(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -400,6 +406,14 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
|||||||
*/
|
*/
|
||||||
private void exportOneDeploymnet(ArrayList<RecordingPeriod> selectedDeployments) {
|
private void exportOneDeploymnet(ArrayList<RecordingPeriod> selectedDeployments) {
|
||||||
// do the lot, whatever ...
|
// do the lot, whatever ...
|
||||||
|
Float sampleRate = null;
|
||||||
|
AcquisitionControl daq = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||||
|
if (daq != null) {
|
||||||
|
DaqSystem system = daq.findDaqSystem(null);
|
||||||
|
AcquisitionParameters daqParams = daq.acquisitionParameters;
|
||||||
|
sampleRate = daqParams.sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
selectedDeployments = getDeploymentOverview().getRecordingPeriods();
|
selectedDeployments = getDeploymentOverview().getRecordingPeriods();
|
||||||
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
|
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
|
||||||
RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(),
|
RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(),
|
||||||
@ -412,11 +426,37 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
|||||||
deployment.setCruise(globalMeta.getCruise());
|
deployment.setCruise(globalMeta.getCruise());
|
||||||
deployment.setSite(globalMeta.getSite());
|
deployment.setSite(globalMeta.getSite());
|
||||||
if (selectedDeployments.size() > 1) {
|
if (selectedDeployments.size() > 1) {
|
||||||
// now need to remove the
|
// // now need to remove the sampling details - don't though, add invalid periods instead.
|
||||||
SamplingDetails samplingDetails = deployment.getSamplingDetails();
|
// SamplingDetails samplingDetails = deployment.getSamplingDetails();
|
||||||
samplingDetails.getChannel().clear();
|
// samplingDetails.getChannel().clear();
|
||||||
for (int i = 0; i < selectedDeployments.size(); i++) {
|
// for (int i = 0; i < selectedDeployments.size(); i++) {
|
||||||
addSamplingDetails(deployment, selectedDeployments.get(i));
|
// addSamplingDetails(deployment, selectedDeployments.get(i));
|
||||||
|
// }
|
||||||
|
/*
|
||||||
|
* Instead, we're putting invalid periods into the QA section.
|
||||||
|
*/
|
||||||
|
AcousticDataQAType qa = deployment.getQualityAssurance();
|
||||||
|
if (qa == null) {
|
||||||
|
deployment.setQualityAssurance(qa = new AcousticDataQAType());
|
||||||
|
}
|
||||||
|
List<Quality> qualityList = qa.getQuality();
|
||||||
|
for (int i = 1; i < selectedDeployments.size(); i++) {
|
||||||
|
long end = selectedDeployments.get(i-1).getRecordStop();
|
||||||
|
long start = selectedDeployments.get(i).getRecordStart();
|
||||||
|
Quality q = new Quality();
|
||||||
|
q.setStart(TethysTimeFuncs.xmlGregCalFromMillis(end));
|
||||||
|
q.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(start));
|
||||||
|
q.setCategory("unusable");
|
||||||
|
if (sampleRate != null) {
|
||||||
|
FrequencyRange f = q.getFrequencyRange();
|
||||||
|
if (f == null) {
|
||||||
|
q.setFrequencyRange(f = new FrequencyRange());
|
||||||
|
}
|
||||||
|
f.setLowHz(0);
|
||||||
|
f.setHighHz(sampleRate/2);
|
||||||
|
}
|
||||||
|
q.setComment("No data (probably off or out of water)");
|
||||||
|
qualityList.add(q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect();
|
DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect();
|
||||||
|
@ -39,11 +39,12 @@ public class DeploymentDataCard extends PamWizardCard {
|
|||||||
this.tethysControl = tethysControl;
|
this.tethysControl = tethysControl;
|
||||||
deploymentHandler = tethysControl.getDeploymentHandler();
|
deploymentHandler = tethysControl.getDeploymentHandler();
|
||||||
ButtonGroup bg = new ButtonGroup();
|
ButtonGroup bg = new ButtonGroup();
|
||||||
exportOne = new JRadioButton("Export a single detection document for all data");
|
exportOne = new JRadioButton("Export a single deployment document for all data");
|
||||||
exportMany = new JRadioButton("Export separate documents for each ad-hoc recording period");
|
exportMany = new JRadioButton("Export separate deployment documents for each ad-hoc recording period");
|
||||||
bg.add(exportOne);
|
bg.add(exportOne);
|
||||||
bg.add(exportMany);
|
bg.add(exportMany);
|
||||||
|
|
||||||
|
|
||||||
JPanel optsPanel = new JPanel(new GridBagLayout());
|
JPanel optsPanel = new JPanel(new GridBagLayout());
|
||||||
optsPanel.setBorder(new TitledBorder("Number of documents"));
|
optsPanel.setBorder(new TitledBorder("Number of documents"));
|
||||||
GridBagConstraints c = new PamGridBagContraints();
|
GridBagConstraints c = new PamGridBagContraints();
|
||||||
@ -95,6 +96,15 @@ public class DeploymentDataCard extends PamWizardCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setParams(DeploymentExportOpts exportOptions, Deployment deployment) {
|
public void setParams(DeploymentExportOpts exportOptions, Deployment deployment) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* temp code to only allow export of multiple documents.
|
||||||
|
*/
|
||||||
|
// exportOptions.separateDeployments = true;
|
||||||
|
// exportOne.setEnabled(false);
|
||||||
|
// exportOne.setToolTipText("Feature not yet enabled");
|
||||||
|
|
||||||
|
|
||||||
exportOne.setSelected(exportOptions.separateDeployments == false);
|
exportOne.setSelected(exportOptions.separateDeployments == false);
|
||||||
exportMany.setSelected(exportOptions.separateDeployments == true);
|
exportMany.setSelected(exportOptions.separateDeployments == true);
|
||||||
setParams(deployment);
|
setParams(deployment);
|
||||||
|
@ -43,6 +43,7 @@ import tethys.output.DatablockSynchInfo;
|
|||||||
import tethys.output.StreamExportParams;
|
import tethys.output.StreamExportParams;
|
||||||
import tethys.output.TethysExportParams;
|
import tethys.output.TethysExportParams;
|
||||||
import tethys.pamdata.TethysDataProvider;
|
import tethys.pamdata.TethysDataProvider;
|
||||||
|
import tethys.reporter.TethysReporter;
|
||||||
import tethys.species.DataBlockSpeciesManager;
|
import tethys.species.DataBlockSpeciesManager;
|
||||||
import tethys.swing.export.DetectionsExportWizard;
|
import tethys.swing.export.DetectionsExportWizard;
|
||||||
|
|
||||||
@ -587,6 +588,7 @@ public class DetectionsHandler {
|
|||||||
this.dataBlock = dataBlock;
|
this.dataBlock = dataBlock;
|
||||||
this.exportParams = exportParams;
|
this.exportParams = exportParams;
|
||||||
this.exportObserver = exportObserver;
|
this.exportObserver = exportObserver;
|
||||||
|
TethysReporter.getTethysReporter().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void publish(DetectionExportProgress exportProgress) {
|
public void publish(DetectionExportProgress exportProgress) {
|
||||||
@ -617,6 +619,7 @@ public class DetectionsHandler {
|
|||||||
DetectionExportProgress prog = new DetectionExportProgress(null, null, 0, 0, 0, 0, DetectionExportProgress.STATE_COMPLETE);
|
DetectionExportProgress prog = new DetectionExportProgress(null, null, 0, 0, 0, 0, DetectionExportProgress.STATE_COMPLETE);
|
||||||
tethysControl.exportedDetections(dataBlock);
|
tethysControl.exportedDetections(dataBlock);
|
||||||
exportObserver.update(prog);
|
exportObserver.update(prog);
|
||||||
|
TethysReporter.getTethysReporter().showReport(tethysControl.getGuiFrame(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
417
src/tethys/niluswraps/NilusChecker.java
Normal file
417
src/tethys/niluswraps/NilusChecker.java
Normal file
@ -0,0 +1,417 @@
|
|||||||
|
package tethys.niluswraps;
|
||||||
|
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.renjin.methods.Methods;
|
||||||
|
|
||||||
|
import PamView.dialog.warn.WarnOnce;
|
||||||
|
import nilus.Calibration;
|
||||||
|
import nilus.Calibration.QualityAssurance;
|
||||||
|
import nilus.Helper;
|
||||||
|
import nilus.ResponsibleParty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A few static checks of some nilus classes to see if it's
|
||||||
|
* worth writing them or not.
|
||||||
|
* @author dg50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class NilusChecker {
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
Calibration cal = new Calibration();
|
||||||
|
try {
|
||||||
|
Helper.createRequiredElements(cal);
|
||||||
|
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
QualityAssurance qa;
|
||||||
|
cal.setQualityAssurance(qa = new QualityAssurance());
|
||||||
|
qa.setComment("Nothing to comment on ");
|
||||||
|
|
||||||
|
int removed = removeEmptyFields(cal);
|
||||||
|
System.out.printf("%d fields removed from object %s\n", removed, cal);
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<Field> missing = checkEmptyFields(cal);
|
||||||
|
for (Field field : missing) {
|
||||||
|
System.out.printf("Field %s is required but empty in %s\n", field.getName(), field.getDeclaringClass().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean warnEmptyFields(Window owner, Object nilusObject) {
|
||||||
|
ArrayList<Field> emptyFields = findEmptyFields(nilusObject, true);
|
||||||
|
if (emptyFields == null || emptyFields.size() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String msg = String.format("<html>One or more fields in the nilus object %s are required but empty:<br>", nilusObject.getClass().getName());
|
||||||
|
for (Field f : emptyFields) {
|
||||||
|
msg += String.format("<br>Field %s in object %s", f.getName(), f.getDeclaringClass().getName());
|
||||||
|
}
|
||||||
|
msg += "<br><br>It is likely that this document will fail to write to the Tethys database.</html>";
|
||||||
|
String tit = "Incomplete Tethys data";
|
||||||
|
WarnOnce.showWarning(owner, tit, msg, WarnOnce.WARNING_MESSAGE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find empty fields
|
||||||
|
* @param nilusObject object to search
|
||||||
|
* @param onlyRequired only list required fields.
|
||||||
|
* @return list of empty, and optionally also required, fields.
|
||||||
|
*/
|
||||||
|
public static ArrayList<Field> findEmptyFields(Object nilusObject, boolean onlyRequired) {
|
||||||
|
return findEmptyFields(nilusObject, new ArrayList<Field>(), onlyRequired);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArrayList<Field> findEmptyFields(Object nilusObject, ArrayList<Field> found, boolean onlyRequired) {
|
||||||
|
if (nilusObject == null) {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
int removed = 0;
|
||||||
|
|
||||||
|
Class<? extends Object> nilusClass = nilusObject.getClass();
|
||||||
|
if (nilusClass.getCanonicalName().contains("java.lang")) {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
Method[] methods = nilusClass.getDeclaredMethods();
|
||||||
|
Field[] fields = nilusClass.getDeclaredFields();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Method getter = findGetter(fields[i], methods);
|
||||||
|
if (getter == null) {
|
||||||
|
// System.out.printf("Unable to find getter for field %s in %s\n", fields[i].getName(), nilusClass.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean required = isRequired(fields[i]);
|
||||||
|
// System.out.printf("Field %30s is %s required\n", fields[i].getName(), required ? " " : "NOT");
|
||||||
|
Object gotObj = null;
|
||||||
|
try {
|
||||||
|
gotObj = getter.invoke(nilusObject, new Object[0]);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
// System.out.printf("Unable to invoce getter %s on %s\n", getter.getName(), nilusObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean empty = isEmpty(gotObj);
|
||||||
|
if (empty) {
|
||||||
|
if (required || !onlyRequired) {
|
||||||
|
found.add(fields[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found = findEmptyFields(gotObj, found, onlyRequired);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove empty fields from a nilus object. <br>
|
||||||
|
* An empty field is a field that is null, or has a String that is empty, or
|
||||||
|
* only contains elements which are all themselves empty. i.e. an object that references
|
||||||
|
* empty objects will be considered empty.
|
||||||
|
* @param nilusObject
|
||||||
|
* @return number of empty fields removed.
|
||||||
|
*/
|
||||||
|
public static int removeEmptyFields(Object nilusObject) {
|
||||||
|
if (nilusObject == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int removed = 0;
|
||||||
|
|
||||||
|
Class<? extends Object> nilusClass = nilusObject.getClass();
|
||||||
|
if (nilusClass.getCanonicalName().contains("java.lang")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Method[] methods = nilusClass.getDeclaredMethods();
|
||||||
|
Field[] fields = nilusClass.getDeclaredFields();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Method getter = findGetter(fields[i], methods);
|
||||||
|
Method setter = findSetter(fields[i], methods);
|
||||||
|
if (getter == null) {
|
||||||
|
// System.out.printf("Unable to find getter for field %s in %s\n", fields[i].getName(), nilusClass.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (setter == null) {
|
||||||
|
// System.out.printf("Unable to find setter for field %s in %s\n", fields[i].getName(), nilusClass.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean required = isRequired(fields[i]);
|
||||||
|
// System.out.printf("Field %30s is %s required\n", fields[i].getName(), required ? " " : "NOT");
|
||||||
|
Object gotObj = null;
|
||||||
|
try {
|
||||||
|
gotObj = getter.invoke(nilusObject, null);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
// System.out.printf("Unable to invoce getter %s on %s\n", getter.getName(), nilusObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean empty = isEmpty(gotObj);
|
||||||
|
if (empty && gotObj != null && canRemove(fields[i])) {
|
||||||
|
try {
|
||||||
|
// System.out.printf("Removing empty field %s in object %s\n", fields[i].getName(), nilusObject);
|
||||||
|
// Object args = new Object[1];
|
||||||
|
setter.invoke(nilusObject, new Object[1]);
|
||||||
|
removed++;
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
System.out.printf("Unable to invoce setter %s on %s\n", getter.getName(), nilusObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
removed += removeEmptyFields(gotObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields that can be removed.
|
||||||
|
* @param field
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static boolean canRemove(Field field) {
|
||||||
|
if (field == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Class fClass = field.getType();
|
||||||
|
if (fClass == String.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (List.class.isAssignableFrom(fClass)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fClass.isPrimitive()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String className = fClass.getCanonicalName();
|
||||||
|
if (className.contains("nilus.")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an object for empty and required fields.
|
||||||
|
* @param nilusObject
|
||||||
|
* @return a list of required empty fields in the nilusObjec and any objects references by that object.
|
||||||
|
*/
|
||||||
|
public static ArrayList<Field> checkEmptyFields(Object nilusObject) {
|
||||||
|
return checkEmptyFields(nilusObject, new ArrayList<Field>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an object for empty and required fields.
|
||||||
|
* @param nilusObject
|
||||||
|
* @param emptyFields
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static ArrayList<Field> checkEmptyFields(Object nilusObject, ArrayList<Field> emptyFields) {
|
||||||
|
if (nilusObject == null) {
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<? extends Object> nilusClass = nilusObject.getClass();
|
||||||
|
if (nilusClass.isPrimitive()) {
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
if (nilusClass.getCanonicalName().contains("java.lang")) {
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
Method[] methods = nilusClass.getDeclaredMethods();
|
||||||
|
Field[] fields = nilusClass.getDeclaredFields();
|
||||||
|
for (int i = 0; i < fields.length; i++) {
|
||||||
|
Method getter = findGetter(fields[i], methods);
|
||||||
|
Method setter = findSetter(fields[i], methods);
|
||||||
|
if (getter == null) {
|
||||||
|
// System.out.printf("Unable to find getter for field %s in %s\n", fields[i].getName(), nilusClass.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (setter == null) {
|
||||||
|
// System.out.printf("Unable to find setter for field %s in %s\n", fields[i].getName(), nilusClass.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean required = isRequired(fields[i]);
|
||||||
|
// System.out.printf("Field %30s is %s required\n", fields[i].getName(), required ? " " : "NOT");
|
||||||
|
Object gotObj = null;
|
||||||
|
try {
|
||||||
|
gotObj = getter.invoke(nilusObject, null);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
// System.out.printf("Unable to invoce getter %s on %s\n", getter.getName(), nilusObject);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
boolean empty = isEmpty(gotObj);
|
||||||
|
if (empty) {
|
||||||
|
if (required) {
|
||||||
|
emptyFields.add(fields[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkEmptyFields(gotObj, emptyFields);
|
||||||
|
}
|
||||||
|
// if (required == true && empty == true) {
|
||||||
|
// System.out.printf("Field %s is required but empty in %s\n", fields[i].getName(), nilusObject.toString());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if a field has an annotation that indicates it's required.
|
||||||
|
* @param field field
|
||||||
|
* @return required
|
||||||
|
*/
|
||||||
|
private static boolean isRequired(Field field) {
|
||||||
|
Annotation[] annots = field.getAnnotations();
|
||||||
|
for (int a = 0; a < annots.length; a++) {
|
||||||
|
// System.out.printf("Field %s has annotation %d %s\n", fields[i].getName(), a, annots[a].toString());
|
||||||
|
String str = annots[a].toString();
|
||||||
|
if (str.contains("required=true")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a getter for a field. This will either be get... or is...
|
||||||
|
* @param field
|
||||||
|
* @param methods list of methods to search
|
||||||
|
* @return found method or null
|
||||||
|
*/
|
||||||
|
private static Method findGetter(Field field, Method[] methods) {
|
||||||
|
String name = field.getName();
|
||||||
|
String poss = "get"+name;
|
||||||
|
Method found = findMethod(poss, methods);
|
||||||
|
if (found != null) {
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
poss = "is" + name;
|
||||||
|
return findMethod(poss, methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fine a setter for a field. This will always be set...
|
||||||
|
* @param field field
|
||||||
|
* @param methods list of methods to search
|
||||||
|
* @return found method or null
|
||||||
|
*/
|
||||||
|
private static Method findSetter(Field field, Method[] methods) {
|
||||||
|
String name = field.getName();
|
||||||
|
String poss = "set" + name;
|
||||||
|
return findMethod(poss, methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a method based on it's name (case insensitive).
|
||||||
|
* @param name name of method
|
||||||
|
* @param methods list of methods to search
|
||||||
|
* @return found method or null
|
||||||
|
*/
|
||||||
|
private static Method findMethod(String name, Method[] methods) {
|
||||||
|
for (int i = 0; i < methods.length; i++) {
|
||||||
|
if (methods[i].getName().equalsIgnoreCase(name)) {
|
||||||
|
return methods[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if an object is empty. <br>
|
||||||
|
* An object is considered empty if any of the following criteria are met:
|
||||||
|
* <ul>
|
||||||
|
* <li>The object is null</li>
|
||||||
|
* <li>The object is a zero length string</li>
|
||||||
|
* <li>The object is not null, but all of it's fields satisfy this same criteria of being empty</li>
|
||||||
|
* <li>The object is a list which has no elements</li>
|
||||||
|
* </ul>
|
||||||
|
* Primitive types are never empty.
|
||||||
|
* @param nilusObject
|
||||||
|
* @return true if it's empty
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object nilusObject) {
|
||||||
|
if (nilusObject == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nilusObject instanceof String) {
|
||||||
|
String str = (String) nilusObject;
|
||||||
|
return (str.length() == 0);
|
||||||
|
}
|
||||||
|
if (nilusObject instanceof List) {
|
||||||
|
return isEmptyList((List) nilusObject);
|
||||||
|
}
|
||||||
|
if (nilusObject.getClass().isPrimitive()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean empty = true;
|
||||||
|
// and check all getters
|
||||||
|
Class<? extends Object> nilusClass = nilusObject.getClass();
|
||||||
|
Method[] methods = nilusClass.getDeclaredMethods();
|
||||||
|
// searching for getters.
|
||||||
|
int nGet = 0;
|
||||||
|
for (int i = 0; i < methods.length; i++) {
|
||||||
|
Method method = methods[i];
|
||||||
|
if (method.getName().startsWith("get") && method.getParameterCount() == 0) {
|
||||||
|
nGet ++;
|
||||||
|
try {
|
||||||
|
Object got = method.invoke(nilusObject, null);
|
||||||
|
if (got != null) {
|
||||||
|
if (got instanceof String) {
|
||||||
|
if (isEmptyString((String) got) == false) {
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (got instanceof List<?>) {
|
||||||
|
if (isEmptyList((List) got) == false) {
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isEmpty(got) == false) {// it's some other class type, so recurecively ask back here.
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||||
|
return false; // better save than sorry if we don't understand.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nGet == 0) {
|
||||||
|
// there weren't any understandable getters, so assume not empty. May be some other primitive type.
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list is considered empty if it has no elements
|
||||||
|
* @param list
|
||||||
|
* @return true if empty
|
||||||
|
*/
|
||||||
|
private static boolean isEmptyList(List list) {
|
||||||
|
if (list == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return list.size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A String is empty if it is null or of zero length
|
||||||
|
* @param string string
|
||||||
|
* @return true if empty
|
||||||
|
*/
|
||||||
|
public static boolean isEmptyString(String string) {
|
||||||
|
if (string == null || string.length() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
56
src/tethys/reporter/TethysReport.java
Normal file
56
src/tethys/reporter/TethysReport.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package tethys.reporter;
|
||||||
|
|
||||||
|
import tethys.Collection;
|
||||||
|
|
||||||
|
public class TethysReport {
|
||||||
|
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
private Collection collection;
|
||||||
|
|
||||||
|
private String docName;
|
||||||
|
|
||||||
|
private String docId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param success
|
||||||
|
* @param collection
|
||||||
|
* @param docName
|
||||||
|
* @param docId
|
||||||
|
*/
|
||||||
|
public TethysReport(boolean success, Collection collection, String docName, String docId) {
|
||||||
|
this.success = success;
|
||||||
|
this.collection = collection;
|
||||||
|
this.docName = docName;
|
||||||
|
this.docId = docId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the success
|
||||||
|
*/
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the collection
|
||||||
|
*/
|
||||||
|
public Collection getCollection() {
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the docName
|
||||||
|
*/
|
||||||
|
public String getDocName() {
|
||||||
|
return docName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the docId
|
||||||
|
*/
|
||||||
|
public String getDocId() {
|
||||||
|
return docId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
118
src/tethys/reporter/TethysReporter.java
Normal file
118
src/tethys/reporter/TethysReporter.java
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package tethys.reporter;
|
||||||
|
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import PamController.PamController;
|
||||||
|
import PamView.dialog.warn.WarnOnce;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of functions to provide mesage reports on Tethys output. This
|
||||||
|
* will work with the existing WarnOnce type pop-up, the primary purpose
|
||||||
|
* of the functions here being to collate information, possibly from
|
||||||
|
* several document writes, before issuing an overall report.
|
||||||
|
* @author dg50
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TethysReporter {
|
||||||
|
|
||||||
|
private static TethysReporter singleInstance;
|
||||||
|
|
||||||
|
private ArrayList<TethysReport> tethysReports;
|
||||||
|
|
||||||
|
private TethysReporter() {
|
||||||
|
tethysReports = new ArrayList<TethysReport>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the reporter.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static final TethysReporter getTethysReporter() {
|
||||||
|
if (singleInstance == null) {
|
||||||
|
singleInstance = new TethysReporter();
|
||||||
|
}
|
||||||
|
return singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all reports
|
||||||
|
*/
|
||||||
|
synchronized public void clear() {
|
||||||
|
tethysReports.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a report after attempting to write a document
|
||||||
|
* @param report
|
||||||
|
*/
|
||||||
|
synchronized public void addReport(TethysReport report) {
|
||||||
|
tethysReports.add(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current number of reports
|
||||||
|
* @return number of reports
|
||||||
|
*/
|
||||||
|
synchronized public int getSize() {
|
||||||
|
return tethysReports.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a summary string of all reported writes using html to separate each ont a separat eline
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
synchronized public String getReportString() {
|
||||||
|
if (tethysReports.size() == 0) {
|
||||||
|
return "No reports";
|
||||||
|
}
|
||||||
|
String str = "<html>";
|
||||||
|
for (int i = 0; i < tethysReports.size(); i++) {
|
||||||
|
TethysReport aReport = tethysReports.get(i);
|
||||||
|
String res = aReport.isSuccess() ? "Success" : "Failure";
|
||||||
|
if (i > 0) {
|
||||||
|
str += "<br>";
|
||||||
|
}
|
||||||
|
str += String.format("%s writing %s document %s to Tethys", res, aReport.getCollection().collectionName(), aReport.getDocName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
str += "</html>";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a count of failed document writes
|
||||||
|
* @return failure count
|
||||||
|
*/
|
||||||
|
public int countFails() {
|
||||||
|
int fails = 0;
|
||||||
|
for (TethysReport aReport : tethysReports) {
|
||||||
|
if (aReport.isSuccess() == false) {
|
||||||
|
fails++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fails;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a report in a popup window
|
||||||
|
* @param clear clear the list of reports afterwards
|
||||||
|
*/
|
||||||
|
public void showReport(boolean clear) {
|
||||||
|
showReport(PamController.getMainFrame(), clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a report on a popup window
|
||||||
|
* @param window parent frame
|
||||||
|
* @param clear clear the list of reports afterwards
|
||||||
|
*/
|
||||||
|
public void showReport(Window window, boolean clear) {
|
||||||
|
boolean probs = countFails() > 0;
|
||||||
|
WarnOnce.showNamedWarning("TethysReporter", window, "Tethys Document Writer", getReportString(), WarnOnce.WARNING_MESSAGE);
|
||||||
|
if (clear) {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,7 @@ public class DataBlockSpeciesCodes {
|
|||||||
/**
|
/**
|
||||||
* Probably only to be used when there are no defined names, but helpful if it's set.
|
* Probably only to be used when there are no defined names, but helpful if it's set.
|
||||||
*/
|
*/
|
||||||
private int itisDefault = ITISTypes.UNKNOWN;
|
private int itisDefault = ITISTypes.OTHER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default sound type, which can be used for all 'species', but can get
|
* A default sound type, which can be used for all 'species', but can get
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
package tethys.species;
|
package tethys.species;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
|
||||||
import PamController.settings.output.xml.PAMGuardXMLPreview;
|
import PamController.settings.output.xml.PAMGuardXMLPreview;
|
||||||
import PamController.settings.output.xml.PamguardXMLWriter;
|
import PamController.settings.output.xml.PamguardXMLWriter;
|
||||||
|
import dbxml.Queries;
|
||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
import tethys.dbxml.DBQueryResult;
|
import tethys.dbxml.DBQueryResult;
|
||||||
|
import tethys.dbxml.DBXMLConnect;
|
||||||
import tethys.dbxml.DBXMLQueries;
|
import tethys.dbxml.DBXMLQueries;
|
||||||
import tethys.dbxml.TethysQueryException;
|
import tethys.dbxml.TethysQueryException;
|
||||||
|
|
||||||
@ -81,4 +90,83 @@ public class ITISFunctions {
|
|||||||
|
|
||||||
return new TethysITISResult(itisCode, taxunit, latin, vernacular);
|
return new TethysITISResult(itisCode, taxunit, latin, vernacular);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<SpeciesMapItem> searchSpecies(String searchTerm) {
|
||||||
|
ArrayList<SpeciesMapItem> items = new ArrayList<SpeciesMapItem>();
|
||||||
|
String xQ = "let $target := \"thespeciessearchterm\" \r\n"
|
||||||
|
+ "return\r\n"
|
||||||
|
+ "<Result xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> {\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " for $ranks0 in collection(\"ITIS_ranks\")/ranks/rank[\r\n"
|
||||||
|
+ " dbxml:contains(completename, $target) or \r\n"
|
||||||
|
+ " vernacular[dbxml:contains(name,$target)]]\r\n"
|
||||||
|
+ "return\r\n"
|
||||||
|
+ " <Record> {\r\n"
|
||||||
|
+ " $ranks0/tsn,\r\n"
|
||||||
|
+ " $ranks0/completename,\r\n"
|
||||||
|
+ " <vernacular>\r\n"
|
||||||
|
+ " {string-join($ranks0/vernacular/name, \", \")}\r\n"
|
||||||
|
+ " </vernacular>\r\n"
|
||||||
|
+ " } </Record>\r\n"
|
||||||
|
+ "} </Result>\r\n"
|
||||||
|
+ "";
|
||||||
|
xQ = xQ.replace("thespeciessearchterm", searchTerm);
|
||||||
|
DBXMLConnect dbXMLConnect = tethysControl.getDbxmlConnect();
|
||||||
|
DBXMLQueries dbxmlQueries = tethysControl.getDbxmlQueries();
|
||||||
|
Queries queries = dbXMLConnect.getTethysQueries();
|
||||||
|
|
||||||
|
String queryResult = null;
|
||||||
|
try {
|
||||||
|
queryResult = queries.QueryTethys(xQ);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
// e.printStackTrace();
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DocumentBuilder builder = null;
|
||||||
|
Document doc = null;
|
||||||
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
try {
|
||||||
|
//Create DocumentBuilder with default configuration
|
||||||
|
builder = factory.newDocumentBuilder();
|
||||||
|
|
||||||
|
//Parse the content to Document object
|
||||||
|
doc = builder.parse(new InputSource(new StringReader(queryResult)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// System.out.println(queryResult);
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
// print for now, then comment this out..
|
||||||
|
// PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||||
|
// String fDoc = pamXMLWriter.getAsString(doc, true);
|
||||||
|
// System.out.println(fDoc);
|
||||||
|
// now unpack the xml document.
|
||||||
|
NodeList els = doc.getElementsByTagName("Record");
|
||||||
|
int n = els.getLength();
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
Node aNode = els.item(i);
|
||||||
|
if (aNode instanceof Element) {
|
||||||
|
Element anEl = (Element) aNode;
|
||||||
|
String tsn = dbxmlQueries.getElementData(anEl, "tsn");
|
||||||
|
int nTSN = 0;
|
||||||
|
try {
|
||||||
|
nTSN = Integer.valueOf(tsn);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex) {
|
||||||
|
System.out.println("Invalid TSN read from Tethys: " + tsn);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String completeName = dbxmlQueries.getElementData(anEl, "completename");
|
||||||
|
String vernacular = dbxmlQueries.getElementData(anEl, "vernacular");
|
||||||
|
SpeciesMapItem mapItem = new SpeciesMapItem(nTSN, "", "", completeName, vernacular);
|
||||||
|
items.add(mapItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,12 @@ package tethys.species;
|
|||||||
*/
|
*/
|
||||||
public class ITISTypes {
|
public class ITISTypes {
|
||||||
|
|
||||||
public static final int UNKNOWN = 0;
|
public static final int OTHER = 0;
|
||||||
public static final int ANTHROPOGENIC = 1;
|
public static final int ANTHROPOGENIC = 1;
|
||||||
|
|
||||||
public static final String getName(int code) {
|
public static final String getName(int code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case UNKNOWN:
|
case OTHER:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
case ANTHROPOGENIC:
|
case ANTHROPOGENIC:
|
||||||
return "Anthropogenic";
|
return "Anthropogenic";
|
||||||
|
@ -21,11 +21,11 @@ public class SpeciesTest {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
SpeciesTest st = new SpeciesTest();
|
SpeciesTest st = new SpeciesTest();
|
||||||
st.runJson();
|
// st.runJson();
|
||||||
|
|
||||||
// int spermWhale = 180488;
|
// int spermWhale = 180488;
|
||||||
// st.getCodeInfo(spermWhale);
|
// st.getCodeInfo(spermWhale);
|
||||||
// st.runXQuery();
|
st.runXQuery();
|
||||||
|
|
||||||
}
|
}
|
||||||
private void getCodeInfo(int itisCode) {
|
private void getCodeInfo(int itisCode) {
|
||||||
@ -86,14 +86,31 @@ public class SpeciesTest {
|
|||||||
// + " }</Deployment>\r\n"
|
// + " }</Deployment>\r\n"
|
||||||
// + "} </Result>";
|
// + "} </Result>";
|
||||||
|
|
||||||
String xQ = "<Result xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> {\r\n"
|
// String xQ = "<Result xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> {\r\n"
|
||||||
+ " for $rank0 in collection(\"ITIS_ranks\")/rank[tsn = \"180488\"]\r\n"
|
// + " for $rank0 in collection(\"ITIS_ranks\")/rank[tsn = \"180488\"]\r\n"
|
||||||
+ " return\r\n"
|
// + " return\r\n"
|
||||||
+ " <rank>{\r\n"
|
// + " <rank>{\r\n"
|
||||||
+ " $rank0/completename\r\n"
|
// + " $rank0/completename\r\n"
|
||||||
+ " }</rank>\r\n"
|
// + " }</rank>\r\n"
|
||||||
+ "} </Result>";
|
// + "} </Result>";
|
||||||
|
String xQ = "let $target := \"physeter\" \r\n"
|
||||||
|
+ "return\r\n"
|
||||||
|
+ "<Result xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> {\r\n"
|
||||||
|
+ "\r\n"
|
||||||
|
+ " for $ranks0 in collection(\"ITIS_ranks\")/ranks/rank[\r\n"
|
||||||
|
+ " dbxml:contains(completename, $target) or \r\n"
|
||||||
|
+ " vernacular[dbxml:contains(name,$target)]]\r\n"
|
||||||
|
+ "return\r\n"
|
||||||
|
+ " <Record> {\r\n"
|
||||||
|
+ " $ranks0/tsn,\r\n"
|
||||||
|
+ " $ranks0/completename,\r\n"
|
||||||
|
+ " <vernacular>\r\n"
|
||||||
|
+ " {string-join($ranks0/vernacular/name, \", \")}\r\n"
|
||||||
|
+ " </vernacular>\r\n"
|
||||||
|
+ " } </Record>\r\n"
|
||||||
|
+ "} </Result>\r\n"
|
||||||
|
+ "";
|
||||||
|
System.out.println(xQ);
|
||||||
|
|
||||||
JerseyClient jerseyClient = new JerseyClient(uri);
|
JerseyClient jerseyClient = new JerseyClient(uri);
|
||||||
Queries queries = new Queries(jerseyClient);
|
Queries queries = new Queries(jerseyClient);
|
||||||
|
@ -7,12 +7,14 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
|
||||||
import PamController.PamController;
|
import PamController.PamController;
|
||||||
import PamView.PamGui;
|
import PamView.PamGui;
|
||||||
import PamView.dialog.PamDialog;
|
import PamView.dialog.PamDialog;
|
||||||
|
import PamView.panel.PamNorthPanel;
|
||||||
import PamguardMVC.PamDataBlock;
|
import PamguardMVC.PamDataBlock;
|
||||||
import tethys.species.SpeciesMapManager;
|
import tethys.species.SpeciesMapManager;
|
||||||
|
|
||||||
@ -38,7 +40,16 @@ public class DataBlockSpeciesDialog extends PamDialog {
|
|||||||
});
|
});
|
||||||
JPanel nPanel = new JPanel(new BorderLayout());
|
JPanel nPanel = new JPanel(new BorderLayout());
|
||||||
nPanel.setBorder(new TitledBorder("Code management"));
|
nPanel.setBorder(new TitledBorder("Code management"));
|
||||||
nPanel.add(BorderLayout.EAST, itisButton);
|
nPanel.add(BorderLayout.EAST, new PamNorthPanel(itisButton));
|
||||||
|
String otherMsg =
|
||||||
|
"<html>Specify an ITIS taxonomic serial number (coding)."
|
||||||
|
+ "<br>Press the Find button to look up TSNs by Latin or common name. "
|
||||||
|
+ "<br>Anthropogenic signals should be coded as Homo sapiens (180092). "
|
||||||
|
+ "<br>Noise Measurements and geophonic sounds should be coded as "
|
||||||
|
+ "\"Other Phenomena\" (-10). "
|
||||||
|
+ "<br>When known, a call or sound type should "
|
||||||
|
+ "be specified (see help for more information).</html>";
|
||||||
|
nPanel.add(BorderLayout.CENTER, new JLabel(otherMsg , JLabel.LEFT));
|
||||||
// JPanel nwBit = new JPanel(new FlowLayout());
|
// JPanel nwBit = new JPanel(new FlowLayout());
|
||||||
// JButton exportButton = new JButton("Export");
|
// JButton exportButton = new JButton("Export");
|
||||||
// exportButton.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame));
|
// exportButton.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame));
|
||||||
@ -52,6 +63,7 @@ public class DataBlockSpeciesDialog extends PamDialog {
|
|||||||
mainPanel.add(BorderLayout.NORTH, nPanel);
|
mainPanel.add(BorderLayout.NORTH, nPanel);
|
||||||
setDialogComponent(mainPanel);
|
setDialogComponent(mainPanel);
|
||||||
setResizable(true);
|
setResizable(true);
|
||||||
|
setHelpPoint("utilities.tethys.docs.tethys_speciescodes");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void gotoITIS() {
|
protected void gotoITIS() {
|
||||||
|
282
src/tethys/species/swing/SpeciesSearchDialog.java
Normal file
282
src/tethys/species/swing/SpeciesSearchDialog.java
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
package tethys.species.swing;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.SwingWorker;
|
||||||
|
import javax.swing.border.TitledBorder;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
||||||
|
import PamUtils.worker.PamWorkDialog;
|
||||||
|
import PamUtils.worker.PamWorkProgressMessage;
|
||||||
|
import PamView.dialog.PamDialog;
|
||||||
|
import PamView.dialog.PamGridBagContraints;
|
||||||
|
import PamView.dialog.warn.WarnOnce;
|
||||||
|
import PamView.tables.SwingTableColumnWidths;
|
||||||
|
import PamView.tables.TableColumnWidthData;
|
||||||
|
import tethys.TethysControl;
|
||||||
|
import tethys.species.ITISFunctions;
|
||||||
|
import tethys.species.SpeciesMapItem;
|
||||||
|
|
||||||
|
public class SpeciesSearchDialog extends PamDialog {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private TethysControl tethysControl;
|
||||||
|
|
||||||
|
private SpeciesMapItem selectedItem;
|
||||||
|
|
||||||
|
private static SpeciesSearchDialog singleInstance;
|
||||||
|
|
||||||
|
private JTextField searchText;
|
||||||
|
|
||||||
|
private JButton searchButton;
|
||||||
|
|
||||||
|
private JTable resultTable;
|
||||||
|
|
||||||
|
private ArrayList<SpeciesMapItem> speciesMapItems;
|
||||||
|
|
||||||
|
private DataModel tableModel;
|
||||||
|
|
||||||
|
private volatile PamWorkDialog workDialog;
|
||||||
|
|
||||||
|
private Object synch = new Object();
|
||||||
|
|
||||||
|
|
||||||
|
private SpeciesSearchDialog(Window parentFrame, TethysControl tethysControl) {
|
||||||
|
super(parentFrame, "Species search", false);
|
||||||
|
this.tethysControl = tethysControl;
|
||||||
|
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||||
|
mainPanel.setBorder(new TitledBorder("Search Term"));
|
||||||
|
JPanel topPanel = new JPanel(new GridBagLayout());
|
||||||
|
GridBagConstraints c = new PamGridBagContraints();
|
||||||
|
topPanel.add(new JLabel("Latin or common name ", JLabel.RIGHT), c);
|
||||||
|
c.gridx++;
|
||||||
|
topPanel.add(searchText = new JTextField(12), c);
|
||||||
|
c.gridx++;
|
||||||
|
topPanel.add(searchButton = new JButton("search"), c);
|
||||||
|
mainPanel.add(BorderLayout.NORTH, topPanel);
|
||||||
|
searchButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
searchTethys();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
searchText.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
searchTethys();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tableModel = new DataModel();
|
||||||
|
resultTable = new JTable(tableModel);
|
||||||
|
JPanel centPanel = new JPanel(new BorderLayout());
|
||||||
|
centPanel.add(BorderLayout.NORTH, new JLabel("Possible matches (select one)", JLabel.LEFT));
|
||||||
|
JScrollPane scrollPane = new JScrollPane(resultTable);
|
||||||
|
centPanel.add(BorderLayout.CENTER, scrollPane);
|
||||||
|
mainPanel.add(BorderLayout.CENTER, centPanel);
|
||||||
|
|
||||||
|
resultTable.addMouseListener(new TableMouse());
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
new SwingTableColumnWidths("Species Search Dialog Table", resultTable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setResizable(true);
|
||||||
|
setDialogComponent(mainPanel);
|
||||||
|
}
|
||||||
|
public static SpeciesMapItem showDialog(Window parentFrame, TethysControl tethysControl) {
|
||||||
|
if (singleInstance == null) {
|
||||||
|
singleInstance = new SpeciesSearchDialog(parentFrame, tethysControl);
|
||||||
|
}
|
||||||
|
singleInstance.setParams();
|
||||||
|
singleInstance.setVisible(true);
|
||||||
|
return singleInstance.selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void searchTethys() {
|
||||||
|
clearResults();
|
||||||
|
String str = searchText.getText();
|
||||||
|
if (str == null || str.length() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SearchWorker searchWorker = new SearchWorker(str);
|
||||||
|
searchWorker.execute();
|
||||||
|
// then open the dialog to block this thread.
|
||||||
|
synchronized (synch) {
|
||||||
|
workDialog = new PamWorkDialog(getOwner(), 1, "Searching Tethys Database");
|
||||||
|
workDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapItems(ArrayList<SpeciesMapItem> newMapItems) {
|
||||||
|
this.speciesMapItems = newMapItems;
|
||||||
|
tableModel.fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SearchWorker extends SwingWorker<Integer, PamWorkProgressMessage> {
|
||||||
|
|
||||||
|
private String searchString;
|
||||||
|
private ArrayList<SpeciesMapItem> newMapItems;
|
||||||
|
|
||||||
|
public SearchWorker(String searchString) {
|
||||||
|
this.searchString = searchString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Integer doInBackground() throws Exception {
|
||||||
|
String msg = String.format("Searching database for names containing \"%s\"", searchString);
|
||||||
|
PamWorkProgressMessage pm = new PamWorkProgressMessage(null, msg);
|
||||||
|
publish(pm);
|
||||||
|
try {
|
||||||
|
ITISFunctions itisFunctions = tethysControl.getItisFunctions();
|
||||||
|
this.newMapItems = itisFunctions.searchSpecies(searchString);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (newMapItems == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (workDialog != null) {
|
||||||
|
workDialog.setVisible(false);
|
||||||
|
workDialog.dispose();
|
||||||
|
}
|
||||||
|
return newMapItems.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
if (newMapItems == null || newMapItems.size() == 0) {
|
||||||
|
String msg = String.format("No matching ITIS types for search term %s", searchString);
|
||||||
|
WarnOnce.showNamedWarning("ITIS Lookup failure", getOwner(), "ITIS Code search", msg, WarnOnce.WARNING_MESSAGE);
|
||||||
|
|
||||||
|
}
|
||||||
|
setMapItems(newMapItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void process(List<PamWorkProgressMessage> chunks) {
|
||||||
|
for (PamWorkProgressMessage msg : chunks) {
|
||||||
|
synchronized (synch) {
|
||||||
|
if (workDialog != null) {
|
||||||
|
workDialog.update(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setParams() {
|
||||||
|
searchText.setText(null);
|
||||||
|
clearResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearResults() {
|
||||||
|
speciesMapItems = null;
|
||||||
|
selectedItem = null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean getParams() {
|
||||||
|
if (selectedItem == null) {
|
||||||
|
return showWarning("You must select a row from the table of species");
|
||||||
|
}
|
||||||
|
return selectedItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelButtonPressed() {
|
||||||
|
clearResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreDefaultSettings() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TableMouse extends MouseAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
if (speciesMapItems == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int selectedRow = resultTable.getSelectedRow();
|
||||||
|
if (selectedRow >= 0 && selectedRow < speciesMapItems.size()) {
|
||||||
|
selectedItem = speciesMapItems.get(selectedRow);
|
||||||
|
}
|
||||||
|
tableModel.fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private class DataModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
private String[] colNames = {"Select", "TSN", "Name", "Common Name"};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
if (speciesMapItems == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return speciesMapItems.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return colNames.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||||
|
SpeciesMapItem mapItem = speciesMapItems.get(rowIndex);
|
||||||
|
switch (columnIndex) {
|
||||||
|
case 0:
|
||||||
|
return mapItem == selectedItem;
|
||||||
|
case 1:
|
||||||
|
return mapItem.getItisCode();
|
||||||
|
case 2:
|
||||||
|
return mapItem.getLatinName();
|
||||||
|
case 3:
|
||||||
|
return mapItem.getCommonName();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
return colNames[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
|
if (columnIndex == 0) {
|
||||||
|
return Boolean.class;
|
||||||
|
}
|
||||||
|
return super.getColumnClass(columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -85,7 +85,8 @@ public class SpeciesSubPanel {
|
|||||||
|
|
||||||
pamguardName.setToolTipText("Internal name within PAMGuard module");
|
pamguardName.setToolTipText("Internal name within PAMGuard module");
|
||||||
itisCode.setToolTipText("ITIS species code");
|
itisCode.setToolTipText("ITIS species code");
|
||||||
searchButton.setToolTipText("Search for species code");
|
searchButton.setToolTipText("<html>Either enter a code manually and press \"Find\" for additional information,<br>"
|
||||||
|
+ "or leave the code empty and press \"Find\" to search the Tethys database using common or scientific names.</html>" );
|
||||||
callType.setToolTipText("Descriptive name for call type or measurement");
|
callType.setToolTipText("Descriptive name for call type or measurement");
|
||||||
latinName.setToolTipText("Scientific name");
|
latinName.setToolTipText("Scientific name");
|
||||||
commonName.setToolTipText("Common name");
|
commonName.setToolTipText("Common name");
|
||||||
@ -112,6 +113,17 @@ public class SpeciesSubPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ITISFunctions itisFunctions = tethysControl.getItisFunctions();
|
ITISFunctions itisFunctions = tethysControl.getItisFunctions();
|
||||||
|
String itisString = this.itisCode.getText();
|
||||||
|
if (itisString == null || itisString.length() == 0) {
|
||||||
|
searchForCode(tethysControl, itisFunctions);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getCodeInformation(tethysControl, itisFunctions, itisString);
|
||||||
|
}
|
||||||
|
// System.out.println(itisInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getCodeInformation(TethysControl tethysControl, ITISFunctions itisFunctions, String itisString) {
|
||||||
int itisCode = 0;
|
int itisCode = 0;
|
||||||
try {
|
try {
|
||||||
itisCode = Integer.valueOf(this.itisCode.getText());
|
itisCode = Integer.valueOf(this.itisCode.getText());
|
||||||
@ -129,7 +141,15 @@ public class SpeciesSubPanel {
|
|||||||
commonName.setText(itisInfo.getVernacular());
|
commonName.setText(itisInfo.getVernacular());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// System.out.println(itisInfo);
|
}
|
||||||
|
|
||||||
|
private void searchForCode(TethysControl tethysControl, ITISFunctions itisFunctions) {
|
||||||
|
SpeciesMapItem speciesItem = SpeciesSearchDialog.showDialog(tethysControl.getGuiFrame(), tethysControl);
|
||||||
|
if (speciesItem != null) {
|
||||||
|
itisCode.setText(String.format("%d", speciesItem.getItisCode()));
|
||||||
|
latinName.setText(speciesItem.getLatinName());
|
||||||
|
commonName.setText(speciesItem.getCommonName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JComponent getDialogComponent() {
|
public JComponent getDialogComponent() {
|
||||||
|
@ -147,7 +147,7 @@ public class DatablockSynchPanel extends TethysGUIPanel {
|
|||||||
if (deployments == null || deployments.size() == 0) {
|
if (deployments == null || deployments.size() == 0) {
|
||||||
en = false;
|
en = false;
|
||||||
}
|
}
|
||||||
exportButton.setEnabled(en);
|
exportButton.setEnabled(getTethysControl().isServerOk() & en);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showPopup(MouseEvent e, int row) {
|
public void showPopup(MouseEvent e, int row) {
|
||||||
@ -181,6 +181,9 @@ public class DatablockSynchPanel extends TethysGUIPanel {
|
|||||||
// dataBlockSynchInfo = null;
|
// dataBlockSynchInfo = null;
|
||||||
// getSychInfos();
|
// getSychInfos();
|
||||||
// getTethysControl().coun
|
// getTethysControl().coun
|
||||||
|
break;
|
||||||
|
case UPDATESERVER:
|
||||||
|
enableExportButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchTableModel.fireTableDataChanged();
|
synchTableModel.fireTableDataChanged();
|
||||||
|
@ -154,6 +154,9 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
|||||||
case UPDATEMETADATA:
|
case UPDATEMETADATA:
|
||||||
setInternal();
|
setInternal();
|
||||||
break;
|
break;
|
||||||
|
case UPDATESERVER:
|
||||||
|
enableControls();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +247,7 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
|||||||
|
|
||||||
private void enableControls() {
|
private void enableControls() {
|
||||||
boolean enable = selectedDeployments != null && selectedDeployments.size() > 0;
|
boolean enable = selectedDeployments != null && selectedDeployments.size() > 0;
|
||||||
bigExportButton.setEnabled(enable);
|
bigExportButton.setEnabled(getTethysControl().isServerOk() & enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import javax.swing.border.TitledBorder;
|
|||||||
|
|
||||||
import PamView.panel.PamPanel;
|
import PamView.panel.PamPanel;
|
||||||
import tethys.TethysControl;
|
import tethys.TethysControl;
|
||||||
|
import tethys.TethysState;
|
||||||
import tethys.deployment.DeploymentHandler;
|
import tethys.deployment.DeploymentHandler;
|
||||||
import tethys.deployment.RecordingPeriod;
|
import tethys.deployment.RecordingPeriod;
|
||||||
|
|
||||||
@ -97,14 +98,22 @@ public class DeploymentsPanel extends TethysGUIPanel implements DeploymentTableO
|
|||||||
enableExportButton();
|
enableExportButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void enableExportButton() {
|
private void enableExportButton() {
|
||||||
ArrayList<RecordingPeriod> selected = pamDeploymentsTable.getSelectedPeriods();
|
ArrayList<RecordingPeriod> selected = pamDeploymentsTable.getSelectedPeriods();
|
||||||
// and see if any warnings are needed: basically if anything selected has an output.
|
if (selected == null) {
|
||||||
|
exportButton.setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean existing = false;
|
boolean existing = false;
|
||||||
for (RecordingPeriod aPeriod: selected) {
|
if (selected != null) {
|
||||||
if (aPeriod.getMatchedTethysDeployment() != null) {
|
// and see if any warnings are needed: basically if anything selected has an output.
|
||||||
existing = true;
|
for (RecordingPeriod aPeriod: selected) {
|
||||||
break;
|
if (aPeriod.getMatchedTethysDeployment() != null) {
|
||||||
|
existing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String warning = null;
|
String warning = null;
|
||||||
@ -113,7 +122,13 @@ public class DeploymentsPanel extends TethysGUIPanel implements DeploymentTableO
|
|||||||
exportWarning.setText(warning);
|
exportWarning.setText(warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
exportButton.setEnabled(selected.size()>0 & existing == false);
|
exportButton.setEnabled(selected.size()>0 & existing == false && getTethysControl().isServerOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateState(TethysState tethysState) {
|
||||||
|
super.updateState(tethysState);
|
||||||
|
enableExportButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,6 +326,9 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public ArrayList<RecordingPeriod> getSelectedPeriods() {
|
public ArrayList<RecordingPeriod> getSelectedPeriods() {
|
||||||
|
if (deploymentOverview == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ArrayList<RecordingPeriod> allPeriods = deploymentOverview.getRecordingPeriods();
|
ArrayList<RecordingPeriod> allPeriods = deploymentOverview.getRecordingPeriods();
|
||||||
ArrayList<RecordingPeriod> selPeriods = new ArrayList();
|
ArrayList<RecordingPeriod> selPeriods = new ArrayList();
|
||||||
int n = allPeriods.size();
|
int n = allPeriods.size();
|
||||||
|
80
src/tethys/swing/TethysWizardCard.java
Normal file
80
src/tethys/swing/TethysWizardCard.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package tethys.swing;
|
||||||
|
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
|
||||||
|
import PamView.dialog.PamDialog;
|
||||||
|
import PamView.dialog.warn.WarnOnce;
|
||||||
|
import PamView.wizard.PamWizard;
|
||||||
|
import PamView.wizard.PamWizardCard;
|
||||||
|
import tethys.niluswraps.NilusChecker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wizard card with a few extra functions for Tethys.
|
||||||
|
* @author dg50
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
abstract public class TethysWizardCard<T extends Object> extends PamWizardCard<T> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public TethysWizardCard(PamWizard pamWizard, String title) {
|
||||||
|
super(pamWizard, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string out of a text component, but if the field is
|
||||||
|
* empty, return null rather than an empty, 0 length, string.
|
||||||
|
* @param textField
|
||||||
|
* @return string, or null if it's empty.
|
||||||
|
*/
|
||||||
|
public String getText(JTextComponent textField) {
|
||||||
|
String str = textField.getText();
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (str.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string from a text component, and warn if it is empty or null.
|
||||||
|
* @param owner parent window for warning
|
||||||
|
* @param textComponent text component
|
||||||
|
* @param name control name for warning text
|
||||||
|
* @return String if there was one, or null if it was null or empty.
|
||||||
|
*/
|
||||||
|
public String warnNotNull(Window owner, JTextComponent textComponent, String name) {
|
||||||
|
String str = getText(textComponent);
|
||||||
|
if (str != null) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
String warn = String.format("The field %s cannot be empty", name);
|
||||||
|
PamDialog.showWarning(owner, "Empty or missing data", warn);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for required empty fields.
|
||||||
|
* @param nilusObject
|
||||||
|
* @return true if all OK, false if there are required fields
|
||||||
|
*/
|
||||||
|
public boolean checkEmptyFields(Object nilusObject) {
|
||||||
|
NilusChecker.removeEmptyFields(nilusObject);
|
||||||
|
ArrayList<Field> emptyList = NilusChecker.checkEmptyFields(nilusObject);
|
||||||
|
if (emptyList.size() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Field first = emptyList.get(0);
|
||||||
|
String msg = String.format("The field \"%s\" in \"%s\" is required by Tethys and must be completed", first.getName(), first.getDeclaringClass().getCanonicalName());
|
||||||
|
return PamDialog.showWarning(getPamWizard(), "Missing required data", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user