Calibrations display

display of calibrations documents + some general tidying up of document
management and display.
This commit is contained in:
Douglas Gillespie 2023-12-03 18:21:09 +00:00
parent 6cc01fe77a
commit 275a53c042
19 changed files with 1182 additions and 70 deletions

View File

@ -6,8 +6,9 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -33,7 +33,7 @@ public enum Collection {
case Detections:
return "Detections"; // this one is plural !
case Localizations:
return "Localization";
return "Localize";
case SpeciesAbbreviations:
return "SpeciesAbbreviation";
case Ensembles:

View File

@ -11,6 +11,7 @@ public class DocumentInfo implements Comparable<DocumentInfo> {
private Collection collection;
private String documentName;
private String documentId;
/**
* @param collection
* @param documentName

View File

@ -0,0 +1,32 @@
package tethys;
/**
* information about a document AND the nilus object to go with it.
* @author dg50
*
* @param <T>
*/
public class DocumentNilusObject<T extends Object> extends DocumentInfo {
private T nilusObject;
public DocumentNilusObject(Collection collection, String documentName, String documentId, T nilusObject) {
super(collection, documentName, documentId);
this.nilusObject = nilusObject;
}
/**
* @return the nilusObject
*/
public T getNilusObject() {
return nilusObject;
}
/**
* @param nilusObject the nilusObject to set
*/
public void setNilusObject(T nilusObject) {
this.nilusObject = nilusObject;
}
}

View File

@ -166,7 +166,17 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
openTethysClient();
}
});
tethysMenu.add(menuItem);
menuItem = new JMenuItem("Open temp document folder");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
openTempDocuments();
}
});
tethysMenu.add(menuItem);
JMenuItem collections = new JMenu("Collections");
Collection[] mainCollections = Collection.mainList();
@ -217,6 +227,22 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
return tethysMenu;
}
protected void openTempDocuments() {
File tempFolder = dbxmlConnect.checkTempFolder();
if (tempFolder == null) {
WarnOnce.showWarning("Tethys Error", "Unable to obtain a temporary folder name", WarnOnce.WARNING_MESSAGE);
return;
}
try {
// String cmd = "explorer.exe /select," + tempFolder.getAbsolutePath() + File.separator;
// Runtime.getRuntime().exec(cmd);
Desktop.getDesktop().open(tempFolder);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void showProjectDeploymentsDialog() {
ProjectDeploymentsDialog.showDialog(getGuiFrame(), this);
}
@ -591,7 +617,7 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
public void displayDocument(DocumentInfo docInfo) {
String collectionName = docInfo.getCollection().collectionName();
String docId = docInfo.getDocumentId();
String docId = docInfo.getDocumentName();
displayDocument(collectionName, docId);
}
/**

View File

@ -1,9 +1,18 @@
package tethys.calibration;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.w3c.dom.Document;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionParameters;
import Acquisition.AcquisitionProcess;
import Array.ArrayManager;
import Array.Hydrophone;
@ -11,6 +20,8 @@ import Array.PamArray;
import PamController.PamController;
import PamController.soundMedium.GlobalMedium;
import PamController.soundMedium.GlobalMedium.SoundMedium;
import PamUtils.PamCalendar;
import dbxml.Queries;
import PamController.soundMedium.GlobalMediumManager;
import nilus.Calibration;
import nilus.Calibration.FrequencyResponse;
@ -19,31 +30,92 @@ import nilus.Helper;
import nilus.MetadataInfo;
import nilus.QualityValueBasic;
import nilus.ResponsibleParty;
import tethys.Collection;
import tethys.DocumentInfo;
import tethys.DocumentNilusObject;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.TethysStateObserver;
import tethys.TethysTimeFuncs;
import tethys.dbxml.DBXMLConnect;
import tethys.dbxml.TethysException;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.NilusUnpacker;
import tethys.pamdata.AutoTethysProvider;
public class CalibrationHandler implements TethysStateObserver {
private TethysControl tethysControl;
private ArrayList<DocumentNilusObject<Calibration>> calibrationDataBlock;
/**
* @param tethysControl
*/
public CalibrationHandler(TethysControl tethysControl) {
this.tethysControl = tethysControl;
calibrationDataBlock = new ArrayList();
tethysControl.addStateObserver(this);
}
@Override
public void updateState(TethysState tethysState) {
// TODO Auto-generated method stub
switch (tethysState.stateType) {
case EXPORTING:
break;
case NEWPAMGUARDSELECTION:
case NEWPROJECTSELECTION:
case TRANSFERDATA:
case UPDATEMETADATA:
case UPDATESERVER:
updateDocumentsList();
default:
break;
}
}
private void updateDocumentsList() {
ArrayList<DocumentInfo> docsList = getArrayCalibrations();
// now immediately read the calibrations in again.
calibrationDataBlock.clear();;
NilusUnpacker unpacker = new NilusUnpacker();
for (DocumentInfo aDoc : docsList) {
Queries queries = tethysControl.getDbxmlConnect().getTethysQueries();
String result = null;
Calibration calObj = null;
try {
result = queries.getDocument(Collection.Calibrations.toString(), aDoc.getDocumentName());
if (result != null) {
// create a document and convert it into a Nilus calibrations document.
Document doc = tethysControl.getDbxmlQueries().convertStringToXMLDocument(result);
if (doc == null) {
System.out.println("Unable to convert Calibration result to Document\n " + result);
continue;
}
calObj = (Calibration) unpacker.unpackDocument(doc, Calibration.class);
if (calObj == null) {
System.out.println("Unable to convert Calibration document to nilus object\n " + result);
continue;
}
}
long t = System.currentTimeMillis();
try {
XMLGregorianCalendar gt = calObj.getMetadataInfo().getDate();
if (gt != null) {
t = TethysTimeFuncs.millisFromGregorianXML(gt);
}
}
catch (Exception e) {
}
DocumentNilusObject<Calibration> calDataUnit = new DocumentNilusObject(Collection.Calibrations, aDoc.getDocumentName(), calObj.getId(), calObj);
calibrationDataBlock.add(calDataUnit);
// System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public int exportAllCalibrations() {
@ -54,9 +126,10 @@ public class CalibrationHandler implements TethysStateObserver {
for (int i = 0; i < nPhone; i++) {
// String docName = getHydrophoneId(i);
Calibration calDoc = createCalibrationDocument(i);
String calDocName = getDocumentName(calDoc, i);
boolean ok = false;
try {
ok = dbxml.postAndLog(calDoc);
ok = dbxml.postAndLog(calDoc, calDocName);
} catch (TethysException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -70,6 +143,54 @@ public class CalibrationHandler implements TethysStateObserver {
return nExport;
}
/**
* Get a name for the document, which is a bit like the id within
* the document, but also contain a yymmdd data string.
* @param calDoc
* @param i channel
* @return document name
*/
private String getDocumentName(Calibration calDoc, int iChan) {
long docDate = System.currentTimeMillis();
XMLGregorianCalendar date = calDoc.getMetadataInfo().getDate();
if (date != null) {
docDate = TethysTimeFuncs.millisFromGregorianXML(date);
}
String dateStr = formatDate(docDate);
String name = String.format("%s_%s_ch%d", getCalibrationDocumentRoot(), dateStr, iChan);
return name;
}
/**
* Format the data in the dd MMMM yyyy format
* @param timeInMillis time in milliseconds
* @return formatted string.
*/
public static String formatDate(long timeInMillis) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(timeInMillis);
c.setTimeZone(PamCalendar.defaultTimeZone);
DateFormat df = new SimpleDateFormat("yyMMdd");
df.setTimeZone(PamCalendar.defaultTimeZone);
Date d = c.getTime();
return df.format(d);
}
/**
* Get a start of name for a calibration document. This will be used in the document name
* with a date and a channel, and the document Id just of the root and the channel.
* @return root string for document names and document id's.
*/
public String getCalibrationDocumentRoot() {
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
if (array == null) {
return null;
}
String root = String.format("%s %s", array.getInstrumentType(), array.getInstrumentId());
root = root.replace(" ", "_");
return root;
}
/**
* Create a calibration document for a single hydrophone channel.
* @param pDeployment deployment, for cross referencing.
@ -80,21 +201,6 @@ public class CalibrationHandler implements TethysStateObserver {
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType);
return createCalibrationDocument(daqControl, channelIndex);
}
/**
* Get an id based on the instrument identifiers and channel number.
* @param channelIndex
* @return id string - instrument type + instrument id + channel
*/
public String getHydrophoneId(int channelIndex) {
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
if (array == null) {
return null;
}
String id = String.format("%s_%s_ch%02d", array.getInstrumentType(), array.getInstrumentId(), channelIndex);
id = id.replace(" ", "_");
return id;
}
/**
* Create a calibration document for a single hydrophone channel.
@ -135,7 +241,7 @@ public class CalibrationHandler implements TethysStateObserver {
GlobalMediumManager mediumManager = PamController.getInstance().getGlobalMediumManager();
SoundMedium currentMedium = mediumManager.getCurrentMedium();
double dbRef = GlobalMedium.getdBreference(currentMedium); // probably in Pa, so multiply by 1e6.
double dbRef = GlobalMedium.getdBreference(currentMedium); // probably in Pa, so multiply by 1e6. 20 (air) or 0 (water)
/**
* The calibration id can be a bit tricky, it will need to be cross referenced from the
@ -158,9 +264,10 @@ public class CalibrationHandler implements TethysStateObserver {
// id = String.format("%d", channelIndex);
calibration.setId(id);
calibration.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis()));
calibration.setType(GlobalMedium.getRecieverString(currentMedium, false, false));
// calibration.setType(GlobalMedium.getRecieverString(currentMedium, false, false));
calibration.setType("end-to-end");
calibration.setIntensityReferenceUPa(AutoTethysProvider.roundSignificantFigures(dbRef*1e6,3));
String sensRef = GlobalMedium.getdBRefString(currentMedium);
// String sensRef = GlobalMedium.getdBRefString(currentMedium);
// it doesn't like this since it has a unicode character. Leave it or change the micro to 'u'
// calibration.setSensitivityReference(sensRef);
calibration.setSensitivityDBV(hSens+preampGain);
@ -176,17 +283,66 @@ public class CalibrationHandler implements TethysStateObserver {
db.add(Double.valueOf(hSens+preampGain));
MetadataInfo metaInf = calibration.getMetadataInfo();
if (metaInf == null) {
metaInf = new MetadataInfo();
calibration.setMetadataInfo(metaInf);
}
metaInf.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis()));
metaInf.setUpdateFrequency("as-needed");
ResponsibleParty contact = metaInf.getContact();
if (contact == null) {
contact = new ResponsibleParty();
metaInf.setContact(contact);
}
contact.setIndividualName("Unknown");
contact.setOrganizationName("unknown");
QualityAssurance qa = calibration.getQualityAssurance();
if (qa == null) {
qa = new QualityAssurance();
calibration.setQualityAssurance(qa);
}
qa.setQuality(QualityValueBasic.VALID);
qa.setComment("Unknown calibration");
return calibration;
}
/**
* Get an id based on the instrument identifiers and channel number.
* This is the internal id of the document, not the document name which
* includes an additional date part in the name.
* @param channelIndex
* @return id string - instrument type + instrument id + channel
*/
public String getHydrophoneId(int channelIndex) {
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
if (array == null) {
return null;
}
String id = String.format("%s_ch%02d", getCalibrationDocumentRoot(), channelIndex);
id = id.replace(" ", "_");
return id;
}
/**
* @return the calibrationDataBlock
*/
public ArrayList<DocumentNilusObject<Calibration>> getCalibrationDataList() {
return calibrationDataBlock;
}
private ArrayList<DocumentInfo> getArrayCalibrations() {
ArrayList<DocumentInfo> allCals = tethysControl.getDbxmlQueries().getCollectionDocumentList(Collection.Calibrations);
String prefix = getCalibrationDocumentRoot();
// find doc names that have that root.
ArrayList<DocumentInfo> theseCals = new ArrayList<>();
for (DocumentInfo aDoc : allCals) {
if (aDoc.getDocumentName().startsWith(prefix)) {
theseCals.add(aDoc);
}
}
return theseCals;
}
}

View File

@ -1,5 +1,252 @@
package tethys.calibration.swing;
public class CalibrationsPanel {
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
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 javax.xml.datatype.XMLGregorianCalendar;
import PamController.PamController;
import PamUtils.PamCalendar;
import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.tables.SwingTableColumnWidths;
import nilus.Calibration;
import tethys.Collection;
import tethys.DocumentNilusObject;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.TethysState.StateType;
import tethys.TethysTimeFuncs;
import tethys.calibration.CalibrationHandler;
import tethys.dbxml.TethysException;
import tethys.swing.TethysGUIPanel;
public class CalibrationsPanel extends TethysGUIPanel {
private CalibrationHandler calibrationHandler;
private CalibrationsTableModel calTableModel;
private JPanel mainPanel;
private JTable calTable;
private TethysControl tethysControl;
/**
* @param calibrationHandler
*/
public CalibrationsPanel(TethysControl tethysControl, CalibrationHandler calibrationHandler) {
super(tethysControl);
this.tethysControl = tethysControl;
this.calibrationHandler = calibrationHandler;
calTableModel = new CalibrationsTableModel();
calTable = new JTable(calTableModel);
calTable.setRowSelectionAllowed(true);
calTable.addMouseListener(new TableMouse());
JScrollPane scrollPane = new JScrollPane(calTable);
mainPanel = new PamPanel(new BorderLayout());
mainPanel.setBorder(new TitledBorder("Instrument calibration information"));
mainPanel.add(BorderLayout.CENTER, scrollPane);
calTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
new SwingTableColumnWidths(tethysControl.getUnitName()+"CalibrationsTable", calTable);
}
@Override
public JComponent getComponent() {
return mainPanel;
}
@Override
public void updateState(TethysState tethysState) {
super.updateState(tethysState);
calTableModel.fireTableDataChanged();
}
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);
}
}
}
public void showPopupMenu(MouseEvent e) {
int[] rows = calTable.getSelectedRows();
if (rows == null || rows.length == 0) {
return;
}
int n = rows.length;
DocumentNilusObject<Calibration> doc = calibrationHandler.getCalibrationDataList().get(rows[0]);
JPopupMenu popMenu = new JPopupMenu();
JMenuItem menuItem;
if (n == 1) {
menuItem = new JMenuItem("Show document " + doc.getDocumentName());
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showCalibration(doc);
}
});
popMenu.add(menuItem);
}
if (n > 1) {
menuItem = new JMenuItem("Delete selected documents");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteCalibrations(rows);
}
});
popMenu.add(menuItem);
}
else {
menuItem = new JMenuItem("Delete document " + doc.getDocumentName());
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteCalibration(doc);
}
});
popMenu.add(menuItem);
}
popMenu.show(e.getComponent(), e.getX(), e.getY());
}
protected void deleteCalibration(DocumentNilusObject<Calibration> doc) {
String docName = doc.getDocumentName();
int ans = WarnOnce.showNamedWarning("delete doc " + Collection.Calibrations.collectionName(),
PamController.getMainFrame(), "Delete document",
"Are you sure you want to delete the document " + docName, WarnOnce.OK_CANCEL_OPTION);
if (ans == WarnOnce.OK_OPTION) {
try {
tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations.collectionName(), docName);
} catch (TethysException e) {
System.out.println("Failed to delete " + docName);
System.out.println(e.getMessage());
}
}
updateEverything();
calTableModel.fireTableDataChanged();
}
protected void showCalibration(DocumentNilusObject<Calibration> docInfo) {
tethysControl.displayDocument(docInfo);
}
protected void deleteCalibrations(int[] rows) {
String msg = String.format("Are you sure you want to delete %d calibrations documents ?", rows.length);
int ans = WarnOnce.showNamedWarning("Deletemanycalibrations", PamController.getMainFrame(), "Delete multiple documents", msg, WarnOnce.OK_CANCEL_OPTION);
if (ans != WarnOnce.OK_OPTION) {
return;
}
for (int i = 0; i < rows.length; i++) {
String docName = null;
try {
DocumentNilusObject<Calibration> doc = calibrationHandler.getCalibrationDataList().get(rows[i]);
docName = doc.getDocumentName();
tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations.collectionName(), docName);
} catch (TethysException e) {
System.out.println("Failed to delete " + docName);
System.out.println(e.getMessage());
}
}
updateEverything();
}
private void updateEverything() {
calibrationHandler.updateState(new TethysState(StateType.TRANSFERDATA));
}
class CalibrationsTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private String[] columnNames = {"Document", "Id", "Date", "End to End", "Hydrophone", "Preamp"};
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
DocumentNilusObject<Calibration> dataUnit = null;
try {
dataUnit = calibrationHandler.getCalibrationDataList().get(rowIndex);
}
catch (Exception e) {
return null;
}
if (dataUnit == null) {
return null;
}
Calibration cal = dataUnit.getNilusObject();
switch (columnIndex) {
case 0:
return dataUnit.getDocumentName();
case 1:
return cal.getId();
case 2:
XMLGregorianCalendar ts = cal.getTimeStamp();
if (ts == null) {
return null;
}
long ms = TethysTimeFuncs.millisFromGregorianXML(ts);
return PamCalendar.formatDBDate(ms);
case 3:
return cal.getSensitivityDBFS();
case 4:
return cal.getType();
// return String.format("%3.1fdB %s", cal.getSensitivityV(), cal.getType());
}
return null;
}
@Override
public int getRowCount() {
return calibrationHandler.getCalibrationDataList().size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
}
}

