Merge branch 'main' into main

This commit is contained in:
Douglas Gillespie 2024-07-22 13:50:38 +01:00 committed by GitHub
commit 9eee7434de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 629 additions and 223 deletions

View File

@ -173,8 +173,19 @@ public class AcquisitionControl extends RawInputControlledUnit implements PamSet
registerDaqSystem(new SoundCardSystem(this)); registerDaqSystem(new SoundCardSystem(this));
if (PlatformInfo.calculateOS() == OSType.WINDOWS) { if (PlatformInfo.calculateOS() == OSType.WINDOWS) {
long tic = System.currentTimeMillis();
long toc = tic;
registerDaqSystem(new ASIOSoundSystem(this)); registerDaqSystem(new ASIOSoundSystem(this));
toc = System.currentTimeMillis();
if (toc-tic>1000) {
System.out.printf("Registering ASIOSoundSystem took %3.1fs\n", (double)(toc-tic)/1000.);
}
tic = System.currentTimeMillis();
registerDaqSystem(new NewAsioSoundSystem(this)); registerDaqSystem(new NewAsioSoundSystem(this));
toc = System.currentTimeMillis();
if (toc-tic>1000) {
System.out.printf("Registering NewAsioSoundSystem took %3.1fs\n", (double)(toc-tic)/1000.);
}
} }
registerDaqSystem(new FileInputSystem(this)); registerDaqSystem(new FileInputSystem(this));
registerDaqSystem(folderSystem = new FolderInputSystem(this)); registerDaqSystem(folderSystem = new FolderInputSystem(this));

View File

@ -0,0 +1,21 @@
package Localiser;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
/**
* Interface to attach to localisation algorithms which can provide basic information
* (primarily for better book keeping and Tethys output)
* @author dg50
*
*/
public interface LocalisationAlgorithm {
/**
* Get the likely content flags for this localiser.
* @see LocalisationInfo
* @see LocContents
* @return localisation flags.
*/
public int getLocalisationContents();
}

View File

