Merge from DG (#145)

* Localization output

* update localiser output
This commit is contained in:
Douglas Gillespie 2024-08-08 14:27:05 +01:00 committed by GitHub
parent adf4c87781
commit bea4a544d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 721 additions and 177 deletions

View File

@ -1,5 +1,7 @@
package Localiser; package Localiser;
import java.io.Serializable;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamDetection.LocalisationInfo; import PamDetection.LocalisationInfo;
@ -12,10 +14,9 @@ import PamDetection.LocalisationInfo;
public interface LocalisationAlgorithm { public interface LocalisationAlgorithm {
/** /**
* Get the likely content flags for this localiser. * Get information about the localisation algorithm.
* @see LocalisationInfo * @return algorithm information.
* @see LocContents
* @return localisation flags.
*/ */
public int getLocalisationContents(); public LocalisationAlgorithmInfo getAlgorithmInfo();
} }

View File

@ -0,0 +1,31 @@
package Localiser;
import java.io.Serializable;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
public interface LocalisationAlgorithmInfo {
/**
* Get the likely content flags for this localiser.
* @see LocalisationInfo
* @see LocContents
* @return localisation flags.
*/
public int getLocalisationContents();
/**
* Get the algorithm name
* @return algorithm name
*/
public String getAlgorithmName();
/**
* Get the algorithm parameters. Something else
* can turn these into xml for Tethys.
* @return algorithm parameters object. Might be null;
*/
public Serializable getParameters();
}

View File

@ -1,6 +1,7 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import Localiser.LocalisationAlgorithm; import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import pamMaths.PamVector; import pamMaths.PamVector;
/** /**
@ -9,7 +10,7 @@ import pamMaths.PamVector;
* @author Doug Gillespie * @author Doug Gillespie
* *
*/ */
public interface BearingLocaliser extends LocalisationAlgorithm { public interface BearingLocaliser extends LocalisationAlgorithm, LocalisationAlgorithmInfo {
/** /**
* Do any preparation necessary (e.g. creation of look up tables) * Do any preparation necessary (e.g. creation of look up tables)

View File

@ -1,8 +1,12 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents; import PamDetection.LocContents;
import pamMaths.PamVector; import pamMaths.PamVector;
@Deprecated
public class CombinedBearingLocaliser implements BearingLocaliser { public class CombinedBearingLocaliser implements BearingLocaliser {
private BearingLocaliser firstLocaliser; private BearingLocaliser firstLocaliser;
@ -67,4 +71,19 @@ public class CombinedBearingLocaliser implements BearingLocaliser {
return res2; return res2;
} }
@Override
public String getAlgorithmName() {
return "Combined Simplex bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
} }

View File

@ -1,10 +1,13 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import Array.ArrayManager; import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.LUDecomposition; import Jama.LUDecomposition;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@ -14,7 +17,7 @@ public class LSQBearingLocaliser implements BearingLocaliser {
private int hydrophoneBitMap; private int hydrophoneBitMap;
private long timeMillis; private long timeMillis;
private double timingError; private double timingError;
private Matrix weightedHydrophoneVectors; private Matrix weightedHydrophoneVectors;
private Matrix hydrophoneVectors; private Matrix hydrophoneVectors;
private Matrix hydrophoneErrorVectors; private Matrix hydrophoneErrorVectors;
@ -35,7 +38,7 @@ public class LSQBearingLocaliser implements BearingLocaliser {
public int getLocalisationContents() { public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY; return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
} }
@Override @Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) { public void prepare(int[] arrayElements, long timeMillis, double timingError) {
/* /*
@ -49,7 +52,7 @@ public class LSQBearingLocaliser implements BearingLocaliser {
arrayType = arrayManager.getArrayShape(currentArray, hydrophoneBitMap); arrayType = arrayManager.getArrayShape(currentArray, hydrophoneBitMap);
arrayAxis = arrayManager.getArrayDirections(currentArray, hydrophoneBitMap); arrayAxis = arrayManager.getArrayDirections(currentArray, hydrophoneBitMap);
int nHyd = arrayElements.length; int nHyd = arrayElements.length;
int nDelay = (nHyd*(nHyd-1))/2; int nDelay = (nHyd*(nHyd-1))/2;
weightedHydrophoneVectors = new Matrix(nDelay, 3); weightedHydrophoneVectors = new Matrix(nDelay, 3);
@ -77,12 +80,12 @@ public class LSQBearingLocaliser implements BearingLocaliser {
weightedHydrophoneVectors.set(iRow, e, v.getElement(e)/c*fitWeights[iRow]); weightedHydrophoneVectors.set(iRow, e, v.getElement(e)/c*fitWeights[iRow]);
hydrophoneVectors.set(iRow, e, v.getElement(e)/c); hydrophoneVectors.set(iRow, e, v.getElement(e)/c);
hydrophoneErrorVectors.set(iRow, e, errorVec.getElement(e)/c); hydrophoneErrorVectors.set(iRow, e, errorVec.getElement(e)/c);
// hydrophoneUnitVectors.set(iRow, e, uv.getElement(e)); // hydrophoneUnitVectors.set(iRow, e, uv.getElement(e));
} }
iRow++; iRow++;
} }
} }
// luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors); // luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors);
qrHydrophones = new QRDecomposition(weightedHydrophoneVectors); qrHydrophones = new QRDecomposition(weightedHydrophoneVectors);
} }
@ -100,71 +103,71 @@ public class LSQBearingLocaliser implements BearingLocaliser {
public PamVector[] getArrayAxis() { public PamVector[] getArrayAxis() {
return arrayAxis; return arrayAxis;
} }
/* /*
* @return true if a new grid needs to be created * @return true if a new grid needs to be created
*/ */
private boolean resetArray(long timeMillis){ private boolean resetArray(long timeMillis){
if (currentArray == null || (this.timeMillis!=timeMillis && currentArray.getHydrophoneLocator().isChangeable())){ if (currentArray == null || (this.timeMillis!=timeMillis && currentArray.getHydrophoneLocator().isChangeable())){
prepare(PamUtils.getChannelArray(hydrophoneBitMap), timeMillis, 1e-6); prepare(PamUtils.getChannelArray(hydrophoneBitMap), timeMillis, 1e-6);
this.timeMillis = timeMillis; this.timeMillis = timeMillis;
return true; return true;
} }
return false; return false;
} }
@Override @Override
public double[][] localise(double[] delays, long timeMillis) { public double[][] localise(double[] delays, long timeMillis) {
resetArray(timeMillis); resetArray(timeMillis);
// qrHydrophones = new QRDecomposition(hydrophoneVectors); // qrHydrophones = new QRDecomposition(hydrophoneVectors);
Matrix normDelays = new Matrix(delays.length, 1); Matrix normDelays = new Matrix(delays.length, 1);
for (int i = 0; i < delays.length; i++) { for (int i = 0; i < delays.length; i++) {
normDelays.set(i, 0, -delays[i]*fitWeights[i]); normDelays.set(i, 0, -delays[i]*fitWeights[i]);
} }
// Matrix soln = luHydrophoneUnitMatrix.solve(normDelays); // Matrix soln = luHydrophoneUnitMatrix.solve(normDelays);
Matrix soln2 = qrHydrophones.solve(normDelays); Matrix soln2 = qrHydrophones.solve(normDelays);
double[][] angs = new double[2][2]; double[][] angs = new double[2][2];
PamVector v = new PamVector(soln2.get(0, 0), soln2.get(1,0), soln2.get(2, 0)); PamVector v = new PamVector(soln2.get(0, 0), soln2.get(1,0), soln2.get(2, 0));
// System.out.printf("Vector Norm = %4.3f: ", v.norm()); // System.out.printf("Vector Norm = %4.3f: ", v.norm());
double m = v.normalise(); double m = v.normalise();
angs[0][0] = Math.PI/2. - Math.atan2(v.getElement(0),v.getElement(1)); angs[0][0] = Math.PI/2. - Math.atan2(v.getElement(0),v.getElement(1));
angs[0][1] = Math.asin(v.getElement(2)); angs[0][1] = Math.asin(v.getElement(2));
// timingError = 1e-5; // timingError = 1e-5;
// now take a look at angle errors // now take a look at angle errors
double oneDeg = Math.PI/180.; double oneDeg = Math.PI/180.;
double testDeg = 5; double testDeg = 5;
double[][] er = new double[2][20]; double[][] er = new double[2][20];
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
testDeg = 1+i; testDeg = 1+i;
// pick points testDeg degrees either side of angs and change one at a time // pick points testDeg degrees either side of angs and change one at a time
double aDiff = testDeg * oneDeg; double aDiff = testDeg * oneDeg;
double a; double a;
double l1, l2, l3, l1a, l3a; double l1, l2, l3, l1a, l3a;
l1 = logLikelihood(delays, angs[0][0] - aDiff, angs[0][1]); l1 = logLikelihood(delays, angs[0][0] - aDiff, angs[0][1]);
l2 = logLikelihood(delays, angs[0][0], angs[0][1]); l2 = logLikelihood(delays, angs[0][0], angs[0][1]);
l3 = logLikelihood(delays, angs[0][0] + aDiff, angs[0][1]); l3 = logLikelihood(delays, angs[0][0] + aDiff, angs[0][1]);
er[0][i] = angs[1][0] = Math.sqrt(1./(l1+l3-2*l2))*aDiff; er[0][i] = angs[1][0] = Math.sqrt(1./(l1+l3-2*l2))*aDiff;
l1a = logLikelihood(delays, angs[0][0], angs[0][1] - aDiff); l1a = logLikelihood(delays, angs[0][0], angs[0][1] - aDiff);
// l2 = logLikelihood(delays, angs[0][0], angs[0][1]); // l2 = logLikelihood(delays, angs[0][0], angs[0][1]);
l3a = logLikelihood(delays, angs[0][0], angs[0][1] + aDiff); l3a = logLikelihood(delays, angs[0][0], angs[0][1] + aDiff);
er[1][i] = angs[1][1] = Math.sqrt(1./(l1a+l3a-2*l2))*aDiff; er[1][i] = angs[1][1] = Math.sqrt(1./(l1a+l3a-2*l2))*aDiff;
} }
// double ll[] = new double[21]; // double ll[] = new double[21];
// double a[] = new double[2]; // double a[] = new double[2];
// timingError = 1.e-4; // timingError = 1.e-4;
// a[1] = angs[0][1]; // a[1] = angs[0][1];
// for (int i = 0; i < ll.length; i++) { // for (int i = 0; i < ll.length; i++) {
// a[0] = angs[0][0] + (-10 + i)*oneDeg; // a[0] = angs[0][0] + (-10 + i)*oneDeg;
// ll[i] = logLikelihood(delays, a); // ll[i] = logLikelihood(delays, a);
// } // }
return angs; return angs;
} }
/** /**
@ -181,7 +184,7 @@ public class LSQBearingLocaliser implements BearingLocaliser {
whaleVec.set(2, 0, Math.sin(angle1)); whaleVec.set(2, 0, Math.sin(angle1));
return logLikelihood(delays, whaleVec); return logLikelihood(delays, whaleVec);
} }
/** /**
* Calculate a log likelihood for a given pair of angles * Calculate a log likelihood for a given pair of angles
* @param delays actual delays * @param delays actual delays
@ -190,11 +193,11 @@ public class LSQBearingLocaliser implements BearingLocaliser {
*/ */
public double logLikelihood(double[] delays, double[] angles) { public double logLikelihood(double[] delays, double[] angles) {
return logLikelihood(delays, angles[0], angles[1]); return logLikelihood(delays, angles[0], angles[1]);
// Matrix whaleVec = new Matrix(3,1); // Matrix whaleVec = new Matrix(3,1);
// whaleVec.set(0, 0, Math.cos(angles[1])*Math.cos(angles[0])); // whaleVec.set(0, 0, Math.cos(angles[1])*Math.cos(angles[0]));
// whaleVec.set(1, 0, Math.cos(angles[1])*Math.sin(angles[0])); // whaleVec.set(1, 0, Math.cos(angles[1])*Math.sin(angles[0]));
// whaleVec.set(2, 0, Math.sin(angles[1])); // whaleVec.set(2, 0, Math.sin(angles[1]));
// return logLikelihood(delays, whaleVec); // return logLikelihood(delays, whaleVec);
} }
/** /**
* Calculate a log likelihood for a given whale vector. * Calculate a log likelihood for a given whale vector.
@ -215,5 +218,18 @@ public class LSQBearingLocaliser implements BearingLocaliser {
} }
return chi/2; return chi/2;
} }
@Override
public String getAlgorithmName() {
return "Least Squares bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
} }

View File

@ -1,10 +1,12 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import Array.ArrayManager; import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamUtils.ArrayDump; import PamUtils.ArrayDump;
@ -635,6 +637,19 @@ public class MLGridBearingLocaliser implements BearingLocaliser {
public int getHydrophoneMap() { public int getHydrophoneMap() {
return hydrophoneMap; return hydrophoneMap;
} }
@Override
public String getAlgorithmName() {
return "Maximum likelyhood grid bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
} }

View File

@ -1,10 +1,12 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import Array.ArrayManager; import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import Localiser.algorithms.PeakPosition2D; import Localiser.algorithms.PeakPosition2D;
import Localiser.algorithms.PeakSearch; import Localiser.algorithms.PeakSearch;
@ -13,6 +15,7 @@ import PamUtils.ArrayDump;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamUtils.SystemTiming; import PamUtils.SystemTiming;
import pamMaths.PamVector; import pamMaths.PamVector;
import tethys.pamdata.AutoTethysProvider;
/** /**
* Revamp of the earlier MLGridBearingLocaliser but with a more sensible * Revamp of the earlier MLGridBearingLocaliser but with a more sensible
@ -743,5 +746,36 @@ public class MLGridBearingLocaliser2 implements BearingLocaliser {
public double[][] getLikelihoodLUT() { public double[][] getLikelihoodLUT() {
return likelihoodLUT; return likelihoodLUT;
} }
@Override
public String getAlgorithmName() {
return "Maximum likelyhood grid bearing localiser V2";
}
@Override
public Serializable getParameters() {
return new LocaliserParams(this.thetaStep, this.phiStep);
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
/**
* For passing to Tethys output.
* @author dg50
*
*/
public class LocaliserParams implements Serializable {
private static final long serialVersionUID = 1L;
public double thetaStep, phiStep;
public LocaliserParams(double thetaStep, double phiStep) {
super();
this.thetaStep = Math.toDegrees(thetaStep);
this.phiStep = Math.toDegrees(phiStep);
this.thetaStep = AutoTethysProvider.roundDecimalPlaces(this.thetaStep, 2);
this.phiStep = AutoTethysProvider.roundDecimalPlaces(this.phiStep, 2);
}
}
} }

