Tethys updates

And get rid of some other files that had got into the repo by accident
This commit is contained in:
Douglas Gillespie 2024-08-23 14:58:32 +01:00
parent 34ba7ebceb
commit 51aa658514
16 changed files with 421 additions and 5179 deletions

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:clrMap xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
To build an executable jar file from the PAMGuard source using Eclipse, you need to use this build configuration
'Build PAMGuard.launch'
You cannot simply export the project as a runnable jar file, or you will not get the required Maven dependencies.
To use this with Eclipse, from your workspace, select File, then import, then in the list of things to be imported select
Run/Debug Launch Configurations, hit Next
Then in the Import Launch Configurations panel, browse to this folder. Select the folder (not a specific file)
then in the left panel, select the folder, then in the right panel the configuration you wish to import
(i.e. Build PAMGuard.launch) and hit Finish
Then go to 'Run Configurations' and find the launch in the 'Maven Builds' section. You'll probably have to change the
Base directory at the top of the panel to select the right project within your workspace.
Once that's done, you can Run the configuration. It will take a while to get all the Maven dependencies and will output
a runnable jar file into the 'targets' folder in your workspace.
The name and version number of the created files are taken from the POM.xml file, so edit that if you want a different name.
For unknown reasons, it makes three files. They are all the same, you can delete the ones starting with 'original-' and
ending with '-shared'

View File

@ -14,6 +14,7 @@ public class RWTethysDataProvider extends AutoTethysProvider {
public RWTethysDataProvider(TethysControl tethysControl, PamDataBlock pamDataBlock) {
super(tethysControl, pamDataBlock);
setAddFrequencyInfo(true);
}
@Override

View File

@ -15,8 +15,8 @@ public class ClickBlockSpeciesManager extends DataBlockSpeciesManager<ClickDetec
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
super(clickDataBlock);
this.clickControl = clickControl;
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.OTHER, "Unknown", "Unknown"));
setDefaultSpeciesCode("Unknown");
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.CETACEAN, "Click", "Click"));
setDefaultSpeciesCode("Click");
}
@Override

View File

