From ef1a6cf5ee8f9f6d833279f89b3b383b1085e71d Mon Sep 17 00:00:00 2001
From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date: Wed, 20 Mar 2024 16:31:53 -0700
Subject: [PATCH] Tidying
Lots of GUI improvement and code tidying. Functionality to export
gzipped documents to reduce traffic.
---
.classpath | 3 +-
dependency-reduced-pom.xml | 2 +-
src/PamUtils/worker/PamWorkDialog.java | 4 +
src/tethys/CollectionHandler.java | 38 +++
src/tethys/TethysControl.java | 2 +
.../calibration/CalibrationHandler.java | 17 +-
.../swing/CalibrationsContactCard.java | 33 ++-
.../swing/CalibrationsExportWizard.java | 4 +-
.../swing/CalibrationsMainPanel.java | 98 ++++---
src/tethys/dbxml/DBXMLConnect.java | 120 ++++++---
src/tethys/dbxml/DBXMLQueries.java | 3 +
src/tethys/deployment/DeploymentHandler.java | 98 ++++---
src/tethys/deployment/DeploymentOverview.java | 110 ++++----
src/tethys/deployment/EffortFunctions.java | 242 +++++++-----------
src/tethys/deployment/RecordingList.java | 211 ++++++++++++++-
src/tethys/deployment/RecordingPeriod.java | 7 +
.../deployment/swing/EffortProblemDialog.java | 163 ++++++++++++
.../deployment/swing/RecordingGapDialog.java | 3 +-
.../detection/DetectionExportProgress.java | 1 +
src/tethys/detection/DetectionsHandler.java | 70 +++--
.../localization/LocalizationHandler.java | 17 ++
.../niluswraps/NilusSettingsWrapper.java | 4 +-
src/tethys/output/StreamExportParams.java | 6 +-
src/tethys/output/TethysExportParams.java | 18 ++
.../species/DataBlockSpeciesManager.java | 26 +-
src/tethys/species/ITISFunctions.java | 41 ++-
src/tethys/species/ITISTypes.java | 4 +-
src/tethys/species/SpeciesMapItem.java | 14 +
.../species/swing/DataBlockSpeciesDialog.java | 11 +-
.../species/swing/SpeciesSearchDialog.java | 33 ++-
src/tethys/species/swing/SpeciesSubPanel.java | 20 +-
.../swing/DatablockDetectionsPanel.java | 30 ++-
src/tethys/swing/DatablockSynchPanel.java | 101 ++++++--
src/tethys/swing/DeploymentExportPanel.java | 5 +-
src/tethys/swing/DeploymentsPanel.java | 112 ++++----
src/tethys/swing/FancyClientButton.java | 30 ++-
.../swing/PAMGuardDeploymentsTable.java | 27 +-
src/tethys/swing/TethysConnectionPanel.java | 11 +-
src/tethys/swing/TethysDeploymentsTable.java | 9 +-
src/tethys/swing/TethysExportPanel.java | 227 ++++++++++++++++
src/tethys/swing/TippedButton.java | 77 ++++++
41 files changed, 1585 insertions(+), 467 deletions(-)
create mode 100644 src/tethys/CollectionHandler.java
create mode 100644 src/tethys/deployment/swing/EffortProblemDialog.java
create mode 100644 src/tethys/localization/LocalizationHandler.java
create mode 100644 src/tethys/swing/TethysExportPanel.java
create mode 100644 src/tethys/swing/TippedButton.java
diff --git a/.classpath b/.classpath
index 26c568d7..188c7291 100644
--- a/.classpath
+++ b/.classpath
@@ -6,9 +6,8 @@
-
+
-
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index 73fb08dd..b4db9b43 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -4,7 +4,7 @@
org.pamguard
Pamguard
Pamguard Java12+
- 2.02.10b
+ 2.02.10ad
Pamguard for Java 12+, using Maven to control dependcies
www.pamguard.org
diff --git a/src/PamUtils/worker/PamWorkDialog.java b/src/PamUtils/worker/PamWorkDialog.java
index b4a41d3f..4215707c 100644
--- a/src/PamUtils/worker/PamWorkDialog.java
+++ b/src/PamUtils/worker/PamWorkDialog.java
@@ -1,5 +1,6 @@
package PamUtils.worker;
+import java.awt.Dimension;
import java.awt.Window;
import javax.swing.BoxLayout;
@@ -23,6 +24,9 @@ public class PamWorkDialog extends PamDialog {
mainPanel.setBorder(new TitledBorder("Task Progress"));
// GridBagConstraints c = new PamGridBagContraints();
mainPanel.add(progressBar = new JProgressBar(0, 100));
+ Dimension sz = progressBar.getPreferredSize();
+ sz.width = 300;
+ progressBar.setPreferredSize(sz);
textRows = new PamTextDisplay[nTextRows];
for (int i = 0; i < nTextRows; i++) {
// c.gridy++;
diff --git a/src/tethys/CollectionHandler.java b/src/tethys/CollectionHandler.java
new file mode 100644
index 00000000..66208fa0
--- /dev/null
+++ b/src/tethys/CollectionHandler.java
@@ -0,0 +1,38 @@
+package tethys;
+
+abstract public class CollectionHandler {
+
+ private Collection collection;
+
+ protected TethysControl tethysControl;
+
+ /**
+ * @param tethysControl
+ * @param collection
+ */
+ public CollectionHandler(TethysControl tethysControl, Collection collection) {
+ this.tethysControl = tethysControl;
+ this.collection = collection;
+ }
+
+ public String collectionName() {
+ return collection.collectionName();
+ }
+
+ /**
+ * @return the collection
+ */
+ public Collection getCollection() {
+ return collection;
+ }
+
+ /**
+ * @return the tethysControl
+ */
+ public TethysControl getTethysControl() {
+ return tethysControl;
+ }
+
+ public abstract String getHelpPoint();
+
+}
diff --git a/src/tethys/TethysControl.java b/src/tethys/TethysControl.java
index 83e445b7..cd8bd558 100644
--- a/src/tethys/TethysControl.java
+++ b/src/tethys/TethysControl.java
@@ -469,6 +469,8 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
// case PamControllerInterface.INITIALIZATION_COMPLETE:
initializationStuff();
break;
+ case PamControllerInterface.HYDROPHONE_ARRAY_CHANGED:
+ sendStateUpdate(new TethysState(StateType.UPDATEMETADATA));
}
}
diff --git a/src/tethys/calibration/CalibrationHandler.java b/src/tethys/calibration/CalibrationHandler.java
index 37dc186e..2aff00d8 100644
--- a/src/tethys/calibration/CalibrationHandler.java
+++ b/src/tethys/calibration/CalibrationHandler.java
@@ -1,6 +1,5 @@
package tethys.calibration;
-import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -37,6 +36,7 @@ import nilus.MetadataInfo;
import nilus.QualityValueBasic;
import nilus.ResponsibleParty;
import tethys.Collection;
+import tethys.CollectionHandler;
import tethys.DocumentInfo;
import tethys.DocumentNilusObject;
import tethys.TethysControl;
@@ -52,9 +52,7 @@ import tethys.niluswraps.NilusUnpacker;
import tethys.pamdata.AutoTethysProvider;
import tethys.reporter.TethysReporter;
-public class CalibrationHandler implements TethysStateObserver {
-
- private TethysControl tethysControl;
+public class CalibrationHandler extends CollectionHandler implements TethysStateObserver {
private ArrayList> calibrationsList;
@@ -65,10 +63,14 @@ public class CalibrationHandler implements TethysStateObserver {
public static final String[] qaTypes = {"unverified", "valid", "invalid"};
private Helper nilusHelper;
+
+ public static final String helpPoint = "utilities.tethys.docs.calibrations";
+
/**
* @param tethysControl
*/
public CalibrationHandler(TethysControl tethysControl) {
+ super(tethysControl, Collection.Calibrations);
this.tethysControl = tethysControl;
calibrationsList = new ArrayList();
tethysControl.addStateObserver(this); try {
@@ -504,7 +506,7 @@ public class CalibrationHandler implements TethysStateObserver {
}
String seachPattern = makeChannelNamePart(iChan);
for (int i = 0; i < calibrationsList.size(); i++) {
- String docName = calibrationsList.get(i).getDocumentName();
+ String docName = calibrationsList.get(i).getDocumentId();
if (docName.endsWith(seachPattern)) {
return true;
}
@@ -570,4 +572,9 @@ public class CalibrationHandler implements TethysStateObserver {
}
return theseCals;
}
+
+ @Override
+ public String getHelpPoint() {
+ return helpPoint;
+ }
}
diff --git a/src/tethys/calibration/swing/CalibrationsContactCard.java b/src/tethys/calibration/swing/CalibrationsContactCard.java
index 2dc6e581..0ad03c36 100644
--- a/src/tethys/calibration/swing/CalibrationsContactCard.java
+++ b/src/tethys/calibration/swing/CalibrationsContactCard.java
@@ -5,6 +5,7 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.util.ArrayList;
import java.util.Date;
import javax.swing.BoxLayout;
@@ -18,6 +19,9 @@ import javax.xml.datatype.XMLGregorianCalendar;
import org.jdesktop.swingx.JXDatePicker;
+import Array.ArrayManager;
+import Array.Hydrophone;
+import Array.PamArray;
import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.WestAlignedPanel;
@@ -43,6 +47,8 @@ public class CalibrationsContactCard extends CalibrationsCard {
private JButton copyDown, copyUp;
+ private JComboBox hydrophoneSelection;
+
public CalibrationsContactCard(PamWizard pamWizard) {
super(pamWizard, "Contact Details");
// TODO Auto-generated constructor stub
@@ -57,17 +63,26 @@ public class CalibrationsContactCard extends CalibrationsCard {
JPanel datePanel = new JPanel(new GridBagLayout());
JPanel lp = new WestAlignedPanel(datePanel);
- lp.setBorder(new TitledBorder("Calibration date"));
+ lp.setBorder(new TitledBorder("Date and hydrophones"));
GridBagConstraints c = new PamGridBagContraints();
datePanel.add(new JLabel("Calibration date: ", JLabel.RIGHT), c);
datePicker = new JXDatePicker();
c.gridx++;
datePanel.add(datePicker, c);
- c.gridx = 0;
- c.gridy++;
- datePanel.add(new JLabel("Update Frequency", JLabel.RIGHT), c);
+// c.gridx = 0;
+ c.gridx++;
+ datePanel.add(new JLabel(" Update Frequency ", JLabel.RIGHT), c);
c.gridx++;
datePanel.add(updateInterval, c);
+ c.gridx = 0;
+ c.gridy++;
+ datePanel.add(new JLabel(" Hydrophones ", JLabel.RIGHT), c);
+ c.gridwidth = 5;
+ c.gridx++;
+ hydrophoneSelection = new JComboBox<>();
+ datePanel.add(hydrophoneSelection, c);
+ hydrophoneSelection.setToolTipText("Select which hydrophone calibrations to export");
+
calibrator = new ResponsiblePartyPanel("Technical Person");
dataManager = new ResponsiblePartyPanel("Data Manager");
@@ -202,6 +217,16 @@ public class CalibrationsContactCard extends CalibrationsCard {
datePicker.setDate(new Date(TethysTimeFuncs.millisFromGregorianXML(ts)));
}
+ hydrophoneSelection.removeAllItems();
+ hydrophoneSelection.addItem("All hydrophones");
+ PamArray array = ArrayManager.getArrayManager().getCurrentArray();
+ ArrayList phones = array.getHydrophoneArray();
+ int i = 0;
+ for (Hydrophone phone : phones) {
+ String txt = String.format("Hydrophone %d, %s, %3.1f dBre1\u00B5Pa", i, phone.getType(), phone.getSensitivity());
+ hydrophoneSelection.addItem(txt);
+ i++;
+ }
}
diff --git a/src/tethys/calibration/swing/CalibrationsExportWizard.java b/src/tethys/calibration/swing/CalibrationsExportWizard.java
index 74bb356a..1ab7bc6e 100644
--- a/src/tethys/calibration/swing/CalibrationsExportWizard.java
+++ b/src/tethys/calibration/swing/CalibrationsExportWizard.java
@@ -5,6 +5,7 @@ import java.awt.Window;
import PamView.wizard.PamWizard;
import PamView.wizard.PamWizardCard;
import nilus.Calibration;
+import tethys.calibration.CalibrationHandler;
public class CalibrationsExportWizard extends PamWizard {
@@ -13,8 +14,9 @@ public class CalibrationsExportWizard extends PamWizard {
private CalibrationsExportWizard(Window parentFrame, Calibration sampleDocument) {
super(parentFrame, "Calibrations Export");
this.sampleDocument = sampleDocument;
- addCard(new CalibrationProcessCard(this));
addCard(new CalibrationsContactCard(this));
+ addCard(new CalibrationProcessCard(this));
+ setHelpPoint(CalibrationHandler.helpPoint);
}
public static Calibration showWizard(Window parentFrame, Calibration sampleDocument) {
diff --git a/src/tethys/calibration/swing/CalibrationsMainPanel.java b/src/tethys/calibration/swing/CalibrationsMainPanel.java
index e13365ef..cd1275f7 100644
--- a/src/tethys/calibration/swing/CalibrationsMainPanel.java
+++ b/src/tethys/calibration/swing/CalibrationsMainPanel.java
@@ -15,53 +15,47 @@ import PamView.panel.PamPanel;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.calibration.CalibrationHandler;
+import tethys.deployment.PInstrument;
+import tethys.swing.TethysExportPanel;
import tethys.swing.TethysGUIPanel;
+import tethys.swing.TippedButton;
-public class CalibrationsMainPanel extends TethysGUIPanel {
+public class CalibrationsMainPanel extends TethysExportPanel {
private CalibrationHandler calibrationHandler;
private CalibrationsTable calibrationsTable;
- private JPanel mainPanel;
-
- private JPanel ctrlPanel;
-
- private JButton exportButton;
-
- private JLabel warning;
+// private JPanel mainPanel;
+//
+// private JPanel ctrlPanel;
+//
+// private TippedButton exportButton;
+//
+// private JLabel warning;
public CalibrationsMainPanel(TethysControl tethysControl, CalibrationHandler calibrationHandler) {
- super(tethysControl);
+ super(tethysControl, calibrationHandler, false);
this.calibrationHandler = calibrationHandler;
- mainPanel = new PamPanel(new BorderLayout());
+ JPanel mainPanel = getMainPanel();
+// mainPanel = new PamPanel(new BorderLayout());
mainPanel.setBorder(new TitledBorder("Instrument calibration information"));
calibrationsTable = new CalibrationsTable(tethysControl, calibrationHandler);
mainPanel.add(BorderLayout.CENTER, calibrationsTable.getComponent());
- ctrlPanel = new PamPanel(new BorderLayout());
- exportButton = new JButton("Export ...");
- ctrlPanel.add(BorderLayout.WEST, exportButton);
- warning = new JLabel();
- ctrlPanel.add(BorderLayout.CENTER, warning);
- mainPanel.add(BorderLayout.NORTH, ctrlPanel);
- exportButton.setToolTipText("Export calibration data to database");
- exportButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- exportCalibrations();
- }
- });
- }
-
- protected void exportCalibrations() {
- calibrationHandler.exportAllCalibrations();
- }
-
- @Override
- public JComponent getComponent() {
- return mainPanel;
+// ctrlPanel = new PamPanel(new BorderLayout());
+// exportButton = new TippedButton("Export ...", "Export calibration data to database");
+// ctrlPanel.add(BorderLayout.WEST, exportButton);
+// warning = new JLabel();
+// ctrlPanel.add(BorderLayout.CENTER, warning);
+// mainPanel.add(BorderLayout.NORTH, ctrlPanel);
+// exportButton.addActionListener(new ActionListener() {
+// @Override
+// public void actionPerformed(ActionEvent e) {
+// exportCalibrations();
+// }
+// });
}
@Override
@@ -71,7 +65,45 @@ public class CalibrationsMainPanel extends TethysGUIPanel {
}
private void enableControls() {
- exportButton.setEnabled(getTethysControl().isServerOk());
+ if (getTethysControl().isServerOk() == false) {
+ disableExport("Tethys Server not running");
+ return;
+ }
+ if (isHydrophoneNamed() == false) {
+ disableExport("Can't export calibrations until the Hydrophone array has been correctly named");
+ return;
+ };
+ enableExport(true);
+ }
+
+ /**
+ * Check to see if hydrophone is named correctly.
+ * @return
+ */
+ private boolean isHydrophoneNamed() {
+ PInstrument currentInstrument = getTethysControl().getDeploymentHandler().getCurrentArrayInstrument();
+ if (currentInstrument == null) {
+ return false;
+ }
+ if (currentInstrument.instrumentId == null || currentInstrument.instrumentType == null) {
+ return false;
+ }
+
+ if (currentInstrument.instrumentId.length() == 0 || currentInstrument.instrumentType.length() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void exportButtonPressed(ActionEvent e) {
+ calibrationHandler.exportAllCalibrations();
+ }
+
+ @Override
+ protected void optionsButtonPressed(ActionEvent e) {
+ // TODO Auto-generated method stub
+
}
}
diff --git a/src/tethys/dbxml/DBXMLConnect.java b/src/tethys/dbxml/DBXMLConnect.java
index 9b12ecd5..1da977f0 100644
--- a/src/tethys/dbxml/DBXMLConnect.java
+++ b/src/tethys/dbxml/DBXMLConnect.java
@@ -3,14 +3,17 @@ package tethys.dbxml;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.nio.file.Files;
import java.util.ArrayList;
+import java.util.zip.GZIPOutputStream;
import javax.xml.bind.JAXBException;
@@ -67,7 +70,7 @@ public class DBXMLConnect {
}
return true;
}
-
+
/**
* Get the client. The client will only be recreated if the url changes
@@ -113,9 +116,9 @@ public class DBXMLConnect {
}
return file;
}
-
+
/**
- * Create a temporary nilus file.
+ * Create a temporary nilus file.
* @param nilusObject
* @return
* @throws TethysException
@@ -124,20 +127,20 @@ public class DBXMLConnect {
String tempName = getTempFileName(nilusObject);
tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml";
File tempFile = new File(tempName);
- File retFile = createXMLDocument(nilusObject, tempFile);
+ File retFile = createXMLDocument(nilusObject, tempFile);
retFile.deleteOnExit();
return retFile;
}
-
-
+
+
public boolean postAndLog(Object nilusObject) throws TethysException
{
return postAndLog(nilusObject, null);
}
-
+
/**
* I don't think this should ever be used since everything goes a bit pear
- * shaped if the documentName isn't the same as the Id. However, for Calibration
+ * shaped if the documentName isn't the same as the Id. However, for Calibration
* documents this is no longer the case, since a Calibration can have multiple
* entries on different dates, so allow it !
* @param nilusObject
@@ -145,11 +148,11 @@ public class DBXMLConnect {
* @return
* @throws TethysException
*/
- public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
- {
+ public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
+ {
boolean ok = NilusChecker.warnEmptyFields(tethysControl.getGuiFrame(), nilusObject);
-
-
+
+
TethysException e = null;
boolean success = false;
try {
@@ -168,13 +171,13 @@ public class DBXMLConnect {
}
return success;
}
-
+
/**
* take a nilus object loaded with PamGuard data and post it to the Tethys database
*
* @param pamGuardObjs a nilus object loaded with PamGuard data
* @return error string, null string means there are no errors
- * @throws TethysException
+ * @throws TethysException
*/
private boolean postToTethys(Object nilusObject, String documentName) throws TethysException
{
@@ -192,12 +195,35 @@ public class DBXMLConnect {
MarshalXML marshal = new MarshalXML();
marshal.createInstance(objClass);
marshal.marshal(nilusObject, tempFile.toString());
+ // above lines have made a file. Are now going to gzip it before sending to Tethys
+ File zipFile = null;
+ try {
+ zipFile = zipOutputFile(tempFile);
+ }
+ catch (FileNotFoundException e1){
+ System.out.println(e1.getMessage());
+ }
+ catch (IOException e2) {
+ System.out.println(e2.getMessage());
+ }
+ String finalName;
+ if (zipFile == null) {
+ finalName = bodgeName;
+ }
+ else {
+ finalName = zipFile.toString();
+ }
+
+
// tempFile = stripXMLHeader(tempFile);
importReturn = Importer.ImportFiles(params.getFullServerName(), collection.collectionName(),
- new String[] { bodgeName }, "", "", false);
+ new String[] { finalName }, "", "", false);
tempFile.deleteOnExit();
+ if (zipFile != null) {
+ zipFile.deleteOnExit();
+ }
} catch(IllegalArgumentException e) {
throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null);
} catch (IOException e) {
@@ -207,21 +233,49 @@ public class DBXMLConnect {
}
/*
- * The returned string consists of the file name, then an XML report.
- * Quite hard to see much common structure in this, so just look for
+ * The returned string consists of the file name, then an XML report.
+ * Quite hard to see much common structure in this, so just look for
* two words, and
*/
boolean error = importReturn.contains("");
String name = tempFile.getName();
TethysReporter.getTethysReporter().addReport(new TethysReport(success, collection, name, name));
-// error = !success; might be a better options.
+// error = !success; might be a better options.
if (error) {
throw new TethysException("Error posting to Tethys", importReturn);
}
return success;
}
+ /**
+ * Zip an xml file (or any file) into a gz file with a new end
+ * @param xmlFile
+ * @return
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ private File zipOutputFile(File xmlFile) throws FileNotFoundException, IOException {
+ String zipName = xmlFile.toString() + "-temp-.gz";
+ File zipFile = new File(zipName);
+ GZIPOutputStream opStream = new GZIPOutputStream(new FileOutputStream(zipFile));
+ InputStream fis = new FileInputStream(xmlFile);
+ int chunkSize = 100*1024;
+ byte[] buffer = new byte[chunkSize];
+// ZipEntry zipEntry = new ZipEntry(xmlFile.getName());
+ int bytesRead;
+ while ((bytesRead = fis.read(buffer)) >= 0) {
+ opStream.write(buffer, 0, bytesRead);
+ }
+
+ opStream.close();
+
+ fis.close();
+
+
+ return zipFile;
+ }
+
/**
* Update a document within Tethys. We're assuming that a
* document with the same name in the same collection already
@@ -229,7 +283,7 @@ public class DBXMLConnect {
* the removedocument function
* @param nilusDocument
* @return
- * @throws TethysException
+ * @throws TethysException
*/
public boolean updateDocument(Object nilusDocument) throws TethysException {
deleteDocument(nilusDocument);
@@ -242,7 +296,7 @@ public class DBXMLConnect {
* class to identify the correct collection.
* @param nilusDocument
* @return
- * @throws TethysException
+ * @throws TethysException
*/
public boolean deleteDocument(Object nilusDocument) throws TethysException {
@@ -259,7 +313,7 @@ public class DBXMLConnect {
- ['ECoastNARW0']
-An error will throw an exception.
+An error will throw an exception.
*/
}
catch (Exception e) {
@@ -275,7 +329,7 @@ An error will throw an exception.
* Delete a Deploymnet and any contained Detections document. Doesn't work !
* @param deploymentId
* @return
- * @throws TethysException
+ * @throws TethysException
*/
public boolean deleteDeployment(String deploymentId) throws TethysException {
ArrayList detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(deploymentId);
@@ -292,8 +346,8 @@ An error will throw an exception.
}
/**
- * Remove a document based on a collection name and a cdocument Id.
- * @param collection collection name.
+ * Remove a document based on a collection name and a cdocument Id.
+ * @param collection collection name.
* @param documentName document name (not the internal Document Id)
* @return
* @throws TethysException
@@ -303,8 +357,8 @@ An error will throw an exception.
}
/**
- * Remove a document based on a collection name and a document namw.
- * @param collectionName collection name.
+ * Remove a document based on a collection name and a document namw.
+ * @param collectionName collection name.
* @param documentName document name (not the internal Document Id)
* @return
* @throws TethysException
@@ -319,7 +373,7 @@ An error will throw an exception.
- ['ECoastNARW0']
- An error will throw an exception.
+ An error will throw an exception.
*/
}
catch (Exception e) {
@@ -330,14 +384,14 @@ An error will throw an exception.
}
/**
- * check the return string from importFiles and if it's an
- * error, throw an exception. Otherwise do nothing.
+ * check the return string from importFiles and if it's an
+ * error, throw an exception. Otherwise do nothing.
* @param fileError
*/
private void checkReturnString(String fileError) {
/**
* Example good string is
- *
+ *
C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xml: 7360 bytes
@@ -367,7 +421,7 @@ C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 b
/**
* Seems we have to get rid of the line
- * which is being put there by the marshaller ?
+ * which is being put there by the marshaller ?
* @param tempFile
*/
private File stripXMLHeader(File tempFile) {
@@ -377,7 +431,7 @@ C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 b
try {
BufferedReader reader = new BufferedReader(new FileReader(tempFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempTemp));
- String line = reader.readLine();
+ String line = reader.readLine();
while (line != null) {
// see if the line has any unicode in it
int len = line.length();
diff --git a/src/tethys/dbxml/DBXMLQueries.java b/src/tethys/dbxml/DBXMLQueries.java
index 460fbc66..d4c0be9a 100644
--- a/src/tethys/dbxml/DBXMLQueries.java
+++ b/src/tethys/dbxml/DBXMLQueries.java
@@ -515,6 +515,9 @@ public class DBXMLQueries {
* first query for Detections documents associated with this deployment and datablock.
* updated May 23
*/
+ if (dataBlock == null) {
+ return null;
+ }
String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}";
String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}";
String query;
diff --git a/src/tethys/deployment/DeploymentHandler.java b/src/tethys/deployment/DeploymentHandler.java
index 0c435fc0..8d82ac48 100644
--- a/src/tethys/deployment/DeploymentHandler.java
+++ b/src/tethys/deployment/DeploymentHandler.java
@@ -73,6 +73,7 @@ import nilus.UnknownSensor;
import pamMaths.PamVector;
import pamMaths.STD;
import tethys.Collection;
+import tethys.CollectionHandler;
import tethys.TethysControl;
import tethys.TethysLocationFuncs;
import tethys.TethysState;
@@ -83,6 +84,7 @@ import tethys.TethysState.StateType;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.deployment.swing.DeploymentWizard;
+import tethys.deployment.swing.EffortProblemDialog;
import tethys.deployment.swing.RecordingGapDialog;
import tethys.niluswraps.PDeployment;
import tethys.output.TethysExportParams;
@@ -98,16 +100,9 @@ import tethys.swing.DeploymentTableObserver;
* @author dg50
*
*/
-public class DeploymentHandler implements TethysStateObserver, DeploymentTableObserver {
+public class DeploymentHandler extends CollectionHandler implements TethysStateObserver, DeploymentTableObserver {
- private TethysControl tethysControl;
-
- /**
- * @return the tethysControl
- */
- public TethysControl getTethysControl() {
- return tethysControl;
- }
+// private TethysControl tethysControl;
private EffortFunctions effortFunctions;
@@ -119,8 +114,11 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
private DeploymentExportOpts deploymentExportOptions = new DeploymentExportOpts();
+ public static final String helpPoint = "utilities.tethys.docs.deployments";
+
public DeploymentHandler(TethysControl tethysControl) {
- super();
+
+ super(tethysControl, Collection.Deployments);
this.tethysControl = tethysControl;
@@ -368,8 +366,39 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
public void createPamguardOverview() {
deploymentOverview = effortFunctions.makeRecordingOverview();
+
+ checkDeploymentOverview(deploymentOverview);
+
updateProjectDeployments();
matchPamguard2Tethys(deploymentOverview, projectDeployments);
+
+ tethysControl.sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION));
+ }
+
+ /**
+ * Check the deployment overview for consistency.
+ * Take the raw audio information and the binary information and check they are similar.
+ * if not, ask the user what to do.
+ * @param deploymentOverview
+ */
+ private void checkDeploymentOverview(DeploymentOverview overview) {
+ RecordingList rawList = overview.getRawDataList();
+ RecordingList binList = overview.getBinaryDataList();
+ if (rawList == null || binList == null) {
+ return; // nothing to do
+ }
+ double similarity = rawList.getSimilarity(binList);
+ if (similarity > 0.95) {
+ return;
+ }
+ /*
+ * if we get here, it seems like the two lists are very different, so
+ * show a dialog to ask the user what to do.
+ */
+ RecordingList selList = EffortProblemDialog.showDialog(tethysControl.getGuiFrame(), overview);
+ if (selList != null) {
+ tethysControl.getTethysExportParams().setEffortSourceName(selList.getSourceName());
+ }
}
/**
@@ -381,22 +410,22 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
if (exportOptions != null) {
this.deploymentExportOptions = exportOptions;
deploymentOverview = getDeploymentOverview();
- ArrayList allPeriods = deploymentOverview.getRecordingPeriods();
+ RecordingList allPeriods = deploymentOverview.getMasterList(getTethysControl());
exportDeployments(allPeriods);
}
}
/**
* Export deployments docs. Playing with a couple of different ways of doing this.
- * @param selectedDeployments
+ * @param allPeriods
*/
- public void exportDeployments(ArrayList selectedDeployments) {
+ public void exportDeployments(RecordingList allPeriods) {
TethysReporter.getTethysReporter().clear();
if (deploymentExportOptions.separateDeployments) {
- exportSeparateDeployments(selectedDeployments);
+ exportSeparateDeployments(allPeriods);
}
else {
- exportOneDeploymnet(selectedDeployments);
+ exportOneDeploymnet(allPeriods);
}
TethysReporter.getTethysReporter().showReport(tethysControl.getGuiFrame(), true);
}
@@ -404,7 +433,7 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
/**
* Make one big deployment document with all the recording periods in it.
*/
- private void exportOneDeploymnet(ArrayList selectedDeployments) {
+ private void exportOneDeploymnet(RecordingList recordingList) {
// do the lot, whatever ...
Float sampleRate = null;
AcquisitionControl daq = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
@@ -414,10 +443,9 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
sampleRate = daqParams.sampleRate;
}
- selectedDeployments = getDeploymentOverview().getRecordingPeriods();
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
- RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(),
- selectedDeployments.get(selectedDeployments.size()-1).getRecordStop());
+ RecordingPeriod onePeriod = new RecordingPeriod(recordingList.getStart(),
+ recordingList.getEnd());
TethysExportParams exportParams = tethysControl.getTethysExportParams();
String id = String.format("%s_%s", exportParams.getDatasetName(), "all");
Deployment deployment = createDeploymentDocument(freeId, onePeriod, id);
@@ -425,7 +453,8 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
deployment.setCruise(globalMeta.getCruise());
deployment.setSite(globalMeta.getSite());
- if (selectedDeployments.size() > 1) {
+ ArrayList effortPeriods = recordingList.getEffortPeriods();
+ if (recordingList.size() > 1) {
// // now need to remove the sampling details - don't though, add invalid periods instead.
// SamplingDetails samplingDetails = deployment.getSamplingDetails();
// samplingDetails.getChannel().clear();
@@ -440,9 +469,9 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
deployment.setQualityAssurance(qa = new AcousticDataQAType());
}
List qualityList = qa.getQuality();
- for (int i = 1; i < selectedDeployments.size(); i++) {
- long end = selectedDeployments.get(i-1).getRecordStop();
- long start = selectedDeployments.get(i).getRecordStart();
+ for (int i = 1; i < recordingList.size(); i++) {
+ long end = effortPeriods.get(i-1).getRecordStop();
+ long start = effortPeriods.get(i).getRecordStart();
Quality q = new Quality();
q.setStart(TethysTimeFuncs.xmlGregCalFromMillis(end));
q.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(start));
@@ -479,14 +508,15 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
/**
* Make a separate deployment document for every recording period.
*/
- private void exportSeparateDeployments(ArrayList selectedDeployments) {
+ private void exportSeparateDeployments(RecordingList recordingList) {
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
// fill in a few things from here
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
TethysExportParams exportParams = tethysControl.getTethysExportParams();
- for (int i = 0; i < selectedDeployments.size(); i++) {
- RecordingPeriod recordPeriod = selectedDeployments.get(i);
+ ArrayList effortPeriods = recordingList.getEffortPeriods();
+ for (int i = 0; i < recordingList.size(); i++) {
+ RecordingPeriod recordPeriod = effortPeriods.get(i);
PDeployment exDeploymnet = recordPeriod.getMatchedTethysDeployment();
Deployment deployment = null;
String id = String.format("%s_%d", exportParams.getDatasetName(), i);
@@ -532,8 +562,9 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
if (deployments == null || deploymentOverview == null) {
return;
}
- ArrayList recordingPeriods = deploymentOverview.getRecordingPeriods();
- for (RecordingPeriod aPeriod : recordingPeriods) {
+ RecordingList recordingList = deploymentOverview.getMasterList(getTethysControl());
+ ArrayList effortPeriods = recordingList.getEffortPeriods();
+ for (RecordingPeriod aPeriod : effortPeriods) {
PDeployment closestDeployment = findClosestDeployment(aPeriod, deployments);
aPeriod.setMatchedTethysDeployment(closestDeployment);
if (closestDeployment != null) {
@@ -592,7 +623,8 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
if (deploymentOverview == null) {
return matched;
}
- for (RecordingPeriod period : deploymentOverview.getRecordingPeriods()) {
+ ArrayList effortPeriods = deploymentOverview.getMasterList(getTethysControl()).getEffortPeriods();
+ for (RecordingPeriod period : effortPeriods) {
PDeployment deployment = period.getMatchedTethysDeployment();
if (deployment != null) {
if (matched.contains(deployment) == false) {
@@ -1230,7 +1262,8 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
}
regimens.add(regimen);
- DutyCycleInfo dutyCycleInf = deploymentOverview.getDutyCycleInfo();
+ RecordingList recordingList = deploymentOverview.getMasterList(getTethysControl());
+ DutyCycleInfo dutyCycleInf = recordingList.assessDutyCycle();
boolean isDS = dutyCycleInf != null && dutyCycleInf.isDutyCycled;
if (isDS) {
DutyCycle dutyCycle = new DutyCycle();
@@ -1307,4 +1340,9 @@ public class DeploymentHandler implements TethysStateObserver, DeploymentTableOb
return deploymentExportOptions;
}
+ @Override
+ public String getHelpPoint() {
+ return helpPoint;
+ }
+
}
diff --git a/src/tethys/deployment/DeploymentOverview.java b/src/tethys/deployment/DeploymentOverview.java
index f296df8e..3f39c653 100644
--- a/src/tethys/deployment/DeploymentOverview.java
+++ b/src/tethys/deployment/DeploymentOverview.java
@@ -1,16 +1,6 @@
package tethys.deployment;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.ListIterator;
-
-import Acquisition.AcquisitionControl;
-import Acquisition.AcquisitionParameters;
-import Acquisition.DaqStatusDataUnit;
-import PamController.PamControlledUnit;
-import PamController.PamController;
-import PamguardMVC.PamDataBlock;
+import tethys.TethysControl;
/**
* Class to give a general overview of all the effort in PAMGuard which will form the
@@ -22,59 +12,83 @@ import PamguardMVC.PamDataBlock;
*/
public class DeploymentOverview {
- private ArrayList recordingPeriods = new ArrayList<>();
+ private RecordingList rawDataList;
- private DutyCycleInfo dutyCycleInfo;
+ private RecordingList binaryDataList;
+
+// private DutyCycleInfo dutyCycleInfo;
- public DeploymentOverview(DutyCycleInfo dutyCycleInfo) {
- super();
- this.dutyCycleInfo = dutyCycleInfo;
- }
+// public DeploymentOverview(DutyCycleInfo dutyCycleInfo) {
+// super();
+// this.dutyCycleInfo = dutyCycleInfo;
+// }
- public DeploymentOverview(DutyCycleInfo dutyCycleInfo, ArrayList tempPeriods) {
- this.dutyCycleInfo = dutyCycleInfo;
- this.recordingPeriods = tempPeriods;
- }
-
-
- public void addRecordingPeriod(long start, long stop) {
- addRecordingPeriod(new RecordingPeriod(start, stop));
+ public DeploymentOverview(DutyCycleInfo dutyCycleInfo, RecordingList rawDataList, RecordingList binaryDataList) {
+// this.dutyCycleInfo = dutyCycleInfo;
+ this.rawDataList = rawDataList;
+ this.binaryDataList = binaryDataList;
}
- private void addRecordingPeriod(RecordingPeriod recordingPeriod) {
- recordingPeriods.add(recordingPeriod);
+ /**
+ * @return the rawDataList
+ */
+ public RecordingList getRawDataList() {
+ return rawDataList;
}
- public ArrayList getRecordingPeriods() {
- return recordingPeriods;
+ /**
+ * @return the binaryDataList
+ */
+ public RecordingList getBinaryDataList() {
+ return binaryDataList;
}
- public DutyCycleInfo getDutyCycleInfo() {
- return dutyCycleInfo;
+// /**
+// * @return the dutyCycleInfo
+// */
+// public DutyCycleInfo getDutyCycleInfo() {
+// return dutyCycleInfo;
+// }
+
+ public RecordingList getMasterList(TethysControl tethysControl) {
+ return getMasterList(tethysControl.getTethysExportParams().getEffortSourceName());
+ }
+
+ public RecordingList getMasterList(String effortSourceName) {
+ if (effortSourceName == null) {
+ return getLongestList();
+ }
+ if (binaryDataList != null & binaryDataList.getSourceName().equals(effortSourceName)) {
+ return binaryDataList;
+ }
+ if (rawDataList != null & rawDataList.getSourceName().equals(effortSourceName)) {
+ return rawDataList;
+ }
+ return getLongestList();
}
/**
- * Get the start time of the first recording
+ * Get the recording list with the greatest duration (start to end)
+ * not looking at coverage between those times.
* @return
*/
- public Long getFirstStart() {
- if (recordingPeriods.size() > 0) {
- return recordingPeriods.get(0).getRecordStart();
+ public RecordingList getLongestList() {
+ if (binaryDataList == null) {
+ return rawDataList;
}
- return null;
- }
-
- /**
- * Get the end time of the last recording
- * @return
- */
- public Long getLastEnd() {
- if (recordingPeriods.size() > 0) {
- return recordingPeriods.get(recordingPeriods.size()-1).getRecordStop();
+ if (rawDataList == null) {
+ return binaryDataList;
+ }
+ long lRaw = rawDataList.duration();
+ long lBin = binaryDataList.duration();
+
+ if (lRaw > lBin) {
+ return rawDataList;
+ }
+ else {
+ return binaryDataList;
}
- return null;
}
-
-
+
}
diff --git a/src/tethys/deployment/EffortFunctions.java b/src/tethys/deployment/EffortFunctions.java
index 2fd8f383..b7e5b260 100644
--- a/src/tethys/deployment/EffortFunctions.java
+++ b/src/tethys/deployment/EffortFunctions.java
@@ -41,36 +41,40 @@ public class EffortFunctions {
this.tethysControl = tethysControl;
}
- private DeploymentOverview createOverview(RecordingList tempPeriods) {
-
- DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods);
- if (dutyCycleinfo == null) {
- return null;
- }
-
- // if it's duty cycles, then we only want a single entry.
- RecordingList deploymentPeriods;
- if (dutyCycleinfo.isDutyCycled == false) {
- deploymentPeriods = tempPeriods;
- }
- else {
- deploymentPeriods = new RecordingList();
- deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop()));
- }
- /*
- * do another sort of the deploymentPeriods. The start stops were in the order they went into the
- * database in the hope that pairs were the right way round. Now check all data are/
- */
- Collections.sort(deploymentPeriods, new Comparator() {
- @Override
- public int compare(RecordingPeriod o1, RecordingPeriod o2) {
- return (int) (o1.getRecordStart()-o2.getRecordStart());
- }
- });
-
- DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods);
- return deploymentOverview;
- }
+// private DeploymentOverview createOverview(RecordingList tempPeriods) {
+//
+// tempPeriods.sort();
+//
+// DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods);
+// if (dutyCycleinfo == null) {
+// return null;
+// }
+//
+//
+// // if it's duty cycles, then we only want a single entry.
+// RecordingList deploymentPeriods;
+// if (dutyCycleinfo.isDutyCycled == false) {
+// deploymentPeriods = tempPeriods;
+// }
+// else {
+// deploymentPeriods = new RecordingList(tempPeriods.getSourceName());
+// deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop()));
+// }
+// /*
+// * do another sort of the deploymentPeriods. The start stops were in the order they went into the
+// * database in the hope that pairs were the right way round. Now check all data are/
+// */
+// deploymentPeriods.sort();
+//// Collections.sort(deploymentPeriods, new Comparator() {
+//// @Override
+//// public int compare(RecordingPeriod o1, RecordingPeriod o2) {
+//// return (int) (o1.getRecordStart()-o2.getRecordStart());
+//// }
+//// });
+//
+// DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods);
+// return deploymentOverview;
+// }
public DeploymentOverview makeRecordingOverview() {
@@ -79,13 +83,18 @@ public class EffortFunctions {
RecordingList binaryPeriods = listBinaryFiles();
- long l1 = listDuration(recordingPeriods);
- long l2 = listDuration(binaryPeriods);
- if (listDuration(binaryPeriods) > listDuration(recordingPeriods)) {
- recordingPeriods = binaryPeriods;
- }
+ // see what the similarity is between them
+// double sim = recordingPeriods.getSimilarity(binaryPeriods);
+// double testSim = recordingPeriods.getSimilarity(recordingPeriods);
- DeploymentOverview deploymentOverview = createOverview(recordingPeriods);
+// long l1 = listDuration(recordingPeriods);
+// long l2 = listDuration(binaryPeriods);
+// if (listDuration(binaryPeriods) > listDuration(recordingPeriods)) {
+// recordingPeriods = binaryPeriods;
+// }
+//
+// DeploymentOverview deploymentOverview = createOverview(recordingPeriods);
+ DeploymentOverview deploymentOverview = new DeploymentOverview(null, recordingPeriods, binaryPeriods);
return deploymentOverview;
}
@@ -128,7 +137,8 @@ public class EffortFunctions {
}
}
}
- bestList = mergeRecordings(bestList);
+ DeploymentExportOpts exportOptions = tethysControl.getDeploymentHandler().getDeploymentExportOptions();
+ bestList.mergeRecordingPeriods(exportOptions.maxRecordingGapSeconds*1000);
return bestList;
}
@@ -138,7 +148,7 @@ public class EffortFunctions {
if (mapPoints == null) {
return null;
}
- RecordingList periods = new RecordingList();
+ RecordingList periods = new RecordingList(dataMap.getDataMapName());
for (OfflineDataMapPoint mapPoint : mapPoints) {
periods.add(new RecordingPeriod(mapPoint.getStartTime(), mapPoint.getEndTime()));
}
@@ -219,117 +229,60 @@ public class EffortFunctions {
// PamCalendar.formatDBDateTime(aP.getRecordStop()));
// }
- tempPeriods = mergeRecordings(tempPeriods);
-
- return tempPeriods;
- }
-
- /**
- * Merge close recordings and discard ones that are too short.
- * @param tempPeriods all recording periods, may be from consecutive files.
- * @return merged list.
- */
- private RecordingList mergeRecordings(RecordingList tempPeriods) {
- // now go through those and merge into longer periods where there is no gap between files.
- if (tempPeriods == null) {
- return null;
- }
-
+ tempPeriods.sort();
DeploymentExportOpts exportOptions = tethysControl.getDeploymentHandler().getDeploymentExportOptions();
-
- ListIterator iterator = tempPeriods.listIterator();
- RecordingPeriod prevPeriod = null;
- while (iterator.hasNext()) {
- RecordingPeriod nextPeriod = iterator.next();
- long nextDur = nextPeriod.getRecordStop()-nextPeriod.getRecordStart();
- if (nextDur == 0) {
- continue;
- }
- if (prevPeriod != null) {
- long gap = nextPeriod.getRecordStart() - prevPeriod.getRecordStop();
- long prevDur = prevPeriod.getRecordStop()-prevPeriod.getRecordStart();
- if (gap < exportOptions.maxRecordingGapSeconds*1000) {
- // ignoring up to 3s gap or a sample error < 2%.Dunno if this is sensible or not.
- prevPeriod.setRecordStop(nextPeriod.getRecordStop());
- iterator.remove();
- nextPeriod = prevPeriod;
- }
- }
- prevPeriod = nextPeriod;
- }
- // now remove ones which are too short even after merging.
- iterator = tempPeriods.listIterator();
- while (iterator.hasNext()) {
- RecordingPeriod nextPeriod = iterator.next();
- long duration = nextPeriod.getDuration();
- if (duration < exportOptions.minRecordingLengthSeconds*1000L) {
- iterator.remove();
- }
- }
+ tempPeriods.mergeRecordingPeriods(exportOptions.maxRecordingGapSeconds*1000);
return tempPeriods;
}
- /**
- * Work out whether or not the data are evenly duty cycled by testing the
- * distributions of on and off times.
- * @param tempPeriods
- * @return
- */
- private DutyCycleInfo assessDutyCycle(RecordingList tempPeriods) {
- if (tempPeriods == null) {
- return null;
- }
- int n = tempPeriods.size();
- if (n < 2) {
- return new DutyCycleInfo(false, 0,0,n);
- }
- double[] ons = new double[n-1]; // ignore the last one since it may be artificially shortened which is OK
- double[] gaps = new double[n-1];
- for (int i = 0; i < n-1; i++) {
- ons[i] = tempPeriods.get(i).getDuration()/1000.;
- gaps[i] = (tempPeriods.get(i+1).getRecordStart()-tempPeriods.get(i).getRecordStop())/1000.;
- }
- /* now look at how consistent those values are
- * But some data gets messed by small gaps, so want to
- * remove outliers and concentrate on say 80% of the data.
- */
- ons = getDistributionCentre(ons, 80);
- gaps = getDistributionCentre(gaps, 80);
- Arrays.sort(gaps);
+// /**
+// * Merge close recordings and discard ones that are too short.
+// * @param tempPeriods all recording periods, may be from consecutive files.
+// * @return merged list.
+// */
+// private RecordingList mergeRecordings(RecordingList tempPeriods) {
+// // now go through those and merge into longer periods where there is no gap between files.
+// if (tempPeriods == null) {
+// return null;
+// }
+//
+// DeploymentExportOpts exportOptions = tethysControl.getDeploymentHandler().getDeploymentExportOptions();
+//
+// ListIterator iterator = tempPeriods.listIterator();
+// RecordingPeriod prevPeriod = null;
+// while (iterator.hasNext()) {
+// RecordingPeriod nextPeriod = iterator.next();
+// long nextDur = nextPeriod.getRecordStop()-nextPeriod.getRecordStart();
+// if (nextDur == 0) {
+// continue;
+// }
+// if (prevPeriod != null) {
+// long gap = nextPeriod.getRecordStart() - prevPeriod.getRecordStop();
+// long prevDur = prevPeriod.getRecordStop()-prevPeriod.getRecordStart();
+// if (gap < exportOptions.maxRecordingGapSeconds*1000) {
+// // ignoring up to 3s gap or a sample error < 2%.Dunno if this is sensible or not.
+// prevPeriod.setRecordStop(nextPeriod.getRecordStop());
+// iterator.remove();
+// nextPeriod = prevPeriod;
+// }
+// }
+// prevPeriod = nextPeriod;
+// }
+// // now remove ones which are too short even after merging.
+// iterator = tempPeriods.listIterator();
+// while (iterator.hasNext()) {
+// RecordingPeriod nextPeriod = iterator.next();
+// long duration = nextPeriod.getDuration();
+// if (duration < exportOptions.minRecordingLengthSeconds*1000L) {
+// iterator.remove();
+// }
+// }
+//
+// return tempPeriods;
+// }
- STD std = new STD();
- double onsMean = std.getMean(ons);
- double onsSTD = std.getSTD(ons);
- double gapsMean = std.getMean(gaps);
- double gapsSTD = std.getSTD(gaps);
- boolean dutyCycle = onsSTD/onsMean < .05 && gapsSTD/gapsMean < 0.05;
- DutyCycleInfo cycleInfo = new DutyCycleInfo(dutyCycle, onsMean, gapsMean, tempPeriods.size());
- return cycleInfo;
- }
-
- /**
- * Get the central part of a distribution without any outliers so
- * that we can get a better assessment of duty cycle.
- * @param data unsorted distribution data.
- * @param percent percentage to include (half this removed from top and bottom)
- * @return
- */
- private double[] getDistributionCentre(double[] data, double percent) {
- if (data == null) {
- return null;
- }
- Arrays.sort(data);
- int nRem = (int) Math.round(data.length * (100-percent)/200);
- int newLen = data.length-nRem*2;
- double[] subdata = Arrays.copyOfRange(data, nRem, data.length-2*nRem);
- if (subdata.length < 2) {
- return data;
- }
- return subdata;
- }
-
/**
* Get data times from any other datamap, since this will generally match the acquisition anyway
@@ -360,16 +313,17 @@ public class EffortFunctions {
return null;
}
// get the times out of it.
- RecordingList recPeriods = new RecordingList();
+ RecordingList recPeriods = new RecordingList(bestMap.getDataMapName());
List mapPoints = bestMap.getMapPoints();
for (OfflineDataMapPoint mapPoint : mapPoints) {
recPeriods.add(new RecordingPeriod(mapPoint.getStartTime(), mapPoint.getEndTime()));
+ recPeriods.add(mapPoint.getStartTime(), mapPoint.getEndTime());
}
return recPeriods;
}
private RecordingList extractTimesFromStatus(ArrayList allStatusData) {
- RecordingList tempPeriods = new RecordingList();
+ RecordingList tempPeriods = new RecordingList("Data acquisition status");
long dataStart = Long.MAX_VALUE;
long dataEnd = Long.MIN_VALUE;
Long lastStart = null;
diff --git a/src/tethys/deployment/RecordingList.java b/src/tethys/deployment/RecordingList.java
index 34b41c1d..038c0e69 100644
--- a/src/tethys/deployment/RecordingList.java
+++ b/src/tethys/deployment/RecordingList.java
@@ -1,12 +1,43 @@
package tethys.deployment;
+import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Iterator;
-public class RecordingList extends ArrayList {
+import PamUtils.PamCalendar;
+import pamMaths.STD;
+
+/**
+ * Information about periods of effort that might come from either the raw data recordings or
+ * an analysis of binary data maps.
+ * @author dg50
+ *
+ */
+public class RecordingList implements Serializable {
private static final long serialVersionUID = 1L;
+
+ private ArrayList effortPeriods = new ArrayList();
+
+ /**
+ * Name / source of this list.
+ */
+ private String sourceName;
+
+ /**
+ * @param sourceName
+ */
+ public RecordingList(String sourceName) {
+ this.sourceName = sourceName;
+ }
+
+ public RecordingList(String sourceName, ArrayList selectedDeployments) {
+ this.sourceName = sourceName;
+ this.effortPeriods = selectedDeployments;
+ }
/**
* Get the duration of the recording periods from start to end.
@@ -21,27 +52,27 @@ public class RecordingList extends ArrayList {
* @return
*/
public long getStart() {
- if (size() == 0) {
+ if (effortPeriods.size() == 0) {
return 0;
}
- return get(0).getRecordStart();
+ return effortPeriods.get(0).getRecordStart();
}
/**
* get the end of the last in the list.
*/
public long getEnd() {
- if (size() == 0) {
+ if (effortPeriods.size() == 0) {
return 0;
}
- return get(size()-1).getRecordStop();
+ return effortPeriods.get(effortPeriods.size()-1).getRecordStop();
}
/**
* Sort the list in ascending order.
*/
public void sort() {
- Collections.sort(this, new Comparator() {
+ Collections.sort(effortPeriods, new Comparator() {
@Override
public int compare(RecordingPeriod o1, RecordingPeriod o2) {
@@ -49,4 +80,172 @@ public class RecordingList extends ArrayList {
}
});
}
+
+ /**
+ * Get the coverage as a fraction. This is the sum of the individual periods divided
+ * by the start to end times
+ * @return
+ */
+ public double getCoverage() {
+ long cov = 0;
+ long durTot = 0;
+ if (effortPeriods.size() == 0) {
+ return 0;
+ }
+ Iterator it = effortPeriods.iterator();
+ while (it.hasNext()) {
+ RecordingPeriod rp = it.next();
+ cov += rp.getDuration();
+ }
+ durTot = getEnd()-getStart();
+ return (double) cov / (double) durTot;
+ }
+
+ /**
+ * Merge recording periods, with a max gap between periods in milliseconds.
+ * @param maxGap
+ * @return the number of periods removed.
+ */
+ public int mergeRecordingPeriods(long maxGap) {
+ if (effortPeriods.size() < 2) {
+ return 0;
+ }
+ Iterator it = effortPeriods.iterator();
+ RecordingPeriod prev = it.next();
+ int removed = 0;
+ while (it.hasNext()) {
+ RecordingPeriod curr = it.next();
+ if (curr.getRecordStart() - prev.getRecordStop() <= maxGap) {
+ prev.setRecordStop(curr.getRecordStop());
+ it.remove();
+ removed++;
+ }
+ else {
+ prev = curr;
+ }
+ }
+ return removed;
+ }
+
+ /**
+ * Work out whether or not the data are evenly duty cycled by testing the
+ * distributions of on and off times.
+ * @param tempPeriods
+ * @return
+ */
+ public DutyCycleInfo assessDutyCycle() {
+ if (effortPeriods == null) {
+ return null;
+ }
+ int n = effortPeriods.size();
+ if (n < 2) {
+ return new DutyCycleInfo(false, 0,0,n);
+ }
+ double[] ons = new double[n-1]; // ignore the last one since it may be artificially shortened which is OK
+ double[] gaps = new double[n-1];
+ for (int i = 0; i < n-1; i++) {
+ ons[i] = effortPeriods.get(i).getDuration()/1000.;
+ gaps[i] = (effortPeriods.get(i+1).getRecordStart()-effortPeriods.get(i).getRecordStop())/1000.;
+ }
+ /* now look at how consistent those values are
+ * But some data gets messed by small gaps, so want to
+ * remove outliers and concentrate on say 80% of the data.
+ */
+ ons = getDistributionCentre(ons, 80);
+ gaps = getDistributionCentre(gaps, 80);
+ Arrays.sort(gaps);
+
+ STD std = new STD();
+ double onsMean = std.getMean(ons);
+ double onsSTD = std.getSTD(ons);
+ double gapsMean = std.getMean(gaps);
+ double gapsSTD = std.getSTD(gaps);
+ boolean dutyCycle = onsSTD/onsMean < .05 && gapsSTD/gapsMean < 0.05;
+ DutyCycleInfo cycleInfo = new DutyCycleInfo(dutyCycle, onsMean, gapsMean, effortPeriods.size());
+ return cycleInfo;
+ }
+ /**
+ * Get the central part of a distribution without any outliers so
+ * that we can get a better assessment of duty cycle.
+ * @param data unsorted distribution data.
+ * @param percent percentage to include (half this removed from top and bottom)
+ * @return
+ */
+ private double[] getDistributionCentre(double[] data, double percent) {
+ if (data == null) {
+ return null;
+ }
+ Arrays.sort(data);
+ int nRem = (int) Math.round(data.length * (100-percent)/200);
+ int newLen = data.length-nRem*2;
+ double[] subdata = Arrays.copyOfRange(data, nRem, data.length-2*nRem);
+ if (subdata.length < 2) {
+ return data;
+ }
+ return subdata;
+ }
+
+ /**
+ * @return the sourceName
+ */
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ @Override
+ public String toString() {
+ if (effortPeriods.size() == 0) {
+ return "Empty recording list";
+ }
+ String str = String.format("%s: %s to %s, %3.1f%% coverage", getSourceName(),
+ PamCalendar.formatDBDateTime(getStart()),
+ PamCalendar.formatDBDateTime(getEnd()), getCoverage()*100);
+ return str;
+ }
+
+ /**
+ * Get similarity to another recording list. 1 = identical, 0 means not even overlapping.
+ * @param other other recording list.
+ * @return measure of similarity.
+ */
+ public double getSimilarity(RecordingList other) {
+ double sim1 = (double) other.duration() / (double) this.duration();
+ if (sim1 > 1) {
+ sim1 = 1./sim1;
+ }
+ long overlap = Math.min(other.getEnd(), this.getEnd()) - Math.max(other.getStart(), this.getStart());
+ overlap = Math.max(0, overlap);
+ long longest = Math.max(other.duration(), this.duration());
+ double sim2 = (double) overlap / (double) longest;
+
+ return Math.min(sim1, sim2);
+ }
+
+ /**
+ * Add a recording period to the list.
+ * @param recordingPeriod
+ */
+ public void add(RecordingPeriod recordingPeriod) {
+ effortPeriods.add(recordingPeriod);
+ }
+
+ /**
+ * Add a recording period to the list.
+ * @param startTime
+ * @param endTime
+ */
+ public void add(long startTime, long endTime) {
+ add (new RecordingPeriod(startTime, endTime));
+ }
+
+ public int size() {
+ return effortPeriods.size();
+ }
+
+ /**
+ * @return the effortPeriods
+ */
+ public ArrayList getEffortPeriods() {
+ return effortPeriods;
+ }
}
diff --git a/src/tethys/deployment/RecordingPeriod.java b/src/tethys/deployment/RecordingPeriod.java
index ad010827..ae985347 100644
--- a/src/tethys/deployment/RecordingPeriod.java
+++ b/src/tethys/deployment/RecordingPeriod.java
@@ -1,5 +1,6 @@
package tethys.deployment;
+import PamUtils.PamCalendar;
import tethys.niluswraps.PDeployment;
public class RecordingPeriod {
@@ -71,5 +72,11 @@ public class RecordingPeriod {
selected = !selected;
return selected;
}
+
+ @Override
+ public String toString() {
+ return String.format("%s to %s, %s", PamCalendar.formatDBDateTime(recordStart),
+ PamCalendar.formatDBDateTime(recordStop), PamCalendar.formatDuration(getDuration()));
+ }
}
diff --git a/src/tethys/deployment/swing/EffortProblemDialog.java b/src/tethys/deployment/swing/EffortProblemDialog.java
new file mode 100644
index 00000000..5fafa71b
--- /dev/null
+++ b/src/tethys/deployment/swing/EffortProblemDialog.java
@@ -0,0 +1,163 @@
+package tethys.deployment.swing;
+
+import java.awt.BorderLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Window;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.border.TitledBorder;
+
+import PamUtils.PamCalendar;
+import PamView.dialog.PamDialog;
+import PamView.dialog.PamGridBagContraints;
+import tethys.deployment.DeploymentOverview;
+import tethys.deployment.RecordingList;
+
+/**
+ * Handle problems when binary and raw effort don't add up
+ * @author dg50
+ *
+ */
+public class EffortProblemDialog extends PamDialog {
+
+ private JRadioButton useRaw, useBinary, useNeither;
+
+ private JLabel generalInfo;
+
+ private InfoSet[] infoSets = new InfoSet[2];
+
+ private RecordingList chosenList;
+
+ private DeploymentOverview deploymentOverview;
+
+ private static EffortProblemDialog singleInstance;
+
+ private static final String[] setNames = {"Raw data", "Binary data"};
+
+ private EffortProblemDialog(Window parentFrame) {
+ super(parentFrame, "Deployment Effort", false);
+ JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.setBorder(new TitledBorder("Effort information"));
+ String info = "There is a mismatch between the time period covered by the raw
"
+ + "data recordings and the time covered in the binary data.
"
+ + "Select the one you wish to use, or Cancel and sort out your data
"
+ + "prior to restarting the Tethys export process";
+ generalInfo = new JLabel(info);
+// generalInfo.setBorder(new TitledBorder("General"));
+ mainPanel.add(generalInfo, BorderLayout.NORTH);
+ JPanel botPanel = new JPanel(new GridLayout(2, 1));
+ mainPanel.add(botPanel, BorderLayout.CENTER);
+ ButtonGroup bg = new ButtonGroup();
+ for (int i = 0; i < 2; i++) {
+ GridBagConstraints c = new PamGridBagContraints();
+ JPanel subPanel = new JPanel(new GridBagLayout());
+ botPanel.add(subPanel);
+ infoSets[i] = new InfoSet(setNames[i]);
+ c.gridwidth = 2;
+ subPanel.add(infoSets[i].name, c);
+ c.gridx += c.gridwidth;
+ subPanel.add(infoSets[i].select, c);
+ c.gridx = 0;
+ c.gridy++;
+ c.gridwidth = 1;
+ subPanel.add(new JLabel("Start: ", JLabel.RIGHT), c);
+ c.gridx++;
+ subPanel.add(infoSets[i].start, c);
+ c.gridx++;
+ subPanel.add(new JLabel("End: ", JLabel.RIGHT), c);
+ c.gridx++;
+ subPanel.add(infoSets[i].end, c);
+ c.gridy++;
+ c.gridx = 0;
+ subPanel.add(new JLabel("Duration: ", JLabel.RIGHT), c);
+ c.gridx++;
+ subPanel.add(infoSets[i].duration, c);
+ c.gridx++;
+ subPanel.add(new JLabel("Coverage: ", JLabel.RIGHT), c);
+ c.gridx++;
+ subPanel.add(infoSets[i].occupancy, c);
+
+ bg.add(infoSets[i].select);
+ }
+
+ setDialogComponent(mainPanel);
+ setResizable(true);
+ }
+
+ public static RecordingList showDialog(Window parentFrame, DeploymentOverview deploymentOverview) {
+ singleInstance = new EffortProblemDialog(parentFrame);
+ singleInstance.setData(deploymentOverview);
+ singleInstance.setVisible(true);
+ return singleInstance.chosenList;
+ }
+
+ private void setData(DeploymentOverview deploymentOverview) {
+ this.deploymentOverview = deploymentOverview;
+ RecordingList rl;
+ for (int i = 0; i < 2; i++) {
+ if (i == 0) {
+ rl = deploymentOverview.getRawDataList();
+ }
+ else {
+ rl = deploymentOverview.getBinaryDataList();
+ }
+ infoSets[i].start.setText(PamCalendar.formatDBDateTime(rl.getStart()));
+ infoSets[i].end.setText(PamCalendar.formatDBDateTime(rl.getEnd()));
+ infoSets[i].duration.setText(PamCalendar.formatDuration(rl.duration()));
+ infoSets[i].occupancy.setText(String.format("%3.0f%%", rl.getCoverage()*100.));
+ }
+ invalidate();
+ pack();
+ }
+
+ @Override
+ public boolean getParams() {
+ if (infoSets[0].select.isSelected()) {
+ chosenList = deploymentOverview.getRawDataList();
+ return true;
+ }
+ if (infoSets[1].select.isSelected()) {
+ chosenList = deploymentOverview.getBinaryDataList();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void cancelButtonPressed() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void restoreDefaultSettings() {
+ // TODO Auto-generated method stub
+
+ }
+
+ private class InfoSet {
+ JLabel name, start, end, duration, occupancy;
+ JCheckBox select;
+ /**
+ *
+ */
+ public InfoSet(String name) {
+ super();
+ this.name = new JLabel(name);
+ this.start = new JLabel(" ");
+ this.end = new JLabel(" ");
+ this.select = new JCheckBox("Select " + name);
+ duration = new JLabel(" ");
+ occupancy = new JLabel(" ");
+ }
+ }
+
+}
diff --git a/src/tethys/deployment/swing/RecordingGapDialog.java b/src/tethys/deployment/swing/RecordingGapDialog.java
index 399eb3bc..9915a0e4 100644
--- a/src/tethys/deployment/swing/RecordingGapDialog.java
+++ b/src/tethys/deployment/swing/RecordingGapDialog.java
@@ -36,7 +36,7 @@ public class RecordingGapDialog extends PamDialog {
c.gridx++;
mainPanel.add(new JLabel(" seconds", JLabel.RIGHT), c);
- maxGap.setToolTipText("Maximum gap between recording periods. Periods with a gap less than this will be counted as one");
+ maxGap.setToolTipText("Maximum gap between recording periods. Sequential periods with a gap less than this will be counted as one");
minLength.setToolTipText("Minimum recording length. Recording sections shorter than this will be ignored");
setDialogComponent(mainPanel);
@@ -80,6 +80,7 @@ public class RecordingGapDialog extends PamDialog {
@Override
public void restoreDefaultSettings() {
DeploymentExportOpts defaults = new DeploymentExportOpts();
+ setParams(defaults);
}
}
diff --git a/src/tethys/detection/DetectionExportProgress.java b/src/tethys/detection/DetectionExportProgress.java
index abfa74b8..abdd0209 100644
--- a/src/tethys/detection/DetectionExportProgress.java
+++ b/src/tethys/detection/DetectionExportProgress.java
@@ -17,6 +17,7 @@ public class DetectionExportProgress {
public int exportCount;
public int skipCount;
public int state;
+ public int totalDeployments, deploymentsDone;
public DetectionExportProgress(PDeployment currentDeployment, Detections currentDetections, long lastUnitTime,
long totalUnits, int exportCount, int skipCount, int state) {
diff --git a/src/tethys/detection/DetectionsHandler.java b/src/tethys/detection/DetectionsHandler.java
index f797c8ee..5e9bc44f 100644
--- a/src/tethys/detection/DetectionsHandler.java
+++ b/src/tethys/detection/DetectionsHandler.java
@@ -11,7 +11,6 @@ import PamController.PamguardVersionInfo;
import PamModel.PamPluginInterface;
import PamUtils.PamCalendar;
import PamView.dialog.PamDialog;
-import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamProcess;
@@ -32,6 +31,7 @@ import nilus.Detections;
import nilus.GranularityEnumType;
import nilus.Helper;
import tethys.Collection;
+import tethys.CollectionHandler;
import tethys.TethysControl;
import tethys.TethysTimeFuncs;
import tethys.dbxml.DBXMLConnect;
@@ -39,7 +39,6 @@ import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.PDetections;
-import tethys.output.DatablockSynchInfo;
import tethys.output.StreamExportParams;
import tethys.output.TethysExportParams;
import tethys.pamdata.TethysDataProvider;
@@ -54,9 +53,7 @@ import tethys.swing.export.DetectionsExportWizard;
* @author dg50
*
*/
-public class DetectionsHandler {
-
- private TethysControl tethysControl;
+public class DetectionsHandler extends CollectionHandler {
public int uniqueDetectionsId=1;
public int uniqueDetectionId;
@@ -65,12 +62,14 @@ public class DetectionsHandler {
private ExportWorker exportWorker;
+ public static final String helpPoint = "utilities.tethys.docs.detect_localize";
+
/**
*
* @param tethysControl
*/
public DetectionsHandler(TethysControl tethysControl) {
- super();
+ super(tethysControl, Collection.Detections);
this.tethysControl = tethysControl;
}
@@ -296,6 +295,9 @@ public class DetectionsHandler {
viewerLoadPolicy = ViewerLoadPolicy.LOAD_UTCNORMAL;
}
GranularityHandler granularityHandler = GranularityHandler.getHandler(streamExportParams.granularity, tethysControl, dataBlock, exportParams, streamExportParams);
+ int totalMaps = 0;
+ int totalMappedPoints = 0;
+ int totalLoadedDatas = 0;
for (PDeployment deployment : deployments) {
int documentCount = 0;
prog = new DetectionExportProgress(deployment, null,
@@ -311,6 +313,7 @@ public class DetectionsHandler {
prog = new DetectionExportProgress(deployment, null,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_CANCELED);
exportObserver.update(prog);
+ break;
}
if (mapPoint.getEndTime() < deployment.getAudioStart()) {
@@ -319,10 +322,13 @@ public class DetectionsHandler {
if (mapPoint.getStartTime() >= deployment.getAudioEnd()) {
break;
}
+ totalMaps ++;
+ totalMappedPoints += mapPoint.getNDatas();
dataBlock.loadViewerData(mapPoint.getStartTime(), mapPoint.getEndTime(), null);
ArrayList dataCopy = dataBlock.getDataCopy(deployment.getAudioStart(), deployment.getAudioEnd(), true, dataSelector);
-// System.out.printf("%d loaded from %s to %s %d kept\n", dataBlock.getUnitsCount(), PamCalendar.formatDateTime(mapPoint.getStartTime()),
-// PamCalendar.formatDateTime(mapPoint.getEndTime()), dataCopy.size());
+ totalLoadedDatas += dataCopy.size();
+ System.out.printf("%d loaded from %s to %s %d kept\n", dataBlock.getUnitsCount(), PamCalendar.formatDateTime(mapPoint.getStartTime()),
+ PamCalendar.formatDateTime(mapPoint.getEndTime()), dataCopy.size());
skipCount += dataBlock.getUnitsCount() - dataCopy.size();
for (PamDataUnit dataUnit : dataCopy) {
/*
@@ -353,7 +359,9 @@ public class DetectionsHandler {
if (viewerLoadPolicy == ViewerLoadPolicy.LOAD_ALWAYS_EVERYTHING) {
break;
}
-
+ if (!activeExport) {
+ return 0;
+ }
}
Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd());
if (dets != null) {
@@ -405,10 +413,6 @@ public class DetectionsHandler {
exportObserver.update(prog);
granularityHandler.prepare(deployment.getAudioStart());
- if (currentDetections == null) {
- currentDetections = startDetectionsDocument(deployment, dataBlock, streamExportParams);
- currentDetections.getEffort().setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart()));
- }
// export everything in that deployment.
// need to loop through all map points in this interval.
List mapPoints = dataMap.getMapPoints();
@@ -417,8 +421,15 @@ public class DetectionsHandler {
prog = new DetectionExportProgress(deployment, currentDetections,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_CANCELED);
exportObserver.update(prog);
+ break;
}
+ if (currentDetections == null) {
+ // needed in inner loop in case doc gets written at 500000.
+ currentDetections = startDetectionsDocument(deployment, dataBlock, streamExportParams);
+ currentDetections.getEffort().setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart()));
+ }
+
if (mapPoint.getEndTime() < deployment.getAudioStart()) {
continue;
}
@@ -453,7 +464,7 @@ public class DetectionsHandler {
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_GATHERING);
exportObserver.update(prog);
- if (documentCount > 500000 && mapPoint != dataMap.getLastMapPoint()) {
+ if (documentCount > 50000000 && mapPoint != dataMap.getLastMapPoint()) {
prog = new DetectionExportProgress(deployment, currentDetections,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
exportObserver.update(prog);
@@ -469,8 +480,14 @@ public class DetectionsHandler {
if (viewerLoadPolicy == ViewerLoadPolicy.LOAD_ALWAYS_EVERYTHING) {
break;
}
+ if (!activeExport) {
+ break;
+ }
+ }
+
+ if (!activeExport) {
+ return DetectionExportProgress.STATE_CANCELED;
}
-
if (currentDetections != null) {
Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd());
@@ -552,7 +569,7 @@ public class DetectionsHandler {
supportSoft.setVersion(getSupportSoftwareVersion(dataBlock));
supSoft.add(supportSoft);
detections.setAlgorithm(algorithm);
- detections.setUserId("Unknown user");
+ detections.setUserId("PAMGuard user");
detections.setEffort(getDetectorEffort(deployment, dataBlock, exportParams));
return detections;
@@ -599,13 +616,16 @@ public class DetectionsHandler {
protected Integer doInBackground() throws Exception {
Integer ans = null;
try {
- int count = countDetections(dataBlock, exportParams, exportObserver);
- String msg = String.format("Do you want to go ahead and output %d %s detections to Tethys?",
- count, exportParams.granularity);
- int doit = WarnOnce.showWarning("Tethys Detections Export", msg, WarnOnce.OK_CANCEL_OPTION);
- if (doit == WarnOnce.OK_OPTION) {
+// int count = countDetections(dataBlock, exportParams, exportObserver);
+// if (activeExport == false) {
+// return 0;
+// }
+// String msg = String.format("Do you want to go ahead and output %d %s detections to Tethys?",
+// count, exportParams.granularity);
+// int doit = WarnOnce.showWarning("Tethys Detections Export", msg, WarnOnce.OK_CANCEL_OPTION);
+// if (doit == WarnOnce.OK_OPTION) {
ans = exportDetections(dataBlock, exportParams, this);
- }
+// }
}
catch (Exception e) {
e.printStackTrace();
@@ -661,4 +681,10 @@ public class DetectionsHandler {
DetectionsExportWizard.showDialog(tethysControl.getGuiFrame(), tethysControl, dataBlock);
}
+
+
+ @Override
+ public String getHelpPoint() {
+ return helpPoint;
+ }
}
diff --git a/src/tethys/localization/LocalizationHandler.java b/src/tethys/localization/LocalizationHandler.java
new file mode 100644
index 00000000..69105b5e
--- /dev/null
+++ b/src/tethys/localization/LocalizationHandler.java
@@ -0,0 +1,17 @@
+package tethys.localization;
+
+import nilus.CylindricalCoordinateType;
+import nilus.LocalizationType;
+import nilus.Localize.Effort.CoordinateReferenceSystem;
+
+public class LocalizationHandler {
+
+
+ public LocalizationType getLoc() {
+ LocalizationType lt = new LocalizationType();
+ CylindricalCoordinateType cct = new CylindricalCoordinateType();
+// cct.set
+ CoordinateReferenceSystem cr;
+ return null;
+ }
+}
diff --git a/src/tethys/niluswraps/NilusSettingsWrapper.java b/src/tethys/niluswraps/NilusSettingsWrapper.java
index 68fa9628..6cb3f0ce 100644
--- a/src/tethys/niluswraps/NilusSettingsWrapper.java
+++ b/src/tethys/niluswraps/NilusSettingsWrapper.java
@@ -129,7 +129,9 @@ public class NilusSettingsWrapper implements Serializable, Clo
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
return doc;
} catch (Exception e) {
- e.printStackTrace();
+ System.out.println(e.getMessage());
+ System.out.println("Nilus Settings wrapper - Error parsing string\n" + xmlString);
+// e.printStackTrace();
}
return null;
}
diff --git a/src/tethys/output/StreamExportParams.java b/src/tethys/output/StreamExportParams.java
index aabbff2d..ca4b18ed 100644
--- a/src/tethys/output/StreamExportParams.java
+++ b/src/tethys/output/StreamExportParams.java
@@ -98,7 +98,11 @@ public class StreamExportParams implements Serializable {
* @return
*/
public DescriptionType getNilusDetectionDescription() {
- return getDetectionDescription().getDescription();
+ WrappedDescriptionType desc = getDetectionDescription();
+ if (desc == null) {
+ return null;
+ }
+ return desc.getDescription();
}
}
diff --git a/src/tethys/output/TethysExportParams.java b/src/tethys/output/TethysExportParams.java
index 5eb129cb..a0ff683b 100644
--- a/src/tethys/output/TethysExportParams.java
+++ b/src/tethys/output/TethysExportParams.java
@@ -45,6 +45,8 @@ public class TethysExportParams implements Serializable, Cloneable{
private String datasetName;
public boolean listDocsInPamguard;
+
+ private String effortSourceName;
/**
@@ -121,6 +123,22 @@ public class TethysExportParams implements Serializable, Cloneable{
return streamParamsMap.get(longDataName);
}
+ /**
+ * Source name for type of effort.
+ * @param sourceName
+ */
+ public void setEffortSourceName(String sourceName) {
+ this.effortSourceName = sourceName;
+ }
+
+ /**
+ * Source name for type of effort.
+ * @return the effortSourceName
+ */
+ public String getEffortSourceName() {
+ return effortSourceName;
+ }
+
}
diff --git a/src/tethys/species/DataBlockSpeciesManager.java b/src/tethys/species/DataBlockSpeciesManager.java
index 7817cf82..28c89a23 100644
--- a/src/tethys/species/DataBlockSpeciesManager.java
+++ b/src/tethys/species/DataBlockSpeciesManager.java
@@ -97,7 +97,10 @@ abstract public class DataBlockSpeciesManager {
public SpeciesMapItem getSpeciesItem(T dataUnit) {
String speciesString = getSpeciesCode(dataUnit);
if (speciesString == null) {
- return getDefaultDefaultSpecies();
+ SpeciesMapItem def = getDefaultDefaultSpecies();
+ if (def != null) {
+ speciesString = def.getPamguardName();
+ }
}
DataBlockSpeciesMap speciesMap = getDatablockSpeciesMap();
if (speciesMap == null) {
@@ -127,7 +130,26 @@ abstract public class DataBlockSpeciesManager {
if (allCodes.size() == 0) {
allCodes.add("Unknown");
}
- return allCodes;
+ return makeUniqueList(allCodes);
+ }
+
+ /**
+ * Make sure all entries in an array list are unique.
+ * @param list
+ * @return updated list.
+ */
+ public ArrayList makeUniqueList(ArrayList list) {
+ if (list == null) {
+ return null;
+ }
+ ArrayList newList = new ArrayList();
+ for (String aStr : list) {
+ if (newList.contains(aStr)) {
+ continue;
+ }
+ newList.add(aStr);
+ }
+ return newList;
}
public DataBlockSpeciesMap getDatablockSpeciesMap() {
diff --git a/src/tethys/species/ITISFunctions.java b/src/tethys/species/ITISFunctions.java
index 763c99f3..252e3bb8 100644
--- a/src/tethys/species/ITISFunctions.java
+++ b/src/tethys/species/ITISFunctions.java
@@ -70,7 +70,7 @@ public class ITISFunctions {
// PAMGuardXMLPreview xmlPreview = new PAMGuardXMLPreview(null, "returned", qResult.queryResult)
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
String fDoc = pamXMLWriter.getAsString(doc, true);
- System.out.println(fDoc);
+// System.out.println(fDoc);
String tsn = dbQueries.getElementData(docEl, "tsn");
if (tsn == null) {
@@ -91,7 +91,46 @@ public class ITISFunctions {
return new TethysITISResult(itisCode, taxunit, latin, vernacular);
}
+ /**
+ * Search species codes. If the search term is a valid Integer number
+ * then it's assumed to be an ITIS code and the function should
+ * return a single map item. If it's non-integer, it's assumed to
+ * be a common or latin name search
+ * @param searchTerm
+ * @return array list of possible matches.
+ */
public ArrayList searchSpecies(String searchTerm) {
+ Integer intVal = null;
+ try {
+ intVal = Integer.valueOf(searchTerm);
+ }
+ catch (NumberFormatException e) {
+ intVal = null;
+ }
+ if (intVal != null) {
+ return searchCodes(intVal);
+ }
+ else { // assume name search
+ return searchNames(searchTerm);
+ }
+ }
+
+ private ArrayList searchCodes(Integer intCode) {
+ ArrayList mapItems = new ArrayList();
+ TethysITISResult result = getITISInformation(intCode);
+ if (result != null) {
+ mapItems.add(new SpeciesMapItem(intCode, "", "", result.getLatin(), result.getVernacular()));
+ }
+ return mapItems;
+ }
+
+ /**
+ * Search common and latin names for partial matched of the search term
+ * and return an array list of all possible matches.
+ * @param searchTerm
+ * @return
+ */
+ public ArrayList searchNames(String searchTerm) {
ArrayList items = new ArrayList();
String xQ = "let $target := \"thespeciessearchterm\" \r\n"
+ "return\r\n"
diff --git a/src/tethys/species/ITISTypes.java b/src/tethys/species/ITISTypes.java
index 771b180d..f1503c2e 100644
--- a/src/tethys/species/ITISTypes.java
+++ b/src/tethys/species/ITISTypes.java
@@ -7,8 +7,8 @@ package tethys.species;
*/
public class ITISTypes {
- public static final int OTHER = 0;
- public static final int ANTHROPOGENIC = 1;
+ public static final int OTHER = -10;
+ public static final int ANTHROPOGENIC = 1758;
public static final String getName(int code) {
switch (code) {
diff --git a/src/tethys/species/SpeciesMapItem.java b/src/tethys/species/SpeciesMapItem.java
index f1595a7a..82edd9b4 100644
--- a/src/tethys/species/SpeciesMapItem.java
+++ b/src/tethys/species/SpeciesMapItem.java
@@ -41,6 +41,14 @@ public class SpeciesMapItem implements Serializable, Cloneable {
*/
private String callType;
+ /**
+ *
+ * @param itisCode
+ * @param callType
+ * @param pamguardName
+ * @param latinName
+ * @param commonName
+ */
public SpeciesMapItem(int itisCode, String callType, String pamguardName, String latinName, String commonName) {
super();
this.itisCode = itisCode;
@@ -50,6 +58,12 @@ public class SpeciesMapItem implements Serializable, Cloneable {
this.commonName = commonName;
}
+ /**
+ *
+ * @param itisCode
+ * @param callType
+ * @param pamguardName
+ */
public SpeciesMapItem(int itisCode, String callType, String pamguardName) {
super();
this.itisCode = itisCode;
diff --git a/src/tethys/species/swing/DataBlockSpeciesDialog.java b/src/tethys/species/swing/DataBlockSpeciesDialog.java
index 3181493f..5c6ed347 100644
--- a/src/tethys/species/swing/DataBlockSpeciesDialog.java
+++ b/src/tethys/species/swing/DataBlockSpeciesDialog.java
@@ -49,16 +49,7 @@ public class DataBlockSpeciesDialog extends PamDialog {
+ "\"Other Phenomena\" (-10). "
+ "
When known, a call or sound type should "
+ "be specified (see help for more information).