From 1c11e3da15048f49c1e3268e8cd5b6e7a6e8788f Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Fri, 27 Jan 2023 11:11:02 +0000 Subject: [PATCH] DBXM Export A few functions to help find data. --- .classpath | 2 +- src/PamController/PamguardVersionInfo.java | 2 +- src/PamguardMVC/PamDataBlock.java | 26 ++ .../SweepClassifierSetPaneFX.java | 96 +++---- src/metadata/MetaDataContol.java | 14 + src/tethys/TethysControl.java | 9 + src/tethys/TethysExporter.java | 133 ---------- src/tethys/dbxml/DBXMLConnect.java | 24 ++ src/tethys/exchange/TethysExchange.java | 5 - src/tethys/output/TethysExporter.java | 244 ++++++++++++++++++ .../output/swing/TethysExportDialog.java | 24 +- src/tethys/pamdata/AutoTethysProvider.java | 42 +++ src/tethys/pamdata/TethysDataPoint.java | 18 ++ src/tethys/pamdata/TethysDataProvider.java | 32 +++ src/tethys/pamdata/TethysSchema.java | 32 +++ 15 files changed, 511 insertions(+), 192 deletions(-) delete mode 100644 src/tethys/TethysExporter.java create mode 100644 src/tethys/dbxml/DBXMLConnect.java delete mode 100644 src/tethys/exchange/TethysExchange.java create mode 100644 src/tethys/output/TethysExporter.java create mode 100644 src/tethys/pamdata/AutoTethysProvider.java create mode 100644 src/tethys/pamdata/TethysDataPoint.java create mode 100644 src/tethys/pamdata/TethysDataProvider.java create mode 100644 src/tethys/pamdata/TethysSchema.java diff --git a/.classpath b/.classpath index daee38d4..d60e2620 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,7 @@ - + diff --git a/src/PamController/PamguardVersionInfo.java b/src/PamController/PamguardVersionInfo.java index 67b45c46..072ba3de 100644 --- a/src/PamController/PamguardVersionInfo.java +++ b/src/PamController/PamguardVersionInfo.java @@ -24,7 +24,7 @@ public class PamguardVersionInfo { * PAMGuard can work with. */ static public final String minJavaVersion = "11.0.0"; - static public final String maxJavaVersion = "18.99.99"; + static public final String maxJavaVersion = "19.99.99"; /** diff --git a/src/PamguardMVC/PamDataBlock.java b/src/PamguardMVC/PamDataBlock.java index b6056e9c..f26f24c9 100644 --- a/src/PamguardMVC/PamDataBlock.java +++ b/src/PamguardMVC/PamDataBlock.java @@ -50,6 +50,8 @@ import org.w3c.dom.Element; import Acquisition.AcquisitionControl; import Acquisition.AcquisitionProcess; import pamScrollSystem.ViewLoadObserver; +import tethys.pamdata.AutoTethysProvider; +import tethys.pamdata.TethysDataProvider; import dataGram.DatagramProvider; import dataMap.BespokeDataMapGraphic; import dataMap.OfflineDataMap; @@ -64,6 +66,7 @@ import PamController.PamController; import PamController.PamControllerInterface; import PamDetection.LocContents; import PamDetection.LocalisationInfo; +import PamDetection.PamDetection; import PamUtils.PamCalendar; import PamUtils.PamUtils; import PamView.symbol.PamSymbolManager; @@ -2835,8 +2838,11 @@ public class PamDataBlock extends PamObservable { private Vector offlineDataMaps = null; private SQLLogging logging; + + private TethysDataProvider tethysDataProvider; private JSONObjectDataSource jsonDataSource; + public Vector getProcessAnnotations() { return processAannotations; @@ -3046,6 +3052,26 @@ public class PamDataBlock extends PamObservable { public SQLLogging getLogging() { return logging; } + + /** + * Gets a data provider for Tethys. These will probably need + * to be bespoke, but for now will autogenerate based on the SALLogging information. + * @return the tethysDataProvider + */ + public TethysDataProvider getTethysDataProvider() { + if (tethysDataProvider == null && PamDetection.class.isAssignableFrom(unitClass) && getLogging() != null) { + tethysDataProvider = new AutoTethysProvider(this); + } + return tethysDataProvider; + } + + /** + * Set a data provider for Tethys. + * @param tethysDataProvider the tethysDataProvider to set + */ + public void setTethysDataProvider(TethysDataProvider tethysDataProvider) { + this.tethysDataProvider = tethysDataProvider; + } final public boolean getCanLog() { return (logging != null); diff --git a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java index 477b5b78..9e8ee5c0 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java @@ -1600,22 +1600,22 @@ public class SweepClassifierSetPaneFX extends SettingsPane { p.setLayout(new GridBagLayout()); GridBagConstraints c = new PamGridBagContraints(); - c.gridx = 0; - addComponent(p, enableBearings, c); - c.gridx += c.gridwidth; - addComponent(p, bearingsExcludeBox, c); - c.gridx += c.gridwidth; - addComponent(p, new JLabel("bearings between ", JLabel.RIGHT), c); - c.gridx += c.gridwidth; - addComponent(p, minBearing, c); - c.gridx += c.gridwidth; - addComponent(p, new JLabel(" and ", JLabel.RIGHT), c); - c.gridx += c.gridwidth; - addComponent(p, maxBearing, c); - c.gridx += c.gridwidth; - addComponent(p, new JLabel("(\u00B0)", JLabel.LEFT), c); - - add(BorderLayout.WEST, p); +// c.gridx = 0; +// addComponent(p, enableBearings, c); +// c.gridx += c.gridwidth; +// addComponent(p, bearingsExcludeBox, c); +// c.gridx += c.gridwidth; +// addComponent(p, new JLabel("bearings between ", JLabel.RIGHT), c); +// c.gridx += c.gridwidth; +// addComponent(p, minBearing, c); +// c.gridx += c.gridwidth; +// addComponent(p, new JLabel(" and ", JLabel.RIGHT), c); +// c.gridx += c.gridwidth; +// addComponent(p, maxBearing, c); +// c.gridx += c.gridwidth; +// addComponent(p, new JLabel("(\u00B0)", JLabel.LEFT), c); +// +// add(BorderLayout.WEST, p); this.multiChan = checkMultiChan(); @@ -1661,21 +1661,21 @@ public class SweepClassifierSetPaneFX extends SettingsPane { return true; } - @Override - protected void enableControls() { - checkMultiChan(); - - enableBearings.setEnabled(multiChan); - bearingsExcludeBox.setEnabled(multiChan); - minBearing.setEnabled(multiChan); - maxBearing.setEnabled(multiChan); - - if (!multiChan) return; - - bearingsExcludeBox.setEnabled(enableBearings.isSelected()); - minBearing.setEnabled(enableBearings.isSelected()); - maxBearing.setEnabled(enableBearings.isSelected()); - } +// @Override +// protected void enableControls() { +// checkMultiChan(); +// +// enableBearings.setEnabled(multiChan); +// bearingsExcludeBox.setEnabled(multiChan); +// minBearing.setEnabled(multiChan); +// maxBearing.setEnabled(multiChan); +// +// if (!multiChan) return; +// +// bearingsExcludeBox.setEnabled(enableBearings.isSelected()); +// minBearing.setEnabled(enableBearings.isSelected()); +// maxBearing.setEnabled(enableBearings.isSelected()); +// } @Override protected void disbleControls(boolean disable) { @@ -1692,23 +1692,23 @@ public class SweepClassifierSetPaneFX extends SettingsPane { private boolean checkMultiChan() { boolean multiChan = false; //do we have multi-channel clicks? - if (clickControl!=null) { - int[] chanGroups = clickControl.getClickParameters().getGroupedSourceParameters().getChannelGroups(); - multiChan = false; - - if (chanGroups==null) return multiChan; - - for (int i=0; i1) { - multiChan = true; - break; - } - } - } - else multiChan = true; -// Debug.out.println("Check multi-channel: " + multiChan); +// if (clickControl!=null) { +// int[] chanGroups = clickControl.getClickParameters().getGroupedSourceParameters().getChannelGroups(); +// multiChan = false; +// +// if (chanGroups==null) return multiChan; +// +// for (int i=0; i1) { +// multiChan = true; +// break; +// } +// } +// } +// else multiChan = true; +//// Debug.out.println("Check multi-channel: " + multiChan); return multiChan; } diff --git a/src/metadata/MetaDataContol.java b/src/metadata/MetaDataContol.java index 42993911..98c60eb1 100644 --- a/src/metadata/MetaDataContol.java +++ b/src/metadata/MetaDataContol.java @@ -27,4 +27,18 @@ public class MetaDataContol extends PamControlledUnit { return deploymentSetManager.getMenuItem(parentFrame); } + /** + * @return the deploymentData + */ + public DeploymentData getDeploymentData() { + return deploymentData; + } + + /** + * @param deploymentData the deploymentData to set + */ + public void setDeploymentData(DeploymentData deploymentData) { + this.deploymentData = deploymentData; + } + } diff --git a/src/tethys/TethysControl.java b/src/tethys/TethysControl.java index f700ebb0..da74b248 100644 --- a/src/tethys/TethysControl.java +++ b/src/tethys/TethysControl.java @@ -15,6 +15,7 @@ import nilus.Deployment; import nilus.Deployment.Instrument; import tethys.output.StreamExportParams; import tethys.output.TethysExportParams; +import tethys.output.TethysExporter; import tethys.output.swing.TethysExportDialog; /** @@ -93,5 +94,13 @@ public class TethysControl extends PamControlledUnit { TethysExporter tethysExporter = new TethysExporter(this, tethysExportParams); tethysExporter.doExport(); } + + /** + * A name for any deta selectors. + * @return + */ + public String getDataSelectName() { + return getUnitName(); + } } diff --git a/src/tethys/TethysExporter.java b/src/tethys/TethysExporter.java deleted file mode 100644 index 6dc816a0..00000000 --- a/src/tethys/TethysExporter.java +++ /dev/null @@ -1,133 +0,0 @@ -package tethys; - -import java.util.ArrayList; - -import org.w3c.dom.Document; - -import PamController.PamControlledUnit; -import PamController.PamController; -import PamController.settings.output.xml.PamguardXMLWriter; -import PamguardMVC.PamDataBlock; -import generalDatabase.DBSchemaWriter; -import generalDatabase.SQLLogging; -import tethys.output.StreamExportParams; -import tethys.output.TethysExportParams; - -public class TethysExporter { - - private TethysControl tethysControl; - private TethysExportParams tethysExportParams; - - public TethysExporter(TethysControl tethysControl, TethysExportParams tethysExportParams) { - this.tethysControl = tethysControl; - this.tethysExportParams = tethysExportParams; - } - - /** - * Does the work. In reality this will need an awful lot of changing, for instance - * to provide feedback to an observer class to show progress on the display. - * @return OK if success. - */ - public boolean doExport() { - /* - * Call some general export function - */ - exportGeneralData(tethysExportParams); - /* - * go through the export params and call something for every - * data block that's enabled. - */ - ArrayList allDataBlocks = PamController.getInstance().getDataBlocks(); - for (PamDataBlock aDataBlock : allDataBlocks) { - StreamExportParams streamExportParams = tethysExportParams.getStreamParams(aDataBlock); - if (streamExportParams == null || streamExportParams.selected == false) { - continue; // not interested in this one. - } - exportDataStream(aDataBlock, tethysExportParams, streamExportParams); - } - /* - * Then do whatever else is needed to complete the document. - */ - - return true; - } - - /** - * No idea if we need this or not. May want to return something different to void, e.g. - * a reference to the main object for a tethys export. I've no idea ! - * @param tethysExportParams2 - */ - private void exportGeneralData(TethysExportParams tethysExportParams) { - // TODO Auto-generated method stub - - } - - /** - * Here is where we export data for a specific data stream to Tethys. - * - * @param aDataBlock - * @param tethysExportParams - * @param streamExportParams - */ - private void exportDataStream(PamDataBlock aDataBlock, TethysExportParams tethysExportParams, - StreamExportParams streamExportParams) { - /** - * This will probably need to be passed additional parameters and may also want to return something - * other than void in order to build a bigger Tethys document. - */ - /* - * Some examples of how to do whatever is needed to get schema and data out of PAMGuard. - */ - /* - * first we'll probably want a reference to the module containing the data. - * in principle this can't get null, since the datablock was found be searching in - * the other direction. - */ - PamControlledUnit pamControlledUnit = aDataBlock.getParentProcess().getPamControlledUnit(); - /* - * Get the XML settings for that datablock. - */ - PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); - Document doc = pamXMLWriter.writeOneModule(pamXMLWriter, System.currentTimeMillis()); - String moduleXML = null; - if (doc != null) { - // this string should be XML of all the settings for the module controlling this datablock. - moduleXML = pamXMLWriter.getAsString(doc, true); // change to false to get smaller xml - System.out.printf("Module settings for datablock %s are:\n", moduleXML); - System.out.println(moduleXML); - } - /* - * This also should never be null, because we only selected datablocks that had a database - * interface. - * Future versions may need to change this to use binary stores. This will require - * the overriding datablock to return something different to SQLLogging - probably a TethysLogging - * interface, which can probably by default just wrap the SQLLogging , but does allow the - * option of modifying behaviour and of making something work for binary stores. - */ - SQLLogging logging = aDataBlock.getLogging(); - if (logging == null) return; - /** - * From the logging, it's possible to automatically generate a XML schema. This may not - * be entirely right, but will be easy to fix. - */ - DBSchemaWriter schemaWriter = new DBSchemaWriter(); - Document schemaDoc = schemaWriter.generateDatabaseSchema(aDataBlock, logging, logging.getTableDefinition()); - String schemaXML = null; - if (schemaDoc != null) { - schemaXML = pamXMLWriter.getAsString(schemaDoc, true); - } - System.out.printf("Database schema for Module Type %s Name %s are:\n", pamControlledUnit.getUnitType(), pamControlledUnit.getUnitName()); - System.out.println(schemaXML); - - /** - * Now can go through the data. Probably, we'll want to go through all the data in - * the project, but we can hold off on that for now and just go for data that - * are in memory. We'll also have to think a lot about updating parts of the - * database which have been reprocessed - what we want to do, should eventually all - * be options set in the dialog and available within TethysExportParams - * For now though, we're just going to export data that are in memory. - */ - - } - -} diff --git a/src/tethys/dbxml/DBXMLConnect.java b/src/tethys/dbxml/DBXMLConnect.java new file mode 100644 index 00000000..154be543 --- /dev/null +++ b/src/tethys/dbxml/DBXMLConnect.java @@ -0,0 +1,24 @@ +package tethys.dbxml; + +import tethys.TethysControl; + +public class DBXMLConnect { + + private TethysControl tethysControl; + + public DBXMLConnect(TethysControl tethysControl) { + this.tethysControl = tethysControl; + } + + public boolean openDatabase() { + + return true; + } + + public void closeDatabase() { + + } + + // add whatever calls are necessary to set up schema's etc. + +} diff --git a/src/tethys/exchange/TethysExchange.java b/src/tethys/exchange/TethysExchange.java deleted file mode 100644 index 79f24ce5..00000000 --- a/src/tethys/exchange/TethysExchange.java +++ /dev/null @@ -1,5 +0,0 @@ -package tethys.exchange; - -public interface TethysExchange { -// JAXB -} diff --git a/src/tethys/output/TethysExporter.java b/src/tethys/output/TethysExporter.java new file mode 100644 index 00000000..f8d94061 --- /dev/null +++ b/src/tethys/output/TethysExporter.java @@ -0,0 +1,244 @@ +package tethys.output; + +import java.util.ArrayList; + +import org.w3c.dom.Document; + +import Acquisition.AcquisitionControl; +import Acquisition.AcquisitionProcess; +import Array.ArrayManager; +import Array.Hydrophone; +import Array.PamArray; +import Array.SnapshotGeometry; +import PamController.PamControlledUnit; +import PamController.PamController; +import PamController.settings.output.xml.PamguardXMLWriter; +import PamUtils.PamCalendar; +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamDataUnit; +import generalDatabase.DBSchemaWriter; +import generalDatabase.SQLLogging; +import metadata.MetaDataContol; +import metadata.deployment.DeploymentData; +import tethys.TethysControl; +import tethys.dbxml.DBXMLConnect; +import tethys.pamdata.TethysDataProvider; +import tethys.pamdata.TethysSchema; + +/** + * Class sitting at the centre of all operations. It will talk to PAMGuard objects to get schemas and data + * and talk to the database connection to move data out (and possibly in). Eventually, a lot of the functionality + * in here will be moved to worker threads (SwingWorker?) so that it's easy to keep dialogs alive, show + * progress for big export jobs, etc. For now though, it's a relatively simple set of function which + * we can use to a) open the database, b) check everything such as schemas, etc. c) export data and d) clean up. + * @author dg50 + * + */ +public class TethysExporter { + + private TethysControl tethysControl; + private TethysExportParams tethysExportParams; + + private DBXMLConnect dbxmlConnect; + + public TethysExporter(TethysControl tethysControl, TethysExportParams tethysExportParams) { + this.tethysControl = tethysControl; + this.tethysExportParams = tethysExportParams; + dbxmlConnect = new DBXMLConnect(tethysControl); + } + + /** + * Does the work. In reality this will need an awful lot of changing, for instance + * to provide feedback to an observer class to show progress on the display. + * @return OK if success. + */ + public boolean doExport() { + + boolean dbOK = dbxmlConnect.openDatabase(); + if (!dbOK) { + /* + * should we set up some exceptions to throw ? Can be a lot + * more informative than a simple 'false' + */ + return false; + } + + SnapshotGeometry arrayGeometry = findArrayGeometrey(); + + /* + * Call some general export function + */ + exportGeneralData(tethysExportParams); + /* + * go through the export params and call something for every + * data block that's enabled. + */ + ArrayList allDataBlocks = PamController.getInstance().getDataBlocks(); + for (PamDataBlock aDataBlock : allDataBlocks) { + StreamExportParams streamExportParams = tethysExportParams.getStreamParams(aDataBlock); + if (streamExportParams == null || streamExportParams.selected == false) { + continue; // not interested in this one. + } + exportDataStream(aDataBlock, tethysExportParams, streamExportParams); + } + /* + * Then do whatever else is needed to complete the document. + */ + + dbxmlConnect.closeDatabase(); + + return true; + } + + /** + * find Deployment data. This is stored in a separate PAMGuard module, which may not + * be present. + * @return + */ + public DeploymentData findDeploymentData() { + /** + * What to do if this isn't present or is incomplete ? Should we be showing this in the + * main export dialog at some point ? More a Q for when we make a nicer UI later in the project. + */ + MetaDataContol metaControl = (MetaDataContol) PamController.getInstance().findControlledUnit(MetaDataContol.unitType); + if (metaControl == null) { + return null; + } + else { + return metaControl.getDeploymentData(); + } + } + + public SnapshotGeometry findArrayGeometrey() { + /* + * this should never be null, but again, we might want to put some warnings + * and exception handlers in here anyway. Really just an example to show how + * to find this. We'll need to dig a bit elsewhere to get more detailed + * hydrophone information. + */ + /* + * In PAMGuard hydrophones are assigned to streamers, which can have different methods for estimating + * their positions from GPS. The geometry is a sum of xyz in the streamer and xyz in the hydrophone object + * Within a streamer, hydrophones are considered rigid relative to each other. The stremer will floow + * a choice of modesl (rigid, threading, etc) to estimate it's position relative to the GPS track. Different + * errors are used when estimating localisation errors within and between streamers. + * The Snapshot geometry sorts a lot of this out for a point in time and will give back a single object + * which is most of what we'll be wanting. + */ + PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray(); + SnapshotGeometry currentGeometry = currentArray.getSnapshotGeometry(PamCalendar.getTimeInMillis()); + /* + * The following lines of code show how to get more detailed calibration info for each + * hydrophone, but we'll have to think about the easiest way to repackage this for Tethys. + * e.g. this function could be modified to return the correct Tethys object in one go. + */ + ArrayList hydrophones = currentArray.getHydrophoneArray(); + /* + * each object in the list will have more detailed cal information for each phone. But + * for the full system calibration we'd need to go to the Acquisition module. + */ + AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType); + if (daqControl != null) { + AcquisitionProcess daqProcess = daqControl.getAcquisitionProcess(); + for (int iPhone = 0; iPhone < hydrophones.size(); iPhone++) { + Hydrophone aPhone = hydrophones.get(iPhone); + double totalCal = -daqProcess.rawAmplitude2dB(1, iPhone, false); + System.out.printf("hydrophone %d has sensitivity %3.1fdB + gain %3.1fdB. Total calibration is %3.1fdB re1U/uPa\n", + iPhone, aPhone.getSensitivity(), aPhone.getPreampGain(), totalCal); + } + } + + + return currentGeometry; + } + + /** + * No idea if we need this or not. May want to return something different to void, e.g. + * a reference to the main object for a tethys export. I've no idea ! + * @param tethysExportParams2 + */ + private void exportGeneralData(TethysExportParams tethysExportParams) { + // TODO Auto-generated method stub + + } + + /** + * Here is where we export data for a specific data stream to Tethys. + * + * @param aDataBlock + * @param tethysExportParams + * @param streamExportParams + */ + private void exportDataStream(PamDataBlock aDataBlock, TethysExportParams tethysExportParams, + StreamExportParams streamExportParams) { + /** + * This will probably need to be passed additional parameters and may also want to return something + * other than void in order to build a bigger Tethys document. + */ + /* + * Some examples of how to do whatever is needed to get schema and data out of PAMGuard. + */ + /* + * first we'll probably want a reference to the module containing the data. + * in principle this can't get null, since the datablock was found be searching in + * the other direction. + */ + PamControlledUnit pamControlledUnit = aDataBlock.getParentProcess().getPamControlledUnit(); + + TethysDataProvider dataProvider = aDataBlock.getTethysDataProvider(); + + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + if (dataProvider == null) { + return; + } + + TethysSchema tethysSchema = dataProvider.getSchema(); + /* + * the schema should have a Document object in it. If we wanted to turn + * that into an XML string we can ... + * (though I'd assume that having the Document is more useful) + */ + String schemaXMLString = pamXMLWriter.getAsString(tethysSchema.getXsd(), false); +// System.out.printf("Schema for %s is %s\n", aDataBlock.getDataName(), schemaXMLString); + + + /* + * Get the XML settings for that datablock. This is (or should be + * the parameters that were controlling that module, with adequate data about + * upstream modules). I think this has to go somewhere into the Detections document. + */ + Document doc = pamXMLWriter.writeOneModule(pamXMLWriter, System.currentTimeMillis()); + String moduleXML = null; + if (doc != null) { + // this string should be XML of all the settings for the module controlling this datablock. + moduleXML = pamXMLWriter.getAsString(doc, true); // change to false to get smaller xml + System.out.printf("Module settings for datablock %s are:\n", moduleXML); + System.out.println(moduleXML); + } + + + + + /** + * Now can go through the data. Probably, we'll want to go through all the data in + * the project, but we can hold off on that for now and just go for data that + * are in memory. We'll also have to think a lot about updating parts of the + * database which have been reprocessed - what we want to do, should eventually all + * be options set in the dialog and available within TethysExportParams + * For now though, we're just going to export data that are in memory. + * Once basic export is working, I can easily enough write something which will go + * through an entire data set, go through between two times, etc. + */ + // so this is a way of iterating through the data that are in memory, which will do for now .. + // do it with a data copy which can avoid synchronising the entire block for what may be a long time + // the copy function is itself synched, and is quite fast, so easier and safe this way + ArrayList dataCopy = aDataBlock.getDataCopy(); + for (PamDataUnit aData : dataCopy) { + // then we do whatever we need to do to convert this into + } + + + } + +} diff --git a/src/tethys/output/swing/TethysExportDialog.java b/src/tethys/output/swing/TethysExportDialog.java index d9477c52..ae86b315 100644 --- a/src/tethys/output/swing/TethysExportDialog.java +++ b/src/tethys/output/swing/TethysExportDialog.java @@ -6,7 +6,9 @@ import java.awt.GridBagLayout; import java.awt.Window; import java.util.ArrayList; +import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.TitledBorder; @@ -14,6 +16,7 @@ import PamController.PamController; import PamView.dialog.PamDialog; import PamView.dialog.PamGridBagContraints; import PamguardMVC.PamDataBlock; +import PamguardMVC.dataSelector.DataSelector; import tethys.TethysControl; import tethys.output.StreamExportParams; import tethys.output.TethysExportParams; @@ -81,22 +84,35 @@ public class TethysExportDialog extends PamDialog { streamsPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new PamGridBagContraints(); dataStreamSets = findDataStreams(); + streamsPanel.add(new JLabel(" Data Stream ", JLabel.CENTER), c); + c.gridx++; + streamsPanel.add(new JLabel(" Data Select ", JLabel.CENTER), c); for (DataStreamSet aSet : dataStreamSets) { - streamsPanel.add(aSet.checkBox, c); + c.gridx = 0; c.gridy++; + streamsPanel.add(aSet.checkBox, c); + // try to add a data selector + DataSelector dataSelector = aSet.dataBlock.getDataSelector(tethysControl.getDataSelectName(), false); + if (dataSelector != null) { + c.gridx++; + JButton button = dataSelector.getDialogButton(this); + if (button != null) { + streamsPanel.add(button, c); + } + } } pack(); } /** - * Get a set of data blocks that have SQLLogging. - * @return + * Get a set of data blocks that can provide Tethys data. + * @return datablocks which can provide Tethys data */ private ArrayList findDataStreams() { ArrayList sets = new ArrayList<>(); ArrayList allDataBlocks = PamController.getInstance().getDataBlocks(); for (PamDataBlock aDataBlock : allDataBlocks) { - if (aDataBlock.getLogging() != null) { + if (aDataBlock.getTethysDataProvider() != null) { sets.add(new DataStreamSet(aDataBlock)); } } diff --git a/src/tethys/pamdata/AutoTethysProvider.java b/src/tethys/pamdata/AutoTethysProvider.java new file mode 100644 index 00000000..52243cc9 --- /dev/null +++ b/src/tethys/pamdata/AutoTethysProvider.java @@ -0,0 +1,42 @@ +package tethys.pamdata; + +import org.w3c.dom.Document; + +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamDataUnit; +import generalDatabase.DBSchemaWriter; +import generalDatabase.SQLLogging; + +/** + * Automatically provides Tethys data based on the SQL database interface + * for a data block. + * @author dg50 + * + */ +public class AutoTethysProvider implements TethysDataProvider { + + private PamDataBlock pamDataBlock; + + public AutoTethysProvider(PamDataBlock pamDataBlock) { + this.pamDataBlock = pamDataBlock; + } + + @Override + public TethysSchema getSchema() { + SQLLogging logging = pamDataBlock.getLogging(); + if (logging == null) { + return null; + } + DBSchemaWriter schemaWriter = new DBSchemaWriter(); + Document doc = schemaWriter.generateDatabaseSchema(pamDataBlock, logging, logging.getTableDefinition()); + TethysSchema schema = new TethysSchema(doc); + return schema; + } + + @Override + public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/tethys/pamdata/TethysDataPoint.java b/src/tethys/pamdata/TethysDataPoint.java new file mode 100644 index 00000000..5eefdae1 --- /dev/null +++ b/src/tethys/pamdata/TethysDataPoint.java @@ -0,0 +1,18 @@ +package tethys.pamdata; + +import PamguardMVC.PamDataUnit; + +/** + * This will be a unit of Tethys Data, e.g. a Detection. + * Can it also be used for things like GPS data ? + * @author dg50 + * + */ +public class TethysDataPoint { + + public TethysDataPoint(PamDataUnit dataUnit) { + // TODO Auto-generated constructor stub + } + + +} diff --git a/src/tethys/pamdata/TethysDataProvider.java b/src/tethys/pamdata/TethysDataProvider.java new file mode 100644 index 00000000..ffa7df67 --- /dev/null +++ b/src/tethys/pamdata/TethysDataProvider.java @@ -0,0 +1,32 @@ +package tethys.pamdata; + +import PamguardMVC.PamDataUnit; + +/** + * Any PAMGuard data stream which can provide Detection data to PAMGuard will + * be able to return one of these. It will provide a schema and a function which + * can turn individual data units into data formatted for Tethys. The nature of how these + * work TBD. + * @author dg50 + * + */ +public interface TethysDataProvider { + + /** + * This gets the Tethys schema for this type of data in whatever + * form we decide it's best stored in, an XML string, or what ? + * @return + */ + public TethysSchema getSchema(); + + + /** + * This will convert a data unit for this provider into whatever format we need the + * data to be in for Tethys. Some base function but also bespoke stuff depending on the + * data type. Will probably need writing for every module individually? + * @param pamDataUnit + * @return + */ + public TethysDataPoint getDataPoint(PamDataUnit pamDataUnit); + +} diff --git a/src/tethys/pamdata/TethysSchema.java b/src/tethys/pamdata/TethysSchema.java new file mode 100644 index 00000000..4ddb9b08 --- /dev/null +++ b/src/tethys/pamdata/TethysSchema.java @@ -0,0 +1,32 @@ +package tethys.pamdata; + +import org.w3c.dom.Document; + +/** + * object for a Tethys Schema. This may just be a very simple + * wrapper around an XML string, or a JAXB object or something, + * but may get more sophisticated. TBD in discussions with SDSU + */ +public class TethysSchema { + + private Document schemaDoc; + + public TethysSchema(Document doc) { + this.setXsd(doc); + } + + /** + * @return the xsd + */ + public Document getXsd() { + return schemaDoc; + } + + /** + * @param xsd the xsd to set + */ + public void setXsd(Document xsd) { + this.schemaDoc = xsd; + } + +}