@ -1,5 +1,6 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import Localiser.LocalisationAlgorithm;
import pamMaths.PamVector; import pamMaths.PamVector;
/** /**
@ -8,7 +9,7 @@ import pamMaths.PamVector;
* @author Doug Gillespie * @author Doug Gillespie
* *
*/ */
public interface BearingLocaliser { public interface BearingLocaliser extends LocalisationAlgorithm {
/** /**
* 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,5 +1,6 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import PamDetection.LocContents;
import pamMaths.PamVector; import pamMaths.PamVector;
public class CombinedBearingLocaliser implements BearingLocaliser { public class CombinedBearingLocaliser implements BearingLocaliser {
@ -23,6 +24,11 @@ public class CombinedBearingLocaliser implements BearingLocaliser {
firstSimplexStep[0] = firstSimplexStep[1] = Math.PI/180.; firstSimplexStep[0] = firstSimplexStep[1] = Math.PI/180.;
} }
@Override
public int getLocalisationContents() {
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) {
firstLocaliser.prepare(arrayElements, timeMillis, timingError); firstLocaliser.prepare(arrayElements, timeMillis, timingError);

View File

@ -5,6 +5,7 @@ import Array.PamArray;
import Jama.LUDecomposition; import Jama.LUDecomposition;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@ -30,6 +31,11 @@ public class LSQBearingLocaliser implements BearingLocaliser {
this.timingError = timingError; this.timingError = timingError;
} }
@Override
public int getLocalisationContents() {
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) {
/* /*

View File

@ -6,6 +6,7 @@ import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import PamDetection.LocContents;
import PamUtils.ArrayDump; import PamUtils.ArrayDump;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamUtils.SystemTiming; import PamUtils.SystemTiming;
@ -60,6 +61,11 @@ public class MLGridBearingLocaliser implements BearingLocaliser {
public void prepare(int[] arrayElements, long timMillis, double timingError) { public void prepare(int[] arrayElements, long timMillis, double timingError) {
prepare(arrayElements, timMillis, timingError, Math.toRadians(1), Math.toRadians(1)); prepare(arrayElements, timMillis, timingError, Math.toRadians(1), Math.toRadians(1));
} }
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) { synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) {
this.timingError = timingError; this.timingError = timingError;

View File

@ -8,6 +8,7 @@ import Jama.Matrix;
import Localiser.algorithms.Correlations; import Localiser.algorithms.Correlations;
import Localiser.algorithms.PeakPosition2D; import Localiser.algorithms.PeakPosition2D;
import Localiser.algorithms.PeakSearch; import Localiser.algorithms.PeakSearch;
import PamDetection.LocContents;
import PamUtils.ArrayDump; import PamUtils.ArrayDump;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamUtils.SystemTiming; import PamUtils.SystemTiming;
@ -72,6 +73,11 @@ public class MLGridBearingLocaliser2 implements BearingLocaliser {
this.useDefaults=true; this.useDefaults=true;
prepare(arrayElements, timMillis, timingError, Math.toRadians(3), Math.toRadians(3)); prepare(arrayElements, timMillis, timingError, Math.toRadians(3), Math.toRadians(3));
} }
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) { synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) {
this.timingError = timingError; this.timingError = timingError;

View File

@ -3,6 +3,8 @@
*/ */
package Localiser.algorithms.timeDelayLocalisers.bearingLoc; package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import PamDetection.LocContents;
/** /**
* @author dg50 * @author dg50
* *
@ -19,6 +21,11 @@ public class MLLineBearingLocaliser2 extends MLGridBearingLocaliser2 {
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY | LocContents.HAS_AMBIGUITY;
}
/** /**
* Convert a bin into an angle. * Convert a bin into an angle.
* @param bin bin index * @param bin bin index

View File

@ -6,6 +6,7 @@ import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@ -17,111 +18,111 @@ import pamMaths.PamVector;
*/ */
public class PairBearingLocaliser implements BearingLocaliser { public class PairBearingLocaliser implements BearingLocaliser {
public class LSQBearingLocaliser implements BearingLocaliser { // 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 hydrophoneVectors, hydrophoneUnitVectors; // private Matrix hydrophoneVectors, hydrophoneUnitVectors;
private double[] hydrophoneSpacing; // private double[] hydrophoneSpacing;
private PamArray currentArray; // private PamArray currentArray;
private int arrayType; // private int arrayType;
private PamVector[] arrayAxis; // private PamVector[] arrayAxis;
// private LUDecomposition luHydrophoneUnitMatrix; // // private LUDecomposition luHydrophoneUnitMatrix;
private QRDecomposition qrHydrophones; // private QRDecomposition qrHydrophones;
//
public LSQBearingLocaliser(int hydrophoneBitMap, long timeMillis, double timingError) { // public LSQBearingLocaliser(int hydrophoneBitMap, long timeMillis, double timingError) {
this.hydrophoneBitMap = hydrophoneBitMap; // this.hydrophoneBitMap = hydrophoneBitMap;
this.timeMillis = timeMillis; // this.timeMillis = timeMillis;
this.timingError = timingError; // this.timingError = timingError;
} // }
//
@Override // @Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) { // public void prepare(int[] arrayElements, long timeMillis, double timingError) {
/* // /*
* Set up the matrixes of inter hydrophone vectors. // * Set up the matrixes of inter hydrophone vectors.
*/ // */
//
hydrophoneBitMap = PamUtils.makeChannelMap(arrayElements); // hydrophoneBitMap = PamUtils.makeChannelMap(arrayElements);
ArrayManager arrayManager = ArrayManager.getArrayManager(); // ArrayManager arrayManager = ArrayManager.getArrayManager();
currentArray = arrayManager.getCurrentArray(); // currentArray = arrayManager.getCurrentArray();
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;
hydrophoneVectors = new Matrix(nDelay, 3); // hydrophoneVectors = new Matrix(nDelay, 3);
hydrophoneUnitVectors = new Matrix(nDelay, 3); // hydrophoneUnitVectors = new Matrix(nDelay, 3);
hydrophoneSpacing = new double[nDelay]; // hydrophoneSpacing = new double[nDelay];
int iRow = 0; // int iRow = 0;
for (int i = 0; i < nHyd; i++) { // for (int i = 0; i < nHyd; i++) {
PamVector vi = currentArray.getAbsHydrophoneVector(i, timeMillis); // PamVector vi = currentArray.getAbsHydrophoneVector(i, timeMillis);
for (int j = i+1; j <nHyd; j++) { // for (int j = i+1; j <nHyd; j++) {
PamVector vj = currentArray.getAbsHydrophoneVector(j, timeMillis); // PamVector vj = currentArray.getAbsHydrophoneVector(j, timeMillis);
PamVector v = vj.sub(vi); // PamVector v = vj.sub(vi);
hydrophoneSpacing[iRow] = v.norm(); // hydrophoneSpacing[iRow] = v.norm();
PamVector uv = v.getUnitVector(); // PamVector uv = v.getUnitVector();
for (int e = 0; e < 3; e++) { // for (int e = 0; e < 3; e++) {
hydrophoneVectors.set(iRow, e, v.getElement(e)); // hydrophoneVectors.set(iRow, e, v.getElement(e));
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(hydrophoneUnitVectors); // qrHydrophones = new QRDecomposition(hydrophoneUnitVectors);
} // }
//
@Override // @Override
public int getArrayType() { // public int getArrayType() {
return arrayType; // return arrayType;
} // }
//
@Override // @Override
public int getHydrophoneMap() { // public int getHydrophoneMap() {
return hydrophoneBitMap; // return hydrophoneBitMap;
} // }
//
@Override // @Override
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);
Matrix normDelays = new Matrix(delays.length, 1); // Matrix normDelays = new Matrix(delays.length, 1);
double c = currentArray.getSpeedOfSound(); // double c = currentArray.getSpeedOfSound();
for (int i = 0; i < delays.length; i++) { // for (int i = 0; i < delays.length; i++) {
normDelays.set(i, 0, -delays[i]*c/hydrophoneSpacing[i]); // normDelays.set(i, 0, -delays[i]*c/hydrophoneSpacing[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));
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));
return angs; // return angs;
} // }
//
} // }
private int[] phoneNumbers; private int[] phoneNumbers;
@ -206,6 +207,11 @@ public class PairBearingLocaliser implements BearingLocaliser {
} }
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY | LocContents.HAS_AMBIGUITY;
}
/** /**
* Some hydrophone locators have arrays which change with time. In this case the ML grid localiser will need to recalculate the look up table for localised ppositions * Some hydrophone locators have arrays which change with time. In this case the ML grid localiser will need to recalculate the look up table for localised ppositions
* *

View File

@ -14,6 +14,7 @@ import Array.ArrayManager;
import Array.PamArray; import Array.PamArray;
import Jama.Matrix; import Jama.Matrix;
import Jama.QRDecomposition; import Jama.QRDecomposition;
import PamDetection.LocContents;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import pamMaths.PamVector; import pamMaths.PamVector;
@ -39,6 +40,11 @@ public class SimplexBearingLocaliser implements BearingLocaliser {
this.timingError = timingError; this.timingError = timingError;
} }
@Override
public int getLocalisationContents() {
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) {
/* /*

View File

@ -10,6 +10,7 @@ package PamDetection;
public class LocContents implements LocalisationInfo { public class LocContents implements LocalisationInfo {
/**Flags for what type of 'Raw' localisation information from a detection**/ /**Flags for what type of 'Raw' localisation information from a detection**/
/** /**
* Time delays are present * Time delays are present
@ -78,8 +79,47 @@ public class LocContents implements LocalisationInfo {
/** /**
* Errors parallel and perpendicular to the ships track. * Errors parallel and perpendicular to the ships track.
*/ */
static public final int HAS_PERPENDICULARERRORS = 0x100; static public final int HAS_PERPENDICULARERRORS = 0x1000;
static public final int[] allTypes = {HAS_TIMEDELAYS, HAS_ECHO, HAS_BEARING, HAS_BEARINGERROR, HAS_RANGE, HAS_RANGEERROR, HAS_DEPTH, HAS_DEPTHERROR,
HAS_LATLONG, HAS_XY, HAS_XYZ, HAS_AMBIGUITY, HAS_PERPENDICULARERRORS};
/**
* Main types of interest.
*/
static public final int[] mainTypes = {HAS_BEARING, HAS_RANGE, HAS_DEPTH, HAS_LATLONG, HAS_XY, HAS_XYZ};
public static String getTypeString(int type) {
switch (type) {
case HAS_TIMEDELAYS:
return "Time delays";
case HAS_ECHO:
return "Echoes";
case HAS_BEARING:
return "Bearing";
case HAS_BEARINGERROR:
return "Bearing Error";
case HAS_RANGE:
return "Range";
case HAS_DEPTH:
return "Depth";
case HAS_RANGEERROR:
return "Range Error";
case HAS_DEPTHERROR:
return "Depth Error";
case HAS_LATLONG:
return "Lat Long";
case HAS_XY:
return "XY";
case HAS_XYZ:
return "XYZ";
case HAS_AMBIGUITY:
return "Ambiguity";
case HAS_PERPENDICULARERRORS:
return "Perpendicular Errors";
}
return null;
}
/** /**
* bitmap of flags saying what's in the localisation information * bitmap of flags saying what's in the localisation information

View File

@ -234,6 +234,8 @@ public class PamModuleInfo implements PamDependent{
// Class[] paramList = new Class[1]; // Class[] paramList = new Class[1];
// paramList[0] = unitName.getClass(); // paramList[0] = unitName.getClass();
boolean error = false; boolean error = false;
long tic = System.currentTimeMillis();
long toc = tic;
try { try {
Constructor constructor = moduleClass.getConstructor(constrParams1); Constructor constructor = moduleClass.getConstructor(constrParams1);
newUnit = (PamControlledUnit) constructor.newInstance(pamConfiguration, unitName); newUnit = (PamControlledUnit) constructor.newInstance(pamConfiguration, unitName);
@ -262,6 +264,11 @@ public class PamModuleInfo implements PamDependent{
return null; return null;
} }
} }
toc = System.currentTimeMillis();
if (toc-tic > 1000) {
System.out.printf("Module %s-%s was slow to load, taking %3.1f seconds\n", newUnit.getUnitType(),
newUnit.getUnitName(), (double)(toc-tic)/1000.);
}
setNInstances(nInstances + 1); setNInstances(nInstances + 1);

View File

@ -62,7 +62,7 @@ public class RWEProcess extends PamProcess {
this.rweControl = rweControl; this.rweControl = rweControl;
rweDataBlock = new RWEDataBlock(rweControl, rweControl.getUnitName(), this, 0); rweDataBlock = new RWEDataBlock(rweControl, rweControl.getUnitName(), this, 0);
addOutputDataBlock(rweDataBlock); addOutputDataBlock(rweDataBlock);
rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING); // rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING);
rweDataBlock.setDatagramProvider(new RWEDatagramProvider()); rweDataBlock.setDatagramProvider(new RWEDatagramProvider());
rweDataBlock.setOverlayDraw(new RWEOverlayGraphics(this, rweDataBlock)); rweDataBlock.setOverlayDraw(new RWEOverlayGraphics(this, rweDataBlock));
StandardSymbolManager symbolManager = symbolManager = new RWESymbolManager(rweDataBlock, RWEOverlayGraphics.defaultSymbol, true); StandardSymbolManager symbolManager = symbolManager = new RWESymbolManager(rweDataBlock, RWEOverlayGraphics.defaultSymbol, true);
@ -138,6 +138,11 @@ public class RWEProcess extends PamProcess {
rweChannelProcesses[i] = new RWEChannelProcess(this, i); rweChannelProcesses[i] = new RWEChannelProcess(this, i);
} }
} }
int nChan = PamUtils.getNumChannels(channelMap);
if (nChan > 1) {
// really needs properly setting up with channel groups
rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING);
}
// checkBearingLocaliser(sourceDataBlock.getChannelMap()); // checkBearingLocaliser(sourceDataBlock.getChannelMap());
} }
@ -433,6 +438,7 @@ public class RWEProcess extends PamProcess {
int hydrophoneMap = sourceDataBlock.getChannelListManager().channelIndexesToPhones(chanMap); int hydrophoneMap = sourceDataBlock.getChannelListManager().channelIndexesToPhones(chanMap);
return findBearingLocaliser(hydrophoneMap); return findBearingLocaliser(hydrophoneMap);
} }
private synchronized BearingLocaliser findBearingLocaliser(int hydrophoneMap) { private synchronized BearingLocaliser findBearingLocaliser(int hydrophoneMap) {
int nPhones = PamUtils.getNumChannels(hydrophoneMap); int nPhones = PamUtils.getNumChannels(hydrophoneMap);
if (nPhones < 2) { if (nPhones < 2) {

View File

@ -132,6 +132,7 @@ import PamguardMVC.PamProcess;
import PamguardMVC.PamRawDataBlock; import PamguardMVC.PamRawDataBlock;
import PamguardMVC.SimpleDataObserver; import PamguardMVC.SimpleDataObserver;
import PamguardMVC.dataOffline.OfflineDataLoading; import PamguardMVC.dataOffline.OfflineDataLoading;
import PamguardMVC.dataSelector.DataSelectParams;
import PamguardMVC.dataSelector.DataSelector; import PamguardMVC.dataSelector.DataSelector;
import dataPlotsFX.data.DataTypeInfo; import dataPlotsFX.data.DataTypeInfo;
import fftManager.FFTDataBlock; import fftManager.FFTDataBlock;
@ -2927,6 +2928,10 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett
// PamCalendar.formatTime(currentTimeMilliseconds))); // PamCalendar.formatTime(currentTimeMilliseconds)));
String name = spectrogramDisplay.getDataSelectorName(panelId); String name = spectrogramDisplay.getDataSelectorName(panelId);
DataSelector dataSelector = usedDataBlock.getDataSelector(name, false); DataSelector dataSelector = usedDataBlock.getDataSelector(name, false);
if (dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) {
dataSelector = null;
}
directDrawProjector.setDataSelector(dataSelector); directDrawProjector.setDataSelector(dataSelector);
if (usedDataBlock.getPamSymbolManager() != null) { if (usedDataBlock.getPamSymbolManager() != null) {
directDrawProjector.setPamSymbolChooser(usedDataBlock.getPamSymbolManager().getSymbolChooser(name, directDrawProjector)); directDrawProjector.setPamSymbolChooser(usedDataBlock.getPamSymbolManager().getSymbolChooser(name, directDrawProjector));

View File

@ -25,7 +25,15 @@ public class AsioDriverInfos {
} }
/**
* Gets called back from the jni call to callJniGetAsioDrivers
* @param driverName
* @param maxChannels
* @param sampleRateInfo
*/
public void addDriverToList(String driverName, int[] maxChannels, int[]sampleRateInfo){ public void addDriverToList(String driverName, int[] maxChannels, int[]sampleRateInfo){
lastDriverEnumeration = System.currentTimeMillis();
System.out.printf("Getting driver detail for ASIO %s took %3.1fs\n", driverName, (double) (lastDriverEnumeration-driverEnumerationStart)/1000.);
ArrayList<Integer>sampleRates = new ArrayList<Integer>(); ArrayList<Integer>sampleRates = new ArrayList<Integer>();
ArrayList<Integer>maxAvailableChannels = new ArrayList<Integer>(); ArrayList<Integer>maxAvailableChannels = new ArrayList<Integer>();
for(int i = 0;i<sampleRateInfo.length;i++){ for(int i = 0;i<sampleRateInfo.length;i++){
@ -34,30 +42,44 @@ public class AsioDriverInfos {
} }
AsioDriverInfo asioDriverInfo = new AsioDriverInfo(driverName, maxAvailableChannels,sampleRates); AsioDriverInfo asioDriverInfo = new AsioDriverInfo(driverName, maxAvailableChannels,sampleRates);
asioDriverList.add(asioDriverInfo); asioDriverList.add(asioDriverInfo);
driverEnumerationStart = System.currentTimeMillis();
} }
long driverEnumerationStart;
long lastDriverEnumeration;
private ArrayList<AsioDriverInfo> getAsioDriverList() { private ArrayList<AsioDriverInfo> getAsioDriverList() {
clearDriverList(); clearDriverList();
long t1 = System.currentTimeMillis();
driverEnumerationStart = t1;
asioJniInterface.callJniGetAsioDrivers(this); asioJniInterface.callJniGetAsioDrivers(this);
long t2 = System.currentTimeMillis();
System.out.printf("Call to asioJniInterface.callJniGetAsioDrivers took %3.1fs\n", (double) (t2-t1)/1000.);
for(int i = 0; i<asioDriverList.size();i++){ for(int i = 0; i<asioDriverList.size();i++){
System.out.printf("ASIO drivers: " + asioDriverList.get(i).driverName + " maxChannels: " + asioDriverList.get(i).maxChannels + " Can sample at "); System.out.printf("ASIO drivers: " + asioDriverList.get(i).driverName + " maxChannels: " + asioDriverList.get(i).maxChannels + " Can sample at ");
long tic = System.currentTimeMillis();
boolean firstHz = true; boolean firstHz = true;
for(int j = 0;j<asioDriverList.get(i).sampleRateInfo.size();j++){ for(int j = 0;j<asioDriverList.get(i).sampleRateInfo.size();j++){
if (firstHz == false) { if (firstHz == false) {
System.out.printf(", "); System.out.printf(", ");
}
else {
}
System.out.printf("%d", asioDriverList.get(i).sampleRateInfo.get(j));
firstHz = false;
} }
System.out.printf(" Hz\n"); else {
}
System.out.printf("%d", asioDriverList.get(i).sampleRateInfo.get(j));
firstHz = false;
} }
// System.out.println(); System.out.printf(" Hz\n");
// System.out.println("Java:: just called asioJniInterface.callJniGetAsioDrivers(this);"); long toc = System.currentTimeMillis();
// System.out.flush(); if (toc-tic > 1000) {
System.out.printf("Checking cababilities for ASIO %s took %3.1fs\n", asioDriverList.get(i).driverName,
(double) (toc-tic)/1000.);
}
}
// System.out.println();
// System.out.println("Java:: just called asioJniInterface.callJniGetAsioDrivers(this);");
// System.out.flush();
return asioDriverList; return asioDriverList;
} }
@ -65,11 +87,14 @@ public class AsioDriverInfos {
// System.out.println("getCurrentAsioDriverList():: asioDriverList.size()=" + asioDriverList.size()); // System.out.println("getCurrentAsioDriverList():: asioDriverList.size()=" + asioDriverList.size());
// System.out.flush(); // System.out.flush();
if(asioDriverList.size()==0){ if(asioDriverList.size()==0){
return asioDriverList = getAsioDriverList(); long tic = System.currentTimeMillis();
} asioDriverList = getAsioDriverList();
else{ long toc = System.currentTimeMillis();
return asioDriverList; if (toc-tic>1000) {
System.out.printf("Enumerating ASIO driver list took %3.1fs\n", (double)(toc-tic)/1000.);
}
} }
return asioDriverList;
} }

