mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-10-29 23:30:44 +00:00
Merge pull request #2 from douggillespie/main
Add Tethys output to DL module
This commit is contained in:
commit
f9b13da1d1
2
.gitignore
vendored
2
.gitignore
vendored
@ -109,3 +109,5 @@ settings.xml
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.settings/org.eclipse.jdt.core.prefs
|
||||
|
@ -1456,13 +1456,14 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
|
||||
pamControlledUnits.get(iU).pamHasStopped();
|
||||
}
|
||||
guiFrameManager.pamEnded();
|
||||
|
||||
long stopTime = PamCalendar.getTimeInMillis();
|
||||
saveEndSettings(stopTime);
|
||||
|
||||
setPamStatus(PAM_IDLE);
|
||||
|
||||
guiFrameManager.pamEnded();
|
||||
|
||||
// no good having this here since it get's called at the end of every file.
|
||||
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
|
||||
//// can exit here, since we've auto started, can auto exit.
|
||||
|
@ -31,12 +31,12 @@ public class PamguardVersionInfo {
|
||||
* Version number, major version.minorversion.sub-release.
|
||||
* Note: can't go higher than sub-release 'f'
|
||||
*/
|
||||
static public final String version = "2.02.10bd";
|
||||
static public final String version = "2.02.11c";
|
||||
|
||||
/**
|
||||
* Release date
|
||||
*/
|
||||
static public final String date = "23 April 2024";
|
||||
static public final String date = "29 April 2024";
|
||||
|
||||
// /**
|
||||
// * Release type - Beta or Core
|
||||
|
@ -583,6 +583,28 @@ public class PamguardXMLWriter implements PamSettings {
|
||||
// }
|
||||
return el;
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to use a modified function here since some of Jamies DL params
|
||||
* classes cast to their own type before the have checked type in the
|
||||
* equals functoins he's written.
|
||||
* @param objectHierarchy
|
||||
* @return
|
||||
*/
|
||||
private boolean hasData(ArrayList<Object> objectHierarchy, Object object) {
|
||||
if (objectHierarchy == null) {
|
||||
return false;
|
||||
}
|
||||
for (Object o : objectHierarchy) {
|
||||
if (object.getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (o.equals(object)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Element writeObjectData(Document doc, Element el, Object data, ArrayList<Object> objectHierarchy) {
|
||||
if (data == null) {
|
||||
@ -591,7 +613,7 @@ public class PamguardXMLWriter implements PamSettings {
|
||||
if (objectHierarchy == null) {
|
||||
objectHierarchy = new ArrayList<>();
|
||||
}
|
||||
if (objectHierarchy.contains(data)) {
|
||||
if (hasData(objectHierarchy, data)) {
|
||||
// just write the reference, but nothing else or we'll end up in an infinite loop of objects.
|
||||
Element e = doc.createElement("Object");
|
||||
e.setAttribute("Class", data.getClass().getName());
|
||||
@ -794,6 +816,8 @@ public class PamguardXMLWriter implements PamSettings {
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error in PamguardXMLWriter.writeObjectArray: " + e.getMessage());
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ final public class PamModel implements PamSettings {
|
||||
mi.setModulesMenuGroup(utilitiesGroup);
|
||||
mi.setMaxNumber(1);
|
||||
//mi.addGUICompatabilityFlag(PamGUIManager.FX); //has FX enabled GUI.
|
||||
mi.setHidden(SMRUEnable.isEnable() == false);
|
||||
// mi.setHidden(SMRUEnable.isEnable() == false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -189,11 +189,11 @@ public class OfflineDataLoading<T extends PamDataUnit> {
|
||||
switch (offlineDataInfo.getInterrupt()) {
|
||||
case OFFLINE_DATA_INTERRUPT:
|
||||
// System.out.println("Request order cancelling");
|
||||
|
||||
int giveUp = 0;
|
||||
|
||||
if (orderData.cancelOrder()) {
|
||||
|
||||
while (orderData!=null || !orderData.isDone()) {
|
||||
while ((orderData!=null || !orderData.isDone()) & giveUp++ < 300) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -7,22 +7,19 @@ import java.io.Serializable;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import KernelSmoothing.KernelSmoothingProcess;
|
||||
import PamController.PamControlledUnit;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.PamControllerInterface;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamUtils.PamUtils;
|
||||
import PamView.GroupedDataSource;
|
||||
import PamView.GroupedSourceParameters;
|
||||
import PamView.dialog.GroupedSourcePanel;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.ProcessAnnotation;
|
||||
import RightWhaleEdgeDetector.graphics.RWEDataPlotProviderFX;
|
||||
import dataPlotsFX.data.TDDataProviderRegisterFX;
|
||||
|
||||
/**
|
||||
* Exact implementation of the 2003 Right Whale detector I developed when I was
|
||||
@ -43,6 +40,7 @@ public class RWEControl extends PamControlledUnit implements PamSettings {
|
||||
super("RW Edge Detector", unitName);
|
||||
rweProcess = new RWEProcess(this);
|
||||
addPamProcess(rweProcess);
|
||||
|
||||
PamSettingManager.getInstance().registerSettings(this);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliser;
|
||||
import Localiser.algorithms.timeDelayLocalisers.bearingLoc.BearingLocaliserSelector;
|
||||
import annotation.calcs.snr.SNRAnnotationType;
|
||||
import autecPhones.AutecGraphics;
|
||||
import dataPlotsFX.data.TDDataProviderRegisterFX;
|
||||
import fftManager.Complex;
|
||||
import fftManager.FFTDataBlock;
|
||||
import fftManager.FFTDataUnit;
|
||||
@ -33,6 +34,7 @@ import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.PamObservable;
|
||||
import PamguardMVC.PamProcess;
|
||||
import PamguardMVC.debug.Debug;
|
||||
import RightWhaleEdgeDetector.graphics.RWEDataPlotProviderFX;
|
||||
import RightWhaleEdgeDetector.graphics.RWESymbolManager;
|
||||
|
||||
public class RWEProcess extends PamProcess {
|
||||
@ -53,6 +55,7 @@ public class RWEProcess extends PamProcess {
|
||||
*/
|
||||
private boolean isPreSmoothed;
|
||||
private KernelSmoothing kernelSmoothing;
|
||||
private RWEDataPlotProviderFX fxPlotProvider;
|
||||
|
||||
public RWEProcess(RWEControl rweControl) {
|
||||
super(rweControl, null);
|
||||
@ -71,6 +74,9 @@ public class RWEProcess extends PamProcess {
|
||||
rweDataBlock.setCanClipGenerate(true);
|
||||
rweDataBlock.SetLogging(new RWESQLLogging(rweControl, rweDataBlock));
|
||||
rweDataBlock.addDataAnnotationType(new SNRAnnotationType());
|
||||
|
||||
fxPlotProvider = new RWEDataPlotProviderFX(this, rweDataBlock);
|
||||
TDDataProviderRegisterFX.getInstance().registerDataInfo(fxPlotProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -262,7 +268,7 @@ public class RWEProcess extends PamProcess {
|
||||
backgroundData[i] += (magData[i]-backgroundData[i])/updateConstant[0];
|
||||
}
|
||||
if (Double.isNaN(backgroundData[i]) || Double.isInfinite(backgroundData[i])) {
|
||||
System.out.println(String.format("Bad bg data slice %d = %3.5f", i, backgroundData[i]));
|
||||
// System.out.println(String.format("Bad bg data slice %d = %3.5f", i, backgroundData[i]));
|
||||
backgroundData[i] = magData[i] * 10.;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package RightWhaleEdgeDetector.graphics;
|
||||
|
||||
import RightWhaleEdgeDetector.RWEDataBlock;
|
||||
import RightWhaleEdgeDetector.RWEProcess;
|
||||
import dataPlotsFX.data.TDDataInfoFX;
|
||||
import dataPlotsFX.data.TDDataProviderFX;
|
||||
import dataPlotsFX.layout.TDGraphFX;
|
||||
|
||||
public class RWEDataPlotProviderFX extends TDDataProviderFX {
|
||||
|
||||
private RWEDataBlock rweDataBlock;
|
||||
private RWEProcess rweProcess;
|
||||
|
||||
public RWEDataPlotProviderFX(RWEProcess rweProcess, RWEDataBlock rweDataBlock) {
|
||||
super(rweDataBlock);
|
||||
this.rweProcess = rweProcess;
|
||||
this.rweDataBlock = rweDataBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TDDataInfoFX createDataInfo(TDGraphFX tdGraph) {
|
||||
return new RWEDataPlotinfoFX(this, rweProcess, tdGraph, rweDataBlock);
|
||||
}
|
||||
|
||||
}
|
168
src/RightWhaleEdgeDetector/graphics/RWEDataPlotinfoFX.java
Normal file
168
src/RightWhaleEdgeDetector/graphics/RWEDataPlotinfoFX.java
Normal file
@ -0,0 +1,168 @@
|
||||
package RightWhaleEdgeDetector.graphics;
|
||||
|
||||
import PamUtils.Coordinate3d;
|
||||
import PamView.GeneralProjector.ParameterType;
|
||||
import PamView.GeneralProjector.ParameterUnits;
|
||||
import PamView.symbol.PamSymbolChooser;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import RightWhaleEdgeDetector.RWEDataBlock;
|
||||
import RightWhaleEdgeDetector.RWEDataUnit;
|
||||
import RightWhaleEdgeDetector.RWEProcess;
|
||||
import RightWhaleEdgeDetector.RWESound;
|
||||
import dataPlots.data.TDSymbolChooser;
|
||||
import dataPlotsFX.SimpleSymbolChooserFX;
|
||||
import dataPlotsFX.TDSymbolChooserFX;
|
||||
import dataPlotsFX.data.TDDataInfoFX;
|
||||
import dataPlotsFX.data.TDScaleInfo;
|
||||
import dataPlotsFX.data.generic.GenericDataPlotInfo;
|
||||
import dataPlotsFX.data.generic.GenericSettingsPane;
|
||||
import dataPlotsFX.layout.TDGraphFX;
|
||||
import dataPlotsFX.layout.TDSettingsPane;
|
||||
import dataPlotsFX.projector.TDProjectorFX;
|
||||
import fftManager.FFTDataBlock;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import pamViewFX.fxNodes.PamSymbolFX;
|
||||
|
||||
public class RWEDataPlotinfoFX extends GenericDataPlotInfo {
|
||||
|
||||
private RWEDataBlock rweDataBlock;
|
||||
private TDScaleInfo bearingScaleInfo;
|
||||
private TDScaleInfo frequencyInfo;
|
||||
private RWEProcess rweProcess;
|
||||
|
||||
// private SimpleSymbolChooserFX symbolChooser = new SimpleSymbolChooserFX();
|
||||
private GenericSettingsPane settingsPane;
|
||||
|
||||
public RWEDataPlotinfoFX(RWEDataPlotProviderFX tdDataProvider, RWEProcess rweProcess, TDGraphFX tdGraph, RWEDataBlock rweDataBlock) {
|
||||
super(tdDataProvider, tdGraph, rweDataBlock);
|
||||
this.rweProcess = rweProcess;
|
||||
this.rweDataBlock = rweDataBlock;
|
||||
|
||||
bearingScaleInfo = new TDScaleInfo(0,180, ParameterType.BEARING, ParameterUnits.DEGREES);
|
||||
bearingScaleInfo.setReverseAxis(true); //set the axis to be reverse so 0 is at top of graph
|
||||
frequencyInfo = new TDScaleInfo(0, 1, ParameterType.FREQUENCY, ParameterUnits.HZ);
|
||||
this.getScaleInfos().add(bearingScaleInfo);
|
||||
this.getScaleInfos().add(frequencyInfo);
|
||||
|
||||
//set correct frequency range based on nyquist.
|
||||
frequencyInfo.setMaxVal(rweDataBlock.getSampleRate()/2.);
|
||||
|
||||
|
||||
settingsPane = new GenericSettingsPane(this);
|
||||
settingsPane.setShowingName("Right Whale");
|
||||
// settingsPane.setIcon(tdGraph)
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDataValue(PamDataUnit pamDataUnit) {
|
||||
if (pamDataUnit.getLocalisation() == null) {
|
||||
return null;
|
||||
}
|
||||
double[] angles = pamDataUnit.getLocalisation().getAngles();
|
||||
if (angles != null && angles.length > 0) {
|
||||
return Math.toDegrees(angles[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TDScaleInfo getScaleInfo() {
|
||||
|
||||
setNPlotPanes(frequencyInfo, this.getDataBlock(), false);
|
||||
|
||||
double min = Math.min(bearingScaleInfo.getMinVal(), bearingScaleInfo.getMaxVal());
|
||||
double max = Math.max(bearingScaleInfo.getMinVal(), bearingScaleInfo.getMaxVal());
|
||||
|
||||
bearingScaleInfo.setMaxVal(max);
|
||||
bearingScaleInfo.setMinVal(min);
|
||||
|
||||
return super.getScaleInfo();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public TDSymbolChooserFX getSymbolChooser() {
|
||||
// return symbolChooser;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Polygon drawDataUnit(int plotNumber, PamDataUnit pamDataUnit, GraphicsContext g, double scrollStart, TDProjectorFX tdProjector,int type) {
|
||||
// if drawing FFT then need to use slight more complex drawing functions.
|
||||
if (getScaleInfoIndex()==3) {
|
||||
return drawRWContour(plotNumber, pamDataUnit, g, scrollStart, tdProjector, type);
|
||||
}
|
||||
else {
|
||||
return super.drawDataUnit(plotNumber, pamDataUnit, g, scrollStart, tdProjector ,type);
|
||||
}
|
||||
// return null;
|
||||
}
|
||||
|
||||
private Polygon drawRWContour(int plotNumber, PamDataUnit pamDataUnit, GraphicsContext g, double scrollStart,
|
||||
TDProjectorFX tdProjector, int type) {
|
||||
if (!shouldDraw(plotNumber, pamDataUnit)){
|
||||
//System.out.println("Cannot plot whistle");
|
||||
// iCol++;
|
||||
return null;
|
||||
}
|
||||
RWEDataUnit rweDataUnit = (RWEDataUnit) pamDataUnit;
|
||||
RWESound rweSound = rweDataUnit.rweSound;
|
||||
int[] hf = rweSound.highFreq;
|
||||
int[] lf = rweSound.lowFreq;
|
||||
int[] pf = rweSound.peakFreq;
|
||||
|
||||
FFTDataBlock dataSource = (FFTDataBlock) rweProcess.getParentDataBlock();
|
||||
if (dataSource == null) {
|
||||
return null;
|
||||
}
|
||||
double fs = dataSource.getSampleRate();
|
||||
int fftLen = dataSource.getFftLength();
|
||||
int fftHop = dataSource.getFftHop();
|
||||
|
||||
TDSymbolChooserFX symbols = getSymbolChooser();
|
||||
if (symbols != null) {
|
||||
PamSymbolFX symbFX = symbols.getPamSymbol(rweDataUnit, TDSymbolChooser.NORMAL_SYMBOL);
|
||||
if (symbFX != null) {
|
||||
g.setStroke(symbFX.getLineColor());
|
||||
// g.setStroke(Color.ALICEBLUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Polygon outer = new Poly
|
||||
int nOut = hf.length*2;
|
||||
double[] outsideX = new double[nOut];
|
||||
double[] outsideY = new double[nOut];
|
||||
for (int i = 0; i < hf.length; i++) {
|
||||
long t = (long) (i*1000*fftHop/fs)+rweDataUnit.getTimeMilliseconds();
|
||||
double f = lf[i]*fs/fftLen;
|
||||
double tdPix = tdProjector.getTimePix(t-scrollStart);
|
||||
double fPix = tdProjector.getYPix(f);
|
||||
// Coordinate3d coord = tdProjector.getCoord3d(i, t, f);
|
||||
outsideX[i] = tdPix;
|
||||
outsideY[i] = fPix;
|
||||
|
||||
f = hf[i]*fs/fftLen;
|
||||
// coord = tdProjector.getCoord3d(i, t, f);
|
||||
fPix = tdProjector.getYPix(f);
|
||||
outsideX[nOut-1-i] = tdPix;
|
||||
outsideY[nOut-1-i] = fPix;
|
||||
|
||||
}
|
||||
g.strokePolygon(outsideX, outsideY, nOut);
|
||||
double topX = outsideX[hf.length];
|
||||
double topY = outsideY[hf.length];
|
||||
String txt = String.format("%d", rweSound.soundType);
|
||||
g.strokeText(txt, topX, topY);
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TDSettingsPane getGraphSettingsPane() {
|
||||
if (settingsPane == null) {
|
||||
}
|
||||
return settingsPane;
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane
|
||||
/*
|
||||
* The raw clip info.
|
||||
*/
|
||||
private TDDataInfoFX rawClipDataInfo;
|
||||
private TDDataInfoFX tdDataInfoFX;
|
||||
|
||||
/**
|
||||
* The icon for the pane.
|
||||
@ -52,8 +52,8 @@ public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane
|
||||
/**
|
||||
* The clip plot pane.
|
||||
*/
|
||||
public GenericSettingsPane(TDDataInfoFX rawClipDataInfo){
|
||||
this.rawClipDataInfo = rawClipDataInfo;
|
||||
public GenericSettingsPane(TDDataInfoFX tdDataInfoFX){
|
||||
this.tdDataInfoFX = tdDataInfoFX;
|
||||
createPane();
|
||||
this.setPrefWidth(PREF_WIDTH);
|
||||
setParams();
|
||||
@ -81,7 +81,7 @@ public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane
|
||||
private void newSettings(long milliswait) {
|
||||
getParams();
|
||||
|
||||
this.rawClipDataInfo.getTDGraph().repaint(milliswait);
|
||||
this.tdDataInfoFX.getTDGraph().repaint(milliswait);
|
||||
}
|
||||
|
||||
|
||||
@ -112,10 +112,10 @@ public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane
|
||||
*/
|
||||
private StandardSymbolOptionsPane createSymbolOptionsPane(){
|
||||
|
||||
PamSymbolManager<?> pamSymbolManager= rawClipDataInfo.getDataBlock().getPamSymbolManager();
|
||||
PamSymbolManager<?> pamSymbolManager= tdDataInfoFX.getDataBlock().getPamSymbolManager();
|
||||
|
||||
symbolOptionsPane= pamSymbolManager.getFXOptionsPane(rawClipDataInfo.getTDGraph().getUniqueName(),
|
||||
rawClipDataInfo.getTDGraph().getGraphProjector());
|
||||
symbolOptionsPane= pamSymbolManager.getFXOptionsPane(tdDataInfoFX.getTDGraph().getUniqueName(),
|
||||
tdDataInfoFX.getTDGraph().getGraphProjector());
|
||||
|
||||
//create a new settings listener
|
||||
symbolOptionsPane.addSettingsListener(()->{
|
||||
|
@ -348,6 +348,7 @@ public class DLControl extends PamControlledUnit implements PamSettings {
|
||||
|
||||
this.segmenterProcess.setupSegmenter();
|
||||
this.dlClassifyProcess.setupProcess();
|
||||
this.checkModelParams();
|
||||
|
||||
// this is a bit of a hack. Annotations are added to data units but the
|
||||
// datablock knows nothing about them
|
||||
@ -514,6 +515,34 @@ public class DLControl extends PamControlledUnit implements PamSettings {
|
||||
|
||||
public void setParams(RawDLParams newParams) {
|
||||
this.rawDLParmas = newParams;
|
||||
checkModelParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when setParams is called, which should have new model params
|
||||
* after the dialog was closed. Puts these into dlParams so they get serialised
|
||||
* with rest of XML.
|
||||
*/
|
||||
public void checkModelParams() {
|
||||
RawDLParams dlParams = getDLParams();
|
||||
DLClassiferModel model = getDLModel();
|
||||
Serializable modelParams = null;
|
||||
if (model != null) {
|
||||
modelParams = model.getDLModelSettings();
|
||||
}
|
||||
dlParams.setModelParameters(modelParams);
|
||||
|
||||
// see what else we can find in the model in terms of metadata.
|
||||
// if (model == null) {
|
||||
// return;
|
||||
// }
|
||||
// try {
|
||||
// String modelName = model.getName();
|
||||
// System.out.println("Model name: " + modelName);
|
||||
// }
|
||||
// catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,6 +100,8 @@ public class RawDLParams implements Serializable, Cloneable {
|
||||
*/
|
||||
public short classNameIndex = 0;
|
||||
|
||||
private Serializable modelParameters;
|
||||
|
||||
@Override
|
||||
public RawDLParams clone() {
|
||||
RawDLParams newParams = null;
|
||||
@ -118,4 +120,22 @@ public class RawDLParams implements Serializable, Cloneable {
|
||||
return newParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model parameters. These aren't really needed in here are aren't really
|
||||
* used except when the parameters are serialized to XML for book keeping.
|
||||
* @param modelParameters
|
||||
*/
|
||||
public Serializable getModelParameters() {
|
||||
return modelParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model parameters. These aren't really needed in here are aren't really
|
||||
* used except when the parameters are serialized to XML for book keeping.
|
||||
* @param modelParameters the modelParameters to set
|
||||
*/
|
||||
public void setModelParameters(Serializable modelParameters) {
|
||||
this.modelParameters = modelParameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -536,6 +536,39 @@ public class DLClassifyProcess extends PamInstantProcess {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the result with the highest score.
|
||||
* @return model result with the highest score.
|
||||
*/
|
||||
public PredictionResult getBestModelResult(DLDetection dlDetection) {
|
||||
ArrayList<PredictionResult> results = dlDetection.getModelResults();
|
||||
if (results == null || results.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
* probably need to improve this function to only look at results
|
||||
* that are in a list of used results or something crazy ?
|
||||
*/
|
||||
|
||||
// dlControl.getDLModel().;
|
||||
PredictionResult bestResult = null;
|
||||
float bestScore = 0;
|
||||
for (PredictionResult pred : results) {
|
||||
float[] scores = pred.getPrediction();
|
||||
if (scores == null) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < scores.length; i++) {
|
||||
if (scores[i] > bestScore) {
|
||||
bestScore = scores[i];
|
||||
bestResult = pred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the data unit buffer.
|
||||
*/
|
||||
@ -645,4 +678,8 @@ public class DLClassifyProcess extends PamInstantProcess {
|
||||
return this.dlControl.getDLParams();
|
||||
}
|
||||
|
||||
public DLControl getDLControl() {
|
||||
return dlControl;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -132,7 +132,6 @@ public class DLDetection extends PamDataUnit implements PamDetection, RawDataHol
|
||||
if (annotation!=null) return annotation.getModelResults();
|
||||
else return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,12 @@ package rawDeepLearningClassifier.dlClassification;
|
||||
import PamView.GroupedDataSource;
|
||||
import PamView.GroupedSourceParameters;
|
||||
import PamguardMVC.AcousticDataBlock;
|
||||
import rawDeepLearningClassifier.DLControl;
|
||||
import rawDeepLearningClassifier.tethys.DLSpeciesManager;
|
||||
import rawDeepLearningClassifier.tethys.DLTethysDataProvider;
|
||||
import tethys.TethysControl;
|
||||
import tethys.pamdata.TethysDataProvider;
|
||||
import tethys.species.DataBlockSpeciesManager;
|
||||
|
||||
/**
|
||||
* Holds classified data units from deep learning model.
|
||||
@ -13,10 +19,14 @@ import PamguardMVC.AcousticDataBlock;
|
||||
public class DLDetectionDataBlock extends AcousticDataBlock<DLDetection> implements GroupedDataSource {
|
||||
|
||||
private DLClassifyProcess dlClassifyProcess;
|
||||
private DLTethysDataProvider dlTethysDataProvider;
|
||||
private DLSpeciesManager dlSpeciesManager;
|
||||
private DLControl dlControl;
|
||||
|
||||
public DLDetectionDataBlock(String dataName, DLClassifyProcess parentProcess, int channelMap) {
|
||||
super(DLDetection.class, dataName, parentProcess, channelMap);
|
||||
this.dlClassifyProcess = parentProcess;
|
||||
dlControl = dlClassifyProcess.getDLControl();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -24,5 +34,21 @@ public class DLDetectionDataBlock extends AcousticDataBlock<DLDetection> impleme
|
||||
return dlClassifyProcess.getDLParams().groupedSourceParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) {
|
||||
if (dlTethysDataProvider == null) {
|
||||
dlTethysDataProvider = new DLTethysDataProvider(tethysControl, dlControl, this);
|
||||
}
|
||||
return dlTethysDataProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBlockSpeciesManager<DLDetection> getDatablockSpeciesManager() {
|
||||
if (dlSpeciesManager == null) {
|
||||
dlSpeciesManager = new DLSpeciesManager(dlClassifyProcess.getDLControl(), this);
|
||||
}
|
||||
return dlSpeciesManager;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -89,6 +89,14 @@ public class GenericModelParams extends StandardModelParams implements Cloneable
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o instanceof GenericModelParams == false) {
|
||||
/*
|
||||
* have to add this since the equals function is used in a list comparason
|
||||
* in the XML output and that list contains objects of different types
|
||||
* so need to get out HERE or get a classcastexception at the next line
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
GenericModelParams params = (GenericModelParams) o;
|
||||
|
||||
|
||||
|
105
src/rawDeepLearningClassifier/tethys/DLSpeciesManager.java
Normal file
105
src/rawDeepLearningClassifier/tethys/DLSpeciesManager.java
Normal file
@ -0,0 +1,105 @@
|
||||
package rawDeepLearningClassifier.tethys;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import PamUtils.PamArrayUtils;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import annotation.DataAnnotation;
|
||||
import rawDeepLearningClassifier.DLControl;
|
||||
import rawDeepLearningClassifier.dlClassification.DLClassName;
|
||||
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
|
||||
import rawDeepLearningClassifier.dlClassification.DLDetection;
|
||||
import rawDeepLearningClassifier.dlClassification.PredictionResult;
|
||||
import rawDeepLearningClassifier.logging.DLAnnotation;
|
||||
import tethys.species.DataBlockSpeciesCodes;
|
||||
import tethys.species.DataBlockSpeciesManager;
|
||||
|
||||
public class DLSpeciesManager extends DataBlockSpeciesManager<DLDetection> {
|
||||
|
||||
private DLControl dlControl;
|
||||
|
||||
private static final String unknown = "Unknown";
|
||||
|
||||
public DLSpeciesManager(DLControl dlControl, PamDataBlock<DLDetection> dataBlock) {
|
||||
super(dataBlock);
|
||||
this.dlControl = dlControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataBlockSpeciesCodes getSpeciesCodes() {
|
||||
DLClassName[] classNames = getClassNames();
|
||||
String[] classStrings = getClassStrings(classNames);
|
||||
return new DataBlockSpeciesCodes(unknown, classStrings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get just the strings of the class names.
|
||||
* @param classNames
|
||||
* @return
|
||||
*/
|
||||
private String[] getClassStrings(DLClassName[] classNames) {
|
||||
if (classNames == null) {
|
||||
return null;
|
||||
}
|
||||
String[] classStrings = new String[classNames.length];
|
||||
for (int i = 0; i < classStrings.length; i++) {
|
||||
classStrings[i] = classNames[i].className;
|
||||
}
|
||||
return classStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of class names, or make a single unknown category.
|
||||
* @return
|
||||
*/
|
||||
private DLClassName[] getClassNames() {
|
||||
DLClassiferModel currentModel = dlControl.getDLModel();
|
||||
DLClassName[] classNames = null;
|
||||
if (currentModel != null) {
|
||||
classNames = currentModel.getClassNames();
|
||||
}
|
||||
if (classNames == null) {
|
||||
classNames = new DLClassName[1];
|
||||
classNames[0] = new DLClassName(unknown, (short) 0);
|
||||
}
|
||||
return classNames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getSpeciesCode(DLDetection dlDetection) {
|
||||
int nAnnot = dlDetection.getNumDataAnnotations();
|
||||
if (nAnnot == 0) {
|
||||
return unknown;
|
||||
}
|
||||
// DataAnnotation annot = dlDetection.getDataAnnotation(0);
|
||||
// ArrayList<PredictionResult> results = null;
|
||||
// if (annot instanceof DLAnnotation) {
|
||||
// DLAnnotation dlAnnot = (DLAnnotation) annot;
|
||||
// results = dlAnnot.getModelResults();
|
||||
// }
|
||||
PredictionResult result = dlControl.getDLClassifyProcess().getBestModelResult(dlDetection);
|
||||
if (result == null) {
|
||||
return unknown;
|
||||
}
|
||||
int resInd = 0;
|
||||
float bestScore = 0;
|
||||
float[] scores = result.getPrediction();
|
||||
if (scores == null || scores.length == 0) {
|
||||
return unknown;
|
||||
}
|
||||
for (int i = 0; i < scores.length; i++) {
|
||||
if (scores[i] > bestScore) {
|
||||
bestScore = scores[i];
|
||||
resInd = i;
|
||||
}
|
||||
}
|
||||
String[] names = getClassStrings(getClassNames());
|
||||
if (resInd < names.length) {
|
||||
return names[resInd];
|
||||
}
|
||||
return unknown;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package rawDeepLearningClassifier.tethys;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import nilus.Detection;
|
||||
import nilus.Detection.Parameters;
|
||||
import rawDeepLearningClassifier.DLControl;
|
||||
import rawDeepLearningClassifier.RawDLParams;
|
||||
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
|
||||
import rawDeepLearningClassifier.dlClassification.DLDetection;
|
||||
import tethys.TethysControl;
|
||||
import tethys.output.StreamExportParams;
|
||||
import tethys.output.TethysExportParams;
|
||||
import tethys.pamdata.AutoTethysProvider;
|
||||
import tethys.pamdata.TethysParameterPacker;
|
||||
|
||||
public class DLTethysDataProvider extends AutoTethysProvider {
|
||||
|
||||
private DLControl dlControl;
|
||||
|
||||
public DLTethysDataProvider(TethysControl tethysControl, DLControl dlControl, PamDataBlock pamDataBlock) {
|
||||
super(tethysControl, pamDataBlock);
|
||||
this.dlControl = dlControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams,
|
||||
StreamExportParams streamExportParams) {
|
||||
Detection detection = super.createDetection(dataUnit, tethysExportParams, streamExportParams);
|
||||
if (detection == null) {
|
||||
return null;
|
||||
}
|
||||
DLDetection dlDetection = (DLDetection) dataUnit;
|
||||
|
||||
// result =
|
||||
String annotSummary = dlDetection.getAnnotationsSummaryString();
|
||||
if (annotSummary != null) {
|
||||
Parameters parameters = detection.getParameters();
|
||||
addUserDefined(parameters, "Annotation", annotSummary);
|
||||
}
|
||||
|
||||
return detection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public nilus.AlgorithmType.Parameters getAlgorithmParameters() {
|
||||
|
||||
/**
|
||||
* Add the model parameters to the main dlControl parameters so that they get
|
||||
* correctly serialized to the XML output
|
||||
// */
|
||||
// RawDLParams dlParams = dlControl.getDLParams();
|
||||
// DLClassiferModel model = dlControl.getDLModel();
|
||||
// Serializable modelParams = null;
|
||||
// if (model != null) {
|
||||
// modelParams = model.getDLModelSettings();
|
||||
// }
|
||||
// dlParams.setModelParameters(modelParams);
|
||||
dlControl.checkModelParams();
|
||||
|
||||
nilus.AlgorithmType.Parameters parameters = super.getAlgorithmParameters();
|
||||
|
||||
return parameters;
|
||||
}
|
||||
}
|
@ -197,15 +197,15 @@ public class DBXMLConnect {
|
||||
marshal.marshal(nilusObject, tempFile.toString());
|
||||
// above lines have made a file. Are now going to gzip it before sending to Tethys
|
||||
File zipFile = null;
|
||||
try {
|
||||
zipFile = zipOutputFile(tempFile);
|
||||
}
|
||||
catch (FileNotFoundException e1){
|
||||
System.out.println(e1.getMessage());
|
||||
}
|
||||
catch (IOException e2) {
|
||||
System.out.println(e2.getMessage());
|
||||
}
|
||||
// try {
|
||||
// zipFile = zipOutputFile(tempFile);
|
||||
// }
|
||||
// catch (FileNotFoundException e1){
|
||||
// System.out.println(e1.getMessage());
|
||||
// }
|
||||
// catch (IOException e2) {
|
||||
// System.out.println(e2.getMessage());
|
||||
// }
|
||||
String finalName;
|
||||
if (zipFile == null) {
|
||||
finalName = bodgeName;
|
||||
|
@ -498,5 +498,12 @@ abstract public class AutoTethysProvider implements TethysDataProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the tethysControl
|
||||
*/
|
||||
public TethysControl getTethysControl() {
|
||||
return tethysControl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user