View File

@ -134,13 +134,15 @@ public class DBXMLConnect {
/**
* I don't think this should ever be used since everything goes a bit pear
* shaped if the documentName isn't the same as the Id.
* shaped if the documentName isn't the same as the Id. However, for Calibration
* documents this is no longer the case, since a Calibration can have multiple
* entries on different dates, so allow it !
* @param nilusObject
* @param documentName
* @return
* @throws TethysException
*/
private boolean postAndLog(Object nilusObject, String documentName) throws TethysException
public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
{
TethysException e = null;
boolean success = false;
@ -283,15 +285,15 @@ An error will throw an exception.
/**
* Remove a document based on a collection name and a cdocument Id.
* @param collection
* @param docId
* @param collection collection name.
* @param documentName document name (not the internal Document Id)
* @return
* @throws TethysException
*/
public boolean removeDocument(String collection, String docId) throws TethysException {
public boolean removeDocument(String collection, String documentName) throws TethysException {
try {
// docId = "SoundTrap_600_HF_7129_ch00";
Object result = jerseyClient.removeDocument(collection, docId );
Object result = jerseyClient.removeDocument(collection, documentName );
/**
* Return from a sucessful delete is something like
*
@ -304,7 +306,7 @@ An error will throw an exception.
}
catch (Exception e) {
// System.out.printf("Error deleting %s %s: %s\n", collection, docId, e.getMessage());
String msg = String.format("Error deleting %s:%s", collection, docId);
String msg = String.format("Error deleting %s:%s", collection, documentName);
throw new TethysException(msg, e.getLocalizedMessage());
}
return true;
@ -419,7 +421,7 @@ C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 b
* temp folder + /PAMGuardTethys. Files will be left here until PAMGUard
* exits then should delete automatically
*/
private void checkTempFolder() {
public File checkTempFolder() {
String javaTmpDirs = System.getProperty("java.io.tmpdir") + File.separator + "PAMGuardTethys";
File tempDir = new File(javaTmpDirs);
@ -432,7 +434,7 @@ C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 b
if (tempDirectory == null) {
tempDirectory = new File(System.getProperty("java.io.tmpdir"));
}
return tempDirectory;
}
/**

View File

@ -228,15 +228,45 @@ public class DBXMLQueries {
String toStrip = "dbxml:///"+collection.collectionName()+"/";
for (int i = 0; i < n; i++) {
Node aNode = returns.item(i);
String nameStr = null;
String id = null;
NodeList kids = aNode.getChildNodes();
for (int k = 0; k < kids.getLength(); k++) {
Node kidNode = kids.item(k);
String name = kidNode.getNodeName();
String cont = kidNode.getTextContent();
switch(name) {
case "#text":
nameStr = cont;
nameStr = nameStr.replaceFirst(toStrip, "");
break;
case "Id":
id = kidNode.getTextContent();
break;
default:
System.out.printf("Uknonwn node in Collection list %s item %d, Node %d name %s content %s\n",
collection, i, k, name, cont);
}
}
// if (i > 428) {
// System.out.println("MARU cal doc");
// }
// this is the doc name with a load of stuff in front,
// e.g. dbxml:///Deployments/1705_Array-2017-09-261705_Array-2017-09-26
String nameStr = aNode.getTextContent();
nameStr = nameStr.replaceFirst(toStrip, "");
String id = null;
if (aNode instanceof Element) {
id = getElementData((Element) aNode, "Id");
if (nameStr == null) {
nameStr = aNode.getTextContent();
nameStr = nameStr.replaceFirst(toStrip, "");
}
// if (aNode instanceof Element) {
// nameStr = getElementData((Element) aNode, "#text");
// }
if (id == null) {
if (aNode instanceof Element) {
id = getElementData((Element) aNode, "Id");
}
}
DocumentInfo docInfo = new DocumentInfo(collection, nameStr, id);
documentInfos.add(docInfo);
// System.out.println(nameStr + " : " + id);
@ -285,6 +315,10 @@ public class DBXMLQueries {
// return docIds;
}
/**
* Get a list of project names.
* @return
*/
public ArrayList<String> getProjectNames() {
String projectQuery = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}";
@ -957,12 +991,12 @@ public class DBXMLQueries {
String encounterGap_m = getElementAttribute(result, "Effort.Kind.Granularity", "EncounterGap_m");
String firstBinStart = getElementAttribute(result, "Effort.Kind.Granularity", "FirstBinStart");
try {
granularityType.setBinSizeM(Double.valueOf(binSize_m));
granularityType.setBinSizeMin(Double.valueOf(binSize_m));
}
catch (NumberFormatException e) {
}
try {
granularityType.setEncounterGapM(Double.valueOf(encounterGap_m));
granularityType.setEncounterGapMin(Double.valueOf(encounterGap_m));
}
catch (NumberFormatException e) {
}

View File

@ -48,6 +48,7 @@ import nilus.Deployment.Instrument;
import nilus.Deployment.SamplingDetails;
import nilus.Deployment.Sensors;
import nilus.DeploymentRecoveryDetails;
import nilus.DescriptionType;
import nilus.GeometryTypeM;
import nilus.Helper;
import nilus.UnknownSensor;
@ -764,6 +765,16 @@ public class DeploymentHandler implements TethysStateObserver {
TethysLocationFuncs.getTrackAndPositionData(deployment);
getProjectData(deployment);
DescriptionType description = deployment.getDescription();
if (description == null ) {
description = new DescriptionType();
deployment.setDescription(description);
description.setAbstract("No abstract");
description.setMethod("no methods");
description.setObjectives("No objectives");
}
// description.set
addSamplingDetails(deployment, recordingPeriod);

View File

@ -31,6 +31,7 @@ import nilus.DetectionGroup;
import nilus.Detections;
import nilus.GranularityEnumType;
import nilus.Helper;
import tethys.Collection;
import tethys.TethysControl;
import tethys.TethysTimeFuncs;
import tethys.dbxml.DBXMLConnect;
@ -38,7 +39,6 @@ import tethys.dbxml.TethysException;
import tethys.deployment.DeploymentHandler;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.PDetections;
import tethys.niluswraps.TethysCollections;
import tethys.output.StreamExportParams;
import tethys.output.TethysExportParams;
import tethys.pamdata.TethysDataProvider;
@ -521,7 +521,7 @@ public class DetectionsHandler {
*/
while (true) {
fullId = String.format("%s_%d", prefix, uniqueDetectionsId++);
if (!tethysControl.getDbxmlQueries().documentExists(TethysCollections.Detections.toString(), fullId)) {
if (!tethysControl.getDbxmlQueries().documentExists(Collection.Detections.toString(), fullId)) {
break;
}
}

View File

@ -0,0 +1,608 @@
package tethys.niluswraps;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import nilus.ChannelInfo.Sampling.Regimen;
import nilus.Deployment;
import nilus.Helper;
import nilus.QualityValueBasic;
import tethys.TethysTimeFuncs;
/**
* Functions to automatically unpack a document from Tethys into a nilus object.
* @author dg50
*
*/
public class NilusUnpacker {
public Object unpackDocument(Document doc, Class nilusClass) throws SecurityException {
Object nilusObject = null;
nilusObject = unpackNilusClass(nilusClass, doc.getDocumentElement(), true);
return nilusObject;
}
/**
* Unpack an xml element into a nilus class. Should recursively work through
* all sub elements and lists, etc.
* @param nilusClass class to unpack to
* @param nilusElement xml element
* @return nilus object.
*/
private Object unpackNilusClass(Class<?> nilusClass, Node nilusElement, boolean useHelper) {
Object nilusObject = null;
/*
* First, find the constructor. Every class should have a zero argument
* constructor.
*/
QualityValueBasic qb = null;
Constructor<?> nilusConstructor = null;;
try {
nilusConstructor = nilusClass.getConstructor(null);
nilusObject = nilusConstructor.newInstance(null);
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// e.printStackTrace();
// return null;
}
if (useHelper) {
try {
Helper.createRequiredElements(nilusObject);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
}
return unpackNilusObject(nilusObject, nilusElement);
}
private Object unpackNilusObject(Object nilusObject, Node nilusElement) {
// if (nilusConstructor == null) {
// // try to find any constructor and see what it takes.
// Constructor<?>[] allConstructors = nilusClass.getConstructors();
// if (allConstructors.length == 0) {
// System.out.println("Nilus unpacker: Unable to find constructor for class " + nilusClass.toString());
// return null;
// }
// nilusConstructor = allConstructors[0]; // only try the first one for now.
// Parameter[] params = nilusConstructor.getParameters();
// if (params.length == 1 && params[0].getType() == String.class) {
// try {
// nilusObject = nilusConstructor.newInstance(nilusElement.getTextContent());
// } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
// | InvocationTargetException | DOMException e) {
// e.printStackTrace();
//// return null;
// }
// }
// }
// if (nilusObject == null) {
// System.out.println("Nilus unpacker: Unable to construct nilus object " + nilusClass.toString());
// return null;
// }
if (nilusObject == null) {
return null;
}
Class nilusClass = nilusObject.getClass();
/**
* Get the declared fields for this class. May need to worry about
* inherited fields ? .
*/
Field[] fields = nilusClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (isFieldFinal(fields[i])) {
continue;
}
String fieldName = fields[i].getName();
String elementName = fieldName;
// now try to find an annotation for the name, which might be
// different.
XmlElement an = fields[i].getAnnotation(XmlElement.class);
if (an == null) {
// System.out.printf("No XmlElement annotation found for field %s in class %s\n",
// nilusClass.getName(), fieldName);
}
boolean required = false;
if (an != null) {
required = an.required();
elementName = an.name();
}
// find the xml element for it in parent
Element child = findChild(nilusElement, elementName);
/**
* Here we can put in some bespoke 'fixes', e.g. if the name in the xml has
* changed for some reason.
*/
if (child == null) {
String altName = alternateElName(fieldName);
if (altName != null) {
child = findChild(nilusElement, altName);
}
}
/**
* It is OK for a child not to exist, since not all elements are required, so
* it's possible that they are simply not there.
*/
if (child == null) {
if (required) {
System.out.printf("Field %s in class %s is required but cannot be found\n", fieldName, nilusClass.getName());
}
continue;
}
String childName = child.getNodeName();
Object exObject = null; // this is the object (which may be a primitive) we're going to give to the setter.
if (List.class.isAssignableFrom(fields[i].getType())) {
exObject = getNilusList(nilusObject, fields[i], (Element) nilusElement);
}
else {
// find a setter for it.
Method setter = findSetter(nilusClass, fieldName);
// System.out.printf("Field %s with element %s and setter %s\n", fieldName, childName, setter);
if (setter == null) {
System.out.printf("No setter available for field %s and element %s\n", fieldName, elementName);
continue; // eventually do something more intelligent here.
}
Parameter[] params = setter.getParameters();
Parameter setterParam = params[0];
Class<?> paramClass = setterParam.getType();
exObject = getElementObject(nilusObject, fieldName, paramClass, child);
if (exObject != null) {
try {
// every nilus setter should have a single argument.
setter.invoke(nilusObject, exObject);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
return nilusObject;
}
private boolean isFieldFinal(Field field) {
int mods = field.getModifiers();
return Modifier.isFinal(mods);
}
/**
* Unpack the child element into the given parameter class. The element will
* either be a primitive type, or a class, which has to be one of the nulus classes
* so should follow nilus rules of constructors, setters, etc.
* @param fieldName
* @param nilusObject
* @param paramClass
* @param child
* @return
*/
private Object getElementObject(Object nilusObject, String fieldName, Class<?> paramClass, Node child) {
String className = paramClass.getName();
switch(className) {
case "int":
case "java.lang.Integer":
return unpackInteger(child);
case "java.math.BigInteger":
return unpackBigInteger(child);
case "java.lang.String":
return unpackString(child);
case "double":
case "java.lang.Double":
return unpackDouble(child);
case "javax.xml.datatype.XMLGregorianCalendar":
return unpackGregorianCalendar(child);
}
if (className.startsWith("nilus.")) {
Object gotObject = null;
gotObject = handleFunnys(nilusObject, fieldName, paramClass, child);
if (gotObject == null) {
// the helper should have made most required objects. so try to find a getter.
// and get a pre created version of the object.
Method getter = findGetter(nilusObject.getClass(), fieldName);
if (getter != null) {
try {
gotObject = getter.invoke(nilusObject, null);
if (gotObject == null) {
Helper.createElement(nilusObject, fieldName);
gotObject = getter.invoke(nilusObject, null);
}
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
// e.printStackTrace();
}
}
}
if (gotObject != null) {
return unpackNilusObject(gotObject, child);
}
else {
return unpackNilusClass(paramClass, child, false);
}
}
System.out.println("Unnown or unhandled data type: " + className);
return null;
}
private Object handleFunnys(Object nilusObject, String fieldName, Class<?> paramClass, Node child) {
Method setter = findSetter(nilusObject.getClass(), fieldName);
if (setter == null) {
return null;
}
if (paramClass == QualityValueBasic.class) {
String val = child.getTextContent();
QualityValueBasic qb = QualityValueBasic.fromValue(val);
try {
setter.invoke(nilusObject, qb);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return qb;
}
return null;
}
/**
* Unpack a list of nilus objects (or primatives?)
* @param parentObject parent object that will contain the list
* @param field field name
* @param parentEl parent element that contains the listed items.
* @return
*/
private Object getNilusList(Object parentObject, Field field, Element parentEl) {
//
String fieldName = field.getName();
Method setter = findSetter(parentObject.getClass(), fieldName);
Method getter = findGetter(parentObject.getClass(), fieldName);
List nilusList = null;
try {
nilusList = (List) getter.invoke(parentObject, null);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println(nilusList);
// need to work out what type of object is in the list from the getter signaturel
Class<?> retType = getter.getReturnType();
AnnotatedType aRet = getter.getAnnotatedReturnType();
String nm = aRet.getType().getTypeName();
int n1 = nm.indexOf("<");
int n2 = nm.indexOf(">");
if (n1 < 1) {
System.out.println("Invalid class");
}
String clsName = nm.substring(n1+1, n2);
Class listCls = null;
try {
listCls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (listCls == null) {
System.out.printf("Unable to find list class %s for nilus element %s\n", clsName, fieldName);
return null;
}
Element el = (Element) parentEl;
// el.get
// System.out.println("Unpack children of " + parentEl.getNodeName());
NodeList nodeList = parentEl.getChildNodes();
int n = nodeList.getLength();
int m = 0;
for (int i = 0; i < n; i++) {
Node aNode = nodeList.item(i);
if (aNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
// System.out.println("Unpack node: " + aNode.getNodeName());
Object listObject = getElementObject(parentObject, field.getName(), listCls, aNode);
if (listObject != null) {
nilusList.add(listObject);
m++;
}
}
// System.out.printf("Added %d children to list\n", m);
// Node aChild = parentEl.getFirstChild();
// while (aChild != null) {
// System.out.println("Unpack node: " + aChild.getNodeName());
// Object listObject = getElementObject(listCls, aChild);
// if (listObject != null) {
// nilusList.add(listObject);
// }
// aChild.getNextSibling();
// }
//
return nilusList;
}
/**
* Unpack an element as a String
* @param child
* @return
*/
private Object unpackString(Node child) {
if (child == null) {
return null;
}
return child.getTextContent();
}
/**
* Unpack an element as a BigInteger
* @param child
* @return long integer converted to BigInteger
*/
private BigInteger unpackBigInteger(Node child) {
if (child == null) {
return null;
}
Long value = null;
value = Long.valueOf(child.getTextContent());
return BigInteger.valueOf(value);
}
/**
* Unpack an element as am int32 (Integer)
* @param child
* @return int32 value
*/
private Integer unpackInteger(Node child) {
if (child == null) {
return null;
}
Integer value = null;
value = Integer.valueOf(child.getTextContent());
return value;
}
/**
* Unpack an element as a Double
* @param child
* @return double precision value or null
*/
private Double unpackDouble(Node child) {
if (child == null) {
return null;
}
Double value = null;
value = Double.valueOf(child.getTextContent());
return value;
}
/**
* Unpack an element as a GregorianCalendar
* @param child
* @return GregorianCalendar value
*/
private XMLGregorianCalendar unpackGregorianCalendar(Node child) {
if (child == null) {
return null;
}
String calString = child.getTextContent();
XMLGregorianCalendar xCal = TethysTimeFuncs.fromGregorianXML(calString);
return xCal;
}
/**
* Find a child element with a given name. Assumes there is only one
* so not used with lists.
* @param parentNode parent XML node
* @param childName name of child node.
* @return
*/
Element findChild(Node parentNode, String childName) {
if (parentNode instanceof Element == false) {
return null;
}
Element parent = (Element) parentNode;
NodeList children = parent.getElementsByTagName(childName);
if (children == null || children.getLength() == 0) {
String ch1 = childName.substring(0,1).toUpperCase();
childName = ch1+childName.substring(1);
children = parent.getElementsByTagName(childName);
if (children == null) {
return null;
}
}
int n = children.getLength();
for (int i = 0; i < n; i++) {
Node child = children.item(i);
String childNodeName = child.getNodeName();
if (child.getNodeName().equals(childName)) {
return (Element) child;
}
}
return null;
}
/**
* Get an alternative element name (for old databases ?)
* @param fieldName
* @return
*/
private String alternateElName(String fieldName) {
switch(fieldName) {
case "sampleRateKHz":
return "sampleRate_kHz";
}
return null;
}
/**
* Return all the setters in a class;
* @param nilusClass
* @return
*/
private ArrayList<Method> findSetters(Class<?> nilusClass) {
Method[] methods = nilusClass.getMethods();
ArrayList methodList = new ArrayList<>();
for (int i = 0; i < methods.length; i++) {
String name = methods[i].getName();
if (name.startsWith("set")) {
methodList.add(methods[i]);
}
}
return methodList;
}
/**
* Find setter functions for a given field name. Generally
* this is a capitalization of the first character and 'set'
* in front of it.
* @param nilusClass class containing the method
* @param fieldName field name
* @return Method or null
*/
private Method findSetter(Class nilusClass, String fieldName) {
String setterName = fieldName;
if (setterName.startsWith("set") == false) {
setterName = "set" + setterName;
}
Method[] methods = nilusClass.getMethods();
if (methods == null) {
return null;
}
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equalsIgnoreCase(setterName)) {
return methods[i];
}
}
return null;
}
/**
* Find getter functions for a given field name. Generally
* this is a capitalization of the first character and 'get'
* in front of it.
* @param nilusClass class containing the method
* @param fieldName field name
* @return Method or null
*/
private Method findGetter(Class nilusClass, String fieldName) {
String setterName = fieldName;
if (setterName.startsWith("get") == false) {
setterName = "get" + setterName;
}
Method[] methods = nilusClass.getMethods();
if (methods == null) {
return null;
}
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equalsIgnoreCase(setterName)) {
return methods[i];
}
}
return null;
}
public static void main(String[] args) {
String demoFile = "C:\\PAMGuardTest\\Tethys\\Meygen20223.xml";
File file = new File(demoFile);
System.out.printf("Unpacking file %s exists %s\n" , demoFile, file.exists());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
Document doc = null;
try {
db = dbf.newDocumentBuilder();
doc = db.parse(file);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
NilusUnpacker unpacker = new NilusUnpacker();
Class<Regimen> nilusClass = Regimen.class;
ArrayList<Method> setters = null;
try {
setters = unpacker.findSetters(nilusClass);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// for (Method aSetter : setters) {
// XmlElement an = aSetter.getAnnotation(XmlElement.class);
// System.out.printf("Class %s Setter %s has xmlElement %s\n", nilusClass.getName(), aSetter.getName(), an);
// Annotation[] anns = aSetter.getAnnotations();
// for (int i = 0; i < anns.length; i++) {
//
// System.out.printf("Class %s Setter %s has xmlElement %s\n", nilusClass.getName(), aSetter.getName(), anns[i]);
// }
// }
//
// Field[] fields = nilusClass.getDeclaredFields();
// for (int i = 0; i < fields.length; i++) {
// XmlElement an = fields[i].getAnnotation(XmlElement.class);
// String fieldName = "unk";
// if (an != null) {
// fieldName = an.name();
// }
// System.out.printf("Class %s Field %s has xmlElement %s\n", nilusClass.getName(), fields[i].getName(), fieldName);
// }
// BeanInfo beanInfo = null;
// try {
// beanInfo = Introspector.getBeanInfo(aClass);
// } catch (IntrospectionException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
Object obj = null;
try {
obj = unpacker.unpackDocument(doc, Deployment.class);
} catch (SecurityException e) {
e.printStackTrace();
}
System.out.println(obj);
}
}

View File

@ -67,11 +67,11 @@ public class PDeployment {
return null;
}
String str = String.format("%s", granularity.getValue());
Double bin = granularity.getBinSizeM();
Double bin = granularity.getBinSizeMin();
if (bin != null) {
str += String.format(" (%3.1f s)", bin*60);
}
Double gap = granularity.getEncounterGapM();
Double gap = granularity.getEncounterGapMin();
if (gap != null) {
str += String.format( " (%3.1f s)", gap*60.);
}

View File

@ -1,13 +0,0 @@
package tethys.niluswraps;
public enum TethysCollections {
Deployments, Detections, Localizations, Calibrations, SpeciesAbreviations;
@Override
public String toString() {
return super.toString();
}
}

View File

@ -407,14 +407,14 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
// nilus.DetectionEffortKind.Parameters granularityParams = kind.getParameters();
switch (exportParams.granularity) {
case BINNED:
kind.getGranularity().setBinSizeM(exportParams.binDurationS/60.);
kind.getGranularity().setBinSizeMin(exportParams.binDurationS/60.);
long firstBin = DetectionsHandler.roundDownBinStart(pDeployment.getAudioStart(), (long) (exportParams.binDurationS*1000));
kind.getGranularity().setFirstBinStart(TethysTimeFuncs.xmlGregCalFromMillis(firstBin));
break;
case CALL:
break;
case ENCOUNTER:
kind.getGranularity().setEncounterGapM(exportParams.encounterGapS/60.);
kind.getGranularity().setEncounterGapMin(exportParams.encounterGapS/60.);
break;
case GROUPED:
break;

View File

@ -26,13 +26,13 @@ import PamguardMVC.PamDataBlock;
import nilus.DetectionEffortKind;
import nilus.Detections;
import nilus.GranularityType;
import tethys.Collection;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.dbxml.TethysException;
import tethys.detection.StreamDetectionsSummary;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.PDetections;
import tethys.niluswraps.TethysCollections;
/**
* Table of Detections documents for a single PAMGuard datablock.
@ -211,12 +211,12 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
}
private void displayDocument(PDetections pDets) {
getTethysControl().displayDocument(TethysCollections.Detections.toString(), pDets.detections.getId());
getTethysControl().displayDocument(Collection.Detections.collectionName(), pDets.detections.getId());
}
private void exportDocument(PDetections pDets) {
getTethysControl().exportDocument(TethysCollections.Detections.toString(), pDets.detections.getId());
getTethysControl().exportDocument(Collection.Detections.toString(), pDets.detections.getId());
}

View File

@ -25,6 +25,7 @@ import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.tables.SwingTableColumnWidths;
import nilus.Deployment;
import tethys.Collection;
import tethys.TethysControl;
import tethys.TethysState;
import tethys.TethysState.StateType;
@ -33,7 +34,6 @@ import tethys.deployment.DeploymentHandler;
import tethys.deployment.DeploymentOverview;
import tethys.deployment.RecordingPeriod;
import tethys.niluswraps.PDeployment;
import tethys.niluswraps.TethysCollections;
/**
* Table view of PAMGuard deployments. For a really simple deployment, this may have only
@ -174,11 +174,11 @@ public class PAMGuardDeploymentsTable extends TethysGUIPanel {
}
protected void exportDeployment(PDeployment pDeployment) {
getTethysControl().exportDocument(TethysCollections.Deployments.toString(), pDeployment.deployment.getId());
getTethysControl().exportDocument(Collection.Deployments.collectionName(), pDeployment.deployment.getId());
}
protected void displayDeployment(PDeployment pDeployment) {
getTethysControl().displayDocument(TethysCollections.Deployments.toString(), pDeployment.deployment.getId());
getTethysControl().displayDocument(Collection.Deployments.collectionName(), pDeployment.deployment.getId());
}
protected void deleteDeployment(PDeployment pDeployment) {

View File

@ -8,6 +8,7 @@ import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import tethys.TethysControl;
import tethys.calibration.swing.CalibrationsPanel;
public class TethysMainPanel extends TethysGUIPanel {
@ -24,6 +25,8 @@ public class TethysMainPanel extends TethysGUIPanel {
private DatablockDetectionsPanel datablockDetectionsPanel;
private DetectionsExportPanel detectionsExportPanel;
private CalibrationsPanel calibrationPanel;
public TethysMainPanel(TethysControl tethysControl) {
super(tethysControl);
@ -36,6 +39,7 @@ public class TethysMainPanel extends TethysGUIPanel {
detectionsExportPanel = new DetectionsExportPanel(tethysControl);
datablockSynchPanel.addTableObserver(detectionsExportPanel);
datablockSynchPanel.addTableObserver(datablockDetectionsPanel);
calibrationPanel = new CalibrationsPanel(tethysControl, tethysControl.getCalibrationHandler());
JSplitPane southwestSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JPanel southEastPanel = new JPanel(new BorderLayout());
@ -48,7 +52,10 @@ public class TethysMainPanel extends TethysGUIPanel {
// splitPane.set
mainPanel.add(BorderLayout.CENTER, splitPane);
// mainPanel.add(BorderLayout.CENTER, datablockSynchPanel.getComponent());
splitPane.add(deploymentsPanel.getComponent());
JPanel splitNorth = new JPanel(new BorderLayout());
splitNorth.add(BorderLayout.WEST, calibrationPanel.getComponent());
splitNorth.add(deploymentsPanel.getComponent());
splitPane.add(splitNorth);
southwestSplit.add(datablockSynchPanel.getComponent());
southwestSplit.add(southEastPanel);
southEastPanel.add(datablockDetectionsPanel.getComponent(), BorderLayout.CENTER);

View File

@ -148,7 +148,7 @@ public class TethysDocumentTable implements PamDialogPanel {
"Are you sure you want to delete the document " + docInfo, WarnOnce.OK_CANCEL_OPTION);
if (ans == WarnOnce.OK_OPTION) {
try {
tethysControl.getDbxmlConnect().removeDocument(docInfo.getCollection().collectionName(), docInfo.getDocumentId());
tethysControl.getDbxmlConnect().removeDocument(docInfo.getCollection().collectionName(), docInfo.getDocumentName());
} catch (TethysException e) {
System.out.println("Failed to delete " + docInfo);
System.out.println(e.getMessage());