View File

@ -312,19 +312,19 @@ public class ClickDetector extends PamProcess {
offlineEventDataBlock.SetLogging(offlineEventLogging); offlineEventDataBlock.SetLogging(offlineEventLogging);
targetMotionSQLLogging = new TargetMotionSQLLogging(2); targetMotionSQLLogging = new TargetMotionSQLLogging(2);
offlineEventLogging.addAddOn(targetMotionSQLLogging); offlineEventLogging.addAddOn(targetMotionSQLLogging);
if (isViewer) { // if (isViewer) {
// offlineEventDataBlock = new // // offlineEventDataBlock = new
// OfflineEventDataBlock(clickControl.getUnitName()+"_OfflineEvents", // // OfflineEventDataBlock(clickControl.getUnitName()+"_OfflineEvents",
// this, 0); // // this, 0);
// offlineEventLogging = new OfflineEventLogging(clickControl, // // offlineEventLogging = new OfflineEventLogging(clickControl,
// offlineEventDataBlock); // // offlineEventDataBlock);
// targetMotionSQLLogging = new TargetMotionSQLLogging(2); // // targetMotionSQLLogging = new TargetMotionSQLLogging(2);
// offlineEventLogging.addAddOn(targetMotionSQLLogging); // // offlineEventLogging.addAddOn(targetMotionSQLLogging);
// offlineEventDataBlock.SetLogging(offlineEventLogging); // // offlineEventDataBlock.SetLogging(offlineEventLogging);
} else { // for normal and mixed mode. // } else { // for normal and mixed mode.
offlineEventDataBlock.setLocalisationContents(LocContents.HAS_BEARING | LocContents.HAS_RANGE offlineEventDataBlock.setLocalisationContents(LocContents.HAS_BEARING | LocContents.HAS_RANGE
| LocContents.HAS_LATLONG | LocContents.HAS_AMBIGUITY | LocContents.HAS_PERPENDICULARERRORS); | LocContents.HAS_LATLONG | LocContents.HAS_AMBIGUITY | LocContents.HAS_PERPENDICULARERRORS);
} // }
// set up the subtable for the Event Logger, and force creation // set up the subtable for the Event Logger, and force creation
offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging()); offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging());
@ -458,6 +458,8 @@ public class ClickDetector extends PamProcess {
nChannelGroups = GroupedSourcePanel.countChannelGroups(cp.getChannelBitmap(), cp.getChannelGroups()); nChannelGroups = GroupedSourcePanel.countChannelGroups(cp.getChannelBitmap(), cp.getChannelGroups());
int groupChannels; int groupChannels;
channelGroupDetectors = new ChannelGroupDetector[nChannelGroups]; channelGroupDetectors = new ChannelGroupDetector[nChannelGroups];
int locContents = 0;
for (int i = 0; i < nChannelGroups; i++) { for (int i = 0; i < nChannelGroups; i++) {
groupChannels = GroupedSourcePanel.getGroupChannels(i, cp.getChannelBitmap(), cp.getChannelGroups()); groupChannels = GroupedSourcePanel.getGroupChannels(i, cp.getChannelBitmap(), cp.getChannelGroups());
channelGroupDetectors[i] = new ChannelGroupDetector(i, groupChannels); channelGroupDetectors[i] = new ChannelGroupDetector(i, groupChannels);
@ -467,9 +469,21 @@ public class ClickDetector extends PamProcess {
if (multiThread) { if (multiThread) {
channelGroupDetectors[i].halfBuiltClicks.addObserver(newClickMonitor, true); channelGroupDetectors[i].halfBuiltClicks.addObserver(newClickMonitor, true);
} }
if (channelGroupDetectors[i].bearingLocaliser != null) {
locContents |= channelGroupDetectors[i].bearingLocaliser.getLocalisationContents();
}
// System.out.println("Group " + i + " contains channels list " + // System.out.println("Group " + i + " contains channels list " +
// groupChannels); // groupChannels);
} }
outputClickData.setLocalisationContents(locContents);
if (locContents == 0) {
offlineEventDataBlock.setLocalisationContents(0);
}
else {
int eventLocCont = LocContents.HAS_LATLONG | LocContents.HAS_XYZ | LocContents.HAS_RANGE;
eventLocCont |= (locContents & LocContents.HAS_AMBIGUITY);
offlineEventDataBlock.setLocalisationContents(eventLocCont);
}
globalChannelList = new int[nChan = PamUtils globalChannelList = new int[nChan = PamUtils
.getNumChannels(clickControl.clickParameters.getChannelBitmap())]; .getNumChannels(clickControl.clickParameters.getChannelBitmap())];

View File

@ -27,6 +27,7 @@ public class ClickEventTethysDataProvider extends AutoTethysProvider {
@Override @Override
public GranularityEnumType[] getAllowedGranularities() { public GranularityEnumType[] getAllowedGranularities() {
// these are by definition grouped.
GranularityEnumType[] allowed = {GranularityEnumType.GROUPED}; GranularityEnumType[] allowed = {GranularityEnumType.GROUPED};
return allowed; return allowed;
} }
@ -59,14 +60,19 @@ public class ClickEventTethysDataProvider extends AutoTethysProvider {
addUserDefined(params, numName, number.toString()); addUserDefined(params, numName, number.toString());
} }
// @Override
// public boolean wantExportDialogCard(ExportWizardCard wizPanel) {
//// if (wizPanel.getClass() == GranularityCard.class) {
//// return false;
//// }
//// else {
// return true;
//// }
// }
@Override @Override
public boolean wantExportDialogCard(ExportWizardCard wizPanel) { public boolean granularityOK(GranularityEnumType granularityType) {
if (wizPanel.getClass() == GranularityCard.class) { return true;
return false;
}
else {
return true;
}
} }
} }

