mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-25 08:32:32 +00:00
Merge pull request #61 from douggillespie/Tethys
TethysMerge in from Tetthys
This commit is contained in:
commit
f4993425b5
@ -1,7 +1,5 @@
|
||||
package PamView.wizard;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ public class ClickBlockSpeciesManager extends DataBlockSpeciesManager<ClickDetec
|
||||
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
|
||||
super(clickDataBlock);
|
||||
this.clickControl = clickControl;
|
||||
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.UNKNOWN, "Unknown", "Unknown"));
|
||||
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.OTHER, "Unknown", "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
|
||||
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="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="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="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="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="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="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="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.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="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.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="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="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="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="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="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.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-->
|
||||
|
||||
<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 database interface " target="utilities.tethys.docs.tethys_overview"/>
|
||||
|
@ -198,10 +198,20 @@
|
||||
<tocitem text="Tethys Interface ">
|
||||
<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="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 text="Sensors ">
|
||||
|
@ -55,6 +55,14 @@ ol {
|
||||
|
||||
img.wrap {float: left}
|
||||
img.wrapright {float: right}
|
||||
img.wrapcenter {float: center}
|
||||
|
||||
.center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
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>
|
@ -22,47 +22,67 @@ img {
|
||||
</head>
|
||||
<body>
|
||||
<h1>Tethys Interface</h1>
|
||||
<p></p>
|
||||
<h2>Overview</h2>
|
||||
|
||||
<p align="right">
|
||||
<img class="wrap" SRC="images/Tethys-200.png" alt="Tethys mosaic">
|
||||
</p>
|
||||
<div>
|
||||
<img SRC="images/Tethys-200.png" alt="Tethys mosaic"
|
||||
style="float: right; margin 10px;"/>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
PAMGuard is compatible
|
||||
with <a href="https://tethys.sdsu.edu/tethys3/">Tethys 3.0</a> or
|
||||
later.
|
||||
<a href="https://tethys.sdsu.edu/">Tethys</a> is a freely
|
||||
available open source temporal-spatial database for metadata related
|
||||
to acoustic recordings. The database is intended to house the metadata
|
||||
from marine mammal detection and localization studies, allowing the
|
||||
user to perform meta analyses or to aggregate data from many
|
||||
experimental efforts based on a common attribute. This resulting
|
||||
database can then be queried based on time, space, or any desired
|
||||
attribute and the results can be integrated with external datasets
|
||||
such as NASA's Ocean Color, lunar illumination, etc. in a consistent
|
||||
manner. While Tethys is designed primarily for acoustic metadata from
|
||||
marine mammals, the design is general enough to permit use in other
|
||||
areas as well.
|
||||
|
||||
</p>
|
||||
<p>PAMGuard is compatible with <a href="https://tethys.sdsu.edu/tethys3/">Tethys 3.0</a> or above, released early in 2024. </p>
|
||||
<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.
|
||||
available open source temporal-spatial database for metadata
|
||||
related to acoustic recordings. The database is intended to house
|
||||
the metadata from marine mammal detection and localization
|
||||
studies, allowing the user to perform meta analyses or to
|
||||
aggregate data from many experimental efforts based on a common
|
||||
attribute. This resulting database can then be queried based on
|
||||
time, space, or any desired attribute and the results can be
|
||||
integrated with external datasets such as NASA's Ocean Color,
|
||||
lunar illumination, etc. in a consistent manner. While Tethys is
|
||||
designed primarily for acoustic metadata from marine mammals, the
|
||||
design is general enough to permit use in other areas as well.
|
||||
</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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
<a href="tethys_quickstart.html">Next: Quick Start</a>
|
||||
<p>
|
||||
Module help:
|
||||
</p>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<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>
|
||||
|
||||
|
||||
</body>
|
||||
</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() {
|
||||
ServerStatus serverState = dbxmlConnect.pingServer();
|
||||
if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) {
|
||||
lastServerStatus = serverState; // set before sending notification!
|
||||
sendStateUpdate(new TethysState(StateType.UPDATESERVER));
|
||||
}
|
||||
lastServerStatus = serverState;
|
||||
// lastServerStatus = serverState;
|
||||
return serverState;
|
||||
}
|
||||
|
||||
@ -699,5 +700,23 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
|
||||
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;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
@ -45,9 +46,11 @@ import tethys.TethysTimeFuncs;
|
||||
import tethys.calibration.swing.CalibrationsExportWizard;
|
||||
import tethys.dbxml.DBXMLConnect;
|
||||
import tethys.dbxml.TethysException;
|
||||
import tethys.niluswraps.NilusChecker;
|
||||
import tethys.niluswraps.NilusSettingsWrapper;
|
||||
import tethys.niluswraps.NilusUnpacker;
|
||||
import tethys.pamdata.AutoTethysProvider;
|
||||
import tethys.reporter.TethysReporter;
|
||||
|
||||
public class CalibrationHandler implements TethysStateObserver {
|
||||
|
||||
@ -186,6 +189,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
int nExport = 0;
|
||||
boolean overwrite = false;
|
||||
boolean exists;
|
||||
TethysReporter.getTethysReporter().clear();
|
||||
for (int i = 0; i < nPhone; i++) {
|
||||
// String docName = getHydrophoneId(i);
|
||||
NilusSettingsWrapper<Calibration> clonedWrap = wrappedSample.clone();
|
||||
@ -195,11 +199,24 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
calDoc.setMetadataInfo(sampleCal.getMetadataInfo());
|
||||
calDoc.setProcess(sampleCal.getProcess());
|
||||
calDoc.setQualityAssurance(sampleCal.getQualityAssurance());
|
||||
if (NilusChecker.isEmpty(sampleCal.getResponsibleParty()) == false) {
|
||||
calDoc.setResponsibleParty(sampleCal.getResponsibleParty());
|
||||
}
|
||||
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);
|
||||
// run some checks of completeness of the data
|
||||
NilusChecker.removeEmptyFields(calDoc);
|
||||
// ArrayList<Field> emptyFields = NilusChecker.checkEmptyFields(calDoc);
|
||||
|
||||
String calDocName = createDocumentName(calDoc, i);
|
||||
exists = calDocumentExists(calDocName);
|
||||
@ -233,6 +250,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
}
|
||||
}
|
||||
tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.EXPORTRDATA, Collection.Calibrations));
|
||||
TethysReporter.getTethysReporter().showReport(true);
|
||||
return nExport;
|
||||
}
|
||||
|
||||
@ -405,6 +423,10 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
hz.add(Double.valueOf(0));
|
||||
db.add(Double.valueOf(hSens+preampGain));
|
||||
|
||||
if (NilusChecker.isEmpty(calibration.getResponsibleParty())) {
|
||||
calibration.setResponsibleParty(null);
|
||||
}
|
||||
|
||||
MetadataInfo metaInf = calibration.getMetadataInfo();
|
||||
if (metaInf == null) {
|
||||
metaInf = new MetadataInfo();
|
||||
@ -417,6 +439,12 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
contact = new ResponsibleParty();
|
||||
metaInf.setContact(contact);
|
||||
}
|
||||
if (NilusChecker.isEmpty(metaInf.getContact())) {
|
||||
metaInf.setContact(null);
|
||||
}
|
||||
if (NilusChecker.isEmpty(metaInf)) {
|
||||
calibration.setMetadataInfo(null);
|
||||
}
|
||||
contact.setIndividualName("Unknown");
|
||||
contact.setOrganizationName("unknown");
|
||||
|
||||
|
@ -4,6 +4,8 @@ import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
@ -15,6 +17,7 @@ import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.dialog.PamDialog;
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import PamView.panel.WestAlignedPanel;
|
||||
import PamView.wizard.PamWizard;
|
||||
@ -23,9 +26,17 @@ import nilus.AlgorithmType.Parameters;
|
||||
import nilus.AlgorithmType.SupportSoftware;
|
||||
import nilus.Calibration;
|
||||
import nilus.Calibration.QualityAssurance;
|
||||
import nilus.Helper;
|
||||
import nilus.QualityValueBasic;
|
||||
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 {
|
||||
|
||||
private JPanel processPanel;
|
||||
@ -123,9 +134,13 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
||||
}
|
||||
process.setMethod((String) calMethod.getSelectedItem());
|
||||
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) {
|
||||
getPamWizard().showWarning("You must specify the calibratin method used");
|
||||
getPamWizard().showWarning("You must specify the calibration method used");
|
||||
}
|
||||
|
||||
QualityAssurance qa = calibration.getQualityAssurance();
|
||||
@ -133,7 +148,11 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
||||
qa = new QualityAssurance();
|
||||
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()));
|
||||
|
||||
// need to add a few fixed things for this to work...
|
||||
@ -142,11 +161,27 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
||||
if (params == null) {
|
||||
params = new Parameters();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setParams(Calibration calibration) {
|
||||
if (calibration == null) {
|
||||
|
@ -3,8 +3,9 @@ package tethys.calibration.swing;
|
||||
import PamView.wizard.PamWizard;
|
||||
import PamView.wizard.PamWizardCard;
|
||||
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) {
|
||||
super(pamWizard, title);
|
||||
|
@ -28,6 +28,7 @@ import nilus.MetadataInfo;
|
||||
import nilus.ResponsibleParty;
|
||||
import tethys.TethysTimeFuncs;
|
||||
import tethys.calibration.CalibrationHandler;
|
||||
import tethys.niluswraps.NilusChecker;
|
||||
import tethys.swing.export.ResponsiblePartyPanel;
|
||||
|
||||
public class CalibrationsContactCard extends CalibrationsCard {
|
||||
@ -125,6 +126,11 @@ public class CalibrationsContactCard extends CalibrationsCard {
|
||||
}
|
||||
metaData.setContact(checkRPChildren(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.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis()));
|
||||
@ -136,6 +142,10 @@ public class CalibrationsContactCard extends CalibrationsCard {
|
||||
long millis = date.getTime();
|
||||
cardParams.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(millis));
|
||||
|
||||
|
||||
checkEmptyFields(rp);
|
||||
checkEmptyFields(metaData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.panel.PamPanel;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
import tethys.calibration.CalibrationHandler;
|
||||
import tethys.swing.TethysGUIPanel;
|
||||
|
||||
@ -63,4 +64,14 @@ public class CalibrationsMainPanel extends TethysGUIPanel {
|
||||
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.database.TethysActions;
|
||||
import tethys.database.TethysLogger;
|
||||
import tethys.niluswraps.NilusChecker;
|
||||
import tethys.output.TethysExportParams;
|
||||
import tethys.reporter.TethysReport;
|
||||
import tethys.reporter.TethysReporter;
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
boolean ok = NilusChecker.warnEmptyFields(tethysControl.getGuiFrame(), nilusObject);
|
||||
|
||||
|
||||
TethysException e = null;
|
||||
boolean success = false;
|
||||
try {
|
||||
@ -207,6 +213,8 @@ public class DBXMLConnect {
|
||||
*/
|
||||
boolean error = importReturn.contains("<Error");
|
||||
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.
|
||||
if (error) {
|
||||
throw new TethysException("Error posting to Tethys", importReturn);
|
||||
|
@ -45,6 +45,9 @@ import dataMap.OfflineDataMapPoint;
|
||||
import generalDatabase.DBControlUnit;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.PamguardMetaData;
|
||||
import nilus.AcousticDataQAType;
|
||||
import nilus.AcousticDataQAType.Quality;
|
||||
import nilus.AcousticDataQAType.Quality.FrequencyRange;
|
||||
import nilus.Audio;
|
||||
import nilus.ChannelInfo;
|
||||
import nilus.ChannelInfo.DutyCycle;
|
||||
@ -84,6 +87,7 @@ import tethys.deployment.swing.RecordingGapDialog;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
import tethys.output.TethysExportParams;
|
||||
import tethys.pamdata.AutoTethysProvider;
|
||||
import tethys.reporter.TethysReporter;
|
||||
import tethys.swing.DeploymentTableObserver;
|
||||
|
||||
/**
|
||||
@ -387,12 +391,14 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
||||
* @param selectedDeployments
|
||||
*/
|
||||
public void exportDeployments(ArrayList<RecordingPeriod> selectedDeployments) {
|
||||
TethysReporter.getTethysReporter().clear();
|
||||
if (deploymentExportOptions.separateDeployments) {
|
||||
exportSeparateDeployments(selectedDeployments);
|
||||
}
|
||||
else {
|
||||
exportOneDeploymnet(selectedDeployments);
|
||||
}
|
||||
TethysReporter.getTethysReporter().showReport(tethysControl.getGuiFrame(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,6 +406,14 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
||||
*/
|
||||
private void exportOneDeploymnet(ArrayList<RecordingPeriod> selectedDeployments) {
|
||||
// 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();
|
||||
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
|
||||
RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(),
|
||||
@ -412,11 +426,37 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
|
||||
deployment.setCruise(globalMeta.getCruise());
|
||||
deployment.setSite(globalMeta.getSite());
|
||||
if (selectedDeployments.size() > 1) {
|
||||
// now need to remove the
|
||||
SamplingDetails samplingDetails = deployment.getSamplingDetails();
|
||||
samplingDetails.getChannel().clear();
|
||||
for (int i = 0; i < selectedDeployments.size(); i++) {
|
||||
addSamplingDetails(deployment, selectedDeployments.get(i));
|
||||
// // now need to remove the sampling details - don't though, add invalid periods instead.
|
||||
// SamplingDetails samplingDetails = deployment.getSamplingDetails();
|
||||
// samplingDetails.getChannel().clear();
|
||||
// for (int i = 0; i < selectedDeployments.size(); 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();
|
||||
|
@ -39,11 +39,12 @@ public class DeploymentDataCard extends PamWizardCard {
|
||||
this.tethysControl = tethysControl;
|
||||
deploymentHandler = tethysControl.getDeploymentHandler();
|
||||
ButtonGroup bg = new ButtonGroup();
|
||||
exportOne = new JRadioButton("Export a single detection document for all data");
|
||||
exportMany = new JRadioButton("Export separate documents for each ad-hoc recording period");
|
||||
exportOne = new JRadioButton("Export a single deployment document for all data");
|
||||
exportMany = new JRadioButton("Export separate deployment documents for each ad-hoc recording period");
|
||||
bg.add(exportOne);
|
||||
bg.add(exportMany);
|
||||
|
||||
|
||||
JPanel optsPanel = new JPanel(new GridBagLayout());
|
||||
optsPanel.setBorder(new TitledBorder("Number of documents"));
|
||||
GridBagConstraints c = new PamGridBagContraints();
|
||||
@ -95,6 +96,15 @@ public class DeploymentDataCard extends PamWizardCard {
|
||||
}
|
||||
|
||||
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);
|
||||
exportMany.setSelected(exportOptions.separateDeployments == true);
|
||||
setParams(deployment);
|
||||
|
@ -43,6 +43,7 @@ import tethys.output.DatablockSynchInfo;
|
||||
import tethys.output.StreamExportParams;
|
||||
import tethys.output.TethysExportParams;
|
||||
import tethys.pamdata.TethysDataProvider;
|
||||
import tethys.reporter.TethysReporter;
|
||||
import tethys.species.DataBlockSpeciesManager;
|
||||
import tethys.swing.export.DetectionsExportWizard;
|
||||
|
||||
@ -587,6 +588,7 @@ public class DetectionsHandler {
|
||||
this.dataBlock = dataBlock;
|
||||
this.exportParams = exportParams;
|
||||
this.exportObserver = exportObserver;
|
||||
TethysReporter.getTethysReporter().clear();
|
||||
}
|
||||
|
||||
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);
|
||||
tethysControl.exportedDetections(dataBlock);
|
||||
exportObserver.update(prog);
|
||||
TethysReporter.getTethysReporter().showReport(tethysControl.getGuiFrame(), true);
|
||||
}
|
||||
|
||||
@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.
|
||||
*/
|
||||
private int itisDefault = ITISTypes.UNKNOWN;
|
||||
private int itisDefault = ITISTypes.OTHER;
|
||||
|
||||
/**
|
||||
* A default sound type, which can be used for all 'species', but can get
|
||||
|
@ -1,14 +1,23 @@
|
||||
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.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import PamController.settings.output.xml.PAMGuardXMLPreview;
|
||||
import PamController.settings.output.xml.PamguardXMLWriter;
|
||||
import dbxml.Queries;
|
||||
import tethys.TethysControl;
|
||||
import tethys.dbxml.DBQueryResult;
|
||||
import tethys.dbxml.DBXMLConnect;
|
||||
import tethys.dbxml.DBXMLQueries;
|
||||
import tethys.dbxml.TethysQueryException;
|
||||
|
||||
@ -81,4 +90,83 @@ public class ITISFunctions {
|
||||
|
||||
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 static final int UNKNOWN = 0;
|
||||
public static final int OTHER = 0;
|
||||
public static final int ANTHROPOGENIC = 1;
|
||||
|
||||
public static final String getName(int code) {
|
||||
switch (code) {
|
||||
case UNKNOWN:
|
||||
case OTHER:
|
||||
return "Unknown";
|
||||
case ANTHROPOGENIC:
|
||||
return "Anthropogenic";
|
||||
|
@ -21,11 +21,11 @@ public class SpeciesTest {
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpeciesTest st = new SpeciesTest();
|
||||
st.runJson();
|
||||
// st.runJson();
|
||||
|
||||
// int spermWhale = 180488;
|
||||
// st.getCodeInfo(spermWhale);
|
||||
// st.runXQuery();
|
||||
st.runXQuery();
|
||||
|
||||
}
|
||||
private void getCodeInfo(int itisCode) {
|
||||
@ -86,14 +86,31 @@ public class SpeciesTest {
|
||||
// + " }</Deployment>\r\n"
|
||||
// + "} </Result>";
|
||||
|
||||
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"
|
||||
+ " return\r\n"
|
||||
+ " <rank>{\r\n"
|
||||
+ " $rank0/completename\r\n"
|
||||
+ " }</rank>\r\n"
|
||||
+ "} </Result>";
|
||||
|
||||
// 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"
|
||||
// + " return\r\n"
|
||||
// + " <rank>{\r\n"
|
||||
// + " $rank0/completename\r\n"
|
||||
// + " }</rank>\r\n"
|
||||
// + "} </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);
|
||||
Queries queries = new Queries(jerseyClient);
|
||||
|
@ -7,12 +7,14 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamView.PamGui;
|
||||
import PamView.dialog.PamDialog;
|
||||
import PamView.panel.PamNorthPanel;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import tethys.species.SpeciesMapManager;
|
||||
|
||||
@ -38,7 +40,16 @@ public class DataBlockSpeciesDialog extends PamDialog {
|
||||
});
|
||||
JPanel nPanel = new JPanel(new BorderLayout());
|
||||
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());
|
||||
// JButton exportButton = new JButton("Export");
|
||||
// exportButton.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame));
|
||||
@ -52,6 +63,7 @@ public class DataBlockSpeciesDialog extends PamDialog {
|
||||
mainPanel.add(BorderLayout.NORTH, nPanel);
|
||||
setDialogComponent(mainPanel);
|
||||
setResizable(true);
|
||||
setHelpPoint("utilities.tethys.docs.tethys_speciescodes");
|
||||
}
|
||||
|
||||
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");
|
||||
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");
|
||||
latinName.setToolTipText("Scientific name");
|
||||
commonName.setToolTipText("Common name");
|
||||
@ -112,6 +113,17 @@ public class SpeciesSubPanel {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
try {
|
||||
itisCode = Integer.valueOf(this.itisCode.getText());
|
||||
@ -129,7 +141,15 @@ public class SpeciesSubPanel {
|
||||
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() {
|
||||
|
@ -147,7 +147,7 @@ public class DatablockSynchPanel extends TethysGUIPanel {
|
||||
if (deployments == null || deployments.size() == 0) {
|
||||
en = false;
|
||||
}
|
||||
exportButton.setEnabled(en);
|
||||
exportButton.setEnabled(getTethysControl().isServerOk() & en);
|
||||
}
|
||||
|
||||
public void showPopup(MouseEvent e, int row) {
|
||||
@ -181,6 +181,9 @@ public class DatablockSynchPanel extends TethysGUIPanel {
|
||||
// dataBlockSynchInfo = null;
|
||||
// getSychInfos();
|
||||
// getTethysControl().coun
|
||||
break;
|
||||
case UPDATESERVER:
|
||||
enableExportButton();
|
||||
}
|
||||
|
||||
synchTableModel.fireTableDataChanged();
|
||||
|
@ -154,6 +154,9 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
||||
case UPDATEMETADATA:
|
||||
setInternal();
|
||||
break;
|
||||
case UPDATESERVER:
|
||||
enableControls();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +247,7 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
||||
|
||||
private void enableControls() {
|
||||
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 tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
import tethys.deployment.DeploymentHandler;
|
||||
import tethys.deployment.RecordingPeriod;
|
||||
|
||||
@ -97,23 +98,37 @@ public class DeploymentsPanel extends TethysGUIPanel implements DeploymentTableO
|
||||
enableExportButton();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void enableExportButton() {
|
||||
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;
|
||||
if (selected != null) {
|
||||
// and see if any warnings are needed: basically if anything selected has an output.
|
||||
for (RecordingPeriod aPeriod: selected) {
|
||||
if (aPeriod.getMatchedTethysDeployment() != null) {
|
||||
existing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String warning = null;
|
||||
if (existing) {
|
||||
warning = " One or more deployment documents already exist. These must be deleted prior to exporting new documents";
|
||||
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
|
||||
*/
|
||||
public ArrayList<RecordingPeriod> getSelectedPeriods() {
|
||||
if (deploymentOverview == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<RecordingPeriod> allPeriods = deploymentOverview.getRecordingPeriods();
|
||||
ArrayList<RecordingPeriod> selPeriods = new ArrayList();
|
||||
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