mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-22 07:02:29 +00:00
Update TethysExporter.java
file importer
This commit is contained in:
parent
7d69992d44
commit
799c7b218e
@ -2,6 +2,15 @@ package tethys.output;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.attribute.FileAttribute;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext;
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
import javax.xml.bind.Marshaller;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
@ -34,12 +43,19 @@ import tethys.dbxml.DBXMLConnect;
|
|||||||
import tethys.pamdata.TethysDataProvider;
|
import tethys.pamdata.TethysDataProvider;
|
||||||
import tethys.pamdata.TethysSchema;
|
import tethys.pamdata.TethysSchema;
|
||||||
|
|
||||||
|
import dbxml.uploader.Importer;
|
||||||
|
import nilus.Deployment;
|
||||||
|
import nilus.MarshalXML;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class sitting at the centre of all operations. It will talk to PAMGuard objects to get schemas and data
|
* Class sitting at the centre of all operations. It will talk to PAMGuard
|
||||||
* and talk to the database connection to move data out (and possibly in). Eventually, a lot of the functionality
|
* objects to get schemas and data and talk to the database connection to move
|
||||||
* in here will be moved to worker threads (SwingWorker?) so that it's easy to keep dialogs alive, show
|
* data out (and possibly in). Eventually, a lot of the functionality in here
|
||||||
* progress for big export jobs, etc. For now though, it's a relatively simple set of function which
|
* will be moved to worker threads (SwingWorker?) so that it's easy to keep
|
||||||
* we can use to a) open the database, b) check everything such as schemas, etc. c) export data and d) clean up.
|
* dialogs alive, show progress for big export jobs, etc. For now though, it's a
|
||||||
|
* relatively simple set of function which we can use to a) open the database,
|
||||||
|
* b) check everything such as schemas, etc. c) export data and d) clean up.
|
||||||
|
*
|
||||||
* @author dg50
|
* @author dg50
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -47,7 +63,7 @@ public class TethysExporter {
|
|||||||
|
|
||||||
private TethysControl tethysControl;
|
private TethysControl tethysControl;
|
||||||
private TethysExportParams tethysExportParams;
|
private TethysExportParams tethysExportParams;
|
||||||
|
|
||||||
private DBXMLConnect dbxmlConnect;
|
private DBXMLConnect dbxmlConnect;
|
||||||
|
|
||||||
public TethysExporter(TethysControl tethysControl, TethysExportParams tethysExportParams) {
|
public TethysExporter(TethysControl tethysControl, TethysExportParams tethysExportParams) {
|
||||||
@ -55,248 +71,288 @@ public class TethysExporter {
|
|||||||
this.tethysExportParams = tethysExportParams;
|
this.tethysExportParams = tethysExportParams;
|
||||||
dbxmlConnect = new DBXMLConnect(tethysControl);
|
dbxmlConnect = new DBXMLConnect(tethysControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the work. In reality this will need an awful lot of changing, for instance
|
* Does the work. In reality this will need an awful lot of changing, for
|
||||||
* to provide feedback to an observer class to show progress on the display.
|
* instance to provide feedback to an observer class to show progress on the
|
||||||
* @return OK if success.
|
* display.
|
||||||
|
*
|
||||||
|
* @return OK if success.
|
||||||
*/
|
*/
|
||||||
public boolean doExport() {
|
public boolean doExport() {
|
||||||
|
|
||||||
boolean dbOK = dbxmlConnect.openDatabase();
|
// boolean dbOK = dbxmlConnect.openDatabase();
|
||||||
if (!dbOK) {
|
// if (!dbOK) {
|
||||||
/*
|
/*
|
||||||
* should we set up some exceptions to throw ? Can be a lot
|
* should we set up some exceptions to throw ? Can be a lot more informative
|
||||||
* more informative than a simple 'false'
|
* than a simple 'false'
|
||||||
*/
|
*/
|
||||||
return false;
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Deployment deployment = new Deployment();
|
||||||
|
deployment.setId("1");
|
||||||
|
|
||||||
|
Path tempFile = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
JAXBContext jaxB = JAXBContext.newInstance(Deployment.class);
|
||||||
|
Marshaller marshall = jaxB.createMarshaller();
|
||||||
|
marshall.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
marshall.marshal(deployment, sw);
|
||||||
|
tempFile = Files.createTempFile("pamGuardToTethys", ".xml");
|
||||||
|
Files.write(tempFile, sw.toString().getBytes());
|
||||||
|
|
||||||
|
String fileText = Importer.ImportFiles("http://localhost:9779", "Deployment",
|
||||||
|
new String[] { tempFile.toString() }, "", "", false);
|
||||||
|
|
||||||
|
tempFile.toFile().deleteOnExit();
|
||||||
|
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (JAXBException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SnapshotGeometry arrayGeometry = findArrayGeometrey();
|
SnapshotGeometry arrayGeometry = findArrayGeometrey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doug populate instrument fields - may need to add a few things. Marie
|
* Doug populate instrument fields - may need to add a few things. Marie to
|
||||||
* to define what we mean by instrument.
|
* define what we mean by instrument. Instrument names probably need to be added
|
||||||
* Instrument names probably need to be added to the PAMGuard Array dialog and can
|
* to the PAMGuard Array dialog and can then be extraced from there. We had some
|
||||||
* then be extraced from there. We had some useful discussion about what constitutes
|
* useful discussion about what constitutes an instrumnet in Tinas dataset where
|
||||||
* an instrumnet in Tinas dataset where there was a deployment of 10 MARU's, but the
|
* there was a deployment of 10 MARU's, but the files from all of them were
|
||||||
* files from all of them were merged into a single 10 channel wav file dataset and
|
* merged into a single 10 channel wav file dataset and processed together for
|
||||||
* processed together for detection and localisation. Clearly this goes into a single
|
* detection and localisation. Clearly this goes into a single Tethys database,
|
||||||
* Tethys database, but do we put 'MARU Array' as the instrument and then include
|
* but do we put 'MARU Array' as the instrument and then include serial numbers
|
||||||
* serial numbers of individual MARU's with the hydrophone data, or what ?
|
* of individual MARU's with the hydrophone data, or what ?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doug write something here to get most of the 'samplingdetails' schema.
|
* Doug write something here to get most of the 'samplingdetails' schema. This
|
||||||
* This all comes out of the Sound Acquisition module. Code below shows how
|
* all comes out of the Sound Acquisition module. Code below shows how to find
|
||||||
* to find this and iterate through various bits of information ...
|
* this and iterate through various bits of information ... (I've put it in a
|
||||||
* (I've put it in a separate function. Currently returning void,but could
|
* separate function. Currently returning void,but could presumably return a
|
||||||
* presumably return a Tethys samplingdetails document?)
|
* Tethys samplingdetails document?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A load of notes Katie put in ....654654654
|
* A load of notes Katie put in ....654654654
|
||||||
*/
|
*/
|
||||||
//1. grab DeploymentRecoveryPair that has deployment details and recovery details
|
// 1. grab DeploymentRecoveryPair that has deployment details and recovery
|
||||||
//a. this is based on start and end times
|
// details
|
||||||
//Douglas calculates out dutycycles to only grab the
|
// a. this is based on start and end times
|
||||||
|
// Douglas calculates out dutycycles to only grab the
|
||||||
//2. loop through the pairs to populate the extra information
|
|
||||||
//one pair is one deployment
|
// 2. loop through the pairs to populate the extra information
|
||||||
//see below for matching
|
// one pair is one deployment
|
||||||
|
// see below for matching
|
||||||
|
|
||||||
//id => unique
|
// id => unique
|
||||||
//project => project in pamguard
|
// project => project in pamguard
|
||||||
//deploymentId == id
|
// deploymentId == id
|
||||||
//deploymentAlias => blank
|
// deploymentAlias => blank
|
||||||
//site => UI addition in pamguard, not done, can be blank
|
// site => UI addition in pamguard, not done, can be blank
|
||||||
//siteAlias => blank
|
// siteAlias => blank
|
||||||
//cruise => UI addition, optional
|
// cruise => UI addition, optional
|
||||||
//Platform=> UI addition in pamguard
|
// Platform=> UI addition in pamguard
|
||||||
//region => UI addition
|
// region => UI addition
|
||||||
//Instrument/Type => UI, array manager details (hydrophone names area)
|
// Instrument/Type => UI, array manager details (hydrophone names area)
|
||||||
//Instrument/Id => UI, array manager details
|
// Instrument/Id => UI, array manager details
|
||||||
//Instrument/Geometry => in pamguard array manager
|
// Instrument/Geometry => in pamguard array manager
|
||||||
//SamplingDetails/Channel
|
// SamplingDetails/Channel
|
||||||
//ChannelNumber => in pamguard, hyrdrophone array
|
// ChannelNumber => in pamguard, hyrdrophone array
|
||||||
//SensorNumber => in pamguard,
|
// SensorNumber => in pamguard,
|
||||||
//Start => same as timestamp deployment detail
|
// Start => same as timestamp deployment detail
|
||||||
//End => same as timestamp recovery detail
|
// End => same as timestamp recovery detail
|
||||||
//Sampling/Regimen (change sample rate, pamgauard doesnt handle, only on, get channel info in that loop)
|
// Sampling/Regimen (change sample rate, pamgauard doesnt handle, only on, get
|
||||||
//TimeStamp => start time
|
// channel info in that loop)
|
||||||
//SampleRate_kHz =>
|
// TimeStamp => start time
|
||||||
//SampleBits =>
|
// SampleRate_kHz =>
|
||||||
//Gain (another func call to get gain info)
|
// SampleBits =>
|
||||||
//DutyCycles => needs to be calculated, not fields in pamguard, have fun Douglas
|
// Gain (another func call to get gain info)
|
||||||
//QualityAssurance => not in pamguard, UI, maybe deployment notes, optional
|
// DutyCycles => needs to be calculated, not fields in pamguard, have fun
|
||||||
//Data/Audio (static)
|
// Douglas
|
||||||
//URI => folder where audio is saved
|
// QualityAssurance => not in pamguard, UI, maybe deployment notes, optional
|
||||||
//Data/Tracks
|
// Data/Audio (static)
|
||||||
//Track => GPS datatable (granularity filter)
|
// URI => folder where audio is saved
|
||||||
//TrackId => not unique between deployments,
|
// Data/Tracks
|
||||||
//TrackEffort
|
// Track => GPS datatable (granularity filter)
|
||||||
//OnPath => scattered throughout pamguard
|
// TrackId => not unique between deployments,
|
||||||
//URI => option, check with Shannon on how they are doing deployments
|
// TrackEffort
|
||||||
//Sensors/Audio (per hydrophone not quad array) streamer info + individual hydrophone data together
|
// OnPath => scattered throughout pamguard
|
||||||
//pamguard hydrophone data
|
// URI => option, check with Shannon on how they are doing deployments
|
||||||
//number => hydrophoneId
|
// Sensors/Audio (per hydrophone not quad array) streamer info + individual
|
||||||
//sensorId => sensor serial number
|
// hydrophone data together
|
||||||
//Geometry => array geometry field goes to
|
// pamguard hydrophone data
|
||||||
//Sensors/Depth
|
// number => hydrophoneId
|
||||||
//optional
|
// sensorId => sensor serial number
|
||||||
//Sensors/Sensor
|
// Geometry => array geometry field goes to
|
||||||
//Number => hydrophoneId in pamguard
|
// Sensors/Depth
|
||||||
//SensorId => addition to UI
|
// optional
|
||||||
//Geometry => array geometry fields
|
// Sensors/Sensor
|
||||||
//Type => Hydrophone Type
|
// Number => hydrophoneId in pamguard
|
||||||
|
// SensorId => addition to UI
|
||||||
|
// Geometry => array geometry fields
|
||||||
|
// Type => Hydrophone Type
|
||||||
|
|
||||||
|
// get list of deployment recovery details (start, stop times and lat/long)
|
||||||
//get list of deployment recovery details (start, stop times and lat/long)
|
// deployment details and recovery details are same structure
|
||||||
//deployment details and recovery details are same structure
|
// per pair, go through a loop to fill in each deployment
|
||||||
//per pair, go through a loop to fill in each deployment
|
// ArrayList<DeploymentRecoveryPair> deployRecover = getSamplingDetails();
|
||||||
ArrayList<DeploymentRecoveryPair> deployRecover = getSamplingDetails();
|
// if (deployRecover == null) {
|
||||||
if (deployRecover == null) {
|
// return false;
|
||||||
return false;
|
// }
|
||||||
}
|
//
|
||||||
|
// for (DeploymentRecoveryPair drd : deployRecover) {
|
||||||
for (DeploymentRecoveryPair drd : deployRecover) {
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call some general export function
|
* Call some general export function
|
||||||
*/
|
*/
|
||||||
exportGeneralData(tethysExportParams);
|
exportGeneralData(tethysExportParams);
|
||||||
/*
|
/*
|
||||||
* go through the export params and call something for every
|
* go through the export params and call something for every data block that's
|
||||||
* data block that's enabled.
|
* enabled.
|
||||||
*/
|
*/
|
||||||
ArrayList<PamDataBlock> allDataBlocks = PamController.getInstance().getDataBlocks();
|
ArrayList<PamDataBlock> allDataBlocks = PamController.getInstance().getDataBlocks();
|
||||||
for (PamDataBlock aDataBlock : allDataBlocks) {
|
for (PamDataBlock aDataBlock : allDataBlocks) {
|
||||||
StreamExportParams streamExportParams = tethysExportParams.getStreamParams(aDataBlock);
|
StreamExportParams streamExportParams = tethysExportParams.getStreamParams(aDataBlock);
|
||||||
if (streamExportParams == null || streamExportParams.selected == false) {
|
if (streamExportParams == null || streamExportParams.selected == false) {
|
||||||
continue; // not interested in this one.
|
continue; // not interested in this one.
|
||||||
}
|
}
|
||||||
exportDataStream(aDataBlock, tethysExportParams, streamExportParams);
|
exportDataStream(aDataBlock, tethysExportParams, streamExportParams);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Then do whatever else is needed to complete the document.
|
* Then do whatever else is needed to complete the document.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dbxmlConnect.closeDatabase();
|
dbxmlConnect.closeDatabase();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find Deployment data. This is stored in a separate PAMGuard module, which may not
|
* find Deployment data. This is stored in a separate PAMGuard module, which may
|
||||||
* be present.
|
* not be present.
|
||||||
* @return
|
*
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public DeploymentData findDeploymentData() {
|
public DeploymentData findDeploymentData() {
|
||||||
/**
|
/**
|
||||||
* What to do if this isn't present or is incomplete ? Should we be showing this in the
|
* What to do if this isn't present or is incomplete ? Should we be showing this
|
||||||
* main export dialog at some point ? More a Q for when we make a nicer UI later in the project.
|
* in the main export dialog at some point ? More a Q for when we make a nicer
|
||||||
|
* UI later in the project.
|
||||||
*/
|
*/
|
||||||
MetaDataContol metaControl = (MetaDataContol) PamController.getInstance().findControlledUnit(MetaDataContol.unitType);
|
MetaDataContol metaControl = (MetaDataContol) PamController.getInstance()
|
||||||
|
.findControlledUnit(MetaDataContol.unitType);
|
||||||
if (metaControl == null) {
|
if (metaControl == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return metaControl.getDeploymentData();
|
return metaControl.getDeploymentData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SnapshotGeometry findArrayGeometrey() {
|
public SnapshotGeometry findArrayGeometrey() {
|
||||||
/*
|
/*
|
||||||
* this should never be null, but again, we might want to put some warnings
|
* this should never be null, but again, we might want to put some warnings and
|
||||||
* and exception handlers in here anyway. Really just an example to show how
|
* exception handlers in here anyway. Really just an example to show how to find
|
||||||
* to find this. We'll need to dig a bit elsewhere to get more detailed
|
* this. We'll need to dig a bit elsewhere to get more detailed hydrophone
|
||||||
* hydrophone information.
|
* information.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* In PAMGuard hydrophones are assigned to streamers, which can have different methods for estimating
|
* In PAMGuard hydrophones are assigned to streamers, which can have different
|
||||||
* their positions from GPS. The geometry is a sum of xyz in the streamer and xyz in the hydrophone object
|
* methods for estimating their positions from GPS. The geometry is a sum of xyz
|
||||||
* Within a streamer, hydrophones are considered rigid relative to each other. The stremer will floow
|
* in the streamer and xyz in the hydrophone object Within a streamer,
|
||||||
* a choice of modesl (rigid, threading, etc) to estimate it's position relative to the GPS track. Different
|
* hydrophones are considered rigid relative to each other. The stremer will
|
||||||
* errors are used when estimating localisation errors within and between streamers.
|
* floow a choice of modesl (rigid, threading, etc) to estimate it's position
|
||||||
* The Snapshot geometry sorts a lot of this out for a point in time and will give back a single object
|
* relative to the GPS track. Different errors are used when estimating
|
||||||
* which is most of what we'll be wanting.
|
* localisation errors within and between streamers. The Snapshot geometry sorts
|
||||||
|
* a lot of this out for a point in time and will give back a single object
|
||||||
|
* which is most of what we'll be wanting.
|
||||||
*/
|
*/
|
||||||
PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray();
|
||||||
SnapshotGeometry currentGeometry = currentArray.getSnapshotGeometry(PamCalendar.getTimeInMillis());
|
SnapshotGeometry currentGeometry = currentArray.getSnapshotGeometry(PamCalendar.getTimeInMillis());
|
||||||
/*
|
/*
|
||||||
* The following lines of code show how to get more detailed calibration info for each
|
* The following lines of code show how to get more detailed calibration info
|
||||||
* hydrophone, but we'll have to think about the easiest way to repackage this for Tethys.
|
* for each hydrophone, but we'll have to think about the easiest way to
|
||||||
* e.g. this function could be modified to return the correct Tethys object in one go.
|
* repackage this for Tethys. e.g. this function could be modified to return the
|
||||||
|
* correct Tethys object in one go.
|
||||||
*/
|
*/
|
||||||
ArrayList<Hydrophone> hydrophones = currentArray.getHydrophoneArray();
|
ArrayList<Hydrophone> hydrophones = currentArray.getHydrophoneArray();
|
||||||
/*
|
/*
|
||||||
* each object in the list will have more detailed cal information for each phone. But
|
* each object in the list will have more detailed cal information for each
|
||||||
* for the full system calibration we'd need to go to the Acquisition module.
|
* phone. But for the full system calibration we'd need to go to the Acquisition
|
||||||
|
* module.
|
||||||
*/
|
*/
|
||||||
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType);
|
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance()
|
||||||
|
.findControlledUnit(AcquisitionControl.unitType);
|
||||||
if (daqControl != null) {
|
if (daqControl != null) {
|
||||||
AcquisitionProcess daqProcess = daqControl.getAcquisitionProcess();
|
AcquisitionProcess daqProcess = daqControl.getAcquisitionProcess();
|
||||||
for (int iPhone = 0; iPhone < hydrophones.size(); iPhone++) {
|
for (int iPhone = 0; iPhone < hydrophones.size(); iPhone++) {
|
||||||
Hydrophone aPhone = hydrophones.get(iPhone);
|
Hydrophone aPhone = hydrophones.get(iPhone);
|
||||||
double totalCal = -daqProcess.rawAmplitude2dB(1, iPhone, false);
|
double totalCal = -daqProcess.rawAmplitude2dB(1, iPhone, false);
|
||||||
System.out.printf("hydrophone %d has sensitivity %3.1fdB + gain %3.1fdB. Total calibration is %3.1fdB re1U/uPa\n",
|
System.out.printf(
|
||||||
|
"hydrophone %d has sensitivity %3.1fdB + gain %3.1fdB. Total calibration is %3.1fdB re1U/uPa\n",
|
||||||
iPhone, aPhone.getSensitivity(), aPhone.getPreampGain(), totalCal);
|
iPhone, aPhone.getSensitivity(), aPhone.getPreampGain(), totalCal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return currentGeometry;
|
return currentGeometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
//in each channel
|
// in each channel
|
||||||
private ArrayList<DeploymentRecoveryPair> getSamplingDetails() {
|
private ArrayList<DeploymentRecoveryPair> getSamplingDetails() {
|
||||||
// first find an acquisition module.
|
// first find an acquisition module.
|
||||||
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
|
||||||
if (aModule instanceof AcquisitionControl == false) {
|
if (aModule instanceof AcquisitionControl == false) {
|
||||||
// will return if it's null. Impossible for it to be the wrong type.
|
// will return if it's null. Impossible for it to be the wrong type.
|
||||||
// but it's good practice to check anyway before casting.
|
// but it's good practice to check anyway before casting.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// cast it to the right type.
|
// cast it to the right type.
|
||||||
AcquisitionControl daqControl = (AcquisitionControl) aModule;
|
AcquisitionControl daqControl = (AcquisitionControl) aModule;
|
||||||
AcquisitionParameters daqParams = daqControl.getAcquisitionParameters();
|
AcquisitionParameters daqParams = daqControl.getAcquisitionParameters();
|
||||||
/**
|
/**
|
||||||
* The daqParams class has most of what we need about the set up in terms of sample rate,
|
* The daqParams class has most of what we need about the set up in terms of
|
||||||
* number of channels, instrument type, ADC input range (part of calibration), etc.
|
* sample rate, number of channels, instrument type, ADC input range (part of
|
||||||
* It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers.
|
* calibration), etc. It also has a hydrophone list, which maps the input
|
||||||
* Realistically, this list is always 0,1,2,etc or it goes horribly wrong !
|
* 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.
|
// 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(),
|
System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n",
|
||||||
daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak);
|
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
|
* then there is the actual sampling. This is a bit harder to find. I thought it
|
||||||
* but the datamap is a simple count of what's in the databasase which is not quite what we want.
|
* would be in the data map but the datamap is a simple count of what's in the
|
||||||
* we're going to have to query the database to get more detailed informatoin I think.
|
* databasase which is not quite what we want. we're going to have to query the
|
||||||
* I'll do that here for now, but we may want to move this when we better organise the code.
|
* database to get more detailed informatoin I think. I'll do that here for now,
|
||||||
* It also seems that there are 'bad' dates in the database when it starts new files, which are the date
|
* but we may want to move this when we better organise the code. It also seems
|
||||||
* data were analysed at. So we really need to check the start and stop records only.
|
* 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();
|
PamDataBlock<DaqStatusDataUnit> daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock();
|
||||||
// just load everything. Probably OK for the acqusition, but will bring down
|
// just load everything. Probably OK for the acqusition, but will bring down
|
||||||
daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null);
|
daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null);
|
||||||
ArrayList<DaqStatusDataUnit> allStatusData = daqInfoDataBlock.getDataCopy();
|
ArrayList<DaqStatusDataUnit> allStatusData = daqInfoDataBlock.getDataCopy();
|
||||||
if (allStatusData != null && allStatusData.size() > 0) {
|
if (allStatusData != null && allStatusData.size() > 0) {
|
||||||
long dataStart = Long.MAX_VALUE;
|
long dataStart = Long.MAX_VALUE;
|
||||||
long dataEnd = Long.MIN_VALUE;
|
long dataEnd = Long.MIN_VALUE;
|
||||||
// find the number of times it started and stopped ....
|
// find the number of times it started and stopped ....
|
||||||
int nStart = 0, nStop = 0, nFile=0;
|
int nStart = 0, nStop = 0, nFile = 0;
|
||||||
for (DaqStatusDataUnit daqStatus : allStatusData) {
|
for (DaqStatusDataUnit daqStatus : allStatusData) {
|
||||||
switch (daqStatus.getStatus()) {
|
switch (daqStatus.getStatus()) {
|
||||||
case "Start":
|
case "Start":
|
||||||
@ -312,12 +368,14 @@ public class TethysExporter {
|
|||||||
break;
|
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",
|
System.out.printf(
|
||||||
PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1);
|
"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 ...
|
// // and we find the datamap within that ...
|
||||||
// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl());
|
// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl());
|
||||||
// if (daqMap != null) {
|
// if (daqMap != null) {
|
||||||
@ -333,24 +391,24 @@ public class TethysExporter {
|
|||||||
// */
|
// */
|
||||||
//// for ()
|
//// for ()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No idea if we need this or not. May want to return something different to void, e.g.
|
* No idea if we need this or not. May want to return something different to
|
||||||
* a reference to the main object for a tethys export. I've no idea !
|
* void, e.g. a reference to the main object for a tethys export. I've no idea !
|
||||||
|
*
|
||||||
* @param tethysExportParams2
|
* @param tethysExportParams2
|
||||||
*/
|
*/
|
||||||
private void exportGeneralData(TethysExportParams tethysExportParams) {
|
private void exportGeneralData(TethysExportParams tethysExportParams) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Here is where we export data for a specific data stream to Tethys.
|
* Here is where we export data for a specific data stream to Tethys.
|
||||||
*
|
*
|
||||||
* @param aDataBlock
|
* @param aDataBlock
|
||||||
* @param tethysExportParams
|
* @param tethysExportParams
|
||||||
@ -359,100 +417,102 @@ public class TethysExporter {
|
|||||||
private void exportDataStream(PamDataBlock aDataBlock, TethysExportParams tethysExportParams,
|
private void exportDataStream(PamDataBlock aDataBlock, TethysExportParams tethysExportParams,
|
||||||
StreamExportParams streamExportParams) {
|
StreamExportParams streamExportParams) {
|
||||||
/**
|
/**
|
||||||
* This will probably need to be passed additional parameters and may also want to return something
|
* This will probably need to be passed additional parameters and may also want
|
||||||
* other than void in order to build a bigger Tethys document.
|
* to return something other than void in order to build a bigger Tethys
|
||||||
|
* document.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Some examples of how to do whatever is needed to get schema and data out of PAMGuard.
|
* Some examples of how to do whatever is needed to get schema and data out of
|
||||||
|
* PAMGuard.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* first we'll probably want a reference to the module containing the data.
|
* first we'll probably want a reference to the module containing the data. in
|
||||||
* in principle this can't get null, since the datablock was found be searching in
|
* principle this can't get null, since the datablock was found be searching in
|
||||||
* the other direction.
|
* the other direction.
|
||||||
*/
|
*/
|
||||||
PamControlledUnit pamControlledUnit = aDataBlock.getParentProcess().getPamControlledUnit();
|
PamControlledUnit pamControlledUnit = aDataBlock.getParentProcess().getPamControlledUnit();
|
||||||
|
|
||||||
TethysDataProvider dataProvider = aDataBlock.getTethysDataProvider();
|
TethysDataProvider dataProvider = aDataBlock.getTethysDataProvider();
|
||||||
|
|
||||||
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter();
|
||||||
|
|
||||||
if (dataProvider == null) {
|
if (dataProvider == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TethysSchema tethysSchema = dataProvider.getSchema();
|
TethysSchema tethysSchema = dataProvider.getSchema();
|
||||||
/*
|
/*
|
||||||
* the schema should have a Document object in it. If we wanted to turn
|
* the schema should have a Document object in it. If we wanted to turn that
|
||||||
* that into an XML string we can ...
|
* into an XML string we can ... (though I'd assume that having the Document is
|
||||||
* (though I'd assume that having the Document is more useful)
|
* more useful)
|
||||||
*/
|
*/
|
||||||
String schemaXMLString = pamXMLWriter.getAsString(tethysSchema.getXsd(), false);
|
String schemaXMLString = pamXMLWriter.getAsString(tethysSchema.getXsd(), false);
|
||||||
System.out.printf("Schema for %s is %s\n", aDataBlock.getDataName(), schemaXMLString);
|
System.out.printf("Schema for %s is %s\n", aDataBlock.getDataName(), schemaXMLString);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the XML settings for that datablock. This is (or should be
|
* Get the XML settings for that datablock. This is (or should be the parameters
|
||||||
* the parameters that were controlling that module, with adequate data about
|
* that were controlling that module, with adequate data about upstream
|
||||||
* upstream modules). I think this has to go somewhere into the Detections document.
|
* modules). I think this has to go somewhere into the Detections document.
|
||||||
*/
|
*/
|
||||||
Document doc = pamXMLWriter.writeOneModule((PamSettings) pamControlledUnit, System.currentTimeMillis());
|
Document doc = pamXMLWriter.writeOneModule((PamSettings) pamControlledUnit, System.currentTimeMillis());
|
||||||
String moduleXML = null;
|
String moduleXML = null;
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
// this string should be XML of all the settings for the module controlling this datablock.
|
// this string should be XML of all the settings for the module controlling this
|
||||||
|
// datablock.
|
||||||
moduleXML = pamXMLWriter.getAsString(doc, true); // change to false to get smaller xml
|
moduleXML = pamXMLWriter.getAsString(doc, true); // change to false to get smaller xml
|
||||||
System.out.printf("Module settings for datablock %s are:\n", moduleXML);
|
System.out.printf("Module settings for datablock %s are:\n", moduleXML);
|
||||||
System.out.println(moduleXML);
|
System.out.println(moduleXML);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Now can go through the data. Probably, we'll want to go through all the data in
|
* Now can go through the data. Probably, we'll want to go through all the data
|
||||||
* the project, but we can hold off on that for now and just go for data that
|
* in the project, but we can hold off on that for now and just go for data that
|
||||||
* are in memory. We'll also have to think a lot about updating parts of the
|
* are in memory. We'll also have to think a lot about updating parts of the
|
||||||
* database which have been reprocessed - what we want to do, should eventually all
|
* database which have been reprocessed - what we want to do, should eventually
|
||||||
* be options set in the dialog and available within TethysExportParams
|
* all be options set in the dialog and available within TethysExportParams For
|
||||||
* For now though, we're just going to export data that are in memory.
|
* now though, we're just going to export data that are in memory. Once basic
|
||||||
* Once basic export is working, I can easily enough write something which will go
|
* export is working, I can easily enough write something which will go through
|
||||||
* through an entire data set, go through between two times, etc.
|
* an entire data set, go through between two times, etc.
|
||||||
*/
|
*/
|
||||||
// so this is a way of iterating through the data that are in memory, which will do for now ..
|
// so this is a way of iterating through the data that are in memory, which will
|
||||||
// do it with a data copy which can avoid synchronising the entire block for what may be a long time
|
// do for now ..
|
||||||
// the copy function is itself synched, and is quite fast, so easier and safe this way
|
// do it with a data copy which can avoid synchronising the entire block for
|
||||||
|
// what may be a long time
|
||||||
|
// the copy function is itself synched, and is quite fast, so easier and safe
|
||||||
|
// this way
|
||||||
ArrayList<PamDataUnit> dataCopy = aDataBlock.getDataCopy();
|
ArrayList<PamDataUnit> dataCopy = aDataBlock.getDataCopy();
|
||||||
DataSelector dataSelector = aDataBlock.getDataSelector(tethysControl.getDataSelectName(), false);
|
DataSelector dataSelector = aDataBlock.getDataSelector(tethysControl.getDataSelectName(), false);
|
||||||
int nSkipped = 0;
|
int nSkipped = 0;
|
||||||
int nExport = 0;
|
int nExport = 0;
|
||||||
|
|
||||||
for (PamDataUnit aData : dataCopy) {
|
for (PamDataUnit aData : dataCopy) {
|
||||||
/*
|
/*
|
||||||
* see if we want this data unit. PAMGuard has a complicated system of data selectors specific to
|
* see if we want this data unit. PAMGuard has a complicated system of data
|
||||||
* each data type. These are centrally managed so you don't need to worry too much about them. They
|
* selectors specific to each data type. These are centrally managed so you
|
||||||
* are identified by name for each data stream and the behaviour here should follow the selections you
|
* don't need to worry too much about them. They are identified by name for each
|
||||||
* made in the dialog.
|
* data stream and the behaviour here should follow the selections you made in
|
||||||
* the data selection system allows different displays to show different data, so a stream can have many differently
|
* the dialog. the data selection system allows different displays to show
|
||||||
* named selectors active at any one time, all doing different things in different parts of PAMGuard.
|
* different data, so a stream can have many differently named selectors active
|
||||||
|
* at any one time, all doing different things in different parts of PAMGuard.
|
||||||
*/
|
*/
|
||||||
if (dataSelector != null) {
|
if (dataSelector != null) {
|
||||||
if (dataSelector.scoreData(aData) <= 0) {
|
if (dataSelector.scoreData(aData) <= 0) {
|
||||||
nSkipped++;
|
nSkipped++;
|
||||||
continue; // don't want this one.
|
continue; // don't want this one.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* then we do whatever we need to do to convert this into something for Tethys
|
* then we do whatever we need to do to convert this into something for Tethys
|
||||||
* this might happen in the tethysSchema object for each data stream ????
|
* this might happen in the tethysSchema object for each data stream ????
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
nExport++;
|
||||||
nExport ++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.printf("Exported %d data units and skipped %d in %s", nExport, nSkipped, aDataBlock.getLongDataName());
|
System.out.printf("Exported %d data units and skipped %d in %s", nExport, nSkipped,
|
||||||
|
aDataBlock.getLongDataName());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user