View File

@ -1,11 +1,13 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import Array.ArrayManager; import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@ -294,4 +296,17 @@ public class PairBearingLocaliser implements BearingLocaliser {
return speedOfSound; return speedOfSound;
} }
@Override
public String getAlgorithmName() {
return "Pair bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
} }

View File

@ -1,5 +1,6 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.FunctionEvaluationException;
@ -14,10 +15,12 @@ import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@Deprecated
public class SimplexBearingLocaliser implements BearingLocaliser { public class SimplexBearingLocaliser implements BearingLocaliser {
private int arrayType; private int arrayType;
private Matrix hydrophoneVectors; private Matrix hydrophoneVectors;
@ -236,7 +239,21 @@ public class SimplexBearingLocaliser implements BearingLocaliser {
public void setFirstStep(double[] firstStep) { public void setFirstStep(double[] firstStep) {
this.firstStep = firstStep; this.firstStep = firstStep;
} }
@Override
public String getAlgorithmName() {
return "Simplex bearing localiser";
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public Serializable getParameters() {
return null;
}
// private class BearingConvergence implements RealConvergenceChecker { // private class BearingConvergence implements RealConvergenceChecker {
// //
// @Override // @Override

View File

@ -49,6 +49,7 @@ import org.w3c.dom.Element;
import Acquisition.AcquisitionControl; import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess; import Acquisition.AcquisitionProcess;
import Localiser.LocalisationAlgorithm;
import pamScrollSystem.ViewLoadObserver; import pamScrollSystem.ViewLoadObserver;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.pamdata.AutoTethysProvider; import tethys.pamdata.AutoTethysProvider;
@ -2530,6 +2531,42 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
public void addLocalisationContents(int localisationContents) { public void addLocalisationContents(int localisationContents) {
this.localisationContents.addLocContent(localisationContents); this.localisationContents.addLocContent(localisationContents);
} }
/**
* Find localisation algorithm for this data.
* This may be within the owning module, or a downstream algorithm.
* @return first found localisation algorithm or null;
*/
public LocalisationAlgorithm getLocalisationAlgorithm() {
/*
* first check downstream modules. If these are in use, they
* probably override anything internal, so look for these first.
*/
List<PamObserver> instObs = getInstantObservers();
for (PamObserver obs : instObs) {
if (obs instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) obs;
}
if (obs instanceof PamProcess) {
PamProcess proc = (PamProcess) obs;
PamControlledUnit pcu = proc.getPamControlledUnit();
if (pcu == null) {
continue;
}
if (pcu instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) pcu;
}
}
}
// if nothing downstream, then check the owning module
PamProcess proc = getParentProcess();
if (proc == null) return null;
PamControlledUnit pcu = proc.getPamControlledUnit();
if (pcu instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) pcu;
}
return null;
}
public static final int ITERATOR_END = -1; public static final int ITERATOR_END = -1;

View File

@ -562,6 +562,20 @@ public class PamObservable {//extends PanelOverlayDraw {
return PamModel.getPamModel().getPamModelSettings().getThreadingJitterMillis(); return PamModel.getPamModel().getPamModelSettings().getThreadingJitterMillis();
} }
/**
* @return the pamObservers
*/
protected List<PamObserver> getPamObservers() {
return pamObservers;
}
/**
* @return the instantObservers
*/
protected List<PamObserver> getInstantObservers() {
return instantObservers;
}
// @Override // @Override
// public boolean hasOptionsDialog(GeneralProjector generalProjector) { // public boolean hasOptionsDialog(GeneralProjector generalProjector) {
// if (overlayDraw != null) { // if (overlayDraw != null) {