@ -12,25 +12,25 @@ import PamDetection.LocContents;
import PamUtils.LatLong;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import nilus.AngularCoordinateType;
import nilus.Helper;
import nilus.LocalizationType;
import nilus.Localize;
import nilus.WGS84CoordinateType;
import nilus.LocalizationType.Angular;
import nilus.LocalizationType.Parameters;
import nilus.LocalizationType.WGS84;
import nilus.LocalizationType.Parameters.TargetMotionAnalysis;
import nilus.Localize.Effort;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import nilus.Localize.Effort.CoordinateReferenceSystem.ReferenceFrame;
import pamMaths.PamVector;
import targetMotionOld.TargetMotionLocaliser;
import tethys.TethysTimeFuncs;
import tethys.localization.Anchor;
import tethys.localization.CoordinateName;
import tethys.localization.LocalizationBuilder;
import tethys.localization.LocalizationCreator;
import tethys.localization.LocalizationSubTypes;
import tethys.localization.LocalizationTypes;
import tethys.localization.ReferenceFrame;
import tethys.localization.TimeReference;
import tethys.pamdata.AutoTethysProvider;
@ -38,7 +38,7 @@ public class TMALocalizationCreator implements LocalizationCreator {
int maxDimension = 2;
public TMALocalizationCreator(TargetMotionLocaliser targetMotionLocaliser) {
// TODO Auto-generated constructor stub
}
@ -53,12 +53,36 @@ public class TMALocalizationCreator implements LocalizationCreator {
locTypes.add(LocalizationTypes.Point.toString());
locTypes.add(LocalizationTypes.PerpendicularRange.toString());
/**
* Currently, TMA is only outputing as WGS84. Future release will have
* options to put out local xyz coordinates instead, in which case this
* will be Engineering and the referenceFrame will become instrument.
*/
CoordinateReferenceSystem coordRefs = locEffort.getCoordinateReferenceSystem();
coordRefs.setName(CoordinateName.WGS84.toString());
coordRefs.setSubtype(LocalizationSubTypes.Geographic.toString());
ReferenceFrame refFrame = localizationBuilder.getDefaultReferenceFrame(CoordinateName.WGS84, LocalizationSubTypes.Geographic);
if (refFrame != null) {
coordRefs.setReferenceFrame(refFrame);
}
// /**
// * TMA is always references to the earth.
// */
// ReferenceFrame refFrame = coordRefs.getReferenceFrame();
// if (refFrame == null) {
// refFrame = new ReferenceFrame();
// try {
// Helper.createRequiredElements(refFrame);
// } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
// e.printStackTrace();
// }
// coordRefs.setReferenceFrame(refFrame);
// }
// refFrame.setAnchor(Anchor.WGS84.toString());
locEffort.setDimension(2);
return true;
}
@ -115,19 +139,19 @@ public class TMALocalizationCreator implements LocalizationCreator {
* Needs a bit of work to get errors in correct direction (needs import
* of track data for this value ?) and conversion to latlong units.
*/
// if (errorVec != null && errorVec.length >= 2) {
// wgsErr = new WGS84CoordinateType();
// wgsErr.setLongitude(errorVec[0]);
// wgsErr.setLatitude(errorVec[1]);
// if (hasDepth && errorVec.length >= 3) {
// wgsErr.setElevationM(errorVec[2]);
// }
// wgs84.setCoordinateError(wgsErr);
// }
// if (errorVec != null && errorVec.length >= 2) {
// wgsErr = new WGS84CoordinateType();
// wgsErr.setLongitude(errorVec[0]);
// wgsErr.setLatitude(errorVec[1]);
// if (hasDepth && errorVec.length >= 3) {
// wgsErr.setElevationM(errorVec[2]);
// }
// wgs84.setCoordinateError(wgsErr);
// }
loc.setWGS84(wgs84);
// set the TMA information
Parameters params = loc.getParameters();
if (params == null) {
@ -142,31 +166,31 @@ public class TMALocalizationCreator implements LocalizationCreator {
if (timeAbeam != null) {
loc.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(timeAbeam));
}
// now also output a perpendicular distance.
// now also output a perpendicular distance.
Double perp = groupLocResult.getPerpendicularDistance();
if (perp != null) {
loc.setPerpendicularRangeM(AutoTethysProvider.roundDecimalPlaces(perp, 2));
}
// con only output one type.
// if (perp != null) {
// AngularCoordinateType acType = new AngularCoordinateType();
// acType.setAngle1(90);
// acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perp,1));
// Angular angular = new Angular();
// angular.setCoordinate(acType);
// if (errors != null) {
// AngularCoordinateType angErr = new AngularCoordinateType();
// angErr.setDistanceM(errors.norm());
// angular.setCoordinateError(angErr);
// }
// loc.setAngular(angular);
// }
// con only output one type.
// if (perp != null) {
// AngularCoordinateType acType = new AngularCoordinateType();
// acType.setAngle1(90);
// acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perp,1));
// Angular angular = new Angular();
// angular.setCoordinate(acType);
// if (errors != null) {
// AngularCoordinateType angErr = new AngularCoordinateType();
// angErr.setDistanceM(errors.norm());
// angular.setCoordinateError(angErr);
// }
// loc.setAngular(angular);
// }
return loc;
}

View File

@ -87,6 +87,7 @@ import tethys.dbxml.TethysException;
import tethys.deployment.swing.DeploymentWizard;
import tethys.deployment.swing.EffortProblemDialog;
import tethys.deployment.swing.RecordingGapDialog;
import tethys.localization.TethysLatLong;
import tethys.niluswraps.PDeployment;
import tethys.output.TethysExportParams;
import tethys.pamdata.AutoTethysProvider;
@ -909,8 +910,8 @@ public class DeploymentHandler extends CollectionHandler implements TethysStateO
GpsData gpsData = gpsDataUnit.getGpsData();
Point gpsPoint = new Point();
gpsPoint.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(gpsDataUnit.getTimeMilliseconds()));
gpsPoint.setLatitude(gpsData.getLatitude());
gpsPoint.setLongitude(PamUtils.constrainedAngle(gpsData.getLongitude()));
gpsPoint.setLatitude(TethysLatLong.formatLatitude(gpsData.getLatitude()));
gpsPoint.setLongitude(TethysLatLong.formatLongitude(gpsData.getLongitude()));
CourseOverGroundDegN cog = gpsPoint.getCourseOverGroundDegN();
if (cog == null) {
cog = new CourseOverGroundDegN();
@ -1080,8 +1081,8 @@ public class DeploymentHandler extends CollectionHandler implements TethysStateO
double recLat = deploymentData.getRecoveryDetails().getLatitude();
double recLong = deploymentData.getRecoveryDetails().getLongitude();
if (recLat != 0 & recLong != 0.) {
deployment.getRecoveryDetails().setLatitude(recLat);
deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLong));
deployment.getRecoveryDetails().setLatitude(TethysLatLong.formatLatitude(recLat));
deployment.getRecoveryDetails().setLongitude(TethysLatLong.formatLongitude(recLong));
}
}