View File

@ -26,6 +26,7 @@ import dataMap.OfflineDataMap;
import dataMap.OfflineDataMapPoint; import dataMap.OfflineDataMapPoint;
import nilus.AlgorithmType; import nilus.AlgorithmType;
import nilus.AlgorithmType.SupportSoftware; import nilus.AlgorithmType.SupportSoftware;
import nilus.Localize.Localizations;
import nilus.DataSourceType; import nilus.DataSourceType;
import nilus.Deployment; import nilus.Deployment;
import nilus.Detection; import nilus.Detection;
@ -380,8 +381,10 @@ public class DetectionsHandler extends CollectionHandler {
} }
return exportCount; return exportCount;
}/** }
* Export detections in all deployments for this PAMGuard dataset.
/**
* Export detections and localisations in all deployments for this PAMGuard dataset.
* @param dataBlock * @param dataBlock
* @param streamExportParams * @param streamExportParams
* @param exportObserver * @param exportObserver
@ -396,7 +399,14 @@ public class DetectionsHandler extends CollectionHandler {
DBXMLConnect dbxmlConnect = tethysControl.getDbxmlConnect(); DBXMLConnect dbxmlConnect = tethysControl.getDbxmlConnect();
DeploymentHandler depHandler = tethysControl.getDeploymentHandler(); DeploymentHandler depHandler = tethysControl.getDeploymentHandler();
ArrayList<PDeployment> deployments = depHandler.getMatchedDeployments(); ArrayList<PDeployment> deployments = depHandler.getMatchedDeployments();
Detections currentDetections = null;
/*
* The main documents for both dets and locs.
*/
Detections detectionsDocument = null;
Localizations localisationsDocument = null;
DetectionGroup onEffortDetections = null;
OfflineDataMap dataMap = dataBlock.getPrimaryDataMap(); OfflineDataMap dataMap = dataBlock.getPrimaryDataMap();
DataSelector dataSelector = dataBlock.getDataSelector(tethysControl.getDataSelectName(), false); DataSelector dataSelector = dataBlock.getDataSelector(tethysControl.getDataSelectName(), false);
int totalCount = dataMap.getDataCount(); int totalCount = dataMap.getDataCount();
@ -427,16 +437,23 @@ public class DetectionsHandler extends CollectionHandler {
List<OfflineDataMapPoint> mapPoints = dataMap.getMapPoints(); List<OfflineDataMapPoint> mapPoints = dataMap.getMapPoints();
for (OfflineDataMapPoint mapPoint : mapPoints) { for (OfflineDataMapPoint mapPoint : mapPoints) {
if (!activeExport) { if (!activeExport) {
prog = new DetectionExportProgress(deployment, currentDetections,totalMapPoints, doneMapPoints, prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_CANCELED); lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_CANCELED);
exportObserver.update(prog); exportObserver.update(prog);
break; break;
} }
if (currentDetections == null) { if (detectionsDocument == null && streamExportParams.exportDetections) {
// needed in inner loop in case doc gets written at 500000. // needed in inner loop in case doc gets written at 500000.
currentDetections = startDetectionsDocument(deployment, dataBlock, streamExportParams); detectionsDocument = startDetectionsDocument(deployment, dataBlock, streamExportParams);
currentDetections.getEffort().setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart())); detectionsDocument.getEffort().setStart(TethysTimeFuncs.xmlGregCalFromMillis(deployment.getAudioStart()));
onEffortDetections = detectionsDocument.getOnEffort();
}
else {
onEffortDetections = null;
}
if (localisationsDocument == null && streamExportParams.exportLocalisations) {
localisationsDocument = startLocalisationDocument(deployment, dataBlock, streamExportParams);
} }
if (mapPoint.getEndTime() < deployment.getAudioStart()) { if (mapPoint.getEndTime() < deployment.getAudioStart()) {
@ -449,7 +466,6 @@ public class DetectionsHandler extends CollectionHandler {
ArrayList<PamDataUnit> dataCopy = dataBlock.getDataCopy(deployment.getAudioStart(), deployment.getAudioEnd(), true, dataSelector); ArrayList<PamDataUnit> dataCopy = dataBlock.getDataCopy(deployment.getAudioStart(), deployment.getAudioEnd(), true, dataSelector);
Collections.sort(dataCopy); Collections.sort(dataCopy);
skipCount += dataBlock.getUnitsCount() - dataCopy.size(); skipCount += dataBlock.getUnitsCount() - dataCopy.size();
DetectionGroup onEffort = currentDetections.getOnEffort();
for (PamDataUnit dataUnit : dataCopy) { for (PamDataUnit dataUnit : dataCopy) {
/* /*
* Here is where we need to handle the different granularities. * Here is where we need to handle the different granularities.
@ -459,11 +475,13 @@ public class DetectionsHandler extends CollectionHandler {
for (int dd = 0; dd < dets.length; dd++) { for (int dd = 0; dd < dets.length; dd++) {
exportCount++; exportCount++;
documentCount++; documentCount++;
onEffort.getDetection().add(dets[dd]); if (streamExportParams.exportDetections) {
onEffortDetections.getDetection().add(dets[dd]);
}
} }
} }
if (exportCount % 100 == 0) { if (exportCount % 100 == 0) {
prog = new DetectionExportProgress(deployment, currentDetections, totalMapPoints, doneMapPoints, prog = new DetectionExportProgress(deployment, detectionsDocument, totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_GATHERING); lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_GATHERING);
exportObserver.update(prog); exportObserver.update(prog);
} }
@ -471,23 +489,25 @@ public class DetectionsHandler extends CollectionHandler {
} }
doneMapPoints ++; doneMapPoints ++;
prog = new DetectionExportProgress(deployment, currentDetections,totalMapPoints, doneMapPoints, prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_GATHERING); lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_GATHERING);
exportObserver.update(prog); exportObserver.update(prog);
if (documentCount > 50000000 && mapPoint != dataMap.getLastMapPoint()) { if (documentCount > 50000000 && mapPoint != dataMap.getLastMapPoint()) {
prog = new DetectionExportProgress(deployment, currentDetections,totalMapPoints, doneMapPoints, prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING); lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
exportObserver.update(prog); exportObserver.update(prog);
closeDetectionsDocument(currentDetections, mapPoint.getEndTime()); if (detectionsDocument != null) {
try { closeDetectionsDocument(detectionsDocument, mapPoint.getEndTime());
if (checkDetectionsDocument(currentDetections, granularityHandler)) { try {
dbxmlConnect.postAndLog(currentDetections); if (checkDetectionsDocument(detectionsDocument, granularityHandler)) {
dbxmlConnect.postAndLog(detectionsDocument);
}
} catch (TethysException e) {
tethysControl.showException(e);
} }
} catch (TethysException e) { detectionsDocument = null;
tethysControl.showException(e);
} }
currentDetections = null;
} }
if (viewerLoadPolicy == ViewerLoadPolicy.LOAD_ALWAYS_EVERYTHING) { if (viewerLoadPolicy == ViewerLoadPolicy.LOAD_ALWAYS_EVERYTHING) {
@ -502,26 +522,26 @@ public class DetectionsHandler extends CollectionHandler {
return DetectionExportProgress.STATE_CANCELED; return DetectionExportProgress.STATE_CANCELED;
} }
if (currentDetections != null) { if (detectionsDocument != null) {
Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd()); Detection dets[] = granularityHandler.cleanup(deployment.getAudioEnd());
if (dets != null) { if (dets != null) {
for (int dd = 0; dd < dets.length; dd++) { for (int dd = 0; dd < dets.length; dd++) {
exportCount++; exportCount++;
documentCount++; documentCount++;
currentDetections.getOnEffort().getDetection().add(dets[dd]); detectionsDocument.getOnEffort().getDetection().add(dets[dd]);
} }
} }
prog = new DetectionExportProgress(deployment, currentDetections,totalMapPoints, doneMapPoints, prog = new DetectionExportProgress(deployment, detectionsDocument,totalMapPoints, doneMapPoints,
lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING); lastUnitTime, totalCount, exportCount, skipCount, DetectionExportProgress.STATE_WRITING);
closeDetectionsDocument(currentDetections, deployment.getAudioEnd()); closeDetectionsDocument(detectionsDocument, deployment.getAudioEnd());
try { try {
if (checkDetectionsDocument(currentDetections, granularityHandler)) { if (checkDetectionsDocument(detectionsDocument, granularityHandler)) {
dbxmlConnect.postAndLog(currentDetections); dbxmlConnect.postAndLog(detectionsDocument);
} }
} catch (TethysException e) { } catch (TethysException e) {
tethysControl.showException(e); tethysControl.showException(e);
} }
currentDetections = null; detectionsDocument = null;
} }
} }
@ -531,6 +551,20 @@ public class DetectionsHandler extends CollectionHandler {
return DetectionExportProgress.STATE_COMPLETE; return DetectionExportProgress.STATE_COMPLETE;
} }
private Localizations startLocalisationDocument(PDeployment deployment, PamDataBlock dataBlock,
StreamExportParams streamExportParams) {
Localizations localisations = new Localizations();
try {
Helper.createRequiredElements(localisations);
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
return null;
}
return localisations;
}
/** /**
* Start a new detections document for the deployment and datablock. <br> * Start a new detections document for the deployment and datablock. <br>
* Add all the standard information to the top of the Document * Add all the standard information to the top of the Document

View File

@ -1,17 +1,17 @@
package tethys.localization; package tethys.localization;
//import nilus.CylindricalCoordinateType; import nilus.CylindricalCoordinateType;
//import nilus.LocalizationType; import nilus.LocalizationType;
//import nilus.Localize.Effort.CoordinateReferenceSystem; import nilus.Localize.Effort.CoordinateReferenceSystem;
public class LocalizationHandler { public class LocalizationHandler {
// 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;
// } }
} }

View File

@ -0,0 +1,40 @@
package tethys.localization;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
import PamguardMVC.PamDataBlock;
/**
* Summary of localisation info in a datablock, specific to Tethys needs.
* @author dg50
*
*/
public class TethysLocalisationInfo {
private PamDataBlock pamDataBlock;
public TethysLocalisationInfo(PamDataBlock pamDataBlock) {
this.pamDataBlock = pamDataBlock;
}
public String getLoclisationTypes() {
LocalisationInfo locCont = pamDataBlock.getLocalisationContents();
if (locCont == null || locCont.getLocContent() == 0) {
return null;
}
String str = null;
int[] mainTypes = LocContents.mainTypes;
for (int i = 0; i < mainTypes.length; i++) {
if (locCont.hasLocContent(mainTypes[i])) {
if (str == null) {
str = LocContents.getTypeString(mainTypes[i]);
}
else {
str += ", " + LocContents.getTypeString(mainTypes[i]);
}
}
}
return str;
}
}

View File

@ -20,7 +20,7 @@ public class PGranularityType {
case BINNED: case BINNED:
return "Binned"; return "Binned";
case CALL: case CALL:
return "Call"; return "Call / detection";
case ENCOUNTER: case ENCOUNTER:
return "Encounter"; return "Encounter";
case GROUPED: case GROUPED:

View File

@ -26,11 +26,19 @@ public class StreamExportParams implements Serializable {
/** /**
* Datablock long data name (used instead of datablock * Datablock long data name (used instead of datablock
* reference so this object and serialise. * reference so this object is serialise.
*/ */
public String longDataName; public String longDataName;
public boolean selected; /**
* Have selected export of detections.
*/
public boolean exportDetections;
/**
* Have selected export of localisations.
*/
public boolean exportLocalisations;
/** /**
* Granularity type, binned, call, encounter, grouped. * Granularity type, binned, call, encounter, grouped.
@ -74,10 +82,9 @@ public class StreamExportParams implements Serializable {
return detectionDescription; return detectionDescription;
} }
public StreamExportParams(TethysControl tethysControl, PamDataBlock dataBlock, boolean selected) { public StreamExportParams(TethysControl tethysControl, PamDataBlock dataBlock) {
super(); super();
this.longDataName = dataBlock.getLongDataName(); this.longDataName = dataBlock.getLongDataName();
this.selected = selected;
autoFill(tethysControl, dataBlock); autoFill(tethysControl, dataBlock);
} }

View File

@ -13,6 +13,7 @@ import PamController.PamControlledUnit;
import PamController.PamSettings; import PamController.PamSettings;
import PamController.PamguardVersionInfo; import PamController.PamguardVersionInfo;
import PamController.settings.output.xml.PamguardXMLWriter; import PamController.settings.output.xml.PamguardXMLWriter;
import PamDetection.LocalisationInfo;
import PamUtils.XMLUtils; import PamUtils.XMLUtils;
import PamguardMVC.DataAutomationInfo; import PamguardMVC.DataAutomationInfo;
import PamguardMVC.DataUnitBaseData; import PamguardMVC.DataUnitBaseData;
@ -37,6 +38,7 @@ import nilus.SpeciesIDType;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.TethysTimeFuncs; import tethys.TethysTimeFuncs;
import tethys.detection.DetectionsHandler; import tethys.detection.DetectionsHandler;
import tethys.localization.TethysLocalisationInfo;
import tethys.niluswraps.PDeployment; import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams; import tethys.output.StreamExportParams;
import tethys.output.TethysExportParams; import tethys.output.TethysExportParams;
@ -505,5 +507,41 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
return tethysControl; return tethysControl;
} }
@Override
public boolean hasDetections() {
return true;
}
@Override
public boolean canExportLocalisations(GranularityEnumType granularityType) {
LocalisationInfo locCont = pamDataBlock.getLocalisationContents();
if (locCont == null) {
return false;
}
return (locCont.getLocContent() > 0 & granularityOK(granularityType));
}
/**
* Granularity is OK for export.
* @param granularityType
* @return
*/
public boolean granularityOK(GranularityEnumType granularityType) {
return (granularityType == null || granularityType == GranularityEnumType.CALL);
}
@Override
public TethysLocalisationInfo getLocalisationInfo() {
LocalisationInfo locCont = pamDataBlock.getLocalisationContents();
if (locCont == null || locCont.getLocContent() == 0) {
return null;
}
else {
return new TethysLocalisationInfo(pamDataBlock);
}
}
} }

View File

@ -2,6 +2,7 @@ package tethys.pamdata;
import java.util.List; import java.util.List;
import PamDetection.LocalisationInfo;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import nilus.AlgorithmType; import nilus.AlgorithmType;
import nilus.AlgorithmType.Parameters; import nilus.AlgorithmType.Parameters;
@ -10,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.localization.TethysLocalisationInfo;
import tethys.niluswraps.PDeployment; import tethys.niluswraps.PDeployment;
import tethys.output.StreamExportParams; import tethys.output.StreamExportParams;
import tethys.output.TethysExportParams; import tethys.output.TethysExportParams;
@ -81,7 +83,23 @@ public interface TethysDataProvider {
* @return A name, similar to datablock.getLongDataName(), but no spaces. * @return A name, similar to datablock.getLongDataName(), but no spaces.
*/ */
public String getDetectionsName(); public String getDetectionsName();
/**
* True if the datablock is detections. This will (nearly) always
* be true or the block wouldn't have a TethysDataProvider, however
* there may be one or two localisers that should really only output
* localisation information.
* @return
*/
public boolean hasDetections();
/**
* See if it's possible for this block to export localisations. This may
* depend on the selected granularity.
* @param granularityType
* @return
*/
public boolean canExportLocalisations(GranularityEnumType granularityType);
/** /**
* Create a Tethys Detection object from a PamDataUnit.<br> * Create a Tethys Detection object from a PamDataUnit.<br>
@ -120,5 +138,12 @@ public interface TethysDataProvider {
*/ */
public boolean wantExportDialogCard(ExportWizardCard wizPanel); public boolean wantExportDialogCard(ExportWizardCard wizPanel);
/**
* Get localisation info for the datablock. Can be null, but probably never is. More likely to have a zero of available types;
* @return
*/
public TethysLocalisationInfo getLocalisationInfo();
} }

View File

@ -42,7 +42,7 @@ public class DetectionsExportWizard extends PamWizard {
streamExportParams = tethysControl.getTethysExportParams().getStreamParams(dataBlock); streamExportParams = tethysControl.getTethysExportParams().getStreamParams(dataBlock);
if (streamExportParams == null) { if (streamExportParams == null) {
streamExportParams = new StreamExportParams(tethysControl, dataBlock, false); streamExportParams = new StreamExportParams(tethysControl, dataBlock);
} }
tethysDataProvider = dataBlock.getTethysDataProvider(tethysControl); tethysDataProvider = dataBlock.getTethysDataProvider(tethysControl);
getMainPanel().add(BorderLayout.NORTH, new ExportStreamInfoPanel(dataBlock)); getMainPanel().add(BorderLayout.NORTH, new ExportStreamInfoPanel(dataBlock));

View File

@ -9,6 +9,7 @@ import java.awt.event.ActionListener;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JRadioButton; import javax.swing.JRadioButton;
@ -17,9 +18,6 @@ import javax.swing.JTextArea;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import org.w3c.dom.Document;
import PamController.settings.output.xml.PamguardXMLWriter;
import PamView.dialog.PamGridBagContraints; import PamView.dialog.PamGridBagContraints;
import PamView.panel.WestAlignedPanel; import PamView.panel.WestAlignedPanel;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
@ -28,6 +26,7 @@ import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.dataSelector.DataSelectorChangeListener; import PamguardMVC.dataSelector.DataSelectorChangeListener;
import nilus.GranularityEnumType; import nilus.GranularityEnumType;
import tethys.TethysControl; import tethys.TethysControl;
import tethys.localization.TethysLocalisationInfo;
import tethys.niluswraps.PGranularityType; import tethys.niluswraps.PGranularityType;
import tethys.output.StreamExportParams; import tethys.output.StreamExportParams;
import tethys.pamdata.TethysDataProvider; import tethys.pamdata.TethysDataProvider;
@ -40,22 +39,51 @@ public class GranularityCard extends ExportWizardCard {
private JTextField binLength, minBinnedCalls, encounterGap, minEncounterCalls; private JTextField binLength, minBinnedCalls, encounterGap, minEncounterCalls;
private JCheckBox exportDetections, exportLocalisations;
private JLabel localisationTypes;
private JRadioButton groupChannels, separateChannels; private JRadioButton groupChannels, separateChannels;
private DataSelector dataSelector; private DataSelector dataSelector;
private DetectionsExportWizard detectionsExportWizard; private DetectionsExportWizard detectionsExportWizard;
private int encounterIndex, binnedIndex; private int callIndex, encounterIndex, binnedIndex;
private GranularityEnumType[] allowedGranularities; private GranularityEnumType[] allowedGranularities;
private TethysDataProvider tethysDataProvider;
public GranularityCard(DetectionsExportWizard detectionsExportWizard, TethysControl tethysControl, PamDataBlock dataBlock) { public GranularityCard(DetectionsExportWizard detectionsExportWizard, TethysControl tethysControl, PamDataBlock dataBlock) {
super(tethysControl, detectionsExportWizard, "Granularity", dataBlock); super(tethysControl, detectionsExportWizard, "Granularity", dataBlock);
this.detectionsExportWizard = detectionsExportWizard; this.detectionsExportWizard = detectionsExportWizard;
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
TethysDataProvider tethysDataProvider = dataBlock.getTethysDataProvider(tethysControl); tethysDataProvider = dataBlock.getTethysDataProvider(tethysControl);
GranularityChange gc = new GranularityChange();
exportDetections = new JCheckBox("Export Detections");
exportLocalisations = new JCheckBox("Export Localisations");
exportDetections.addActionListener(gc);
exportLocalisations.addActionListener(gc);
JPanel whatPanel = new JPanel(new GridBagLayout());
GridBagConstraints cw = new PamGridBagContraints();
cw.gridwidth = 2;
whatPanel.add(exportDetections, cw);
cw.gridy++;
whatPanel.add(exportLocalisations, cw);
cw.gridwidth = 1;
cw.gridy++;
whatPanel.add(new JLabel("Loclisation types: ", JLabel.RIGHT), cw);
cw.gridx++;
whatPanel.add(localisationTypes = new JLabel("none"), cw);
JPanel walPanel = new WestAlignedPanel(whatPanel);
walPanel.setBorder(new TitledBorder("What to export"));
this.add(walPanel);
localisationTypes.setToolTipText("Not all listed localisation types may be present in actual data");
// granularity // granularity
allowedGranularities = tethysDataProvider.getAllowedGranularities(); allowedGranularities = tethysDataProvider.getAllowedGranularities();
granularities = new JRadioButton[allowedGranularities.length]; granularities = new JRadioButton[allowedGranularities.length];
@ -63,7 +91,6 @@ public class GranularityCard extends ExportWizardCard {
GridBagConstraints c = new PamGridBagContraints(); GridBagConstraints c = new PamGridBagContraints();
granPanel.setBorder(new TitledBorder("Granularity")); granPanel.setBorder(new TitledBorder("Granularity"));
ButtonGroup granGroup = new ButtonGroup(); ButtonGroup granGroup = new ButtonGroup();
GranularityChange gc = new GranularityChange();
binLength = new JTextField(5); binLength = new JTextField(5);
minBinnedCalls = new JTextField(5); minBinnedCalls = new JTextField(5);
encounterGap = new JTextField(5); encounterGap = new JTextField(5);
@ -75,6 +102,9 @@ public class GranularityCard extends ExportWizardCard {
granularities[i].addActionListener(gc); granularities[i].addActionListener(gc);
granPanel.add(granularities[i], c); granPanel.add(granularities[i], c);
granGroup.add(granularities[i]); granGroup.add(granularities[i]);
if (allowedGranularities[i] == GranularityEnumType.CALL) {
callIndex = i;
}
if (allowedGranularities[i] == GranularityEnumType.BINNED) { if (allowedGranularities[i] == GranularityEnumType.BINNED) {
binnedIndex = i; binnedIndex = i;
c.gridx++; c.gridx++;
@ -149,16 +179,6 @@ public class GranularityCard extends ExportWizardCard {
} }
private void enableControls() {
binLength.setEnabled(granularities[binnedIndex].isSelected());
minBinnedCalls.setEnabled(granularities[binnedIndex].isSelected());
encounterGap.setEnabled(granularities[encounterIndex].isSelected());
minEncounterCalls.setEnabled(granularities[encounterIndex].isSelected());
boolean binOrencount = granularities[binnedIndex].isSelected() | granularities[encounterIndex].isSelected();
separateChannels.setEnabled(binOrencount);
groupChannels.setEnabled(binOrencount);
}
protected void newDataSelection() { protected void newDataSelection() {
if (dataSelector == null) { if (dataSelector == null) {
return; return;
@ -177,12 +197,9 @@ public class GranularityCard extends ExportWizardCard {
@Override @Override
public boolean getParams(StreamExportParams streamExportParams) { public boolean getParams(StreamExportParams streamExportParams) {
for (int i = 0; i < allowedGranularities.length; i++) {
if (granularities[i].isSelected()) { streamExportParams.granularity = getCurrentGranularity();
streamExportParams.granularity = allowedGranularities[i];
break;
}
}
if (streamExportParams.granularity == GranularityEnumType.BINNED) { if (streamExportParams.granularity == GranularityEnumType.BINNED) {
try { try {
streamExportParams.binDurationS = Double.valueOf(binLength.getText()); streamExportParams.binDurationS = Double.valueOf(binLength.getText());
@ -214,22 +231,87 @@ public class GranularityCard extends ExportWizardCard {
streamExportParams.separateChannels = separateChannels.isSelected(); streamExportParams.separateChannels = separateChannels.isSelected();
streamExportParams.exportDetections = exportDetections.isSelected();
streamExportParams.exportLocalisations = exportLocalisations.isSelected();
if (streamExportParams.exportDetections == false && streamExportParams.exportLocalisations == false) {
return detectionsExportWizard.showWarning("You must select Detections or Localisations for export");
}
return streamExportParams.granularity != null; return streamExportParams.granularity != null;
} }
@Override private GranularityEnumType getCurrentGranularity() {
public void setParams(StreamExportParams streamExportParams) { for (int i = 0; i < allowedGranularities.length; i++) {
for (int i = 0; i < granularities.length; i++) { if (granularities[i].isSelected()) {
granularities[i].setSelected(streamExportParams.granularity == allowedGranularities[i]); return allowedGranularities[i];
}
} }
binLength.setText(String.format("%3.1f", streamExportParams.binDurationS)); return null;
minBinnedCalls.setText(String.format("%d", streamExportParams.minBinCount)); }
encounterGap.setText(String.format("%3.1f", streamExportParams.encounterGapS));
minEncounterCalls.setText(String.format("%d", streamExportParams.minEncounterCount)); @Override
separateChannels.setSelected(streamExportParams.separateChannels); public void setParams(StreamExportParams streamExportParams) {
groupChannels.setSelected(streamExportParams.separateChannels == false); for (int i = 0; i < granularities.length; i++) {
newDataSelection(); granularities[i].setSelected(streamExportParams.granularity == allowedGranularities[i]);
enableControls(); }
binLength.setText(String.format("%3.1f", streamExportParams.binDurationS));
minBinnedCalls.setText(String.format("%d", streamExportParams.minBinCount));
encounterGap.setText(String.format("%3.1f", streamExportParams.encounterGapS));
minEncounterCalls.setText(String.format("%d", streamExportParams.minEncounterCount));
separateChannels.setSelected(streamExportParams.separateChannels);
groupChannels.setSelected(streamExportParams.separateChannels == false);
String locStr = getLocInfString();
if (locStr == null) {
localisationTypes.setText("none");
// exportDetections.setSelected(true);
exportLocalisations.setSelected(false);
}
else {
localisationTypes.setText(locStr);
}
exportDetections.setSelected(streamExportParams.exportDetections);
exportLocalisations.setSelected(streamExportParams.exportLocalisations);
newDataSelection();
enableControls();
}
private void enableControls() {
String locStr = getLocInfString();
boolean dets = exportDetections.isSelected();
boolean locs = exportLocalisations.isSelected();
granularities[binnedIndex].setEnabled(!locs);
granularities[encounterIndex].setEnabled(!locs);
GranularityEnumType granularity = getCurrentGranularity();
boolean canLoc = tethysDataProvider.canExportLocalisations(granularity);
exportLocalisations.setEnabled(canLoc);
if (canLoc == false) {
exportLocalisations.setSelected(false);
exportDetections.setSelected(true);
}
if (granularities.length == 1) {
granularities[0].setSelected(true);
}
binLength.setEnabled(granularities[binnedIndex].isSelected());
minBinnedCalls.setEnabled(granularities[binnedIndex].isSelected());
encounterGap.setEnabled(granularities[encounterIndex].isSelected());
minEncounterCalls.setEnabled(granularities[encounterIndex].isSelected());
boolean binOrencount = granularities[binnedIndex].isSelected() | granularities[encounterIndex].isSelected();
separateChannels.setEnabled(binOrencount);
groupChannels.setEnabled(binOrencount);
}
private String getLocInfString() {
TethysLocalisationInfo locInf = getDataBlock().getTethysDataProvider(getTethysControl()).getLocalisationInfo();
if (locInf == null) {
return null;
}
return locInf.getLoclisationTypes();
} }
} }

View File

@ -38,8 +38,9 @@ public class WMDDataSelector extends DataSelector {
} }
@Override @Override
public double scoreData(PamDataUnit pamDataUnit) { public double scoreData(PamDataUnit pamDataUnit) {
if (getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) { int combFlag = wmAlarmParameters.getCombinationFlag();
if (combFlag == DataSelectParams.DATA_SELECT_DISABLE) {
return 1; return 1;
} }
ConnectedRegionDataUnit crDataUnit = (ConnectedRegionDataUnit) pamDataUnit; ConnectedRegionDataUnit crDataUnit = (ConnectedRegionDataUnit) pamDataUnit;