View File

@ -10,14 +10,18 @@ import java.util.List;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit; import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings; import PamController.PamControlledUnitSettings;
import PamController.PamController; import PamController.PamController;
import PamController.PamSettingManager; import PamController.PamSettingManager;
import PamController.PamSettings; import PamController.PamSettings;
import PamDetection.LocContents;
import PamUtils.SimpleObservable; import PamUtils.SimpleObservable;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import beamformer.algorithms.BeamAlgorithmProvider; import beamformer.algorithms.BeamAlgorithmProvider;
import bearinglocaliser.algorithms.BearingAlgorithm;
import bearinglocaliser.algorithms.BearingAlgorithmProvider; import bearinglocaliser.algorithms.BearingAlgorithmProvider;
import bearinglocaliser.annotation.BearingAnnotationType; import bearinglocaliser.annotation.BearingAnnotationType;
import bearinglocaliser.beamformer.BeamFormBearingWrapper; import bearinglocaliser.beamformer.BeamFormBearingWrapper;
@ -30,7 +34,7 @@ import offlineProcessing.OfflineTaskGroup;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT; import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
import userDisplay.UserDisplayControl; import userDisplay.UserDisplayControl;
public class BearingLocaliserControl extends PamControlledUnit implements PamSettings { public class BearingLocaliserControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm, LocalisationAlgorithmInfo {
public static final String unitType = "Bearing Calculator"; public static final String unitType = "Bearing Calculator";
@ -228,4 +232,46 @@ public class BearingLocaliserControl extends PamControlledUnit implements PamSet
public String getHelpPoint() { public String getHelpPoint() {
return helpPoint; return helpPoint;
} }
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
private BearingAlgorithm findAlgorithm() {
BearingAlgorithmGroup[] groups = bearingProcess.getBearingAlgorithmGroups();
if (groups == null) {
return null;
}
for (int i = 0; i < groups.length; i++) {
BearingAlgorithm ba = groups[i].bearingAlgorithm;
if (ba != null) {
return ba;
}
}
return null;
}
@Override
public int getLocalisationContents() {
int cont = LocContents.HAS_BEARING | LocContents.HAS_BEARINGERROR;
// work out if we should also add ambiguity. How to work that out ?
return cont;
}
@Override
public String getAlgorithmName() {
// BearingAlgorithm ba = findAlgorithm();
// if (ba == null) {
// return null;
// }
// ba.getParams().
return getUnitType();
}
@Override
public Serializable getParameters() {
return bearingLocaliserParams;
}
} }

View File

@ -44,6 +44,8 @@ import targetMotionOld.TargetMotionLocaliser;
import binaryFileStorage.BinaryStore; import binaryFileStorage.BinaryStore;
import Filters.FilterDialog; import Filters.FilterDialog;
import Filters.FilterParams; import Filters.FilterParams;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.detectionGroupLocaliser.GroupDetection; import Localiser.detectionGroupLocaliser.GroupDetection;
import PamController.PamConfiguration; import PamController.PamConfiguration;
import PamController.PamControlledUnit; import PamController.PamControlledUnit;
@ -112,7 +114,7 @@ import offlineProcessing.OfflineTaskGroup;
* *
*/ */
public class ClickControl extends PamControlledUnit implements PamSettings { public class ClickControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm {
protected ClickDetector clickDetector; protected ClickDetector clickDetector;
@ -1293,5 +1295,10 @@ public class ClickControl extends PamControlledUnit implements PamSettings {
return clickFFTDataOrganiser; return clickFFTDataOrganiser;
} }
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return clickDetector.getLocaliserInfo();
}
} }

View File

@ -42,6 +42,7 @@ import Filters.Filter;
import Filters.FilterMethod; import Filters.FilterMethod;
import Filters.FilterType; import Filters.FilterType;
import Localiser.DelayMeasurementParams; import Localiser.DelayMeasurementParams;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import Localiser.algorithms.DelayGroup; import Localiser.algorithms.DelayGroup;
import Localiser.algorithms.TimeDelayData; import Localiser.algorithms.TimeDelayData;
@ -2109,4 +2110,22 @@ public class ClickDetector extends PamProcess {
super.destroyProcess(); super.destroyProcess();
newClickMonitor.destroyProcess(); newClickMonitor.destroyProcess();
} }
/**
* Get information about the internal bearing localiser. Will have to do
* just for the first sub detector.
* @return
*/
public LocalisationAlgorithmInfo getLocaliserInfo() {
if (channelGroupDetectors == null || channelGroupDetectors.length == 0) {
return null;
}
BearingLocaliser bl = channelGroupDetectors[0].bearingLocaliser;
if (bl == null) {
return null;
}
else {
return bl.getAlgorithmInfo();
}
}
} }

View File

