mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
GUI Work.
working on some GUI / control options. Semi functional. Seem to have a problem with time zones converting from XML time to millis which need sorting.
This commit is contained in:
parent
f51a519d82
commit
c7ceba1604
@ -45,6 +45,8 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
private EnvironmentPanel environmentPanel;
|
||||
|
||||
private HydrophoneDiagram hydrophoneDiagram;
|
||||
|
||||
private InstrumentIdentityPanel instrumentIdentityPanel;
|
||||
|
||||
private JButton okButton, cancelButton;
|
||||
|
||||
@ -73,6 +75,7 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
eastPanel.add(channelPanel.getChannelPanel());
|
||||
|
||||
environmentPanel = new EnvironmentPanel(this);
|
||||
instrumentIdentityPanel = new InstrumentIdentityPanel();
|
||||
// eastPanel.add(environmentPanel.getEnvironmentPanel());
|
||||
|
||||
|
||||
@ -80,6 +83,7 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
JPanel westPanel = new JPanel(new BorderLayout());
|
||||
westPanel.add(BorderLayout.CENTER, hydrophoneDiagram.getPlotPanel());
|
||||
westPanel.add(BorderLayout.SOUTH, environmentPanel.getEnvironmentPanel());
|
||||
westPanel.add(BorderLayout.NORTH, instrumentIdentityPanel.getComponent());
|
||||
|
||||
|
||||
splitPanel.add(westPanel);
|
||||
@ -150,6 +154,7 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
hydrophoneDialogPanel.setParams(selArray);
|
||||
channelPanel.setParams();
|
||||
hydrophoneDiagram.rePaint();
|
||||
instrumentIdentityPanel.setParams(selArray);
|
||||
if (selArray != null) {
|
||||
environmentPanel.setNewSpeed(selArray.getSpeedOfSound());
|
||||
}
|
||||
@ -177,6 +182,7 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
array.setSpeedOfSound(environmentPanel.getNewSpeed());
|
||||
array.setSpeedOfSoundError(environmentPanel.getNewError());
|
||||
hydrophoneDialogPanel.getParams();
|
||||
instrumentIdentityPanel.getParams(array);
|
||||
|
||||
if (checkDaqChannels(array) == false) {
|
||||
return false;
|
||||
@ -256,6 +262,7 @@ public class ArrayDialog extends PamDialog implements ActionListener {
|
||||
environmentPanel.setNewSpeed(currentArray.getSpeedOfSound());
|
||||
environmentPanel.setNewError(currentArray.getSpeedOfSoundError());
|
||||
}
|
||||
instrumentIdentityPanel.setParams(currentArray);
|
||||
}
|
||||
|
||||
void newChannelSelection() {
|
||||
|
72
src/Array/InstrumentIdentityPanel.java
Normal file
72
src/Array/InstrumentIdentityPanel.java
Normal file
@ -0,0 +1,72 @@
|
||||
package Array;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import PamView.panel.WestAlignedPanel;
|
||||
|
||||
/**
|
||||
* Instrument identity panel, contrians additional fields required by Tethys.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class InstrumentIdentityPanel {
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private JTextField instrumentId;
|
||||
|
||||
private JTextField instrumentType;
|
||||
|
||||
public InstrumentIdentityPanel() {
|
||||
mainPanel = new WestAlignedPanel();
|
||||
mainPanel.setBorder(new TitledBorder("Instrument information"));
|
||||
mainPanel.setLayout(new GridBagLayout());
|
||||
GridBagConstraints c = new PamGridBagContraints();
|
||||
mainPanel.add(new JLabel("Instrument Type ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(instrumentType = new JTextField(20), c);
|
||||
c.gridx = 0;
|
||||
c.gridy++;
|
||||
mainPanel.add(new JLabel("Instrument Id ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(instrumentId = new JTextField(20), c);
|
||||
|
||||
instrumentType.setToolTipText("Instrument type, e.g. Towed array, HARP, EAR, Popup, DMON, Rock Hopper, etc.");
|
||||
instrumentId.setToolTipText("Instrument identifier, e.g. serial number");
|
||||
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
public void setParams(PamArray currentArray) {
|
||||
if (currentArray == null) {
|
||||
currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
||||
}
|
||||
if (currentArray == null) {
|
||||
return;
|
||||
}
|
||||
instrumentType.setText(currentArray.getInstrumentType());
|
||||
instrumentId.setText(currentArray.getInstrumentId());
|
||||
}
|
||||
|
||||
public void getParams(PamArray currentArray) {
|
||||
if (currentArray == null) {
|
||||
currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
||||
}
|
||||
if (currentArray == null) {
|
||||
return;
|
||||
}
|
||||
currentArray.setInstrumentType(instrumentType.getText());
|
||||
currentArray.setInstrumentId(instrumentId.getText());
|
||||
}
|
||||
}
|
@ -90,6 +90,32 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters {
|
||||
private String arrayName;
|
||||
|
||||
private String arrayFile;
|
||||
|
||||
/**
|
||||
* Type, used for Tethys and other meta data control
|
||||
*/
|
||||
private String instrumentType;
|
||||
|
||||
public String getInstrumentType() {
|
||||
return instrumentType;
|
||||
}
|
||||
|
||||
public void setInstrumentType(String instrumentType) {
|
||||
this.instrumentType = instrumentType;
|
||||
}
|
||||
|
||||
public String getInstrumentId() {
|
||||
return instrumentId;
|
||||
}
|
||||
|
||||
public void setInstrumentId(String instrumentId) {
|
||||
this.instrumentId = instrumentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Id. Can be anything. Compulsory for Tethys.
|
||||
*/
|
||||
private String instrumentId;
|
||||
|
||||
// private int originInterpolation = ORIGIN_USE_LATEST;
|
||||
private int originInterpolation = ORIGIN_USE_PRECEEDING;
|
||||
|
@ -56,25 +56,25 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
|
||||
*/
|
||||
private String cruise;
|
||||
|
||||
/**
|
||||
* On what platform is the instrument deployed? (e.g. mooring, tag)
|
||||
*/
|
||||
private String platform = "Unknown";
|
||||
// /**
|
||||
// * On what platform is the instrument deployed? (e.g. mooring, tag)
|
||||
// */
|
||||
// private String platform = "Unknown";
|
||||
|
||||
/**
|
||||
* Name of geographic region.
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* Instrument type, e.g. HARP, EAR, Popup, DMON, etc.
|
||||
*/
|
||||
private String instrumentType;
|
||||
|
||||
/**
|
||||
* Instrument identifier, e.g. serial number
|
||||
*/
|
||||
private String instrumentId;
|
||||
// /**
|
||||
// * Instrument type, e.g. HARP, EAR, Popup, DMON, etc.
|
||||
// */
|
||||
// private String instrumentType;
|
||||
//
|
||||
// /**
|
||||
// * Instrument identifier, e.g. serial number
|
||||
// */
|
||||
// private String instrumentId;
|
||||
|
||||
public DeploymentData() {
|
||||
}
|
||||
@ -207,19 +207,19 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
|
||||
this.cruise = cruise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the platform
|
||||
*/
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param platform the platform to set
|
||||
*/
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
// /**
|
||||
// * @return the platform
|
||||
// */
|
||||
// public String getPlatform() {
|
||||
// return platform;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param platform the platform to set
|
||||
// */
|
||||
// public void setPlatform(String platform) {
|
||||
// this.platform = platform;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return the region
|
||||
@ -235,32 +235,32 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the instrumentType
|
||||
*/
|
||||
public String getInstrumentType() {
|
||||
return instrumentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instrumentType the instrumentType to set
|
||||
*/
|
||||
public void setInstrumentType(String instrumentType) {
|
||||
this.instrumentType = instrumentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the instrumentId
|
||||
*/
|
||||
public String getInstrumentId() {
|
||||
return instrumentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instrumentId the instrumentId to set
|
||||
*/
|
||||
public void setInstrumentId(String instrumentId) {
|
||||
this.instrumentId = instrumentId;
|
||||
}
|
||||
// /**
|
||||
// * @return the instrumentType
|
||||
// */
|
||||
// public String getInstrumentType() {
|
||||
// return instrumentType;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param instrumentType the instrumentType to set
|
||||
// */
|
||||
// public void setInstrumentType(String instrumentType) {
|
||||
// this.instrumentType = instrumentType;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the instrumentId
|
||||
// */
|
||||
// public String getInstrumentId() {
|
||||
// return instrumentId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param instrumentId the instrumentId to set
|
||||
// */
|
||||
// public void setInstrumentId(String instrumentId) {
|
||||
// this.instrumentId = instrumentId;
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.awt.Desktop;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
@ -12,19 +13,28 @@ import java.util.ArrayList;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import PamController.PamControlledUnit;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamView.PamTabPanel;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Deployment.Instrument;
|
||||
import pamViewFX.PamSettingsMenuPane;
|
||||
import tethys.TethysState.StateType;
|
||||
import tethys.dbxml.DBXMLConnect;
|
||||
import tethys.dbxml.DBXMLQueries;
|
||||
import tethys.dbxml.ServerStatus;
|
||||
import tethys.deployment.DeploymentHandler;
|
||||
import tethys.detection.DetectionsHandler;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
import tethys.output.DatablockSynchInfo;
|
||||
//import nilus.Deployment;
|
||||
//import nilus.Deployment.Instrument;
|
||||
import tethys.output.StreamExportParams;
|
||||
import tethys.output.TethysExportParams;
|
||||
import tethys.output.TethysExporter;
|
||||
import tethys.output.swing.TethysExportDialog;
|
||||
@ -37,13 +47,12 @@ import tethys.swing.TethysTabPanel;
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class TethysControl extends PamControlledUnit {
|
||||
public class TethysControl extends PamControlledUnit implements PamSettings, TethysStateObserver {
|
||||
|
||||
public static final String unitType = "Tethys Interface";
|
||||
public static String defaultName = "Tethys";
|
||||
public static String xmlNameSpace = "http://tethys.sdsu.edu/schema/1.0";
|
||||
|
||||
|
||||
private TethysExportParams tethysExportParams = new TethysExportParams();
|
||||
|
||||
private DBXMLConnect dbxmlConnect;
|
||||
@ -53,12 +62,40 @@ public class TethysControl extends PamControlledUnit {
|
||||
private DBXMLQueries dbxmlQueries;
|
||||
|
||||
private ArrayList<TethysStateObserver> stateObservers;
|
||||
|
||||
private Timer serverCheckTimer;
|
||||
|
||||
private ServerStatus lastServerStatus;
|
||||
|
||||
private ArrayList<DatablockSynchInfo> dataBlockSynchInfos;
|
||||
|
||||
private DeploymentHandler deploymentHandler;
|
||||
|
||||
public TethysControl(String unitName) {
|
||||
super(unitType, unitName);
|
||||
stateObservers = new ArrayList();
|
||||
dbxmlConnect = new DBXMLConnect(this);
|
||||
dbxmlQueries = new DBXMLQueries(this);
|
||||
deploymentHandler = new DeploymentHandler(this);
|
||||
serverCheckTimer = new Timer(10000, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
checkServer();
|
||||
}
|
||||
});
|
||||
serverCheckTimer.setInitialDelay(0);
|
||||
PamSettingManager.getInstance().registerSettings(this);
|
||||
addStateObserver(this);
|
||||
|
||||
if (PamController.getInstance().isInitializationComplete()) {
|
||||
// must be adding module later on ...
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initializationStuff();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +128,60 @@ public class TethysControl extends PamControlledUnit {
|
||||
tethysMenu.add(openClient);
|
||||
return tethysMenu;
|
||||
}
|
||||
|
||||
public ArrayList<PamDataBlock> getExportableDataBlocks() {
|
||||
ArrayList<PamDataBlock> sets = new ArrayList<>();
|
||||
ArrayList<PamDataBlock> allDataBlocks = PamController.getInstance().getDataBlocks();
|
||||
for (PamDataBlock aDataBlock : allDataBlocks) {
|
||||
if (aDataBlock.getTethysDataProvider() != null) {
|
||||
sets.add(aDataBlock);
|
||||
}
|
||||
}
|
||||
return sets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the synchronisation info for all datablocks.
|
||||
* This list should be static, but check it in case something has been
|
||||
* added or removed.
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<DatablockSynchInfo> getSynchronisationInfos() {
|
||||
if (dataBlockSynchInfos == null) {
|
||||
dataBlockSynchInfos = new ArrayList<>();
|
||||
}
|
||||
ArrayList<PamDataBlock> dataBlocks = getExportableDataBlocks();
|
||||
// check all datablocks are in there ...
|
||||
for (PamDataBlock aBlock : dataBlocks) {
|
||||
if (findDatablockSynchInfo(aBlock) == null) {
|
||||
dataBlockSynchInfos.add(new DatablockSynchInfo(this, aBlock));
|
||||
}
|
||||
}
|
||||
// and remove any which are no longer there.
|
||||
for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) {
|
||||
if (dataBlocks.contains(synchInfo.getDataBlock()) == false) {
|
||||
dataBlockSynchInfos.remove(synchInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return dataBlockSynchInfos;
|
||||
}
|
||||
|
||||
public DatablockSynchInfo findDatablockSynchInfo(PamDataBlock dataBlock) {
|
||||
if (dataBlockSynchInfos == null) {
|
||||
return null;
|
||||
}
|
||||
for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) {
|
||||
if (synchInfo.getDataBlock() == dataBlock) {
|
||||
return synchInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* open client in the default web browser
|
||||
*/
|
||||
protected void openTethysClient() {
|
||||
String urlString = tethysExportParams.getFullServerName() + "/Client";
|
||||
System.out.println("Opening url " + urlString);
|
||||
@ -148,8 +238,17 @@ public class TethysControl extends PamControlledUnit {
|
||||
private void exportTethysData(TethysExportParams tethysExportParams) {
|
||||
TethysExporter tethysExporter = new TethysExporter(this, tethysExportParams);
|
||||
tethysExporter.doExport();
|
||||
|
||||
sendStateUpdate(new TethysState(StateType.TRANSFERDATA));
|
||||
countProjectDetections();
|
||||
sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global deployment data. This is a bit of a mess, trying to use a separate module
|
||||
* so that the rest of PAMGuard can use it, but creating the
|
||||
* @return
|
||||
*/
|
||||
public DeploymentData getGlobalDeplopymentData() {
|
||||
PamControlledUnit aUnit = PamController.getInstance().findControlledUnit(MetaDataContol.class, null);
|
||||
// if (aUnit instanceof MetaDataContol == false || true) {
|
||||
@ -163,20 +262,29 @@ public class TethysControl extends PamControlledUnit {
|
||||
// }
|
||||
|
||||
MetaDataContol metaControl = (MetaDataContol) aUnit;
|
||||
DeploymentData deploymentData = metaControl != null ? metaControl.getDeploymentData() : new DeploymentData();
|
||||
DeploymentData deploymentData = metaControl != null ? metaControl.getDeploymentData() : getTethysProjectData();
|
||||
|
||||
deploymentData.setProject("thisIsAProject");
|
||||
deploymentData.setPlatform("Yay a platform");
|
||||
deploymentData.setCruise("cruisey");
|
||||
deploymentData.setDeploymentId(142536);
|
||||
deploymentData.setInstrumentId("super instrument");
|
||||
deploymentData.setSite("in the ocean somewhere");
|
||||
deploymentData.setRegion("ocean water");
|
||||
deploymentData.setInstrumentType("sensor of sorts");
|
||||
// deploymentData.setProject("thisIsAProject");
|
||||
//// deploymentData.setPlatform("Yay a platform");
|
||||
// deploymentData.setCruise("cruisey");
|
||||
// deploymentData.setDeploymentId(142536);
|
||||
//// deploymentData.setInstrumentId("super instrument");
|
||||
// deploymentData.setSite("in the ocean somewhere");
|
||||
// deploymentData.setRegion("ocean water");
|
||||
//// deploymentData.setInstrumentType("sensor of sorts");
|
||||
|
||||
return deploymentData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a copy of Deployment data stored with other Tethys params when the more
|
||||
* general meta data provider is not present.
|
||||
* @return
|
||||
*/
|
||||
private DeploymentData getTethysProjectData() {
|
||||
return tethysExportParams.getProjectData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new state observer.
|
||||
* @param stateObserver
|
||||
@ -215,4 +323,98 @@ public class TethysControl extends PamControlledUnit {
|
||||
return dbxmlQueries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyModelChanged(int changeType) {
|
||||
super.notifyModelChanged(changeType);
|
||||
switch (changeType) {
|
||||
case PamController.INITIALIZATION_COMPLETE:
|
||||
initializationStuff();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stuff to do on initial load (initialization complete or addition of
|
||||
* a Tethys module after initialisation).
|
||||
*/
|
||||
private void initializationStuff() {
|
||||
deploymentHandler.createPamguardOverview();
|
||||
serverCheckTimer.start();
|
||||
updateState(new TethysState(StateType.NEWPAMGUARDSELECTION));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the server. This will send around a notification if the state
|
||||
* has changed since the last call to this function, so it's unlikely you'll
|
||||
* need to use the return value
|
||||
* @return server status.
|
||||
*/
|
||||
public ServerStatus checkServer() {
|
||||
ServerStatus serverState = dbxmlConnect.pingServer();
|
||||
if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) {
|
||||
sendStateUpdate(new TethysState(StateType.UPDATESERVER));
|
||||
}
|
||||
lastServerStatus = serverState;
|
||||
return serverState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getSettingsReference() {
|
||||
return tethysExportParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSettingsVersion() {
|
||||
return TethysExportParams.serialVersionUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
|
||||
tethysExportParams = (TethysExportParams) pamControlledUnitSettings.getSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(TethysState tethysState) {
|
||||
switch (tethysState.stateType) {
|
||||
case NEWPROJECTSELECTION:
|
||||
countProjectDetections();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void countProjectDetections() {
|
||||
if (dataBlockSynchInfos == null) {
|
||||
return;
|
||||
}
|
||||
DeploymentData deplData = getGlobalDeplopymentData();
|
||||
String[] dataPrefixes = new String[dataBlockSynchInfos.size()];
|
||||
int i = 0;
|
||||
ArrayList<PDeployment> matchedDeployments = deploymentHandler.getMatchedDeployments();
|
||||
for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) {
|
||||
// dataPrefixes[i] = DetectionsHandler.getDetectionsDocIdPrefix(deplData.getProject(), synchInfo.getDataBlock());
|
||||
int count = 0;
|
||||
for (PDeployment pDepl : matchedDeployments) {
|
||||
count += dbxmlQueries.countData(synchInfo.getDataBlock(), pDepl.deployment.getId());
|
||||
}
|
||||
synchInfo.setDataCount(count);
|
||||
i++;
|
||||
}
|
||||
// int[] counts = dbxmlQueries.countDataForProject(deplData.getProject(), dataPrefixes);
|
||||
// if (counts != null) {
|
||||
// for ( i = 0; i < counts.length; i++ ) {
|
||||
// dataBlockSynchInfos.get(i).setDataCount(counts[i]);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* One stop place to get Deployment information. Will provide
|
||||
* both information on record periods in PAMGuard and also Deployment docs in Tethys.
|
||||
* @return set of functions for handling deployments.
|
||||
*/
|
||||
public DeploymentHandler getDeploymentHandler() {
|
||||
return deploymentHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
61
src/tethys/TethysMenuActions.java
Normal file
61
src/tethys/TethysMenuActions.java
Normal file
@ -0,0 +1,61 @@
|
||||
package tethys;
|
||||
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import tethys.niluswraps.PDeployment;
|
||||
|
||||
/*
|
||||
* Some standard meny dirven functions which we may want to call from
|
||||
* a few different places.
|
||||
*/
|
||||
public class TethysMenuActions {
|
||||
|
||||
private TethysControl tethysControl;
|
||||
|
||||
public TethysMenuActions(TethysControl tethysControl) {
|
||||
super();
|
||||
this.tethysControl = tethysControl;
|
||||
}
|
||||
|
||||
public void deploymentMouseActions(MouseEvent e, PDeployment pDeployment) {
|
||||
ArrayList<String> detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocsIds(pDeployment.deployment.getId());
|
||||
// System.out.println("Detections for deployment " + pDeployment.deployment.getId());
|
||||
// for (String detName : detDocNames) {
|
||||
// System.out.println(detName);
|
||||
// }
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
if (detDocNames.size() == 0) {
|
||||
JMenuItem menuItem = new JMenuItem("Delete deployment " + pDeployment.deployment.getId());
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
deleteDeployment(pDeployment);
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
}
|
||||
else {
|
||||
String str = String.format("Delete deployment %s and %d Detections documents", pDeployment.deployment.getId(), detDocNames.size());
|
||||
JMenuItem menuItem = new JMenuItem(str);
|
||||
menuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
deleteDeployment(pDeployment);
|
||||
}
|
||||
});
|
||||
menu.add(menuItem);
|
||||
}
|
||||
menu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
|
||||
protected void deleteDeployment(PDeployment pDeployment) {
|
||||
tethysControl.getDbxmlConnect().deleteDeployment(pDeployment.deployment.getId());
|
||||
}
|
||||
}
|
@ -8,7 +8,12 @@ package tethys;
|
||||
*/
|
||||
public class TethysState {
|
||||
|
||||
public enum StateType {UPDATESERVER, TRANSFERDATA};
|
||||
public enum StateType {UPDATESERVER, // Server connection or status has changed
|
||||
TRANSFERDATA, // data have been transferred from PAMGuard to Tethys
|
||||
NEWPROJECTSELECTION, // a new Tethys project has been selected in the GUI
|
||||
NEWPAMGUARDSELECTION, // new PAMGuard data are available (called once on first load)
|
||||
UPDATEMETADATA // META Data being prepared for output have changed (so may be able to enable output!)
|
||||
};
|
||||
|
||||
public StateType stateType;
|
||||
|
||||
|
@ -1,11 +1,18 @@
|
||||
package tethys;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.xml.datatype.DatatypeConfigurationException;
|
||||
import javax.xml.datatype.DatatypeFactory;
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
|
||||
public class TethysTimeFuncs {
|
||||
|
||||
/*
|
||||
@ -36,4 +43,43 @@ public class TethysTimeFuncs {
|
||||
GregorianCalendar gc2 = xmlGregorian.toGregorianCalendar();
|
||||
return gc2.getTimeInMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a Gregorian calendar object from a returned XML string.
|
||||
* @param gregorianString
|
||||
* @return
|
||||
*/
|
||||
public static XMLGregorianCalendar fromGregorianXML(String gregorianString) {
|
||||
// typical string is 2018-10-20T00:00:00Z
|
||||
if (gregorianString == null) {
|
||||
return null;
|
||||
}
|
||||
// GregorianCalendar gCal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||
gregorianString = gregorianString.replace("T", " ");
|
||||
gregorianString = gregorianString.replace("Z", "");
|
||||
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
df.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = null;
|
||||
try {
|
||||
date = df.parse(gregorianString);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return xmlGregCalFromMillis(date.getTime());
|
||||
// gCal.setTimeInMillis(date.getTime());
|
||||
//// gCal.se
|
||||
// return gCal;
|
||||
}
|
||||
|
||||
public static String formatGregorianTime(XMLGregorianCalendar gregCal) {
|
||||
if (gregCal == null) {
|
||||
return null;
|
||||
}
|
||||
Long millis = millisFromGregorianXML(gregCal);
|
||||
if (millis == null) {
|
||||
return gregCal.toString();
|
||||
}
|
||||
return PamCalendar.formatDBDateTime(millis);
|
||||
}
|
||||
}
|
||||
|
26
src/tethys/dbxml/DBQueryResult.java
Normal file
26
src/tethys/dbxml/DBQueryResult.java
Normal file
@ -0,0 +1,26 @@
|
||||
package tethys.dbxml;
|
||||
|
||||
public class DBQueryResult {
|
||||
|
||||
public long queryTimeMillis;
|
||||
|
||||
public String queryResult;
|
||||
|
||||
public String schemaPlan;
|
||||
|
||||
public Exception queryException;
|
||||
|
||||
public DBQueryResult(long queryTimeMillis, String queryResult, String schemaPlan) {
|
||||
super();
|
||||
this.queryTimeMillis = queryTimeMillis;
|
||||
this.queryResult = queryResult;
|
||||
this.schemaPlan = schemaPlan;
|
||||
}
|
||||
|
||||
public DBQueryResult(long queryTimeMillis, Exception queryException) {
|
||||
super();
|
||||
this.queryTimeMillis = queryTimeMillis;
|
||||
this.queryException = queryException;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package tethys.dbxml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
@ -58,7 +59,7 @@ public class DBXMLConnect {
|
||||
fileError = Importer.ImportFiles(params.getFullServerName(), collection,
|
||||
new String[] { tempFile.toString() }, "", "", false);
|
||||
|
||||
System.out.println(fileError);
|
||||
// System.out.println(fileError);
|
||||
|
||||
tempFile.toFile().deleteOnExit();
|
||||
}
|
||||
@ -77,11 +78,11 @@ public class DBXMLConnect {
|
||||
}
|
||||
|
||||
/**
|
||||
* get tethys collection name from nilus collection objects
|
||||
* get Tethys collection name from nilus collection objects
|
||||
* @param className nilus object Class Name
|
||||
* @return name of Tethys collection
|
||||
*/
|
||||
private String getTethysCollection(String className) {
|
||||
public String getTethysCollection(String className) {
|
||||
switch(className) {
|
||||
case "nilus.Deployment":
|
||||
return "Deployments";
|
||||
@ -106,6 +107,44 @@ public class DBXMLConnect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a Deploymnet and any contained Detections document. Doesn't work !
|
||||
* @param deploymentId
|
||||
* @return
|
||||
*/
|
||||
public boolean deleteDeployment(String deploymentId) {
|
||||
ArrayList<String> detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocsIds(deploymentId);
|
||||
JerseyClient jerseyClient = null;
|
||||
try {
|
||||
jerseyClient = new JerseyClient(tethysControl.getTethysExportParams().getFullServerName());
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
String result;
|
||||
for (int i = 0; i < detDocNames.size(); i++) {
|
||||
try {
|
||||
System.out.println("Delete " + detDocNames.get(i));
|
||||
result = jerseyClient.removeDocument("Detections", detDocNames.get(i));
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// return false;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
result = jerseyClient.removeDocument("Deployments", deploymentId);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean openDatabase() {
|
||||
|
||||
return true;
|
||||
@ -117,7 +156,7 @@ public class DBXMLConnect {
|
||||
|
||||
/**
|
||||
* Get the server state via a ping ?
|
||||
* @return String descritption of state ?
|
||||
* @return Server state ?
|
||||
*/
|
||||
public ServerStatus pingServer() {
|
||||
JerseyClient jerseyClient = new JerseyClient(tethysControl.getTethysExportParams().getFullServerName());
|
||||
|
@ -4,6 +4,7 @@ import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
@ -13,12 +14,20 @@ import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import PamController.settings.output.xml.PamguardXMLWriter;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import dbxml.JerseyClient;
|
||||
import nilus.Deployment;
|
||||
import nilus.Deployment.Instrument;
|
||||
import nilus.DeploymentRecoveryDetails;
|
||||
import nilus.Helper;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysTimeFuncs;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
import tethys.output.TethysExportParams;
|
||||
|
||||
/**
|
||||
* Some standard queries we're going to want to make from various
|
||||
* Some standard queries we're going to want to make from various
|
||||
* parts of the system as the user interracts with the GUI.
|
||||
* @author dg50
|
||||
*
|
||||
@ -32,37 +41,57 @@ public class DBXMLQueries {
|
||||
this.tethysControl = tethysControl;
|
||||
}
|
||||
|
||||
public ArrayList<String> getProjectNames() {
|
||||
/**
|
||||
* Execute a DBXML query. Returns an object which included the time
|
||||
* taken to execute the query and either a returned Document or an Exception.
|
||||
* Or will return null if the server is not connected
|
||||
* @param jsonQueryString
|
||||
* @return query result
|
||||
*/
|
||||
private DBQueryResult executeQuery(String jsonQueryString) {
|
||||
|
||||
long t1 = System.currentTimeMillis();
|
||||
|
||||
DBXMLConnect dbxmlConnect = tethysControl.getDbxmlConnect();
|
||||
ServerStatus serverStatus = dbxmlConnect.pingServer();
|
||||
if (serverStatus.ok == false) {
|
||||
if (!serverStatus.ok) {
|
||||
return null;
|
||||
}
|
||||
Document doc = null;
|
||||
|
||||
String queryResult = null;
|
||||
String schemaPlan = null;
|
||||
TethysExportParams params = tethysControl.getTethysExportParams();
|
||||
|
||||
try {
|
||||
JerseyClient jerseyClient = new JerseyClient(params.getFullServerName());
|
||||
JerseyClient jerseyClient = new JerseyClient(params.getFullServerName());
|
||||
|
||||
String testJson = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}";
|
||||
// web browse to http://localhost:9779/Client
|
||||
queryResult = jerseyClient.queryJSON(jsonQueryString, 0);
|
||||
schemaPlan = jerseyClient.queryJSON(jsonQueryString, 1);
|
||||
|
||||
String testResult = jerseyClient.queryJSON(testJson);
|
||||
|
||||
doc = convertStringToXMLDocument(testResult);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new DBQueryResult(System.currentTimeMillis()-t1, e);
|
||||
|
||||
}
|
||||
if (doc == null) {
|
||||
return new DBQueryResult(System.currentTimeMillis()-t1, queryResult, schemaPlan);
|
||||
}
|
||||
|
||||
public ArrayList<String> getProjectNames() {
|
||||
|
||||
String projectQuery = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}";
|
||||
|
||||
DBQueryResult result = executeQuery(projectQuery);
|
||||
|
||||
if (result == null || result.queryResult == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// System.out.println("Project query execution time millis = " + result.queryTimeMillis);
|
||||
|
||||
ArrayList<String> projectNames = new ArrayList<>();
|
||||
// iterate through the document and make a list of names, then make them unique.
|
||||
// iterate through the document and make a list of names, then make them unique.
|
||||
/* looking for elements like this:
|
||||
*
|
||||
*
|
||||
* check out the jaxb unmarshaller ...
|
||||
<Return>
|
||||
<Deployment>
|
||||
@ -70,8 +99,12 @@ public class DBXMLQueries {
|
||||
</Deployment>
|
||||
</Return>
|
||||
*/
|
||||
Document doc = convertStringToXMLDocument(result.queryResult);
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
NodeList returns = doc.getElementsByTagName("Return");
|
||||
// System.out.println("N projects = " + returns.getLength());
|
||||
// System.out.println("N projects = " + returns.getLength());
|
||||
int n = returns.getLength();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Node aNode = returns.item(i);
|
||||
@ -84,19 +117,316 @@ public class DBXMLQueries {
|
||||
Element projEl = (Element) ((Element) depEl).getFirstChild();
|
||||
String projName = projEl.getTextContent();
|
||||
if (projName != null) {
|
||||
if (projectNames.contains(projName) == false) {
|
||||
if (!projectNames.contains(projName)) {
|
||||
projectNames.add(projName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Collections.sort(projectNames);
|
||||
|
||||
return projectNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get some basic (not all) data for deployments associated with a project.
|
||||
* @param projectName
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<nilus.Deployment> getProjectDeployments(String projectName) {
|
||||
String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String qStr = String.format(qBase, projectName);
|
||||
|
||||
DBQueryResult result = executeQuery(qStr);
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
// System.out.println("Deployment query execution time millis = " + result.queryTimeMillis);
|
||||
|
||||
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||
|
||||
Document doc = convertStringToXMLDocument(result.queryResult);
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// System.out.println(pamXMLWriter.getAsString(doc));
|
||||
|
||||
ArrayList<Deployment> deployments = new ArrayList<>();
|
||||
|
||||
NodeList returns = doc.getElementsByTagName("Return");
|
||||
// System.out.println("N projects = " + returns.getLength());
|
||||
int n = returns.getLength();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Node aNode = returns.item(i);
|
||||
if (aNode instanceof Element) {
|
||||
Element returnedEl = (Element) aNode;
|
||||
String Id = getElementData(returnedEl, "Id");
|
||||
String project = getElementData(returnedEl, "Project");
|
||||
String DeploymentId = getElementData(returnedEl, "DeploymentId");
|
||||
String instrType = getElementData(returnedEl, "Instrument.Type");
|
||||
String instrId = getElementData(returnedEl, "Instrument.InstrumentId");
|
||||
String geometry = getElementData(returnedEl, "Instrument.GeometryType");
|
||||
String audioStart = getElementData(returnedEl, "DeploymentDetails.AudioTimeStamp");
|
||||
String audioEnd = getElementData(returnedEl, "RecoveryDetails.AudioTimeStamp");
|
||||
String region = getElementData(returnedEl, "Region");
|
||||
Deployment deployment = new Deployment();
|
||||
try {
|
||||
Helper.createRequiredElements(deployment);
|
||||
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
deployment.setId(Id);
|
||||
deployment.setProject(projectName);
|
||||
deployment.setDeploymentId(Integer.valueOf(DeploymentId));
|
||||
XMLGregorianCalendar gcStart = TethysTimeFuncs.fromGregorianXML(audioStart);
|
||||
XMLGregorianCalendar gcEnd = TethysTimeFuncs.fromGregorianXML(audioEnd);
|
||||
// System.out.printf("Converted %s to %s\n", audioStart,
|
||||
// PamCalendar.formatDBDateTime(TethysTimeFuncs.millisFromGregorianXML(gcStart), true));
|
||||
deployment.getDeploymentDetails().setAudioTimeStamp(gcStart);
|
||||
if (deployment.getRecoveryDetails() == null) {
|
||||
deployment.setRecoveryDetails(new DeploymentRecoveryDetails());
|
||||
}
|
||||
deployment.getRecoveryDetails().setAudioTimeStamp(gcEnd);
|
||||
if (instrType != null || instrId != null) {
|
||||
Instrument instrument = new Instrument();
|
||||
instrument.setType(instrType);
|
||||
instrument.setInstrumentId(instrId);
|
||||
instrument.setGeometryType(geometry);
|
||||
deployment.setInstrument(instrument);
|
||||
}
|
||||
deployment.setRegion(region);
|
||||
deployments.add(deployment);
|
||||
}
|
||||
}
|
||||
return deployments;
|
||||
}
|
||||
|
||||
public int countData(PamDataBlock dataBlock, String deploymentId) {
|
||||
String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Description/Method\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Description/Method\",\"LongDataName\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String query;
|
||||
if (deploymentId == null) {
|
||||
query = queryNoDepl;
|
||||
}
|
||||
else {
|
||||
query = queryWithDepl.replace("TheDeploymentId", deploymentId);
|
||||
}
|
||||
query = query.replace("LongDataName", dataBlock.getLongDataName());
|
||||
DBQueryResult queryResult = executeQuery(query);
|
||||
if (queryResult ==null) {
|
||||
return 0;
|
||||
}
|
||||
Document doc = convertStringToXMLDocument(queryResult.queryResult);
|
||||
if (doc == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
NodeList returns = doc.getElementsByTagName("Return");
|
||||
for (int i = 0; i < returns.getLength(); i++) {
|
||||
Node aNode = returns.item(i);
|
||||
String docName = aNode.getTextContent();
|
||||
// System.out.println(aNode.getTextContent());
|
||||
count += countDetecionsData(docName);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the data in a detections document.
|
||||
* @param detectionDocId
|
||||
* @return count of on effort detections in document.
|
||||
*/
|
||||
private int countDetecionsData(String detectionDocId) {
|
||||
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String query = queryBase.replace("DetectionsDocName", detectionDocId);
|
||||
DBQueryResult queryResult = executeQuery(query);
|
||||
Document doc = convertStringToXMLDocument(queryResult.queryResult);
|
||||
if (doc == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NodeList returns = doc.getElementsByTagName("Start");
|
||||
return returns.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of all detection documents for a given deployment
|
||||
* @param deploymentId
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<String> getDetectionsDocsIds(String deploymentId) {
|
||||
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String queryStr = queryBase.replace("SomeDeploymentId", deploymentId);
|
||||
DBQueryResult queryResult = executeQuery(queryStr);
|
||||
if (queryResult == null || queryResult.queryException != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||
|
||||
Document doc = convertStringToXMLDocument(queryResult.queryResult);
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<String> detectionDocs = new ArrayList<>();
|
||||
|
||||
NodeList returns = doc.getElementsByTagName("Return");
|
||||
for (int i = 0; i < returns.getLength(); i++) {
|
||||
Node aNode = returns.item(i);
|
||||
detectionDocs.add(aNode.getTextContent());
|
||||
}
|
||||
return detectionDocs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a count of the detections in a detections document.
|
||||
* Only looking in onEffort so far.
|
||||
* @param deploymentId
|
||||
* @param detectionDocId
|
||||
* @param dataBlock
|
||||
* @return
|
||||
*/
|
||||
public int getDetectionsDetectionCount(String deploymentId, String detectionDocId, PamDataBlock dataBlock) {
|
||||
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"SomeDetectionsId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String queryStr = queryBase.replace("SomeDetectionsId", detectionDocId);
|
||||
queryStr = queryStr.replace("SomeDeploymentId", deploymentId);
|
||||
DBQueryResult queryResult = executeQuery(queryStr);
|
||||
if (queryResult == null || queryResult.queryException != null) {
|
||||
return 0;
|
||||
}
|
||||
// System.out.println("Detections query time ms = " + queryResult.queryTimeMillis);
|
||||
|
||||
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||
|
||||
Document doc = convertStringToXMLDocument(queryResult.queryResult);
|
||||
if (doc == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// System.out.println(pamXMLWriter.getAsString(doc));
|
||||
|
||||
// ArrayList<String> detectionDocs = new ArrayList<>();
|
||||
|
||||
NodeList returns = doc.getElementsByTagName("Start");
|
||||
int n = returns.getLength();
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the quickest way of counting data in a project, but it will load the start
|
||||
* times for every detection in a project at once, so might use a lot of memory. Also
|
||||
* it wll probably get data for all deployments in a project, which may not be what we want.
|
||||
* @param projectName
|
||||
* @param dataPrefixes
|
||||
* @return
|
||||
*/
|
||||
public int[] countDataForProject(String projectName, String[] dataPrefixes) {
|
||||
int[] n = new int[dataPrefixes.length];
|
||||
ArrayList<PDeployment> matchedDeployments = tethysControl.getDeploymentHandler().getMatchedDeployments();
|
||||
// ArrayList<nilus.Deployment> deployments = getProjectDeployments(projectName);
|
||||
if (matchedDeployments == null) {
|
||||
return null;
|
||||
}
|
||||
for (PDeployment aDeployment : matchedDeployments) {
|
||||
// ArrayList<String> detectionsIds = getDetectionsDocsIds(aDeployment.getId());
|
||||
// for (String detId : detectionsIds) {
|
||||
// n += getDetectionsDetectionCount(aDeployment.getId(), detId, dataBlock);
|
||||
// }
|
||||
int[] newN = countDataForDeployment(projectName, aDeployment.deployment.getId(), dataPrefixes);
|
||||
for (int i = 0; i < n.length; i++) {
|
||||
n[i] += newN[i];
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count data within a deployment document which is associated with a set of datablocks
|
||||
* Since the detections all come back in one query, it's easier to count all datablocks at once so
|
||||
* that it can all happen off a single query.
|
||||
* @param id
|
||||
* @param dataBlockPrefixes
|
||||
* @return
|
||||
*/
|
||||
private int[] countDataForDeployment(String projectId, String deploymentId, String[] dataPrefixes) {
|
||||
String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"ReplaceDeploymentIdString\"],\"optype\":\"binary\"}],\"enclose\":1}";
|
||||
String queryString = queryBase.replace("ReplaceDeploymentIdString", deploymentId);
|
||||
DBQueryResult result = executeQuery(queryString);
|
||||
if (result == null || result.queryResult == null) {
|
||||
return null;
|
||||
}
|
||||
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||
|
||||
Document doc = convertStringToXMLDocument(result.queryResult);
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// System.out.println(pamXMLWriter.getAsString(doc));
|
||||
|
||||
NodeList detsDocs = doc.getElementsByTagName("Detections");
|
||||
int[] blockCounts = new int[dataPrefixes.length];
|
||||
|
||||
// String detDocPrefix = projectId + "_" + dataBlock.getDataName();
|
||||
|
||||
// int totalCalls = 0;
|
||||
int detCount = 0;
|
||||
int dataIndex;
|
||||
for (int i = 0; i < detsDocs.getLength(); i++) {
|
||||
Node detNode = detsDocs.item(i);
|
||||
|
||||
NodeList childNodes = detNode.getChildNodes();
|
||||
detCount = childNodes.getLength()-1;
|
||||
dataIndex = -1;
|
||||
for (int n = 0; n < childNodes.getLength(); n++) {
|
||||
Node aNode = childNodes.item(n);
|
||||
if (aNode instanceof Element) {
|
||||
Element el = (Element) aNode;
|
||||
String nodeName = el.getNodeName();
|
||||
if (nodeName.equals("Id")) {
|
||||
String id = el.getTextContent();
|
||||
for (int j = 0; j < dataPrefixes.length; j++) {
|
||||
if (id != null && id.startsWith(dataPrefixes[j])) {
|
||||
dataIndex = j;
|
||||
}
|
||||
}
|
||||
// if (id != null && id.startsWith(detDocPrefix) == false) {
|
||||
// detCount = 0;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataIndex >= 0) {
|
||||
blockCounts[dataIndex] += detCount;
|
||||
}
|
||||
// System.out.printf("%d Added %d for new total %d\n",i, detCount, totalCalls);
|
||||
}
|
||||
|
||||
return blockCounts;
|
||||
}
|
||||
|
||||
private String getElementData(Element root, String elName) {
|
||||
String[] tree = elName.split("\\.");
|
||||
for (String element : tree) {
|
||||
NodeList nodeList = root.getElementsByTagName(element);
|
||||
// should only be one node for what we're unpacking.
|
||||
if (nodeList == null || nodeList.getLength() == 0) {
|
||||
return null;
|
||||
}
|
||||
Node firstNode = nodeList.item(0);
|
||||
if (firstNode instanceof Element) {
|
||||
root = (Element) firstNode;
|
||||
}
|
||||
}
|
||||
return root.getTextContent();
|
||||
}
|
||||
|
||||
private Document convertStringToXMLDocument(String xmlString) {
|
||||
//Parser that produces DOM object trees from XML content
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
|
@ -21,12 +21,17 @@ import Array.Streamer;
|
||||
import Array.ThreadingHydrophoneLocator;
|
||||
import PamController.PamControlledUnit;
|
||||
import PamController.PamController;
|
||||
import PamUtils.PamUtils;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import SoundRecorder.RecordingInfo;
|
||||
import javafx.scene.chart.PieChart.Data;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Audio;
|
||||
import nilus.ChannelInfo;
|
||||
import nilus.ChannelInfo.DutyCycle;
|
||||
import nilus.ChannelInfo.DutyCycle.Regimen.RecordingDurationS;
|
||||
import nilus.ChannelInfo.DutyCycle.Regimen.RecordingIntervalS;
|
||||
import nilus.ChannelInfo.Sampling;
|
||||
import nilus.ChannelInfo.Sampling.Regimen;
|
||||
import nilus.Deployment;
|
||||
@ -37,30 +42,89 @@ import nilus.DeploymentRecoveryDetails;
|
||||
import nilus.GeometryTypeM;
|
||||
import nilus.Helper;
|
||||
import pamMaths.PamVector;
|
||||
import pamMaths.STD;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysLocationFuncs;
|
||||
import tethys.TethysState;
|
||||
import tethys.TethysStateObserver;
|
||||
import tethys.TethysTimeFuncs;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
|
||||
/**
|
||||
* Functions to gather data for the deployment document from all around PAMGuard.
|
||||
* There should be just one of these, available from TethysControl and it will try
|
||||
* to sensible handle when and how it updates it's list of PAMGuard and Tethys information
|
||||
* <br> Any part of PAMGuard wanting information on Deployments should come here.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class DeploymentHandler {
|
||||
public class DeploymentHandler implements TethysStateObserver {
|
||||
|
||||
private TethysControl tethysControl;
|
||||
|
||||
|
||||
private DeploymentOverview deploymentOverview;
|
||||
|
||||
private ArrayList<PDeployment> projectDeployments;
|
||||
|
||||
public DeploymentHandler(TethysControl tethysControl) {
|
||||
super();
|
||||
this.tethysControl = tethysControl;
|
||||
tethysControl.addStateObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(TethysState tethysState) {
|
||||
switch (tethysState.stateType) {
|
||||
case NEWPROJECTSELECTION:
|
||||
updateProjectDeployments();
|
||||
break;
|
||||
case TRANSFERDATA:
|
||||
updateProjectDeployments();
|
||||
break;
|
||||
case UPDATESERVER:
|
||||
updateProjectDeployments();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of Tethys deployments
|
||||
* @return true if OK
|
||||
*/
|
||||
public boolean updateProjectDeployments() {
|
||||
DeploymentData projData = tethysControl.getGlobalDeplopymentData();
|
||||
ArrayList<Deployment> tethysDocs = tethysControl.getDbxmlQueries().getProjectDeployments(projData.getProject());
|
||||
if (tethysDocs == null) {
|
||||
return false;
|
||||
}
|
||||
projectDeployments = new ArrayList<>();
|
||||
for (Deployment deployment : tethysDocs) {
|
||||
projectDeployments.add(new PDeployment(deployment));
|
||||
}
|
||||
matchPamguard2Tethys(deploymentOverview, projectDeployments);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of Tethys deployment docs. Note that this
|
||||
* doesn't update the list, but uses the one currently in memory
|
||||
* so call updateTethysDeployments() first if necessary.
|
||||
* @return list of (wrapped) nilus Deployment objects.
|
||||
*/
|
||||
public ArrayList<PDeployment> getProjectDeployments() {
|
||||
if (projectDeployments == null) {
|
||||
updateProjectDeployments();
|
||||
}
|
||||
return projectDeployments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an overview of all the deployments.
|
||||
* @return
|
||||
*/
|
||||
public DeploymentOverview createOverview() {
|
||||
public DeploymentOverview createPamguardOverview() {
|
||||
// first find an acquisition module.
|
||||
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||
if (!(aModule instanceof AcquisitionControl)) {
|
||||
@ -118,7 +182,7 @@ public class DeploymentHandler {
|
||||
if (prevPeriod != null) {
|
||||
long gap = nextPeriod.getRecordStart() - prevPeriod.getRecordStop();
|
||||
long prevDur = prevPeriod.getRecordStop()-prevPeriod.getRecordStart();
|
||||
if (gap < 3 || gap < prevDur/50) {
|
||||
if (gap < 3000 || gap < prevDur/50) {
|
||||
// ignoring up to 3s gap or a sample error < 2%.Dunno if this is sensible or not.
|
||||
prevPeriod.setRecordStop(nextPeriod.getRecordStop());
|
||||
iterator.remove();
|
||||
@ -127,9 +191,20 @@ public class DeploymentHandler {
|
||||
}
|
||||
prevPeriod = nextPeriod;
|
||||
}
|
||||
System.out.printf("Data have %d distinct files, but only %d distinct recording periods\n", nPeriods, tempPeriods.size());
|
||||
// System.out.printf("Data have %d distinct files, but only %d distinct recording periods\n", nPeriods, tempPeriods.size());
|
||||
DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods);
|
||||
DeploymentOverview deploymentOverview = new DeploymentOverview(false, tempPeriods);
|
||||
// if it's duty cycles, then we only want a single entry.
|
||||
ArrayList<RecordingPeriod> deploymentPeriods;
|
||||
if (dutyCycleinfo.isDutyCycled == false) {
|
||||
deploymentPeriods = tempPeriods;
|
||||
}
|
||||
else {
|
||||
deploymentPeriods = new ArrayList<>();
|
||||
deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop()));
|
||||
}
|
||||
DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods);
|
||||
matchPamguard2Tethys(deploymentOverview, projectDeployments);
|
||||
this.deploymentOverview = deploymentOverview;
|
||||
return deploymentOverview;
|
||||
// find the number of times it started and stopped ....
|
||||
// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n",
|
||||
@ -138,6 +213,64 @@ public class DeploymentHandler {
|
||||
|
||||
|
||||
}
|
||||
|
||||
public DeploymentOverview getDeploymentOverview() {
|
||||
return deploymentOverview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match what we think the PAMGuard deployment times are with Tethys Deployments read back
|
||||
* from the database.
|
||||
* @param deploymentOverview
|
||||
* @param deployments
|
||||
*/
|
||||
private void matchPamguard2Tethys(DeploymentOverview deploymentOverview, ArrayList<PDeployment> deployments) {
|
||||
if (deployments == null || deploymentOverview == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<RecordingPeriod> recordingPeriods = deploymentOverview.getRecordingPeriods();
|
||||
for (RecordingPeriod aPeriod : recordingPeriods) {
|
||||
PDeployment closestDeployment = findClosestDeployment(aPeriod, deployments);
|
||||
aPeriod.setMatchedTethysDeployment(closestDeployment);
|
||||
if (closestDeployment != null) {
|
||||
closestDeployment.setMatchedPAMGaurdPeriod(aPeriod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find the Tethys deployment that most closely matches the PAMGuard recording period.
|
||||
* @param aPeriod
|
||||
* @param deployments
|
||||
* @return
|
||||
*/
|
||||
private PDeployment findClosestDeployment(RecordingPeriod aPeriod, ArrayList<PDeployment> deployments) {
|
||||
double overlap = -1;
|
||||
PDeployment bestDeployment = null;
|
||||
for (PDeployment aDeployment : deployments) {
|
||||
double newOverlap = getDeploymentOverlap(aDeployment, aPeriod);
|
||||
if (newOverlap > overlap) {
|
||||
bestDeployment = aDeployment;
|
||||
overlap = newOverlap;
|
||||
}
|
||||
}
|
||||
return bestDeployment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the overlap in mills between a nilus Deployment and a PAMGuard recording period
|
||||
* @param aDeployment nilus Deployment from Tethys
|
||||
* @param aPeriod PAMGuard recording period
|
||||
* @return overlap in milliseconds
|
||||
*/
|
||||
public long getDeploymentOverlap(PDeployment aDeployment, RecordingPeriod aPeriod) {
|
||||
long start = aPeriod.getRecordStart();
|
||||
long stop = aPeriod.getRecordStop();
|
||||
long depStart = aDeployment.getAudioStart();
|
||||
long depStop = aDeployment.getAudioEnd();
|
||||
long overlap = (Math.min(stop, depStop)-Math.max(start, depStart));
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work out whether or not the data are evenly duty cycled by testing the
|
||||
@ -148,14 +281,23 @@ public class DeploymentHandler {
|
||||
private DutyCycleInfo assessDutyCycle(ArrayList<RecordingPeriod> tempPeriods) {
|
||||
int n = tempPeriods.size();
|
||||
if (n < 2) {
|
||||
return null;
|
||||
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();
|
||||
ons[i] = tempPeriods.get(i).getDuration()/1000.;
|
||||
gaps[i] = (tempPeriods.get(i+1).getRecordStart()-tempPeriods.get(i).getRecordStop())/1000.;
|
||||
}
|
||||
return null;
|
||||
// now look at how consistent those values are
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -195,102 +337,160 @@ public class DeploymentHandler {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
//in each channel
|
||||
public ArrayList<DeploymentRecoveryPair> getDeployments() {
|
||||
|
||||
DeploymentOverview recordingOverview = createOverview();
|
||||
|
||||
// first find an acquisition module.
|
||||
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||
if (!(aModule instanceof AcquisitionControl)) {
|
||||
// will return if it's null. Impossible for it to be the wrong type.
|
||||
// but it's good practice to check anyway before casting.
|
||||
return null;
|
||||
|
||||
/**
|
||||
* Get a list of Tethys Deployment docs that match the current PAMGuard data.
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<PDeployment> getMatchedDeployments() {
|
||||
ArrayList<PDeployment> matched = new ArrayList<>();
|
||||
if (deploymentOverview == null) {
|
||||
return matched;
|
||||
}
|
||||
// cast it to the right type.
|
||||
AcquisitionControl daqControl = (AcquisitionControl) aModule;
|
||||
AcquisitionParameters daqParams = daqControl.getAcquisitionParameters();
|
||||
/**
|
||||
* The daqParams class has most of what we need about the set up in terms of sample rate,
|
||||
* number of channels, instrument type, ADC input range (part of calibration), etc.
|
||||
* It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers.
|
||||
* Realistically, this list is always 0,1,2,etc or it goes horribly wrong !
|
||||
*/
|
||||
// so write functions here to get information from the daqParams.
|
||||
// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(),
|
||||
// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak);
|
||||
/**
|
||||
* then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map
|
||||
* but the datamap is a simple count of what's in the databasase which is not quite what we want.
|
||||
* we're going to have to query the database to get more detailed informatoin I think.
|
||||
* I'll do that here for now, but we may want to move this when we better organise the code.
|
||||
* It also seems that there are 'bad' dates in the database when it starts new files, which are the date
|
||||
* data were analysed at. So we really need to check the start and stop records only.
|
||||
*/
|
||||
PamDataBlock<DaqStatusDataUnit> daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock();
|
||||
// just load everything. Probably OK for the acqusition, but will bring down
|
||||
daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null);
|
||||
ArrayList<DaqStatusDataUnit> allStatusData = daqInfoDataBlock.getDataCopy();
|
||||
long dataStart = Long.MAX_VALUE;
|
||||
long dataEnd = Long.MIN_VALUE;
|
||||
if (allStatusData != null && allStatusData.size() > 0) {
|
||||
// find the number of times it started and stopped ....
|
||||
int nStart = 0, nStop = 0, nFile=0;
|
||||
for (DaqStatusDataUnit daqStatus : allStatusData) {
|
||||
switch (daqStatus.getStatus()) {
|
||||
case "Start":
|
||||
nStart++;
|
||||
dataStart = Math.min(dataStart, daqStatus.getTimeMilliseconds());
|
||||
break;
|
||||
case "Stop":
|
||||
nStop++;
|
||||
dataEnd = Math.max(dataEnd, daqStatus.getEndTimeInMilliseconds());
|
||||
break;
|
||||
case "NextFile":
|
||||
nFile++;
|
||||
break;
|
||||
}
|
||||
for (RecordingPeriod period : deploymentOverview.getRecordingPeriods()) {
|
||||
if (period.getMatchedTethysDeployment() != null) {
|
||||
matched.add(period.getMatchedTethysDeployment());
|
||||
}
|
||||
|
||||
// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n",
|
||||
// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1);
|
||||
|
||||
}
|
||||
|
||||
// // and we find the datamap within that ...
|
||||
// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl());
|
||||
// if (daqMap != null) {
|
||||
// // iterate through it.
|
||||
// long dataStart = daqMap.getFirstDataTime();
|
||||
// long dataEnd = daqMap.getLastDataTime();
|
||||
// List<OfflineDataMapPoint> mapPoints = daqMap.getMapPoints();
|
||||
// System.out.printf("Input map of sound data indicates data from %s to %s with %d individual files\n",
|
||||
// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), mapPoints.size());
|
||||
// /*
|
||||
// * clearly in the first database I've been looking at of Tinas data, this is NOT getting sensible start and
|
||||
// * end times. Print them out to see what's going on.
|
||||
// */
|
||||
//// for ()
|
||||
// }
|
||||
DeploymentRecoveryPair pair = new DeploymentRecoveryPair();
|
||||
DeploymentRecoveryDetails deployment = new DeploymentRecoveryDetails();
|
||||
DeploymentRecoveryDetails recovery = new DeploymentRecoveryDetails();
|
||||
pair.deploymentDetails = deployment;
|
||||
pair.recoveryDetails = recovery;
|
||||
|
||||
deployment.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart));
|
||||
deployment.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart));
|
||||
recovery.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd));
|
||||
recovery.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd));
|
||||
|
||||
ArrayList<DeploymentRecoveryPair> drPairs = new ArrayList<>();
|
||||
drPairs.add(pair);
|
||||
return drPairs;
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
public Deployment createDeploymentDocument(int i, DeploymentRecoveryPair drd) {
|
||||
/**
|
||||
* Get a list of instruments from the current project deployments.
|
||||
* This may be a shorter list than the list of deployments.
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<PInstrument> getProjectInstruments() {
|
||||
if (projectDeployments == null) {
|
||||
return null;
|
||||
}
|
||||
ArrayList<PInstrument> instruments = new ArrayList<>();
|
||||
for (PDeployment aDepl : projectDeployments) {
|
||||
Instrument intr = aDepl.deployment.getInstrument();
|
||||
if (intr == null) {
|
||||
continue;
|
||||
}
|
||||
PInstrument pInstr = new PInstrument(intr.getType(), intr.getInstrumentId());
|
||||
if (instruments.contains(pInstr) == false) {
|
||||
instruments.add(pInstr);
|
||||
}
|
||||
}
|
||||
return instruments;
|
||||
}
|
||||
//in each channel
|
||||
// public ArrayList<DeploymentRecoveryPair> getDeployments() {
|
||||
//
|
||||
// DeploymentOverview recordingOverview = this.deploymentOverview;
|
||||
//
|
||||
// // first find an acquisition module.
|
||||
// PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||
// if (!(aModule instanceof AcquisitionControl)) {
|
||||
// // will return if it's null. Impossible for it to be the wrong type.
|
||||
// // but it's good practice to check anyway before casting.
|
||||
// return null;
|
||||
// }
|
||||
// // cast it to the right type.
|
||||
// AcquisitionControl daqControl = (AcquisitionControl) aModule;
|
||||
// AcquisitionParameters daqParams = daqControl.getAcquisitionParameters();
|
||||
// /**
|
||||
// * The daqParams class has most of what we need about the set up in terms of sample rate,
|
||||
// * number of channels, instrument type, ADC input range (part of calibration), etc.
|
||||
// * It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers.
|
||||
// * Realistically, this list is always 0,1,2,etc or it goes horribly wrong !
|
||||
// */
|
||||
// // so write functions here to get information from the daqParams.
|
||||
//// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(),
|
||||
//// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak);
|
||||
// /**
|
||||
// * then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map
|
||||
// * but the datamap is a simple count of what's in the databasase which is not quite what we want.
|
||||
// * we're going to have to query the database to get more detailed informatoin I think.
|
||||
// * I'll do that here for now, but we may want to move this when we better organise the code.
|
||||
// * It also seems that there are 'bad' dates in the database when it starts new files, which are the date
|
||||
// * data were analysed at. So we really need to check the start and stop records only.
|
||||
// */
|
||||
// PamDataBlock<DaqStatusDataUnit> daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock();
|
||||
// // just load everything. Probably OK for the acqusition, but will bring down
|
||||
// daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null);
|
||||
// ArrayList<DaqStatusDataUnit> allStatusData = daqInfoDataBlock.getDataCopy();
|
||||
// long dataStart = Long.MAX_VALUE;
|
||||
// long dataEnd = Long.MIN_VALUE;
|
||||
// if (allStatusData != null && allStatusData.size() > 0) {
|
||||
// // find the number of times it started and stopped ....
|
||||
// int nStart = 0, nStop = 0, nFile=0;
|
||||
// for (DaqStatusDataUnit daqStatus : allStatusData) {
|
||||
// switch (daqStatus.getStatus()) {
|
||||
// case "Start":
|
||||
// nStart++;
|
||||
// dataStart = Math.min(dataStart, daqStatus.getTimeMilliseconds());
|
||||
// break;
|
||||
// case "Stop":
|
||||
// nStop++;
|
||||
// dataEnd = Math.max(dataEnd, daqStatus.getEndTimeInMilliseconds());
|
||||
// break;
|
||||
// case "NextFile":
|
||||
// nFile++;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n",
|
||||
//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//// // and we find the datamap within that ...
|
||||
//// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl());
|
||||
//// if (daqMap != null) {
|
||||
//// // iterate through it.
|
||||
//// long dataStart = daqMap.getFirstDataTime();
|
||||
//// long dataEnd = daqMap.getLastDataTime();
|
||||
//// List<OfflineDataMapPoint> mapPoints = daqMap.getMapPoints();
|
||||
//// System.out.printf("Input map of sound data indicates data from %s to %s with %d individual files\n",
|
||||
//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), mapPoints.size());
|
||||
//// /*
|
||||
//// * clearly in the first database I've been looking at of Tinas data, this is NOT getting sensible start and
|
||||
//// * end times. Print them out to see what's going on.
|
||||
//// */
|
||||
////// for ()
|
||||
//// }
|
||||
// DeploymentRecoveryPair pair = new DeploymentRecoveryPair();
|
||||
// DeploymentRecoveryDetails deployment = new DeploymentRecoveryDetails();
|
||||
// DeploymentRecoveryDetails recovery = new DeploymentRecoveryDetails();
|
||||
// pair.deploymentDetails = deployment;
|
||||
// pair.recoveryDetails = recovery;
|
||||
//
|
||||
// deployment.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart));
|
||||
// deployment.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart));
|
||||
// recovery.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd));
|
||||
// recovery.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd));
|
||||
//
|
||||
// ArrayList<DeploymentRecoveryPair> drPairs = new ArrayList<>();
|
||||
// drPairs.add(pair);
|
||||
// return drPairs;
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the first free deploymendId. This will get appended to
|
||||
* the ProjectName to make and id for each Deployment document
|
||||
* @return
|
||||
*/
|
||||
public int getFirstFreeDeploymentId() {
|
||||
/**
|
||||
* This is an integer used for the DeploymentId. Note that the String Id (currentl9) is just the Project name
|
||||
* appended with this number.
|
||||
*/
|
||||
int firstFree = 0;
|
||||
if (projectDeployments != null) {
|
||||
for (PDeployment dep : projectDeployments) {
|
||||
firstFree = Math.max(firstFree, dep.deployment.getDeploymentId()+1);
|
||||
}
|
||||
}
|
||||
return firstFree;
|
||||
}
|
||||
|
||||
public Deployment createDeploymentDocument(int i, RecordingPeriod recordingPeriod) {
|
||||
Deployment deployment = new Deployment();
|
||||
try {
|
||||
nilus.Helper.createRequiredElements(deployment);
|
||||
@ -304,17 +504,26 @@ public class DeploymentHandler {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
String id = String.format("%d", i);
|
||||
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
String id = String.format("%s%d", globalDeplData.getProject(), i);
|
||||
deployment.setId(id);
|
||||
deployment.setDeploymentId(i);
|
||||
deployment.setDeploymentDetails(drd.deploymentDetails);
|
||||
deployment.setRecoveryDetails(drd.recoveryDetails);
|
||||
|
||||
DeploymentRecoveryDetails deploymentDetails = new DeploymentRecoveryDetails();
|
||||
DeploymentRecoveryDetails recoveryDetails = new DeploymentRecoveryDetails();
|
||||
deploymentDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart()));
|
||||
deploymentDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart()));
|
||||
recoveryDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop()));
|
||||
recoveryDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop()));
|
||||
|
||||
deployment.setDeploymentDetails(deploymentDetails);
|
||||
deployment.setRecoveryDetails(recoveryDetails);
|
||||
|
||||
TethysLocationFuncs.getTrackAndPositionData(deployment);
|
||||
|
||||
getProjectData(deployment);
|
||||
|
||||
getSamplingDetails(deployment);
|
||||
getSamplingDetails(deployment, recordingPeriod);
|
||||
|
||||
getSensorDetails(deployment);
|
||||
|
||||
@ -354,11 +563,11 @@ public class DeploymentHandler {
|
||||
deployment.setDeploymentAlias(deploymentData.getDeploymentAlias());
|
||||
deployment.setSite(deploymentData.getSite());
|
||||
deployment.setCruise(deploymentData.getCruise());
|
||||
deployment.setPlatform(deploymentData.getPlatform());
|
||||
deployment.setPlatform(getPlatform());
|
||||
deployment.setRegion(deploymentData.getRegion());
|
||||
Instrument instrument = new Instrument();
|
||||
instrument.setType(deploymentData.getInstrumentType());
|
||||
instrument.setInstrumentId(deploymentData.getInstrumentId());
|
||||
instrument.setType(getInstrumentType());
|
||||
instrument.setInstrumentId(getInstrumentId());
|
||||
// get the geometry type from the array manager.
|
||||
String geomType = getGeometryType();
|
||||
instrument.setGeometryType(geomType);
|
||||
@ -366,6 +575,62 @@ public class DeploymentHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instrument identifier, e.g. serial number
|
||||
* @return
|
||||
*/
|
||||
private String getInstrumentId() {
|
||||
return ArrayManager.getArrayManager().getCurrentArray().getInstrumentId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if it's possible to export Deployment documents. This is basically a test of
|
||||
* various metadata fields that are required, such as instrument id's.
|
||||
* @return null if OK, or a string describing the first encountered error
|
||||
*/
|
||||
public String canExportDeployments() {
|
||||
|
||||
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
if (globalDeplData.getProject() == null) {
|
||||
return "You must set a project name";
|
||||
}
|
||||
|
||||
PInstrument arrayInstrument = getCurrentArrayInstrument();
|
||||
if (arrayInstrument == null) {
|
||||
return "No 'Instrument' set. Goto array manager";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Instrument info for the current array.
|
||||
* @return
|
||||
*/
|
||||
public PInstrument getCurrentArrayInstrument() {
|
||||
PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
||||
String currType = currentArray.getInstrumentType();
|
||||
String currId = currentArray.getInstrumentId();
|
||||
PInstrument currentInstrument = null;
|
||||
if (currType != null || currId != null) {
|
||||
currentInstrument = new PInstrument(currType, currId);
|
||||
}
|
||||
return currentInstrument;
|
||||
}
|
||||
|
||||
/**
|
||||
* On what platform is the instrument deployed? (e.g. mooring, tag)
|
||||
* @return
|
||||
*/
|
||||
private String getPlatform() {
|
||||
return getGeometryType();
|
||||
}
|
||||
/**
|
||||
* Instrument type, e.g. HARP, EAR, Popup, DMON, Rock Hopper, etc.
|
||||
* @return
|
||||
*/
|
||||
private String getInstrumentType() {
|
||||
return ArrayManager.getArrayManager().getCurrentArray().getInstrumentType();
|
||||
}
|
||||
/**
|
||||
* Get a geometry type string for Tethys based on information in the array manager.
|
||||
* @return
|
||||
@ -445,8 +710,9 @@ public class DeploymentHandler {
|
||||
/**
|
||||
* Fill in the sampling details in a Deployment document.
|
||||
* @param deployment
|
||||
* @param recordingPeriod
|
||||
*/
|
||||
private boolean getSamplingDetails(Deployment deployment) {
|
||||
private boolean getSamplingDetails(Deployment deployment, RecordingPeriod recordingPeriod) {
|
||||
SamplingDetails samplingDetails = new SamplingDetails();
|
||||
// this is basically going to be a list of almost identical channel information
|
||||
// currently just for the first acquisition. May extend to more.
|
||||
@ -496,6 +762,23 @@ public class DeploymentHandler {
|
||||
regimen.setSampleBits(system.getSampleBits());
|
||||
}
|
||||
regimens.add(regimen);
|
||||
|
||||
DutyCycleInfo dutyCycleInf = deploymentOverview.getDutyCycleInfo();
|
||||
boolean isDS = dutyCycleInf != null && dutyCycleInf.isDutyCycled;
|
||||
if (isDS) {
|
||||
DutyCycle dutyCycle = new DutyCycle();
|
||||
List<nilus.ChannelInfo.DutyCycle.Regimen> reg = dutyCycle.getRegimen();
|
||||
nilus.ChannelInfo.DutyCycle.Regimen dsr = new nilus.ChannelInfo.DutyCycle.Regimen();
|
||||
reg.add(dsr);
|
||||
RecordingDurationS ssss = new RecordingDurationS();
|
||||
ssss.setValue(dutyCycleInf.meanOnTimeS);
|
||||
dsr.setRecordingDurationS(ssss);
|
||||
RecordingIntervalS ris = new RecordingIntervalS();
|
||||
ris.setValue(dutyCycleInf.meanOnTimeS + dutyCycleInf.meanGapS);
|
||||
dsr.setRecordingIntervalS(ris);
|
||||
dsr.setTimeStamp(deployment.getDeploymentDetails().getAudioTimeStamp());
|
||||
channelInfo.setDutyCycle(dutyCycle);
|
||||
}
|
||||
|
||||
channelInfo.setSampling(sampling);
|
||||
|
||||
|
@ -14,14 +14,15 @@ public class DeploymentOverview {
|
||||
|
||||
private ArrayList<RecordingPeriod> recordingPeriods = new ArrayList<>();
|
||||
|
||||
private boolean dutyCycled;
|
||||
private DutyCycleInfo dutyCycleInfo;
|
||||
|
||||
public DeploymentOverview(boolean dutyCycled) {
|
||||
public DeploymentOverview(DutyCycleInfo dutyCycleInfo) {
|
||||
super();
|
||||
this.dutyCycled = dutyCycled;
|
||||
this.dutyCycleInfo = dutyCycleInfo;
|
||||
}
|
||||
|
||||
public DeploymentOverview(boolean b, ArrayList<RecordingPeriod> tempPeriods) {
|
||||
public DeploymentOverview(DutyCycleInfo dutyCycleInfo, ArrayList<RecordingPeriod> tempPeriods) {
|
||||
this.dutyCycleInfo = dutyCycleInfo;
|
||||
this.recordingPeriods = tempPeriods;
|
||||
}
|
||||
|
||||
@ -33,17 +34,35 @@ public class DeploymentOverview {
|
||||
recordingPeriods.add(recordingPeriod);
|
||||
}
|
||||
|
||||
public boolean isDutyCycled() {
|
||||
return dutyCycled;
|
||||
}
|
||||
|
||||
public void setDutyCycled(boolean dutyCycled) {
|
||||
this.dutyCycled = dutyCycled;
|
||||
}
|
||||
|
||||
public ArrayList<RecordingPeriod> getRecordingPeriods() {
|
||||
return recordingPeriods;
|
||||
}
|
||||
|
||||
public DutyCycleInfo getDutyCycleInfo() {
|
||||
return dutyCycleInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start time of the first recording
|
||||
* @return
|
||||
*/
|
||||
public Long getFirstStart() {
|
||||
if (recordingPeriods.size() > 0) {
|
||||
return recordingPeriods.get(0).getRecordStart();
|
||||
}
|
||||
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();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -4,8 +4,8 @@ import nilus.DeploymentRecoveryDetails;
|
||||
|
||||
public class DeploymentRecoveryPair {
|
||||
|
||||
public DeploymentRecoveryDetails deploymentDetails;
|
||||
|
||||
public DeploymentRecoveryDetails recoveryDetails;
|
||||
// public DeploymentRecoveryDetails deploymentDetails;
|
||||
//
|
||||
// public DeploymentRecoveryDetails recoveryDetails;
|
||||
|
||||
}
|
||||
|
@ -2,4 +2,32 @@ package tethys.deployment;
|
||||
|
||||
public class DutyCycleInfo {
|
||||
|
||||
public boolean isDutyCycled;
|
||||
|
||||
public double meanOnTimeS;
|
||||
|
||||
public double meanGapS;
|
||||
|
||||
int nCycles;
|
||||
|
||||
public DutyCycleInfo(boolean isDutyCycled, double meanOnTimeS, double meanGapS, int nCycles) {
|
||||
super();
|
||||
this.isDutyCycled = isDutyCycled;
|
||||
this.meanOnTimeS = meanOnTimeS;
|
||||
this.meanGapS = meanGapS;
|
||||
this.nCycles = nCycles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isDutyCycled == false) {
|
||||
return "No duty cycle";
|
||||
}
|
||||
else {
|
||||
return String.format("%3.1fs on, %3.1fs off, for %d cycles", meanOnTimeS, meanGapS, nCycles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
49
src/tethys/deployment/PInstrument.java
Normal file
49
src/tethys/deployment/PInstrument.java
Normal file
@ -0,0 +1,49 @@
|
||||
package tethys.deployment;
|
||||
|
||||
/**
|
||||
* Class to handle instrument information
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class PInstrument {
|
||||
|
||||
public String instrumentType;
|
||||
|
||||
public String instrumentId;
|
||||
|
||||
public PInstrument(String instrumentType, String instrumentId) {
|
||||
super();
|
||||
this.instrumentType = instrumentType;
|
||||
this.instrumentId = instrumentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof PInstrument == false) {
|
||||
return false;
|
||||
}
|
||||
PInstrument other = (PInstrument) obj;
|
||||
boolean eq = true;
|
||||
if (this.instrumentType != null) {
|
||||
eq &= this.instrumentType.equals(other.instrumentType);
|
||||
}
|
||||
if (this.instrumentId != null) {
|
||||
eq &= this.instrumentId.equals(other.instrumentId);
|
||||
}
|
||||
if (other.instrumentType != null) {
|
||||
eq &= other.instrumentType.equals(this.instrumentType);
|
||||
}
|
||||
if (other.instrumentId != null) {
|
||||
eq &= other.instrumentId.equals(this.instrumentId);
|
||||
}
|
||||
|
||||
return eq;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s : %s", instrumentType == null ? "Undefined" : instrumentType, instrumentId);
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,18 @@
|
||||
package tethys.deployment;
|
||||
|
||||
import tethys.niluswraps.PDeployment;
|
||||
|
||||
public class RecordingPeriod {
|
||||
|
||||
private long recordStart;
|
||||
|
||||
private long recordStop;
|
||||
|
||||
/**
|
||||
* Reference to a matched nilus Deployment document retrieved
|
||||
* from the database.
|
||||
*/
|
||||
private PDeployment matchedTethysDeployment;
|
||||
|
||||
public RecordingPeriod(long recordStart, long recordStop) {
|
||||
super();
|
||||
@ -31,6 +39,14 @@ public class RecordingPeriod {
|
||||
public long getDuration() {
|
||||
return recordStop-recordStart;
|
||||
}
|
||||
|
||||
public PDeployment getMatchedTethysDeployment() {
|
||||
return matchedTethysDeployment;
|
||||
}
|
||||
|
||||
public void setMatchedTethysDeployment(PDeployment closestDeployment) {
|
||||
this.matchedTethysDeployment = closestDeployment;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.dataSelector.DataSelector;
|
||||
import dataMap.OfflineDataMap;
|
||||
import dataMap.OfflineDataMapPoint;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.DataSourceType;
|
||||
import nilus.Deployment;
|
||||
import nilus.Detection;
|
||||
@ -143,9 +144,12 @@ public class DetectionsHandler {
|
||||
/*
|
||||
* Here, make Detection object and add the DetectionEffort data.
|
||||
*/
|
||||
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
TethysDataProvider dataProvider = dataBlock.getTethysDataProvider();
|
||||
Detections detections = new Detections();
|
||||
detections.setId(String.format("%d", uniqueDetectionsId++));
|
||||
// String prefix = getDetectionsDocIdPrefix(globalDeplData.getProject(), dataBlock);
|
||||
String prefix = deployment.getId();
|
||||
detections.setId(String.format("%s_%d", prefix, uniqueDetectionsId++));
|
||||
detections.setDescription(dataProvider.getDescription(deployment, tethysExportParams));
|
||||
DataSourceType dataSource = new DataSourceType();
|
||||
dataSource.setDeploymentId(deployment.getId());
|
||||
@ -214,4 +218,15 @@ public class DetectionsHandler {
|
||||
return effort;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get a prefix for a id for a Detections document. This is just the project name
|
||||
// * and the datablock name. Something may need to be added to allow for multiple
|
||||
// * analysis going into one database.
|
||||
// * @param project
|
||||
// * @param dataBlock
|
||||
// * @return Detections document prefix.
|
||||
// */
|
||||
// public static final String getDetectionsDocIdPrefix(String project, PamDataBlock dataBlock) {
|
||||
// return project + "_" + dataBlock.getDataName();
|
||||
// }
|
||||
}
|
||||
|
55
src/tethys/niluswraps/PDeployment.java
Normal file
55
src/tethys/niluswraps/PDeployment.java
Normal file
@ -0,0 +1,55 @@
|
||||
package tethys.niluswraps;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import nilus.Deployment;
|
||||
import nilus.DeploymentRecoveryDetails;
|
||||
import tethys.TethysTimeFuncs;
|
||||
import tethys.deployment.RecordingPeriod;
|
||||
/**
|
||||
* Wrapper around a nilus Deployment object to provide a bit of extra bookkeeping
|
||||
* and functionality for PAMGuard.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class PDeployment {
|
||||
|
||||
public Deployment deployment;
|
||||
private RecordingPeriod matchedPAMGaurdPeriod;
|
||||
|
||||
public PDeployment(Deployment deployment) {
|
||||
super();
|
||||
this.deployment = deployment;
|
||||
}
|
||||
|
||||
public Long getAudioStart() {
|
||||
DeploymentRecoveryDetails detail = deployment.getDeploymentDetails();
|
||||
if (detail == null) {
|
||||
return null;
|
||||
}
|
||||
return TethysTimeFuncs.millisFromGregorianXML(detail.getAudioTimeStamp());
|
||||
}
|
||||
|
||||
public Long getAudioEnd() {
|
||||
DeploymentRecoveryDetails detail = deployment.getRecoveryDetails();
|
||||
if (detail == null) {
|
||||
return null;
|
||||
}
|
||||
return TethysTimeFuncs.millisFromGregorianXML(detail.getAudioTimeStamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s:%d; %s - %s", deployment.getId(), deployment.getDeploymentId(),
|
||||
PamCalendar.formatDBDateTime(getAudioStart()), PamCalendar.formatDBDateTime(getAudioEnd()));
|
||||
}
|
||||
|
||||
public RecordingPeriod getMatchedPAMGaurdPeriod() {
|
||||
return matchedPAMGaurdPeriod;
|
||||
}
|
||||
|
||||
public void setMatchedPAMGaurdPeriod(RecordingPeriod matchedPAMGaurdPeriod) {
|
||||
this.matchedPAMGaurdPeriod = matchedPAMGaurdPeriod;
|
||||
}
|
||||
|
||||
|
||||
}
|
48
src/tethys/output/DatablockSynchInfo.java
Normal file
48
src/tethys/output/DatablockSynchInfo.java
Normal file
@ -0,0 +1,48 @@
|
||||
package tethys.output;
|
||||
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import tethys.TethysControl;
|
||||
|
||||
/**
|
||||
* Data about a PAMDataBlock. <br>
|
||||
* All the information needed to populate a table row in the synchronisation table.
|
||||
* some will need to be set as rarely as possible since it may
|
||||
* be slow to update. <br>
|
||||
* This needs to sit alongside the StreamExportParams objects since those others are serialisable wheras
|
||||
* there is a lot of stuff in here which isn't.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class DatablockSynchInfo {
|
||||
|
||||
private PamDataBlock dataBlock;
|
||||
public PamDataBlock getDataBlock() {
|
||||
return dataBlock;
|
||||
}
|
||||
|
||||
private TethysControl tethysControl;
|
||||
private int setDataCount;
|
||||
|
||||
public DatablockSynchInfo(TethysControl tethysControl, PamDataBlock dataBlock) {
|
||||
super();
|
||||
this.tethysControl = tethysControl;
|
||||
this.dataBlock = dataBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stored export params for this data block
|
||||
* @return
|
||||
*/
|
||||
public StreamExportParams getExportParams() {
|
||||
return tethysControl.getTethysExportParams().getStreamParams(dataBlock);
|
||||
}
|
||||
|
||||
public void setDataCount(int n) {
|
||||
this.setDataCount = n;
|
||||
}
|
||||
|
||||
public int getDataCount() {
|
||||
return setDataCount;
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package tethys.output;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import metadata.deployment.DeploymentData;
|
||||
|
||||
|
||||
/**
|
||||
@ -28,6 +29,8 @@ public class TethysExportParams implements Serializable, Cloneable{
|
||||
|
||||
private HashMap<String, StreamExportParams> streamParamsMap = new HashMap();
|
||||
|
||||
private DeploymentData deploymentData;
|
||||
|
||||
@Override
|
||||
public TethysExportParams clone() {
|
||||
try {
|
||||
@ -63,4 +66,11 @@ public class TethysExportParams implements Serializable, Cloneable{
|
||||
return streamParamsMap.get(longDataName);
|
||||
}
|
||||
|
||||
public DeploymentData getProjectData() {
|
||||
if (deploymentData == null) {
|
||||
deploymentData = new DeploymentData();
|
||||
}
|
||||
return deploymentData;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ import nilus.Deployment;
|
||||
import tethys.TethysControl;
|
||||
import tethys.dbxml.DBXMLConnect;
|
||||
import tethys.deployment.DeploymentHandler;
|
||||
import tethys.deployment.DeploymentOverview;
|
||||
import tethys.deployment.DeploymentRecoveryPair;
|
||||
import tethys.deployment.RecordingPeriod;
|
||||
import tethys.detection.DetectionGranularity;
|
||||
import tethys.detection.DetectionGranularity.GRANULARITY;
|
||||
import tethys.detection.DetectionsHandler;
|
||||
@ -168,21 +170,23 @@ public class TethysExporter {
|
||||
//get list of deployment recovery details (start, stop times and lat/long)
|
||||
//deployment details and recovery details are same structure
|
||||
//per pair, go through a loop to fill in each deployment
|
||||
DeploymentHandler deploymentHandler = new DeploymentHandler(tethysControl);
|
||||
// DeploymentHandler deploymentHandler = new DeploymentHandler(tethysControl);
|
||||
DeploymentHandler deploymentHandler = tethysControl.getDeploymentHandler();
|
||||
|
||||
ArrayList<DeploymentRecoveryPair> deployRecover = deploymentHandler.getDeployments();
|
||||
if (deployRecover == null) {
|
||||
return false;
|
||||
}
|
||||
// ArrayList<DeploymentRecoveryPair> deployRecover = deploymentHandler.getDeployments();
|
||||
// if (deployRecover == null) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
ArrayList<Deployment> deploymentDocs = new ArrayList<>();
|
||||
/*
|
||||
* This will become the main loop over deployment documents
|
||||
*/
|
||||
int i = 0;
|
||||
for (DeploymentRecoveryPair drd : deployRecover) {
|
||||
DeploymentOverview deploymentOverview = deploymentHandler.getDeploymentOverview();
|
||||
int i = deploymentHandler.getFirstFreeDeploymentId();
|
||||
for (RecordingPeriod recordingPeriod : deploymentOverview.getRecordingPeriods()) {
|
||||
|
||||
Deployment deployment = deploymentHandler.createDeploymentDocument(i++, drd);
|
||||
Deployment deployment = deploymentHandler.createDeploymentDocument(i++, recordingPeriod);
|
||||
// System.out.println(deployment.toString());
|
||||
deploymentDocs.add(deployment);
|
||||
|
||||
@ -196,10 +200,10 @@ public class TethysExporter {
|
||||
*/
|
||||
DetectionsHandler detectionsHandler = new DetectionsHandler(tethysControl);
|
||||
ArrayList<PamDataBlock> allDataBlocks = PamController.getInstance().getDataBlocks();
|
||||
/**
|
||||
* Outer loop is through deployemnt documents. Will then export detections within each
|
||||
* deployment detector by detector
|
||||
*/
|
||||
// /**
|
||||
// * Outer loop is through deployemnt documents. Will then export detections within each
|
||||
// * deployment detector by detector
|
||||
// */
|
||||
for (Deployment aDeployment : deploymentDocs) {
|
||||
for (PamDataBlock aDataBlock : allDataBlocks) {
|
||||
StreamExportParams streamExportParams = tethysExportParams.getStreamParams(aDataBlock);
|
||||
@ -207,7 +211,7 @@ public class TethysExporter {
|
||||
continue; // not interested in this one.
|
||||
}
|
||||
detectionsHandler.exportDetections(aDataBlock, aDeployment,
|
||||
new DetectionGranularity(GRANULARITY.TIME, 3600), tethysExportParams, streamExportParams);
|
||||
new DetectionGranularity(GRANULARITY.TIME, 3600*12), tethysExportParams, streamExportParams);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -84,7 +84,7 @@ public class AutoTethysProvider implements TethysDataProvider {
|
||||
String fullUnitName = pamControlledUnit.getUnitType() + " " + pamControlledUnit.getUnitName();
|
||||
description.setAbstract(fullUnitName);
|
||||
description.setObjectives(fullUnitName);
|
||||
description.setMethod(pamControlledUnit.getUnitType());
|
||||
description.setMethod(pamDataBlock.getLongDataName());
|
||||
|
||||
return description;
|
||||
}
|
||||
|
112
src/tethys/swing/DatablockSynchPanel.java
Normal file
112
src/tethys/swing/DatablockSynchPanel.java
Normal file
@ -0,0 +1,112 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import PamView.panel.PamPanel;
|
||||
import PamView.tables.SwingTableColumnWidths;
|
||||
import dataMap.OfflineDataMap;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
import tethys.output.DatablockSynchInfo;
|
||||
|
||||
public class DatablockSynchPanel extends TethysGUIPanel {
|
||||
|
||||
public JPanel mainPanel;
|
||||
|
||||
private JTable synchTable;
|
||||
|
||||
private SynchTableModel synchTableModel;
|
||||
|
||||
private ArrayList<DatablockSynchInfo> dataBlockSynchInfo;
|
||||
|
||||
public DatablockSynchPanel(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
mainPanel = new PamPanel(new BorderLayout());
|
||||
mainPanel.setBorder(new TitledBorder("PAMGuard data blocks"));
|
||||
synchTableModel = new SynchTableModel();
|
||||
synchTable = new JTable(synchTableModel);
|
||||
new SwingTableColumnWidths(tethysControl.getUnitName()+"SynchTable", synchTable);
|
||||
JScrollPane scrollPane = new JScrollPane(synchTable);
|
||||
mainPanel.add(BorderLayout.CENTER, scrollPane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateState(TethysState tethysState) {
|
||||
synchTableModel.fireTableDataChanged();
|
||||
}
|
||||
|
||||
private ArrayList<DatablockSynchInfo> getSychInfos() {
|
||||
if (dataBlockSynchInfo == null) {
|
||||
dataBlockSynchInfo = getTethysControl().getSynchronisationInfos();
|
||||
}
|
||||
return dataBlockSynchInfo;
|
||||
}
|
||||
|
||||
private class SynchTableModel extends AbstractTableModel {
|
||||
|
||||
String[] columnNames = {"Data Stream", "N PAM Datas", "PAMGuard Time", "N Tethys Datas", "Tethys Time", "Options"};
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return getSychInfos().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
DatablockSynchInfo synchInfo = getSychInfos().get(rowIndex);
|
||||
return getValueAt(synchInfo, columnIndex);
|
||||
}
|
||||
|
||||
private Object getValueAt(DatablockSynchInfo synchInfo, int columnIndex) {
|
||||
OfflineDataMap dataMap = synchInfo.getDataBlock().getPrimaryDataMap();
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return synchInfo.getDataBlock().getDataName();
|
||||
case 1:
|
||||
if (dataMap == null) {
|
||||
return null;
|
||||
}
|
||||
return synchInfo.getDataBlock().getPrimaryDataMap().getDataCount();
|
||||
case 2:
|
||||
if (dataMap == null) {
|
||||
return null;
|
||||
}
|
||||
if (dataMap.getDataCount() == 0) {
|
||||
return "No data";
|
||||
}
|
||||
long start = synchInfo.getDataBlock().getPrimaryDataMap().getFirstDataTime();
|
||||
long stop = synchInfo.getDataBlock().getPrimaryDataMap().getLastDataTime();
|
||||
return String.format("%s - %s", PamCalendar.formatDBDateTime(start), PamCalendar.formatDBDateTime(stop));
|
||||
case 3:
|
||||
return synchInfo.getDataCount();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
48
src/tethys/swing/DeploymentsPanel.java
Normal file
48
src/tethys/swing/DeploymentsPanel.java
Normal file
@ -0,0 +1,48 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.panel.PamPanel;
|
||||
import tethys.TethysControl;
|
||||
|
||||
public class DeploymentsPanel extends TethysGUIPanel {
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private PAMGuardDeploymentsTable pamDeploymentsTable;
|
||||
|
||||
private TethysDeploymentsTable tethysDeploymentsTable;
|
||||
|
||||
public DeploymentsPanel(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
pamDeploymentsTable = new PAMGuardDeploymentsTable(tethysControl);
|
||||
tethysDeploymentsTable = new TethysDeploymentsTable(tethysControl);
|
||||
mainPanel = new PamPanel(new BorderLayout());
|
||||
mainPanel.setBorder(new TitledBorder("Deployment information"));
|
||||
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
splitPane.add(pamDeploymentsTable.getComponent());
|
||||
splitPane.add(tethysDeploymentsTable.getComponent());
|
||||
mainPanel.add(splitPane,BorderLayout.CENTER);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
splitPane.setDividerLocation(0.6);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
91
src/tethys/swing/NewProjectDialog.java
Normal file
91
src/tethys/swing/NewProjectDialog.java
Normal file
@ -0,0 +1,91 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Window;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import tethys.TethysControl;
|
||||
|
||||
public class NewProjectDialog extends PamView.dialog.PamDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static NewProjectDialog singleInstance;
|
||||
|
||||
private JTextField projectName;
|
||||
|
||||
private JTextField projectRegion;
|
||||
|
||||
private DeploymentData deploymentData;
|
||||
|
||||
private NewProjectDialog(Window parentFrame, TethysControl tethysControl) {
|
||||
super(parentFrame, "New Project", false);
|
||||
JPanel mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.setBorder(new TitledBorder("Project details"));
|
||||
GridBagConstraints c = new PamGridBagContraints();
|
||||
mainPanel.add(new JLabel("Project name ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(projectName = new JTextField(30), c);
|
||||
c.gridx = 0;
|
||||
c.gridy++;
|
||||
mainPanel.add(new JLabel("Geographic region ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(projectRegion = new JTextField(30), c);
|
||||
|
||||
projectName.setToolTipText("Name of project associated with this deployment. Can be related to a geographic region, funding source, etc");
|
||||
projectRegion.setToolTipText("Name of geographic region (optional)");
|
||||
|
||||
setDialogComponent(mainPanel);
|
||||
}
|
||||
|
||||
public static DeploymentData showDialog(Window parent, TethysControl tethysControl, DeploymentData deploymentData) {
|
||||
if (singleInstance == null) {
|
||||
singleInstance = new NewProjectDialog(parent, tethysControl);
|
||||
}
|
||||
singleInstance.setParams(deploymentData);
|
||||
singleInstance.setVisible(true);
|
||||
return singleInstance.deploymentData;
|
||||
}
|
||||
|
||||
private void setParams(DeploymentData deploymentData) {
|
||||
if (deploymentData == null) {
|
||||
return;
|
||||
}
|
||||
this.deploymentData = deploymentData;
|
||||
projectName.setText(deploymentData.getProject());
|
||||
projectRegion.setText(deploymentData.getRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getParams() {
|
||||
if (deploymentData == null) {
|
||||
return false;
|
||||
}
|
||||
deploymentData.setProject(projectName.getText());
|
||||
deploymentData.setRegion(projectRegion.getText());
|
||||
if (deploymentData.getProject() == null || deploymentData.getProject().length() == 0) {
|
||||
return showWarning("you must specify a project name");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelButtonPressed() {
|
||||
deploymentData = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreDefaultSettings() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
215
src/tethys/swing/PAMGuardDeploymentsTable.java
Normal file
215
src/tethys/swing/PAMGuardDeploymentsTable.java
Normal file
@ -0,0 +1,215 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import PamView.panel.PamPanel;
|
||||
import PamView.tables.SwingTableColumnWidths;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
import tethys.deployment.DeploymentHandler;
|
||||
import tethys.deployment.DeploymentOverview;
|
||||
import tethys.deployment.RecordingPeriod;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
|
||||
/**
|
||||
* Table view of PAMGuard deployments. For a really simple deployment, this may have only
|
||||
* one line. For towed surveys where we stop and start a lot, it may have a LOT of lines.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class PAMGuardDeploymentsTable extends TethysGUIPanel {
|
||||
|
||||
private TableModel tableModel;
|
||||
|
||||
private JTable table;
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private DeploymentOverview deploymentOverview;
|
||||
|
||||
public PAMGuardDeploymentsTable(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
// deploymentHandler = new DeploymentHandler(getTethysControl());
|
||||
mainPanel = new PamPanel(new BorderLayout());
|
||||
mainPanel.setBorder(new TitledBorder("PAMGuard recording periods"));
|
||||
tableModel = new TableModel();
|
||||
table = new JTable(tableModel);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.addMouseListener(new TableMouse());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
mainPanel.add(BorderLayout.CENTER, scrollPane);
|
||||
new SwingTableColumnWidths(tethysControl.getUnitName()+"PAMDeploymensTable", table);
|
||||
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private class TableMouse extends MouseAdapter {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
showPopup();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
showPopup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void showPopup() {
|
||||
int aRow = table.getSelectedRow();
|
||||
int[] selRows = table.getSelectedRows();
|
||||
if (selRows == null || selRows.length == 0) {
|
||||
if (aRow >= 0) {
|
||||
selRows = new int[1];
|
||||
selRows[0] = aRow;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// make a list of RecordingPeriods which don't currently have a Deployment document
|
||||
ArrayList<RecordingPeriod> newPeriods = new ArrayList<>();
|
||||
ArrayList<RecordingPeriod> allPeriods = deploymentOverview.getRecordingPeriods();
|
||||
for (int i = 0; i < selRows.length; i++) {
|
||||
if (allPeriods.get(selRows[i]).getMatchedTethysDeployment() == null) {
|
||||
newPeriods.add(allPeriods.get(i));
|
||||
}
|
||||
}
|
||||
if (newPeriods.size() == 0) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if we get here, we've one or more rows without a Tethys output, so can have
|
||||
* a menu to create them.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(TethysState tethysState) {
|
||||
switch(tethysState.stateType) {
|
||||
case NEWPROJECTSELECTION:
|
||||
case NEWPAMGUARDSELECTION:
|
||||
updateDeployments();
|
||||
break;
|
||||
case UPDATEMETADATA:
|
||||
checkExportMeta();
|
||||
}
|
||||
|
||||
tableModel.fireTableDataChanged();
|
||||
}
|
||||
|
||||
private void checkExportMeta() {
|
||||
String metaErr = getTethysControl().getDeploymentHandler().canExportDeployments();
|
||||
if (metaErr != null) {
|
||||
mainPanel.setBackground(Color.RED);
|
||||
}
|
||||
else {
|
||||
JPanel anyPanel = new JPanel();
|
||||
mainPanel.setBackground(anyPanel.getBackground());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDeployments() {
|
||||
DeploymentHandler deploymentHandler = getTethysControl().getDeploymentHandler();
|
||||
deploymentOverview = deploymentHandler.getDeploymentOverview();
|
||||
tableModel.fireTableDataChanged();
|
||||
// DeploymentData deplData = getTethysControl().getGlobalDeplopymentData();
|
||||
// ArrayList<Deployment> projectDeployments = getTethysControl().getDbxmlQueries().getProjectDeployments(deplData.getProject());
|
||||
// deploymentHandler.matchPamguard2Tethys(deploymentOverview, projectDeployments);
|
||||
}
|
||||
|
||||
private class TableModel extends AbstractTableModel {
|
||||
|
||||
private String[] columnNames = {"Id", "Start", "Stop", "Duration", "Cycle", "Tethys Deployment"};
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
if (deploymentOverview == null) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return deploymentOverview.getRecordingPeriods().size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
RecordingPeriod period = deploymentOverview.getRecordingPeriods().get(rowIndex);
|
||||
// DeploymentRecoveryPair deplInfo = deploymentInfo.get(rowIndex);
|
||||
if (columnIndex == 4) {
|
||||
return deploymentOverview.getDutyCycleInfo();
|
||||
}
|
||||
return getValueAt(period, rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
private Object getValueAt(RecordingPeriod period, int rowIndex, int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return rowIndex;
|
||||
case 1:
|
||||
return PamCalendar.formatDBDateTime(period.getRecordStart());
|
||||
// return TethysTimeFuncs.formatGregorianTime(deplInfo.deploymentDetails.getAudioTimeStamp());
|
||||
case 2:
|
||||
return PamCalendar.formatDBDateTime(period.getRecordStop());
|
||||
// return TethysTimeFuncs.formatGregorianTime(deplInfo.recoveryDetails.getAudioTimeStamp());
|
||||
case 3:
|
||||
// long t1 = TethysTimeFuncs.millisFromGregorianXML(deplInfo.deploymentDetails.getAudioTimeStamp());
|
||||
// long t2 = TethysTimeFuncs.millisFromGregorianXML(deplInfo.recoveryDetails.getAudioTimeStamp());
|
||||
return PamCalendar.formatDuration(period.getRecordStop()-period.getRecordStart());
|
||||
case 5:
|
||||
PDeployment deployment = period.getMatchedTethysDeployment();
|
||||
return makeDeplString(period, deployment);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String makeDeplString(RecordingPeriod period, PDeployment deployment) {
|
||||
if (deployment == null) {
|
||||
return "no match";
|
||||
}
|
||||
DeploymentHandler deploymentHandler = getTethysControl().getDeploymentHandler();
|
||||
long overlap = deploymentHandler.getDeploymentOverlap(deployment, period);
|
||||
|
||||
long start = period.getRecordStart();
|
||||
long stop = period.getRecordStop();
|
||||
double percOverlap = (overlap*100.) / (stop-start);
|
||||
return String.format("%s : %3.1f%% overlap", deployment.toString(), percOverlap);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
@ -13,16 +14,24 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import Array.ArrayDialog;
|
||||
import Array.ArrayManager;
|
||||
import Array.PamArray;
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import PamView.dialog.ScrollingPamLabel;
|
||||
import PamView.dialog.SettingsButton;
|
||||
import PamView.panel.PamPanel;
|
||||
import PamView.panel.WestAlignedPanel;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Deployment;
|
||||
import pamViewFX.fxNodes.PamComboBox;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
import tethys.TethysState.StateType;
|
||||
import tethys.TethysTimeFuncs;
|
||||
import tethys.dbxml.ServerStatus;
|
||||
import tethys.deployment.PInstrument;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
import tethys.output.TethysExportParams;
|
||||
|
||||
/**
|
||||
@ -45,6 +54,14 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
|
||||
private JComboBox<String> projectList;
|
||||
|
||||
// private JComboBox<PDeployment> deploymentList;
|
||||
|
||||
private JButton newProjectButton;
|
||||
|
||||
private JComboBox<PInstrument> projectInstruments;
|
||||
|
||||
private JButton newInstrument;
|
||||
|
||||
public TethysConnectionPanel(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
mainPanel = new WestAlignedPanel(new GridBagLayout());
|
||||
@ -61,6 +78,39 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
selectServer();
|
||||
}
|
||||
});
|
||||
newProjectButton = new JButton("New project");
|
||||
newProjectButton.setToolTipText("Create new project information");
|
||||
newProjectButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
createNewProject();
|
||||
}
|
||||
});
|
||||
projectList = new JComboBox<>();
|
||||
projectList.setToolTipText("All projects present in the current Tethys database");
|
||||
projectList.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
newProjectSelect();
|
||||
}
|
||||
});
|
||||
projectInstruments = new JComboBox<PInstrument>();
|
||||
newInstrument = new JButton("New / Edit");
|
||||
projectInstruments.setToolTipText("Instruments currently listed within all deployments of the current project");
|
||||
newInstrument.setToolTipText("Edit or create a new instrument (uses PAMGuard Array dialog)");
|
||||
projectInstruments.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
newInstrumentSelect();
|
||||
}
|
||||
});
|
||||
newInstrument.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
createNewInstrument();
|
||||
}
|
||||
});
|
||||
// deploymentList = new JComboBox<PDeployment>();
|
||||
|
||||
GridBagConstraints c = new PamGridBagContraints();
|
||||
mainPanel.add(new JLabel("Tethys Server "), c);
|
||||
@ -69,23 +119,110 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
c.gridx++;
|
||||
mainPanel.add(serverSelButton, c);
|
||||
c.gridx++;
|
||||
c.gridwidth = 2;
|
||||
mainPanel.add(serverStatus, c);
|
||||
c.gridx++;
|
||||
|
||||
c.gridx =0;
|
||||
c.gridy++;
|
||||
mainPanel.add(new JLabel("Projects "), c);
|
||||
c.gridwidth = 1;
|
||||
mainPanel.add(new JLabel("Projects ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(projectList = new JComboBox<>(), c);
|
||||
mainPanel.add(projectList, c);
|
||||
c.gridx++;
|
||||
mainPanel.add(newProjectButton, c);
|
||||
|
||||
fillServerControl();
|
||||
// instrument section
|
||||
c.gridx++;
|
||||
mainPanel.add(new JLabel(" Instruments ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
mainPanel.add(projectInstruments, c);
|
||||
c.gridx++;
|
||||
mainPanel.add(newInstrument, c);
|
||||
|
||||
|
||||
// c.gridx = 0;
|
||||
// c.gridy++;
|
||||
// mainPanel.add(new JLabel("Deployments ", JLabel.RIGHT), c);
|
||||
// c.gridx += c.gridwidth;
|
||||
// c.gridwidth = 2;
|
||||
// mainPanel.add(deploymentList, c);
|
||||
|
||||
// fillServerControl(); // no need Will get set from TethysControl as soon as all initialised.
|
||||
}
|
||||
|
||||
protected void newInstrumentSelect() {
|
||||
PInstrument pInstr = (PInstrument) projectInstruments.getSelectedItem();
|
||||
if (pInstr == null) {
|
||||
return;
|
||||
}
|
||||
PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
||||
currentArray.setInstrumentType(pInstr.instrumentType);
|
||||
currentArray.setInstrumentId(pInstr.instrumentId);
|
||||
getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATEMETADATA));
|
||||
}
|
||||
|
||||
protected void createNewInstrument() {
|
||||
PamArray updatedArray = ArrayDialog.showDialog(getTethysControl().getGuiFrame(), ArrayManager.getArrayManager());
|
||||
if (updatedArray != null) {
|
||||
updateInstrumentsList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action from new project button
|
||||
*/
|
||||
protected void createNewProject() {
|
||||
DeploymentData pamDeploymentData = getTethysControl().getGlobalDeplopymentData();
|
||||
pamDeploymentData = NewProjectDialog.showDialog(getTethysControl().getGuiFrame(), getTethysControl(), pamDeploymentData);
|
||||
if (pamDeploymentData != null) {
|
||||
updateProjectList();
|
||||
}
|
||||
}
|
||||
|
||||
protected void newProjectSelect() {
|
||||
String project = (String) projectList.getSelectedItem();
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
DeploymentData globData = getTethysControl().getGlobalDeplopymentData();
|
||||
globData.setProject(project);
|
||||
getTethysControl().getDeploymentHandler().updateProjectDeployments();
|
||||
/*
|
||||
* if there are existing deployment data, then copy the info to the
|
||||
* internal project information
|
||||
*/
|
||||
ArrayList<PDeployment> projectDeployments = getTethysControl().getDeploymentHandler().getProjectDeployments();
|
||||
if (projectDeployments != null && projectDeployments.size() > 0) {
|
||||
Deployment dep = projectDeployments.get(0).deployment;
|
||||
globData.setProject(dep.getProject());
|
||||
globData.setRegion(dep.getRegion());
|
||||
getTethysControl().sendStateUpdate(new TethysState(TethysState.StateType.NEWPROJECTSELECTION));
|
||||
}
|
||||
|
||||
updateInstrumentsList();
|
||||
// fillDeploymentsList(project);
|
||||
}
|
||||
|
||||
|
||||
// private void fillDeploymentsList(String project) {
|
||||
// ArrayList<PDeployment> projectDeployments = getTethysControl().getDeploymentHandler().getProjectDeployments();
|
||||
// deploymentList.removeAllItems();
|
||||
// if (projectDeployments == null) {
|
||||
// return;
|
||||
// }
|
||||
// for (PDeployment dep : projectDeployments) {
|
||||
//// String str = String.format("%s:%d, %s to %s", dep.getId(), dep.getDeploymentId(),
|
||||
//// TethysTimeFuncs.formatGregorianTime(dep.getDeploymentDetails().getAudioTimeStamp()),
|
||||
//// TethysTimeFuncs.formatGregorianTime(dep.getRecoveryDetails().getAudioTimeStamp()));
|
||||
// deploymentList.addItem(dep);
|
||||
// }
|
||||
// }
|
||||
|
||||
protected void selectServer() {
|
||||
// will return the same object at the moment, so no need to do anything.
|
||||
TethysExportParams newParams = SelectServerdDialog.showDialog(getTethysControl(), getTethysControl().getGuiFrame(), getTethysControl().getTethysExportParams());
|
||||
if (newParams != null) {
|
||||
getTethysControl().sendStateUpdate(new TethysState(TethysState.StateType.UPDATESERVER));
|
||||
getTethysControl().checkServer();// sendStateUpdate(new TethysState(TethysState.StateType.UPDATESERVER));
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,8 +231,11 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
serverName.setText(exportParams.getFullServerName());
|
||||
ServerStatus status = getTethysControl().getDbxmlConnect().pingServer();
|
||||
serverStatus.setText(status.toString());
|
||||
|
||||
colourBackground(status.ok ? 0 : 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
@ -113,13 +253,53 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
|
||||
private void updateProjectList() {
|
||||
projectList.removeAllItems();
|
||||
ArrayList<String> dbNames = getTethysControl().getDbxmlQueries().getProjectNames();
|
||||
if (dbNames == null || dbNames.size() == 0) {
|
||||
System.out.println("No existing projects");
|
||||
/*
|
||||
* put the project name assigned within this PAMGuard config at the top of the
|
||||
* list.
|
||||
*/
|
||||
String localProjName = null;
|
||||
DeploymentData pamDeploymentData = getTethysControl().getGlobalDeplopymentData();
|
||||
if (pamDeploymentData != null && pamDeploymentData.getProject() != null) {
|
||||
localProjName = pamDeploymentData.getProject();
|
||||
if (localProjName.length() == 0) {
|
||||
localProjName = null;
|
||||
}
|
||||
}
|
||||
if (localProjName != null) {
|
||||
projectList.addItem(localProjName);
|
||||
}
|
||||
|
||||
ArrayList<String> projectNames = getTethysControl().getDbxmlQueries().getProjectNames();
|
||||
if (projectNames == null || projectNames.size() == 0) {
|
||||
// System.out.println("No existing projects");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < dbNames.size(); i++) {
|
||||
projectList.addItem(dbNames.get(i));
|
||||
for (int i = 0; i < projectNames.size(); i++) {
|
||||
String projName = projectNames.get(i);
|
||||
if (projName.equals(localProjName)) {
|
||||
continue;
|
||||
}
|
||||
projectList.addItem(projectNames.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update displayed list of instruments
|
||||
*/
|
||||
private void updateInstrumentsList() {
|
||||
projectInstruments.removeAllItems();
|
||||
PInstrument currentInstrument = getTethysControl().getDeploymentHandler().getCurrentArrayInstrument();
|
||||
if (currentInstrument != null) {
|
||||
projectInstruments.addItem(currentInstrument);
|
||||
}
|
||||
ArrayList<PInstrument> projectInst = getTethysControl().getDeploymentHandler().getProjectInstruments();
|
||||
if (projectInst == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < projectInst.size(); i++) {
|
||||
if (projectInst.get(i).equals(currentInstrument) == false) {
|
||||
projectInstruments.addItem(projectInst.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
151
src/tethys/swing/TethysDeploymentsTable.java
Normal file
151
src/tethys/swing/TethysDeploymentsTable.java
Normal file
@ -0,0 +1,151 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import PamView.panel.PamPanel;
|
||||
import PamView.tables.SwingTableColumnWidths;
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysMenuActions;
|
||||
import tethys.TethysState;
|
||||
import tethys.deployment.DeploymentOverview;
|
||||
import tethys.niluswraps.PDeployment;
|
||||
|
||||
public class TethysDeploymentsTable extends TethysGUIPanel {
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private TableModel tableModel;
|
||||
|
||||
private JTable table;
|
||||
|
||||
private ArrayList<PDeployment> projectDeployments;
|
||||
|
||||
private DeploymentOverview deploymentOverview;
|
||||
|
||||
public TethysDeploymentsTable(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
mainPanel = new PamPanel(new BorderLayout());
|
||||
mainPanel.setBorder(new TitledBorder("All project deployments"));
|
||||
tableModel = new TableModel();
|
||||
table = new JTable(tableModel);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.addMouseListener(new TableMouse());
|
||||
JScrollPane scrollPane = new JScrollPane(table);
|
||||
mainPanel.add(BorderLayout.CENTER, scrollPane);
|
||||
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
new SwingTableColumnWidths(tethysControl.getUnitName()+"AllProjectDeploymentsTable", table);
|
||||
}
|
||||
|
||||
private class TableMouse extends MouseAdapter {
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
showPopupMenu(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
showPopupMenu(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void showPopupMenu(MouseEvent e) {
|
||||
int row = table.getSelectedRow();
|
||||
if (row < 0) {
|
||||
return;
|
||||
}
|
||||
PDeployment pDeployment = projectDeployments.get(row);
|
||||
TethysMenuActions menuActions = new TethysMenuActions(getTethysControl());
|
||||
menuActions.deploymentMouseActions(e, pDeployment);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(TethysState tethysState) {
|
||||
projectDeployments = getTethysControl().getDeploymentHandler().getProjectDeployments();
|
||||
deploymentOverview = getTethysControl().getDeploymentHandler().getDeploymentOverview();
|
||||
tableModel.fireTableDataChanged();
|
||||
}
|
||||
|
||||
private class TableModel extends AbstractTableModel {
|
||||
|
||||
private String[] columnNames = {"Deployment document", "PAMGuard Match"};
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return projectDeployments == null ? 0 : projectDeployments.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
PDeployment deployment = projectDeployments.get(rowIndex);
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return deployment.toString();
|
||||
case 1:
|
||||
return getMatchText(deployment);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
return columnNames[column];
|
||||
}
|
||||
|
||||
|
||||
public String getMatchText(PDeployment deployment) {
|
||||
// TODO Auto-generated method stub
|
||||
if (deployment.getMatchedPAMGaurdPeriod() != null) {
|
||||
return "Matched to PAMGaurd data";
|
||||
};
|
||||
if (deploymentOverview == null) {
|
||||
return "No PAMGuard data";
|
||||
}
|
||||
Long depStart = deploymentOverview.getFirstStart();
|
||||
Long depEnd = deploymentOverview.getLastEnd();
|
||||
if (depStart == null) {
|
||||
return "No PAMGuard recordings";
|
||||
}
|
||||
if (deployment.getAudioEnd() < depStart) {
|
||||
return "Earlier than PAMGuard data";
|
||||
}
|
||||
if (deployment.getAudioStart() > depEnd) {
|
||||
return "Later than PAMGuard data";
|
||||
}
|
||||
return "Partial overlap with PAMGuard data, but no match";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
package tethys.swing;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import tethys.TethysControl;
|
||||
import tethys.TethysState;
|
||||
@ -27,5 +31,28 @@ public abstract class TethysGUIPanel implements TethysStateObserver {
|
||||
|
||||
}
|
||||
|
||||
public Color getNormalColour() {
|
||||
return new JPanel().getBackground();
|
||||
}
|
||||
|
||||
public Color getErrorColour() {
|
||||
return Color.ORANGE;
|
||||
}
|
||||
|
||||
public void colourBackground(int iCol) {
|
||||
Color col = iCol == 0 ? getNormalColour() : getErrorColour();
|
||||
colourPanels(getComponent(), col);
|
||||
}
|
||||
|
||||
private void colourPanels(JComponent component, Color col) {
|
||||
component.setBackground(col);
|
||||
int nChild = component.getComponentCount();
|
||||
for (int i = 0; i < nChild; i++) {
|
||||
Component aChild = component.getComponent(i);
|
||||
if (aChild instanceof JPanel) {
|
||||
colourPanels((JComponent) aChild, col);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import java.awt.BorderLayout;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import tethys.TethysControl;
|
||||
|
||||
@ -15,12 +17,31 @@ public class TethysMainPanel extends TethysGUIPanel {
|
||||
|
||||
private TethysConnectionPanel connectionPanel;
|
||||
|
||||
private DatablockSynchPanel datablockSynchPanel;
|
||||
|
||||
private DeploymentsPanel deploymentsPanel;
|
||||
|
||||
public TethysMainPanel(TethysControl tethysControl) {
|
||||
super(tethysControl);
|
||||
this.tethysControl = tethysControl;
|
||||
mainPanel = new JPanel(new BorderLayout());
|
||||
connectionPanel = new TethysConnectionPanel(tethysControl);
|
||||
datablockSynchPanel = new DatablockSynchPanel(tethysControl);
|
||||
deploymentsPanel = new DeploymentsPanel(tethysControl);
|
||||
|
||||
mainPanel.add(BorderLayout.NORTH, connectionPanel.getComponent());
|
||||
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
|
||||
// splitPane.set
|
||||
mainPanel.add(BorderLayout.CENTER, splitPane);
|
||||
// mainPanel.add(BorderLayout.CENTER, datablockSynchPanel.getComponent());
|
||||
splitPane.add(deploymentsPanel.getComponent());
|
||||
splitPane.add(datablockSynchPanel.getComponent());
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
splitPane.setDividerLocation(0.5);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JPanel getMainPanel() {
|
||||
|
Loading…
Reference in New Issue
Block a user