View File

@ -620,7 +620,7 @@ public class DetectionsHandler extends CollectionHandler {
* Check the document name isn't already used and increment id as necessary.
*/
while (true) {
fullId = String.format("%s_%d", prefix, uniqueDetectionsId++);
fullId = String.format("%s_D_%d", prefix, uniqueDetectionsId++);
if (!tethysControl.getDbxmlQueries().documentExists(Collection.Detections.toString(), fullId)) {
break;
}

View File

@ -0,0 +1,10 @@
package tethys.localization;
/**
* Anchors for localization effort coordinate system.
* @author dg50
*
*/
public enum Anchor {
UTMZone, WGS84, instrument;
}

View File

@ -3,6 +3,18 @@ package tethys.localization;
import java.math.BigInteger;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Element;
import Array.ArrayManager;
import Array.PamArray;
import Array.Streamer;
import Array.streamerOrigin.OriginSettings;
import Array.streamerOrigin.StaticOriginSettings;
import GPS.GpsData;
import GPS.GpsDataUnit;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.detectionGroupLocaliser.GroupLocResult;
@ -14,6 +26,7 @@ import PamUtils.LatLong;
import PamUtils.PamUtils;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import binaryFileStorage.DataUnitFileInformation;
import nilus.AlgorithmType;
import nilus.AngularCoordinateType;
import nilus.BearingType;
@ -31,10 +44,12 @@ import nilus.LocalizationType.Parameters;
import nilus.LocalizationType.References;
import nilus.LocalizationType.WGS84;
import nilus.LocalizationType.Parameters.TargetMotionAnalysis;
import nilus.LocalizationType.Parameters.UserDefined;
import nilus.LocalizationType.References.Reference;
import nilus.Localize.Effort;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import nilus.Localize.Effort.ReferencedDocuments;
import nilus.Localize.Effort.CoordinateReferenceSystem.ReferenceFrame;
import nilus.Localize.Effort.ReferencedDocuments.Document;
import pamMaths.PamVector;
import tethys.Collection;
@ -68,6 +83,8 @@ public class LocalizationBuilder {
private Localize currentDocument;
private LocalizationCreator localisationCreator;
private TethysDataProvider dataProvider;
private Helper helper;
public LocalizationBuilder(TethysControl tethysControl, PDeployment deployment, Detections detectionsDocument, PamDataBlock dataBlock,
StreamExportParams exportParams) {
@ -76,6 +93,11 @@ public class LocalizationBuilder {
this.dataBlock = dataBlock;
this.streamExportParams = exportParams;
this.tethysControl = tethysControl;
try {
helper = new Helper();
} catch (JAXBException e) {
e.printStackTrace();
}
dataProvider = dataBlock.getTethysDataProvider(tethysControl);
localisationHandler = tethysControl.getLocalizationHandler();
localisationAlgorithm = dataBlock.getLocalisationAlgorithm();
@ -123,13 +145,13 @@ public class LocalizationBuilder {
}
Document detectsDoc = new Document();
detectsDoc.setId(detectionsDocument.getId());
detectsDoc.setType(Collection.Localizations.collectionName());
detectsDoc.setType(Collection.Detections.collectionName());
detectsDoc.setIndex(BigInteger.ZERO);
eff.getReferencedDocuments().getDocument().add(detectsDoc);
}
String prefix = deployment.nilusObject.getId() + "_" + dataProvider.getDetectionsName();
String prefix = deployment.nilusObject.getId() + "_" + dataProvider.getDetectionsName() + "_L";
String fullId = localisationHandler.getLocalisationdocId(prefix);
currentDocument.setId(fullId);
// detections.setDescription(dataProvider.getDescription(deployment, tethysExportParams));
@ -185,6 +207,54 @@ public class LocalizationBuilder {
return done;
}
/**
* Get a default reference frame for the header of a localization document. This is very dependent
* on the localization subtype. Also on whether the array is fixed or moving. It it's fixed, then
* we also need to add the instrument lat long.
* @param coordinateName
* @param subType
* @return
*/
public ReferenceFrame getDefaultReferenceFrame(CoordinateName coordinateName, LocalizationSubTypes subType) {
ReferenceFrame referenceFrame = new ReferenceFrame();
switch (subType) {
case Derived:
referenceFrame.setAnchor(Anchor.UTMZone.toString()); // i never use this on. If I do, this will need work !
break;
case Engineering:
referenceFrame.setAnchor(Anchor.instrument.toString());
break;
case Geographic:
referenceFrame.setAnchor(Anchor.WGS84.toString());
break;
default:
break;
}
/*
* And see if it's a fixed or moving array. Will just have to look at the
* first streamer here. Hard to copy with multiples !
*/
PamArray array = ArrayManager.getArrayManager().getCurrentArray();
Streamer streamer = array.getStreamer(0);
if (streamer != null) {
OriginSettings origin = streamer.getOriginSettings();
if (origin instanceof StaticOriginSettings) {
StaticOriginSettings staticOrigin = (StaticOriginSettings) origin;
GpsDataUnit ll = staticOrigin.getStaticPosition();
if (ll != null) {
GpsData pos = ll.getGpsData();
if (pos != null) {
referenceFrame.setLatitude(TethysLatLong.formatLatitude(pos.getLatitude()));
referenceFrame.setLongitude(TethysLatLong.formatLongitude(pos.getLongitude()));
referenceFrame.setDatum(String.format("Altitude %3.2fm", pos.getHeight()));
}
}
}
}
return referenceFrame;
}
public boolean sortStandardCoordinates(PamDataBlock dataBlock) {
LocalisationInfo locInfo = dataBlock.getLocalisationContents();
Effort locEffort = currentDocument.getEffort();
@ -202,6 +272,7 @@ public class LocalizationBuilder {
// List<String> locTypes = locEffort.getLocalizationType();
boolean ambiguity = locInfo.hasLocContent(LocContents.HAS_AMBIGUITY);
CoordinateReferenceSystem coordRefs = locEffort.getCoordinateReferenceSystem();
ReferenceFrame referenceFrame = null;
List<String> locTypes = locEffort.getLocalizationType();
if (locInfo.getLocContent() == 0) {
return false;
@ -217,6 +288,7 @@ public class LocalizationBuilder {
else {
locEffort.setDimension(2);
}
referenceFrame = getDefaultReferenceFrame(CoordinateName.WGS84, LocalizationSubTypes.Geographic);
// locEffort.set
}
else if (locInfo.hasLocContent(LocContents.HAS_XYZ)) {
@ -224,12 +296,14 @@ public class LocalizationBuilder {
coordRefs.setSubtype(LocalizationSubTypes.Engineering.toString());
locTypes.add(LocalizationTypes.Point.toString());
locEffort.setDimension(3);
referenceFrame = getDefaultReferenceFrame(CoordinateName.Cartesian, LocalizationSubTypes.Engineering);
}
else if (locInfo.hasLocContent(LocContents.HAS_XY)) {
coordRefs.setName(CoordinateName.Cartesian.toString());
coordRefs.setSubtype(LocalizationSubTypes.Engineering.toString());
locTypes.add(LocalizationTypes.Point.toString());
locEffort.setDimension(2);
referenceFrame = getDefaultReferenceFrame(CoordinateName.Cartesian, LocalizationSubTypes.Engineering);
}
else if (locInfo.hasLocContent(LocContents.HAS_BEARING)) {
coordRefs.setName(CoordinateName.Polar.toString());
@ -241,10 +315,12 @@ public class LocalizationBuilder {
else {
locEffort.setDimension(2);
}
referenceFrame = getDefaultReferenceFrame(CoordinateName.Polar, LocalizationSubTypes.Engineering);
}
else {
return false;
}
coordRefs.setReferenceFrame(referenceFrame);
return true;
}
@ -329,21 +405,41 @@ public class LocalizationBuilder {
locType.setSpeciesId(species);
}
}
References references = locType.getReferences();
if (references == null) {
references = new References();
try {
Helper.createRequiredElements(references);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
locType.setReferences(references);
/*
* Add references back to PAMGuard data as for Detections.
* Same code as in Detections, but classes are different (though with the same fields).
*/
Parameters params = getParameters(locType);
String uid = BigInteger.valueOf(dataUnit.getUID()).toString();
Element el = addUserDefined(params,"PAMGuardUID", uid);
DataUnitFileInformation fileInf = dataUnit.getDataUnitFileInformation();
if (fileInf != null) {
el.setAttribute("BinaryFile", fileInf.getShortFileName(2048));
el.setAttribute("FileIndex", Long.valueOf(fileInf.getIndexInFile()).toString());
}
Reference reference = new Reference();
reference.setIndex(BigInteger.valueOf(dataUnit.getUID()));
reference.setEventRef("UID");
locType.getReferences().getReference().add(reference);
if (dataUnit.getDatabaseIndex() > 0) {
// only write the database index if it's > 0, i.e. is used.
addUserDefined(params, "DatabaseId", String.format("%d", dataUnit.getDatabaseIndex()));
}
/*
* Not needed. something to do with references to Detection docs.
*/
// References references = locType.getReferences();
// if (references == null) {
// references = new References();
// try {
// Helper.createRequiredElements(references);
// } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
// e.printStackTrace();
// }
// locType.setReferences(references);
// }
// Reference reference = new Reference();
// reference.setIndex(BigInteger.valueOf(dataUnit.getUID()));
// reference.setEventRef("UID");
// locType.getReferences().getReference().add(reference);
return locType;
}
@ -405,11 +501,7 @@ public class LocalizationBuilder {
locType.setWGS84(wgs84);
// locType.setParameters(null);
Parameters params = locType.getParameters();
if (params == null) {
params = new Parameters();
locType.setParameters(params);
}
Parameters params = getParameters(locType);
TargetMotionAnalysis tma = new TargetMotionAnalysis();
tma.setStart(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
tma.setEnd(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getEndTimeInMilliseconds()));
@ -442,6 +534,40 @@ public class LocalizationBuilder {
return locType;
}
/**
* Convenience method to get the Parameters object for a localisation and
* to automatically create it if it doesn't exist.
* @param localization
* @return
*/
public Parameters getParameters(LocalizationType localization) {
Parameters params = localization.getParameters();
if (params == null) {
params = new Parameters();
localization.setParameters(params);
}
return params;
}
public Element addUserDefined(Parameters parameters, String parameterName, String parameterValue) {
UserDefined userDefined = parameters.getUserDefined();
if (userDefined == null) {
userDefined = new UserDefined();
parameters.setUserDefined(userDefined);
}
Element el = null;
try {
el = helper.AddAnyElement(userDefined.getAny(), parameterName, parameterValue);
} catch (JAXBException e) {
e.printStackTrace();
return null;
} catch (ParserConfigurationException e) {
e.printStackTrace();
return null;
}
return el;
}
public LocalizationType createSphericalLoc(PamDataUnit dataUnit) {
// TODO Auto-generated method stub

View File

@ -2,17 +2,8 @@ package tethys.localization;
import java.util.ArrayList;
import Localiser.detectionGroupLocaliser.GroupLocResult;
import Localiser.detectionGroupLocaliser.GroupLocalisation;
import PamDetection.AbstractLocalisation;
import PamDetection.LocContents;
import PamUtils.LatLong;
import PamUtils.PamUtils;
import PamguardMVC.PamDataBlock;
import nilus.Localize;
import nilus.SpeciesIDType;
import pamMaths.PamVector;
import nilus.Localize.Effort.CoordinateReferenceSystem;
import tethys.Collection;
import tethys.CollectionHandler;
import tethys.TethysControl;

View File

@ -0,0 +1,122 @@
package tethys.localization;
import PamUtils.PamUtils;
import tethys.pamdata.AutoTethysProvider;
/**
* Static formatting (rounding and range checking) functions for latlong values.
* @author dg50
*
*/
public class TethysLatLong {
/*
* A degree is 60 minutes and a minute is one mile = 1852m.
* Therefore one metre of latitude is 9e-6 degrees.
* One mm of latitude is therefore 9e-9 degrees.
* GPS Accuracy is generally <3m, so 6dp generally OK for track data. however,
* localisations around a small static array may want mm accuracy, so need 8dp.
* For a double precision number, resolution at 360 degrees is 14dp
*
*/
/**
* Number of decimal places for metre accuracy
*/
public static int metreDecimalPlaces = 6;
/**
* Number of decimal places for mm accuracy.
*/
public static int mmDecimalPlaces = 9;
/**
* Check range of a latitude value.
* This function does absolutely nothing, but is here for completeness.
* @param latitude
* @return
*/
public static Double formatLatitude(Double latitude) {
if (latitude == null) {
return null;
}
return latitude;
}
/**
* Check range and round a latitude value to a set number of decimal places.
* @param latitude
* @param decimalPlaces
* @return
*/
public static Double formatLatitude(Double latitude, int decimalPlaces) {
if (latitude == null) {
return null;
}
return AutoTethysProvider.roundDecimalPlaces(latitude, decimalPlaces);
}
/**
* format a latitude to metre accuracy
* @param latitude
* @return
*/
public static Double formatLatitude_m(Double latitude) {
return formatLatitude(latitude, metreDecimalPlaces);
}
/**
* format a latitude to mm accuracy
* @param latitude
* @return
*/
public static Double formatLatitude_mm(Double latitude) {
return formatLatitude(latitude, mmDecimalPlaces);
}
/**
* Check range of a longitude value which must be between 0 and 360.
* This function does absolutely nothing, but is here for completeness.
* @param latitude
* @return
*/
public static Double formatLongitude(Double longitude) {
if (longitude == null) {
return null;
}
return PamUtils.constrainedAngle(longitude);
}
/**
* Check range and round a longitude value to a set number of decimal places.
* @param latitude
* @param decimalPlaces
* @return
*/
public static Double formatLongitude(Double longitude, int decimalPlaces) {
if (longitude == null) {
return null;
}
longitude = formatLongitude(longitude); // constrain first.
return AutoTethysProvider.roundDecimalPlaces(longitude, decimalPlaces);
}
/**
* format a longitude value to m accuracy.
* @param latitude
* @return
*/
public static Double formatLongitude_m(Double longitude) {
return formatLongitude(longitude, metreDecimalPlaces);
}
/**
* format a longitude value to mm accuracy.
* @param latitude
* @return
*/
public static Double formatLongitude_mm(Double longitude) {
return formatLongitude(longitude, mmDecimalPlaces);
}
}

View File

@ -1,32 +1,34 @@
package tethys.pamdata;
import java.io.StringReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit;
import PamController.PamSettings;
import PamController.PamguardVersionInfo;
import PamController.settings.output.xml.PamguardXMLWriter;
import PamDetection.LocalisationInfo;
import PamUtils.XMLUtils;
import PamguardMVC.DataAutomationInfo;
import PamguardMVC.DataUnitBaseData;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamProcess;
import PamguardMVC.TFContourData;
import PamguardMVC.TFContourProvider;
import binaryFileStorage.DataUnitFileInformation;
import generalDatabase.DBSchemaWriter;
import generalDatabase.SQLLogging;
import nilus.AlgorithmType;
import nilus.Deployment;
import nilus.DescriptionType;
@ -52,23 +54,11 @@ import tethys.species.SpeciesMapItem;
import tethys.swing.export.ExportWizardCard;
import whistleClassifier.WhistleContour;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.URISyntaxException;
/**
* Automatically provides Tethys data for a PAMGuard datablock.
* Automatically provides Tethys data for a PAMGuard datablock.
* Does most of what needs to be done, though individual modules
* will want to override this, call the base createDetection function and then add a
* few more bespoke elements.
* will want to override this, call the base createDetection function and then add a
* few more bespoke elements.
* @author dg50
*
*/
@ -79,6 +69,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
private PamControlledUnit pamControlledUnit;
private TethysControl tethysControl;
private Helper helper;
private boolean addFrequencyInfo = false;
public AutoTethysProvider(TethysControl tethysControl, PamDataBlock pamDataBlock) {
this.tethysControl = tethysControl;
@ -91,7 +82,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
e.printStackTrace();
}
}
@Override
public DescriptionType getDescription(Deployment deployment, TethysExportParams tethysExportParams) {
DescriptionType description = new DescriptionType();
@ -106,9 +97,9 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
@Override
public AlgorithmType getAlgorithm(Collection collection) {
/**
* Probably need to split this to provide detection algorithm parameters and
* localisation algorithm parameters, or pass in the document type as a function
* argument.
* Probably need to split this to provide detection algorithm parameters and
* localisation algorithm parameters, or pass in the document type as a function
* argument.
*/
AlgorithmType algorithm = new AlgorithmType();
try {
@ -116,7 +107,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
// do the parameters as normal whether it's dets or locs.
// do the parameters as normal whether it's dets or locs.
nilus.AlgorithmType.Parameters algoParameters = this.getAlgorithmParameters();
if (algoParameters != null) {
algorithm.setParameters(algoParameters);
@ -125,7 +116,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
nilus.AlgorithmType.Parameters locParameters = this.getLocalisationParameters();
if (locParameters == null) {
/*
* It seems Tethys MUST have parameters, so make an empty one if needed.
* It seems Tethys MUST have parameters, so make an empty one if needed.
*/
locParameters = new nilus.AlgorithmType.Parameters();
}
@ -133,7 +124,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
algorithm.setParameters(locParameters);
}
else if (locParameters != null) {
// merge the two sets, putting the localisation information first.
// merge the two sets, putting the localisation information first.
List<Element> mainList = algoParameters.getAny();
List<Element> locList = locParameters.getAny();
if (mainList != null && locList != null) {
@ -150,7 +141,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
}
/**
* Localisation parameters. Some localisers don't actually have any parameters,
* Localisation parameters. Some localisers don't actually have any parameters,
* but Tethys requires a parameters element, so if there aren't any, set a dummy
* @return
*/
@ -181,13 +172,13 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
nilus.AlgorithmType.Parameters parameters = new nilus.AlgorithmType.Parameters();
List<Element> paramList = parameters.getAny();
paramList.add(paramEl);
return parameters;
}
@Override
public nilus.AlgorithmType.Parameters getAlgorithmParameters() {
if (pamControlledUnit instanceof PamSettings == false) {
if (!(pamControlledUnit instanceof PamSettings)) {
return null;
}
PamSettings pamSettings = (PamSettings) pamControlledUnit;
@ -211,7 +202,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
/**
* Not used. Was an attempt to automatically add name spaces to the PAMGuard settings
* XML I generate, but we found a better way.
* XML I generate, but we found a better way.
* @param doc
* @param settingsEl
* @param xmlNameSpace
@ -270,7 +261,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
DOMSource source = new DOMSource(doc);
// Result
// Result
// Source text = new StreamSource(new File("input.xml"));
DOMResult result = new DOMResult();
transformer.transform(source, result);
@ -294,8 +285,8 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
}
/**
* Algorithm method. Default is the module name. Can change to a paper citation
* by overriding this
* Algorithm method. Default is the module name. Can change to a paper citation
* by overriding this
* @return
*/
private String getAlgorithmMethod() {
@ -335,16 +326,21 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
}
detection.setSpeciesId(species);
/*
* NOTE: I use channel bitmaps throughout since detections are often made on multiple channels.
* NOTE: I use channel bitmaps throughout since detections are often made on multiple channels.
*/
detection.setChannel(BigInteger.valueOf(dataUnit.getChannelBitmap()));
nilus.Detection.Parameters detParams = new nilus.Detection.Parameters();
detection.setParameters(detParams);
double[] freqs = dataUnit.getFrequency();
if (freqs != null && freqs[1] != 0) {
detParams.setMinFreqHz(freqs[0]);
detParams.setMaxFreqHz(freqs[1]);
if (addFrequencyInfo) {
/**
* Don't add by default.
*/
double[] freqs = dataUnit.getFrequency();
if (freqs != null && freqs[1] != 0) {
detParams.setMinFreqHz(freqs[0]);
detParams.setMaxFreqHz(freqs[1]);
}
}
double ampli = dataUnit.getAmplitudeDB();
ampli = roundDecimalPlaces(ampli, 1);
@ -359,7 +355,8 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
el.setAttribute("BinaryFile", fileInf.getShortFileName(2048));
el.setAttribute("FileIndex", Long.valueOf(fileInf.getIndexInFile()).toString());
}
if (dataUnit.getDatabaseIndex() >= 0) {
if (dataUnit.getDatabaseIndex() > 0) {
// only write the database index if it's > 0, i.e. is used.
addUserDefined(detParams, "DatabaseId", String.format("%d", dataUnit.getDatabaseIndex()));
}
@ -387,7 +384,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
/**
* Get tonal sounds contour. Sadly there are two slightly different interfaces in use
* in PAMGuard, so try them both.
* in PAMGuard, so try them both.
* @param detParams
* @return true if a contour was added
*/
@ -402,7 +399,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
List<Double> offsetS = tonal.getOffsetS();
List<Double> hz = tonal.getHz();
for (int i = 0; i < tMillis.length; i++) {
offsetS.add(roundSignificantFigures((double) (tMillis[i]-tMillis[0]) / 1000., 4));
offsetS.add(roundSignificantFigures((tMillis[i]-tMillis[0]) / 1000., 4));
hz.add(roundSignificantFigures(fHz[i], 4));
}
detParams.setTonal(tonal);
@ -485,7 +482,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
kind.setCall(mapItem.getCallType());
effortKinds.add(kind);
effortKinds.add(kind);
}
@ -495,7 +492,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
public String getDetectionsMethod() {
/*
* could really do with knowing what type of detector we're dealing with, i.e. if it's
* automatic or manual. For most blocks this is fixed, though some may have a mixture of both !
* automatic or manual. For most blocks this is fixed, though some may have a mixture of both !
*/
DataAutomationInfo dataAutomation = pamDataBlock.getDataAutomationInfo();
String method;
@ -524,7 +521,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
String blockName = pamDataBlock.getDataName();
String documentName;
/**
* If the datablock name is the same as the unit name, no need to repeat onesself.
* If the datablock name is the same as the unit name, no need to repeat onesself.
*/
if (pcuName.equals(blockName)) {
documentName = new String(pcuName); // copy it, since we're about to modify it!
@ -539,7 +536,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
public static double roundDecimalPlaces(double value, int decPlaces) {
double scale = Math.pow(10, decPlaces);
long longVal = Math.round(value*scale);
return (double) longVal/scale;
return longVal/scale;
}
public static double roundSignificantFigures(double value, int sigFigs) {
@ -551,7 +548,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
double scale = sigFigs-Math.floor(Math.log10(value));
scale = Math.pow(10, scale);
long longVal = Math.round(value*scale);
return sign*(double) longVal/scale;
return sign*longVal/scale;
}
@Override
@ -571,7 +568,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
return true;
}
@Override
public boolean canExportLocalisations(GranularityEnumType granularityType) {
LocalisationInfo locCont = pamDataBlock.getLocalisationContents();
@ -582,7 +579,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
}
/**
* Granularity is OK for export.
* Granularity is OK for export.
* @param granularityType
* @return
*/
@ -607,7 +604,21 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
protected PamDataBlock getPamDataBlock() {
return pamDataBlock;
}
/**
* @return the addFrequencyInfo
*/
public boolean isAddFrequencyInfo() {
return addFrequencyInfo;
}
/**
* @param addFrequencyInfo the addFrequencyInfo to set
*/
public void setAddFrequencyInfo(boolean addFrequencyInfo) {
this.addFrequencyInfo = addFrequencyInfo;
}
}

View File

@ -7,8 +7,14 @@ package tethys.species;
*/
public class ITISTypes {
/*
* A few that get used in defaults copied from itis.gov for convenience.
*/
public static final int OTHER = -10;
public static final int ANTHROPOGENIC = 1758;
public static final int CETACEAN = 180403;
public static final int ODONTOCETE = 180404;
public static final int MYSTICETE = 552298;
public static final String getName(int code) {
switch (code) {

View File

@ -8,6 +8,7 @@ public class WhistleMoanTethysProvider extends AutoTethysProvider {
public WhistleMoanTethysProvider(TethysControl tethysControl, PamDataBlock pamDataBlock) {
super(tethysControl, pamDataBlock);
setAddFrequencyInfo(true);
}
}