@ -31,6 +31,7 @@ public class ClickEventTethysDataProvider extends AutoTethysProvider {
GranularityEnumType[] allowed = {GranularityEnumType.GROUPED}; GranularityEnumType[] allowed = {GranularityEnumType.GROUPED};
return allowed; return allowed;
} }
@Override @Override
public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams, public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams,
StreamExportParams streamExportParams) { StreamExportParams streamExportParams) {

View File

@ -1,22 +1,20 @@
package rawDeepLearningClassifier.tethys; package rawDeepLearningClassifier.tethys;
import java.io.Serializable; import java.util.ArrayList;
import javax.xml.bind.JAXBException;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import nilus.Detection; import nilus.Detection;
import nilus.Detection.Parameters; import nilus.Detection.Parameters;
import rawDeepLearningClassifier.DLControl; import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.RawDLParams;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import rawDeepLearningClassifier.dlClassification.DLDetection; import rawDeepLearningClassifier.dlClassification.DLDetection;
import rawDeepLearningClassifier.dlClassification.PredictionResult;
import rawDeepLearningClassifier.logging.DLAnnotation;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.output.StreamExportParams; import tethys.output.StreamExportParams;
import tethys.output.TethysExportParams; import tethys.output.TethysExportParams;
import tethys.pamdata.AutoTethysProvider; import tethys.pamdata.AutoTethysProvider;
import tethys.pamdata.TethysParameterPacker;
public class DLTethysDataProvider extends AutoTethysProvider { public class DLTethysDataProvider extends AutoTethysProvider {
@ -35,6 +33,26 @@ public class DLTethysDataProvider extends AutoTethysProvider {
return null; return null;
} }
DLDetection dlDetection = (DLDetection) dataUnit; DLDetection dlDetection = (DLDetection) dataUnit;
// try to find the score which is burried in the annotation
DLAnnotation annotation = (DLAnnotation) dlDetection.findDataAnnotation(DLAnnotation.class) ;
if (annotation != null) {
double bestScore = 0;
ArrayList<PredictionResult> results = annotation.getModelResults();
for (PredictionResult res : results) {
float[] resres = res.getPrediction();
if (resres != null) for (int i = 0; i < resres.length; i++) {
double aRes = resres[i];
if (aRes > bestScore) {
bestScore = aRes;
}
}
}
bestScore = roundSignificantFigures(bestScore, 4);
detection.getParameters().setScore(bestScore);
}
// ds = getPamDataBlock().
// result = // result =
String annotSummary = dlDetection.getAnnotationsSummaryString(); String annotSummary = dlDetection.getAnnotationsSummaryString();

View File

@ -570,16 +570,22 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) {
// dataPrefixes[i] = DetectionsHandler.getDetectionsDocIdPrefix(deplData.getProject(), synchInfo.getDataBlock()); // dataPrefixes[i] = DetectionsHandler.getDetectionsDocIdPrefix(deplData.getProject(), synchInfo.getDataBlock());
int detectionCount = 0; int detectionCount = 0;
int documentCount = 0; int locDocumentCount = 0;
int detDocumentCount = 0;
for (PDeployment pDepl : matchedDeployments) { for (PDeployment pDepl : matchedDeployments) {
detectionCount += dbxmlQueries.countData(synchInfo.getDataBlock(), pDepl.getDocumentId()); detectionCount += dbxmlQueries.countData(synchInfo.getDataBlock(), pDepl.getDocumentId());
ArrayList<String> detectionsNames = getDbxmlQueries().getDetectionsDocuments(synchInfo.getDataBlock(), pDepl.getDocumentId()); ArrayList<String> detectionsNames = getDbxmlQueries().getDetectionsDocuments(synchInfo.getDataBlock(), pDepl.getDocumentId());
if (detectionsNames != null) { if (detectionsNames != null) {
documentCount += detectionsNames.size(); detDocumentCount += detectionsNames.size();
}
ArrayList<String> locDocNames = getDbxmlQueries().getLocalizationDocuments(synchInfo.getDataBlock(), pDepl.getDocumentId());
if (locDocNames != null) {
locDocumentCount += locDocNames.size();
} }
} }
synchInfo.setDataCount(detectionCount); synchInfo.setDataCount(detectionCount);
synchInfo.setDetectionDocumentCount(documentCount); synchInfo.setDetectionDocumentCount(detDocumentCount);
synchInfo.setLocalizationDocumentCount(locDocumentCount);
i++; i++;
} }

View File

@ -10,6 +10,8 @@ import javax.swing.SwingWorker;
import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.datatype.XMLGregorianCalendar;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit; import PamController.PamControlledUnit;
import PamController.PamController; import PamController.PamController;
import PamController.PamguardVersionInfo; import PamController.PamguardVersionInfo;
@ -665,7 +667,7 @@ public class DetectionsHandler extends CollectionHandler {
AlgorithmType algorithm = detections.getAlgorithm(); AlgorithmType algorithm = detections.getAlgorithm();
if (dataProvider != null) { if (dataProvider != null) {
algorithm = dataProvider.getAlgorithm(); algorithm = dataProvider.getAlgorithm(Collection.Detections);
// detections.setAlgorithm(algorithm); // detections.setAlgorithm(algorithm);
} }
algorithm.setMethod(getMethodString(dataBlock)); algorithm.setMethod(getMethodString(dataBlock));
@ -750,10 +752,20 @@ public class DetectionsHandler extends CollectionHandler {
AlgorithmType algorithm = localisations.getAlgorithm(); AlgorithmType algorithm = localisations.getAlgorithm();
if (dataProvider != null) { if (dataProvider != null) {
algorithm = dataProvider.getAlgorithm(); algorithm = dataProvider.getAlgorithm(Collection.Localizations);
// detections.setAlgorithm(algorithm); // detections.setAlgorithm(algorithm);
} }
algorithm.setMethod(getMethodString(dataBlock)); LocalisationAlgorithm locAlgorithm = dataBlock.getLocalisationAlgorithm();
LocalisationAlgorithmInfo locAlgoinfo = null;
if (locAlgorithm != null) {
locAlgoinfo = locAlgorithm.getAlgorithmInfo();
}
if (locAlgoinfo != null) {
algorithm.setMethod(locAlgoinfo.getAlgorithmName());
}
else {
algorithm.setMethod(getMethodString(dataBlock));
}
algorithm.setSoftware(getSoftwareString(dataBlock)); algorithm.setSoftware(getSoftwareString(dataBlock));
algorithm.setVersion(getVersionString(dataBlock)); algorithm.setVersion(getVersionString(dataBlock));

View File

@ -1,7 +1,5 @@
package tethys.detection; package tethys.detection;
import java.util.List;
import java.util.ListIterator;
import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.datatype.XMLGregorianCalendar;
@ -9,7 +7,6 @@ import javax.xml.datatype.XMLGregorianCalendar;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import nilus.Detection; import nilus.Detection;
import nilus.DetectionGroup;
import nilus.Detections; import nilus.Detections;
import nilus.GranularityEnumType; import nilus.GranularityEnumType;
import tethys.TethysControl; import tethys.TethysControl;

View File

@ -3,6 +3,8 @@ package tethys.localization;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import Localiser.detectionGroupLocaliser.GroupLocResult;
import Localiser.detectionGroupLocaliser.GroupLocalisation;
import PamDetection.AbstractLocalisation; import PamDetection.AbstractLocalisation;
import PamDetection.LocContents; import PamDetection.LocContents;
import PamUtils.LatLong; import PamUtils.LatLong;
@ -17,7 +19,8 @@ import nilus.LocalizationType;
import nilus.LocalizationType.References; import nilus.LocalizationType.References;
import nilus.LocalizationType.References.Reference; import nilus.LocalizationType.References.Reference;
import nilus.Localize; import nilus.Localize;
import nilus.SpeciesIDType import nilus.SpeciesIDType;
import pamMaths.PamVector;
import nilus.Localize.Effort.CoordinateReferenceSystem; import nilus.Localize.Effort.CoordinateReferenceSystem;
import tethys.Collection; import tethys.Collection;
import tethys.CollectionHandler; import tethys.CollectionHandler;
@ -37,13 +40,13 @@ public class LocalizationHandler extends CollectionHandler {
super(tethysControl, Collection.Localizations); super(tethysControl, Collection.Localizations);
} }
// public LocalizationType getLoc() { // public LocalizationType getLoc() {
// LocalizationType lt = new LocalizationType(); // LocalizationType lt = new LocalizationType();
// CylindricalCoordinateType cct = new CylindricalCoordinateType(); // CylindricalCoordinateType cct = new CylindricalCoordinateType();
//// cct.set //// cct.set
// CoordinateReferenceSystem cr; // CoordinateReferenceSystem cr;
// return null; // return null;
// } // }
/** /**
* Get a list of Localization documents associated with a particular data block for all deployments * Get a list of Localization documents associated with a particular data block for all deployments
@ -55,7 +58,7 @@ public class LocalizationHandler extends CollectionHandler {
ArrayList<PDeployment> deployments = tethysControl.getDeploymentHandler().getMatchedDeployments(); ArrayList<PDeployment> deployments = tethysControl.getDeploymentHandler().getMatchedDeployments();
return getStreamLocalizations(dataBlock, deployments); return getStreamLocalizations(dataBlock, deployments);
} }
/** /**
* Get a list of Localization documents associated with a particular data block for the list of deployments * Get a list of Localization documents associated with a particular data block for the list of deployments
* documents. Group them by abstract or something * documents. Group them by abstract or something
@ -72,14 +75,14 @@ public class LocalizationHandler extends CollectionHandler {
if (someNames == null) { if (someNames == null) {
continue; continue;
} }
// // no have a list of all the Detections documents of interest for this datablock. // // no have a list of all the Detections documents of interest for this datablock.
for (String aDoc : someNames) { for (String aDoc : someNames) {
Localize localize = tethysControl.getDbxmlQueries().getLocalizationDocInfo(aDoc); Localize localize = tethysControl.getDbxmlQueries().getLocalizationDocInfo(aDoc);
int count = tethysControl.getDbxmlQueries().countLocalizations2(aDoc); int count = tethysControl.getDbxmlQueries().countLocalizations2(aDoc);
PLocalization pLocalize = new PLocalization(localize, dataBlock, aDep, count); PLocalization pLocalize = new PLocalization(localize, dataBlock, aDep, count);
localizeDocs.add(pLocalize); localizeDocs.add(pLocalize);
// PDetections pDetections = new PDetections(detections, dataBlock, aDep, count); // PDetections pDetections = new PDetections(detections, dataBlock, aDep, count);
// detectionsDocs.add(pDetections); // detectionsDocs.add(pDetections);
} }
} }
return new StreamDetectionsSummary(localizeDocs); return new StreamDetectionsSummary(localizeDocs);
@ -137,7 +140,7 @@ public class LocalizationHandler extends CollectionHandler {
break; break;
default: default:
break; break;
} }
return locEl; return locEl;
} }
@ -150,7 +153,7 @@ public class LocalizationHandler extends CollectionHandler {
e.printStackTrace(); e.printStackTrace();
} }
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds())); locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataUnit.getTimeMilliseconds()));
DataBlockSpeciesManager spManager = dataBlock.getDatablockSpeciesManager(); DataBlockSpeciesManager spManager = dataBlock.getDatablockSpeciesManager();
if (spManager != null) { if (spManager != null) {
SpeciesMapItem speciesStuff = spManager.getSpeciesItem(dataUnit); SpeciesMapItem speciesStuff = spManager.getSpeciesItem(dataUnit);
@ -160,7 +163,7 @@ public class LocalizationHandler extends CollectionHandler {
locType.setSpeciesId(species); locType.setSpeciesId(species);
} }
} }
References references = locType.getReferences(); References references = locType.getReferences();
if (references == null) { if (references == null) {
references = new References(); references = new References();
@ -175,7 +178,7 @@ public class LocalizationHandler extends CollectionHandler {
reference.setIndex(BigInteger.valueOf(dataUnit.getUID())); reference.setIndex(BigInteger.valueOf(dataUnit.getUID()));
reference.setEventRef("UID"); reference.setEventRef("UID");
locType.getReferences().getReference().add(reference); locType.getReferences().getReference().add(reference);
return locType; return locType;
} }
@ -194,6 +197,22 @@ public class LocalizationHandler extends CollectionHandler {
return deg; return deg;
} }
/**
* Convert a vertical angle from radians to degrees and round.
* @param radians
* @return
*/
private double toSlantAngle(double radians) {
/*
* these really need to be constrained to -90 to 90, but I don't see what to do if
* they are outside that range.
*/
double deg = Math.toDegrees(radians);
deg= PamUtils.constrainedAngle(deg, 180);
deg = AutoTethysProvider.roundDecimalPlaces(deg, 2);
return deg;
}
private LocalizationType createWGS84Loc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit, private LocalizationType createWGS84Loc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) { StreamExportParams streamExportParams) {
AbstractLocalisation loc = dataUnit.getLocalisation(); AbstractLocalisation loc = dataUnit.getLocalisation();
@ -209,9 +228,32 @@ public class LocalizationHandler extends CollectionHandler {
coord.setX(latlong.getLongitude()); coord.setX(latlong.getLongitude());
coord.setY(latlong.getLatitude()); coord.setY(latlong.getLatitude());
coord.setZ(latlong.getHeight()); coord.setZ(latlong.getHeight());
PamVector planarVec = loc.getPlanarVector();
locType.setCoordinate(coord); locType.setCoordinate(coord);
// see if it's possible to get a beam measurement.
if (loc instanceof GroupLocalisation) {
GroupLocalisation groupLoc = (GroupLocalisation) loc;
GroupLocResult groupLocResult = groupLoc.getGroupLocaResult(0);
Double perpDist = groupLocResult.getPerpendicularDistance();
Long beamTime = groupLocResult.getBeamTime();
if (perpDist != null && beamTime != null) {
AngularCoordinateType acType = new AngularCoordinateType();
acType.setAngle1(90);
acType.setDistanceM(AutoTethysProvider.roundDecimalPlaces(perpDist,1));
locType.setAngularCoordinate(acType);
locType.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(beamTime));
locType.setCoordinate(null);
}
// groupLoc.getp
}
/*
* Try to also add a range loc.
*/
// loc.
return locType; return locType;
} }
@ -241,7 +283,10 @@ public class LocalizationHandler extends CollectionHandler {
BearingType angType = new BearingType(); BearingType angType = new BearingType();
angType.setAngle1(constrainRadianAngle(angles[0])); angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) { if (angles.length >= 2) {
angType.setAngle2(constrainRadianAngle(angles[1])); angType.setAngle2(toSlantAngle(angles[1]));
// if (angType.getAngle2() > 360) {
// angType.setAngle2(Math.toDegrees(angles[1]));
// }
} }
locType.setBearing(angType); locType.setBearing(angType);
@ -254,7 +299,7 @@ public class LocalizationHandler extends CollectionHandler {
} }
locType.setBearingError(angErrType); locType.setBearingError(angErrType);
} }
return locType; return locType;
} }
private LocalizationType createPolarLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit, private LocalizationType createPolarLoc(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
@ -264,7 +309,7 @@ public class LocalizationHandler extends CollectionHandler {
return null; return null;
} }
if (loc.hasLocContent(LocContents.HAS_RANGE) == false) { if (loc.hasLocContent(LocContents.HAS_RANGE) == false) {
// do the more basic bearing type instead. // do the more basic bearing type instead.
return createBearingLoc(localiseDocument, dataBlock, dataUnit, streamExportParams); return createBearingLoc(localiseDocument, dataBlock, dataUnit, streamExportParams);
} }
@ -277,6 +322,9 @@ public class LocalizationHandler extends CollectionHandler {
angType.setAngle1(constrainRadianAngle(angles[0])); angType.setAngle1(constrainRadianAngle(angles[0]));
if (angles.length >= 2) { if (angles.length >= 2) {
angType.setAngle2(constrainRadianAngle(angles[1])); angType.setAngle2(constrainRadianAngle(angles[1]));
if (angType.getAngle2() > 360) {
angType.setAngle2(toSlantAngle(angles[1]));
}
} }
if (loc.hasLocContent(LocContents.HAS_RANGE)) { if (loc.hasLocContent(LocContents.HAS_RANGE)) {
angType.setDistanceM(loc.getRange(0)); angType.setDistanceM(loc.getRange(0));
@ -295,10 +343,10 @@ public class LocalizationHandler extends CollectionHandler {
} }
locType.setAngularCoordinateError(angErrType); locType.setAngularCoordinateError(angErrType);
} }
return locType; return locType;
} }
private LocalizationType createPerpRange(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit, private LocalizationType createPerpRange(Localize localiseDocument, PamDataBlock dataBlock, PamDataUnit dataUnit,
StreamExportParams streamExportParams) { StreamExportParams streamExportParams) {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -28,6 +28,8 @@ public class DatablockSynchInfo {
*/ */
private int detectionDocumentCount; private int detectionDocumentCount;
private int localizationDocumentCount;
public DatablockSynchInfo(TethysControl tethysControl, PamDataBlock dataBlock) { public DatablockSynchInfo(TethysControl tethysControl, PamDataBlock dataBlock) {
super(); super();
@ -68,5 +70,19 @@ public class DatablockSynchInfo {
public void setDetectionDocumentCount(int detectionDocumentCount) { public void setDetectionDocumentCount(int detectionDocumentCount) {
this.detectionDocumentCount = detectionDocumentCount; this.detectionDocumentCount = detectionDocumentCount;
} }
/**
* @return the localizationDocumentCount
*/
public int getLocalizationDocumentCount() {
return localizationDocumentCount;
}
/**
* @param localizationDocumentCount the localizationDocumentCount to set
*/
public void setLocalizationDocumentCount(int localizationDocumentCount) {
this.localizationDocumentCount = localizationDocumentCount;
}
} }

View File

@ -79,6 +79,9 @@ public class StreamExportParams implements Serializable {
if (detectionDescription == null) { if (detectionDescription == null) {
detectionDescription = new WrappedDescriptionType(); detectionDescription = new WrappedDescriptionType();
} }
// if (detectionDescription.getMethod() == null) {
//
// }
return detectionDescription; return detectionDescription;
} }
@ -87,6 +90,29 @@ public class StreamExportParams implements Serializable {
this.longDataName = dataBlock.getLongDataName(); this.longDataName = dataBlock.getLongDataName();
autoFill(tethysControl, dataBlock); autoFill(tethysControl, dataBlock);
} }
/**
* Used to get the description data back in again if it's changes
* as PAMGuard updates. This object can't store references to the
* TethysControl or the datablock since they aren't serializable.
* Normally, the description is auto filled at constructoin, but once
* serialized, this can no longer happen, so can call this function to
* sort it all out.
*/
public void checkDescription() {
TethysControl tethysControl = (TethysControl) PamController.getInstance().findControlledUnit(TethysControl.class, null);
PamDataBlock dataBlock = PamController.getInstance().getDataBlockByLongName(longDataName);
if (tethysControl == null || dataBlock == null) {
return; // probably impossible for this to happen, but just in case.
}
DescriptionType desc = getNilusDetectionDescription();
if (desc == null) {
detectionDescription.setDescription(desc = new DescriptionType());
}
if (desc.getMethod() == null || desc.getMethod().length() == 0) {
autoFill(tethysControl, dataBlock);
}
}
/** /**
* Try to put some information automatically into the Methods. * Try to put some information automatically into the Methods.

View File

@ -9,6 +9,8 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit; import PamController.PamControlledUnit;
import PamController.PamSettings; import PamController.PamSettings;
import PamController.PamguardVersionInfo; import PamController.PamguardVersionInfo;
@ -35,6 +37,7 @@ import nilus.DetectionEffortKind;
import nilus.GranularityEnumType; import nilus.GranularityEnumType;
import nilus.Helper; import nilus.Helper;
import nilus.SpeciesIDType; import nilus.SpeciesIDType;
import tethys.Collection;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.TethysTimeFuncs; import tethys.TethysTimeFuncs;
import tethys.detection.DetectionsHandler; import tethys.detection.DetectionsHandler;
@ -101,7 +104,7 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
} }
@Override @Override
public AlgorithmType getAlgorithm() { public AlgorithmType getAlgorithm(Collection collection) {
/** /**
* Probably need to split this to provide detection algorithm parameters and * Probably need to split this to provide detection algorithm parameters and
* localisation algorithm parameters, or pass in the document type as a function * localisation algorithm parameters, or pass in the document type as a function
@ -113,14 +116,64 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace(); e.printStackTrace();
} }
// do the parameters as normal whether it's dets or locs.
nilus.AlgorithmType.Parameters algoParameters = this.getAlgorithmParameters(); nilus.AlgorithmType.Parameters algoParameters = this.getAlgorithmParameters();
if (algoParameters != null) { if (algoParameters != null) {
algorithm.setParameters(algoParameters); algorithm.setParameters(algoParameters);
} }
if (collection == Collection.Localizations) {
nilus.AlgorithmType.Parameters locParameters = this.getLocalisationParameters();
if (algoParameters == null) {
algorithm.setParameters(locParameters);
}
else if (locParameters != null) {
// merge the two sets, putting the localisation information first.
List<Element> mainList = algoParameters.getAny();
List<Element> locList = locParameters.getAny();
if (mainList != null && locList != null) {
for (int i = 0; i < locList.size(); i++) {
mainList.add(i, locList.get(i));
}
}
}
}
else {
}
return algorithm; return algorithm;
} }
public nilus.AlgorithmType.Parameters getLocalisationParameters() {
LocalisationAlgorithm algo = pamDataBlock.getLocalisationAlgorithm();
if (algo == null) {
return null;
}
LocalisationAlgorithmInfo algoInfo = algo.getAlgorithmInfo();
if (algoInfo == null) {
return null;
}
Object params = algoInfo.getParameters();
if (params == null) {
return null;
}
// pack the params object
TethysParameterPacker paramPacker = null;
try {
paramPacker = new TethysParameterPacker(tethysControl);
} catch (JAXBException e) {
e.printStackTrace();
}
Element paramEl = paramPacker.packObject(params, "localizer");
if (paramEl == null) {
return null;
}
nilus.AlgorithmType.Parameters parameters = new nilus.AlgorithmType.Parameters();
List<Element> paramList = parameters.getAny();
paramList.add(paramEl);
return parameters;
}
@Override @Override
public nilus.AlgorithmType.Parameters getAlgorithmParameters() { public nilus.AlgorithmType.Parameters getAlgorithmParameters() {
if (pamControlledUnit instanceof PamSettings == false) { if (pamControlledUnit instanceof PamSettings == false) {
@ -536,6 +589,13 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
return new TethysLocalisationInfo(pamDataBlock); return new TethysLocalisationInfo(pamDataBlock);
} }
} }
/**
* @return the pamDataBlock
*/
protected PamDataBlock getPamDataBlock() {
return pamDataBlock;
}

View File

@ -11,6 +11,7 @@ import nilus.DescriptionType;
import nilus.Detection; import nilus.Detection;
import nilus.DetectionEffortKind; import nilus.DetectionEffortKind;
import nilus.GranularityEnumType; import nilus.GranularityEnumType;
import tethys.Collection;
import tethys.localization.TethysLocalisationInfo; import tethys.localization.TethysLocalisationInfo;
import tethys.niluswraps.PDeployment; import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams; import tethys.output.StreamExportParams;
@ -62,9 +63,10 @@ public interface TethysDataProvider {
/** /**
* Get Algorithm information for a Tethys Detections document * Get Algorithm information for a Tethys Detections document
* @param collection Detections or Localisations may have different parameter sets.
* @return Algorithm information * @return Algorithm information
*/ */
public AlgorithmType getAlgorithm(); public AlgorithmType getAlgorithm(Collection collection);
/** /**
* Get a list of allowed granularity types for this output * Get a list of allowed granularity types for this output

View File

@ -24,6 +24,7 @@ import PamController.settings.output.xml.PamguardXMLWriter;
import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.ManagedParameters;
import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterData;
import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PamParameterSet;
import PamModel.parametermanager.SimplePamParameterData;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess; import PamguardMVC.PamProcess;
import PamguardMVC.dataSelector.DataSelectParams; import PamguardMVC.dataSelector.DataSelectParams;
@ -125,16 +126,13 @@ public class TethysParameterPacker {
e1.printStackTrace(); e1.printStackTrace();
} }
Element elf = docf.getDocumentElement(); Element elf = docf.getDocumentElement();
elList.add(elf);/** elList.add(elf);
/**
* Is there a data filter ? If so, write it's * Is there a data filter ? If so, write it's
* XML parameters out here. * XML parameters out here.
*/ */
Element pEl = xmlWriter.writeObjectData(docf, elf, filterParams, null); Element pEl = xmlWriter.writeObjectData(docf, elf, filterParams, null);
} }
// if (pEl != null) {
//// filterEl.appendChild(pEl);
// elf.appendChild(filterEl);
// }
} }
} }
if (paramOption == TethysExportParams.DETECTOR_DATASELECTOR) { if (paramOption == TethysExportParams.DETECTOR_DATASELECTOR) {
@ -177,6 +175,27 @@ public class TethysParameterPacker {
return elList; return elList;
} }
public Element packObject(Object data) {
return packObject(data, "parameters");
}
public Element packObject(Object data, String elementName) {
Document doc = null;
QName qname = new QName(MarshalXML.schema, elementName, "ty");
JAXBElement<String> jaxel = new JAXBElement<String>(
qname, String.class, data.getClass().getCanonicalName());
try {
doc = marshaller.marshalToDOM(jaxel);
} catch (JAXBException | ParserConfigurationException e1) {
e1.printStackTrace();
}
Element el = doc.getDocumentElement();
Element pEl = xmlWriter.writeObjectData(doc, el, data, null);
return pEl;
}
/** /**
* Get a list of parent modules of the datablock, including it's own. * Get a list of parent modules of the datablock, including it's own.
* @param dataBlock * @param dataBlock
@ -199,7 +218,7 @@ public class TethysParameterPacker {
return chain; return chain;
} }
private boolean createElement(Document document, Element parentEl, Object paramData, PamParameterData pamParam, ArrayList<Object> objectHierarchy) { private Element createElement(Document document, Element parentEl, Object paramData, PamParameterData pamParam, ArrayList<Object> objectHierarchy) {
Class<? extends Object> javaClass = paramData.getClass(); Class<? extends Object> javaClass = paramData.getClass();
if (PamguardXMLWriter.isWritableType(javaClass)) { if (PamguardXMLWriter.isWritableType(javaClass)) {
String name = pamParam.getFieldName(); String name = pamParam.getFieldName();
@ -209,63 +228,20 @@ public class TethysParameterPacker {
el.setTextContent(value); el.setTextContent(value);
parentEl.appendChild(el); parentEl.appendChild(el);
return el;
// QName qname = new QName(MarshalXML.schema, name, "ty");
// JAXBElement<String> jaxel = new JAXBElement<String>(
// qname, String.class, value);
//
//
// try {
// jxbm.marshal(jaxel, dom);
// } catch (JAXBException e) {
// e.printStackTrace();
// }
// Document doc = null;
// try {
// doc = marshaller.marshalToDOM(jaxel);
// } catch (JAXBException e) {
// e.printStackTrace();
// } catch (ParserConfigurationException e) {
// e.printStackTrace();
// }
// Element el = doc.getDocumentElement();
// return el;
return true;
} }
if (javaClass.isArray()) { if (javaClass.isArray()) {
return writeArray(document, parentEl, paramData, pamParam, objectHierarchy); return writeArray(document, parentEl, paramData, pamParam, objectHierarchy);
} }
/* return null;
*
if (javaClass.isArray()) {
return writeArray(doc, el, data, pamParam, objectHierarchy);
}
if (List.class.isAssignableFrom(javaClass)){
return writeList(doc, el, data, pamParam, objectHierarchy);
}
if (Map.class.isAssignableFrom(javaClass)){
return writeMap(doc, el, data, pamParam, objectHierarchy);
}
if (File.class.isAssignableFrom(javaClass)) {
return writeFile(doc, el, data, pamParam);
}
else {
Element e = makeElement(doc, pamParam.getFieldName(), data.getClass().getName());
el.appendChild(e);
writeObjectData(doc, e, data, objectHierarchy);
return e;
}
*/
return false;
} }
private boolean writeArray(Document document, Element parentEl, Object paramData, PamParameterData pamParam, private Element writeArray(Document document, Element parentEl, Object paramData, PamParameterData pamParam,
ArrayList<Object> objectHierarchy) { ArrayList<Object> objectHierarchy) {
if (paramData.getClass().isArray() == false) { if (paramData.getClass().isArray() == false) {
return false; return null;
} }
String name = pamParam.getFieldName(); String name = pamParam.getFieldName();
Element el = document.createElement(name); Element el = document.createElement(name);
@ -274,10 +250,10 @@ public class TethysParameterPacker {
boolean ok = true; boolean ok = true;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
Object arrayEl = Array.get(paramData, i); Object arrayEl = Array.get(paramData, i);
ok &= createElement(document, el, arrayEl, pamParam, objectHierarchy); ok &= (createElement(document, el, arrayEl, pamParam, objectHierarchy) != null);
} }
// TODO Auto-generated method stub // TODO Auto-generated method stub
return ok; return el;
} }

View File

@ -1,5 +1,7 @@
package tethys.swing; package tethys.swing;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
@ -105,24 +107,55 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
// if (rowIndex < 0) { // if (rowIndex < 0) {
// return null; // return null;
// } // }
NilusDataWrapper doc = detectionsForRow(rowIndex);
int colIndex = table.columnAtPoint(p); int colIndex = table.columnAtPoint(p);
switch (colIndex) { switch (colIndex) {
case 0: case 0:
return "Tethys Detections document name"; if (doc != null) {
return "Tethys Detections document Id: " + doc.getDocumentId();
}
return "Tethys Detections document Id";
case 1: case 1:
if (dataBlock != null) {
return "Name of PAMGuard data stream: " + dataBlock.getLongDataName();
}
return "Name of PAMGuard data stream"; return "Name of PAMGuard data stream";
case 2: case 2:
return "Effort period"; return "Deployment type";
case 3: case 3:
return "Output granularity"; return "Output type and granularity ";
case 4: case 4:
return "Number of detection elements in document"; return "Effort period";
case 5: case 5:
return "Document abstract"; return "Number of detection or localization elements in document";
case 6:
DescriptionType desc = findDescription(rowIndex);
if (desc != null) {
String str = "Document abstract: " + desc.getAbstract();
return str;
}
else {
return "Document abstract";
}
} }
return "No tip"; return "No tip";
} }
private DescriptionType findDescription(int rowIndex) {
NilusDataWrapper doc = detectionsForRow(rowIndex);
if (doc == null) {
return null;
}
Object desc = doc.getGotObject("getDescription");
if (desc instanceof DescriptionType) {
return (DescriptionType) desc;
}
else {
return null;
}
}
@Override @Override
public JComponent getComponent() { public JComponent getComponent() {
@ -362,7 +395,7 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
private class TableModel extends AbstractTableModel { private class TableModel extends AbstractTableModel {
private String[] colNames = {"Document", "Detector", "Deployment", "Type", "Effort", "Granularity", "Count", "Abstract"}; private String[] colNames = {"Document", "Detector", "Deployment", "Type (Granularity)", "Effort", "Count", "Abstract"};
@Override @Override
public int getRowCount() { public int getRowCount() {
@ -413,7 +446,10 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
return dataSource.getDeploymentId(); return dataSource.getDeploymentId();
} }
case 3: case 3:
return pDets.getCollection(); // String col = pDets.getCollection().collectionName();
//
// return pDets.getCollection();
return getType(pDets);
case 4: case 4:
// XMLGregorianCalendar start = dets.getEffort().getStart(); // XMLGregorianCalendar start = dets.getEffort().getStart();
// XMLGregorianCalendar stop = dets.getEffort().getEnd(); // XMLGregorianCalendar stop = dets.getEffort().getEnd();
@ -421,27 +457,8 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
XMLGregorianCalendar stop = pDets.getEffortEnd(); XMLGregorianCalendar stop = pDets.getEffortEnd();
return start + " to " + stop; return start + " to " + stop;
case 5: case 5:
Object effort = pDets.getGotObjects("getEffort");
if (effort instanceof DetectionEffort) {
DetectionEffort detectionEffort = (DetectionEffort) effort;
List<DetectionEffortKind> kinds = detectionEffort.getKind();
if (kinds == null) {
return null;
}
for (DetectionEffortKind kind : kinds) {
if (kind.getGranularity() != null) {
GranularityType granularity = kind.getGranularity();
return PDeployment.formatGranularity(granularity);
// if (granularity != null) {
// return granularity.getValue();
// }
}
}
}
break;
case 6:
return pDets.count; return pDets.count;
case 7: case 6:
DescriptionType desc = pDets.getDescription(); DescriptionType desc = pDets.getDescription();
if (desc != null) { if (desc != null) {
return desc.getAbstract(); return desc.getAbstract();
@ -451,4 +468,31 @@ public class DatablockDetectionsPanel extends TethysGUIPanel implements StreamTa
} }
} }
private String getType(NilusDataWrapper<PDetections> pDets) {
String type;
if (pDets == null || pDets.nilusObject == null) {
return null;
}
type = pDets.getCollection().collectionName();
// if it's a detection, also get the granularity.
Object effort = pDets.getGotObjects("getEffort");
if (effort instanceof DetectionEffort) {
DetectionEffort detectionEffort = (DetectionEffort) effort;
List<DetectionEffortKind> kinds = detectionEffort.getKind();
if (kinds == null) {
return type;
}
for (DetectionEffortKind kind : kinds) {
if (kind.getGranularity() != null) {
GranularityType granularity = kind.getGranularity();
if (granularity != null) {
type += " (" + granularity.getValue() + ")";
}
}
}
}
return type;
}
} }

View File

@ -299,7 +299,7 @@ public class DatablockSynchPanel extends TethysExportPanel {
long stop = synchInfo.getDataBlock().getPrimaryDataMap().getLastDataTime(); long stop = synchInfo.getDataBlock().getPrimaryDataMap().getLastDataTime();
return String.format("%s - %s", PamCalendar.formatDBDateTime(start), PamCalendar.formatDBDateTime(stop)); return String.format("%s - %s", PamCalendar.formatDBDateTime(start), PamCalendar.formatDBDateTime(stop));
case 3: case 3:
return synchInfo.getDetectionDocumentCount(); return synchInfo.getDetectionDocumentCount() + synchInfo.getLocalizationDocumentCount();
} }
return null; return null;
} }

View File

@ -2,8 +2,12 @@ package tethys.swing;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
@ -26,11 +30,34 @@ public class XMLStringView extends PamDialog {
textArea.setEditable(false); textArea.setEditable(false);
textArea.setCaretPosition(0); textArea.setCaretPosition(0);
JPopupMenu popMenu = new JPopupMenu();
textArea.setComponentPopupMenu(popMenu);
JMenuItem copyItem = new JMenuItem("Copy");
copyItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textArea.copy();
}
});
JMenuItem selItem = new JMenuItem("Select All");
selItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textArea.selectAll();
}
});
popMenu.add(copyItem);
popMenu.addSeparator();
popMenu.add(selItem);
getCancelButton().setVisible(false); getCancelButton().setVisible(false);
setModal(false); setModal(false);
getOkButton().setText("Close"); getOkButton().setText("Close");
getOkButton().setToolTipText("Close window"); getOkButton().setToolTipText("Close window");
setModal(false);
} }
public static void showDialog(Window parent, String collection, String documentId, String xmlString) { public static void showDialog(Window parent, String collection, String documentId, String xmlString) {

View File

@ -101,12 +101,23 @@ public class DescriptionTypePanel {
tMethod.setText(null); tMethod.setText(null);
} }
else { else {
checkDescription(description);
tObjectives.setText(description.getObjectives()); tObjectives.setText(description.getObjectives());
tAbstract.setText(description.getAbstract()); tAbstract.setText(description.getAbstract());
tMethod.setText(description.getMethod()); tMethod.setText(description.getMethod());
} }
} }
/**
* Auto fill some of the description fields.
* @param description
*/
private void checkDescription(DescriptionType description) {
if (description.getMethod() == null || description.getMethod().length() == 0) {
}
}
public boolean getParams(DescriptionType description) { public boolean getParams(DescriptionType description) {
Window f = PamGui.findComponentWindow(mainPanel); Window f = PamGui.findComponentWindow(mainPanel);
if (checkField(requireObjective, tObjectives) == false) { if (checkField(requireObjective, tObjectives) == false) {

View File

@ -81,6 +81,7 @@ public class DetectionsExportWizard extends PamWizard {
granularityCard.setParams(streamExportParams); granularityCard.setParams(streamExportParams);
} }
if (wizardCard == descriptionCard) { if (wizardCard == descriptionCard) {
streamExportParams.checkDescription();
descriptionCard.setParams(streamExportParams.getNilusDetectionDescription()); descriptionCard.setParams(streamExportParams.getNilusDetectionDescription());
} }
if (wizardCard == algorithmCard) { if (wizardCard == algorithmCard) {

View File

@ -10,6 +10,8 @@ import javax.swing.JMenuItem;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import dataPlots.data.TDDataProviderRegister; import dataPlots.data.TDDataProviderRegister;
import dataPlotsFX.data.TDDataProviderRegisterFX; import dataPlotsFX.data.TDDataProviderRegisterFX;
import dataPlotsFX.whistlePlotFX.WhistleMoanProviderFX; import dataPlotsFX.whistlePlotFX.WhistleMoanProviderFX;
@ -30,7 +32,7 @@ import PamController.PamSettings;
import PamView.PamSidePanel; import PamView.PamSidePanel;
import PamView.WrapperControlledGUISwing; import PamView.WrapperControlledGUISwing;
public class WhistleMoanControl extends PamControlledUnit implements PamSettings { public class WhistleMoanControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm {
private WhistleToneConnectProcess whistleToneProcess; private WhistleToneConnectProcess whistleToneProcess;
@ -229,4 +231,9 @@ public class WhistleMoanControl extends PamControlledUnit implements PamSettings
public String getModuleSummary(boolean clear) { public String getModuleSummary(boolean clear) {
return whistleToneProcess.getModuleSummary(clear); return whistleToneProcess.getModuleSummary(clear);
} }
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return whistleToneProcess.getLocAlgorithmInfo();
}
} }

View File

@ -15,6 +15,7 @@ import fftManager.FFTDataUnit;
import generalDatabase.PamDetectionLogging; import generalDatabase.PamDetectionLogging;
import generalDatabase.SQLLogging; import generalDatabase.SQLLogging;
import Array.ArrayManager; import Array.ArrayManager;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliser; import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliser;
import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliserSelector; import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliserSelector;
@ -1088,4 +1089,23 @@ public class WhistleToneConnectProcess extends PamProcess {
return sumText; return sumText;
} }
/**
* Get info on current localisation algorithm. Grab the BL from the
* first group that has one.
* @return
*/
public LocalisationAlgorithmInfo getLocAlgorithmInfo() {
if (shapeConnectors == null) {
return null;
}
for (int i = 0; i < shapeConnectors.length; i++) {
BearingLocaliser bl = shapeConnectors[i].bearingLocaliser;
if (bl != null && bl.getAlgorithmInfo() != null) {
return bl.getAlgorithmInfo();
}
}
return null;
}
} }