Updates to FPOD and PAMGuardFX

This commit is contained in:
Jamie Mac 2024-02-07 12:39:13 +00:00
parent e25b945d06
commit 68953d12fb
38 changed files with 890 additions and 375 deletions

View File

@ -1,2 +1,6 @@
eclipse.preferences.version=1
encoding//src/rawDeepLearningClassifer/segmenter/SegmenterProcess.java=UTF-8
encoding//src/test=ISO-8859-1
encoding//src/test/resources=ISO-8859-1
encoding/<project>=ISO-8859-1
encoding/src=ISO-8859-1

22
pom.xml
View File

@ -476,25 +476,23 @@
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>12.2.0</version>
<version>12.3.1</version>
</dependency>
<!-- Ikonli FontAwesome5 font pack https://kordamp.org/ikonli/cheat-sheet-fontawesome5.html -->
<!--
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-fontawesome5-pack</artifactId>
<version>12.2.0</version>
</dependency>
-->
<!-- Ikonli MaterialDesign2 (Latest) font pack https://kordamp.org/ikonli/cheat-sheet-materialdesign2.html -->
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-materialdesign2-pack</artifactId>
<version>12.2.0</version>
<version>12.3.1</version>
</dependency>
<!-- Ikonli File Icons (Latest) font pack https://kordamp.org/ikonli/cheat-sheet-materialdesign2.html -->
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-fileicons-pack</artifactId>
<version>12.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.geographiclib/GeographicLib-Java -->
<dependency>
<groupId>net.sf.geographiclib</groupId>

View File

@ -315,7 +315,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
// need to explicity create a new copy of the double[3] coordinate
// and the double[2] bandwidth
Hydrophone h = (Hydrophone) super.clone();
h.setBandwidth(Arrays.copyOf(getBandwidth(), h.getBandwidth().length));
h.setBandwidth(getBandwidth() == null ? null : Arrays.copyOf(getBandwidth(), h.getBandwidth().length));
h.setCoordinate(Arrays.copyOf(getCoordinates(), 3));
h.setCoordinateErrors(Arrays.copyOf(getCoordinateErrors(), 3));
h.checkDepthInversion();

View File

@ -38,7 +38,10 @@ public class ArrayGUIFX extends PamControlledGUIFX {
@Override
public void updateParams() {
System.out.println("The current array is "+ arrayManager.getCurrentArray());
PamArray newParams=arraySettingsPane.getParams(arrayManager.getCurrentArray());
if (newParams!=null) arrayManager.setCurrentArray(newParams);
//setup the controlled unit.
arrayManager.setupControlledUnit();

View File

@ -346,7 +346,10 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
@Override
public PamArray getParams(PamArray currParams) {
public PamArray getParams(PamArray currParams) {
if (currParams==null) currParams = this.currentArray;
currParams = streamerPane.getParams(currParams);
currParams = hydrophonePane.getParams(currParams);
currParams.setHydrophoneInterpolation(hydrophonePane.getHydrophoneInterp());

View File

@ -309,8 +309,9 @@ public class HydrophonesPane extends PamBorderPane {
}
private HydrophoneProperty createDefaultHydrophoneProperty(int id) {
return new HydrophoneProperty(new Hydrophone(id, defaultx, defaulty,defaultz, defaultxErr, defaultyErr, defaultzErr, defaulttype, defaultsensitivity,
null, 0. ));
Hydrophone hydrophone = new Hydrophone(id, defaultx, defaulty,defaultz, defaultxErr, defaultyErr, defaultzErr, defaulttype, defaultsensitivity,
null, 0. );
return new HydrophoneProperty(hydrophone);
}

View File

@ -682,6 +682,7 @@ public class PamArrayUtils {
* @return the summation of all the elements in the array.
*/
public static double sum(double[][] array2) {
if (array2==null) System.out.println("null");
double sum=0;
double[] array;
for (int i=0; i<array2.length; i++) {
@ -698,6 +699,7 @@ public class PamArrayUtils {
* @param array to print
*/
public static void printArray(double[] array) {
if (array==null) System.out.println("null");
for (int i=0; i<array.length; i++) {
System.out.println(i + ": " + array[i]);
}
@ -709,12 +711,14 @@ public class PamArrayUtils {
* @param array to print
*/
public static void printArrayRaw(double[] array) {
if (array==null) System.out.println("null");
for (int i=0; i<array.length; i++) {
System.out.println(array[i]);
}
}
public static void printArray(int[] array) {
if (array==null) System.out.println("null");
for (int i=0; i<array.length; i++) {
System.out.println(i + ": " + array[i]);
}
@ -725,6 +729,7 @@ public class PamArrayUtils {
* @param array - the array
*/
public static void printArray(double[][] array) {
if (array==null) System.out.println("null");
for (int j=0; j<array.length; j++) {
System.out.println("");
for (int i=0; i<array[j].length; i++) {
@ -741,6 +746,7 @@ public class PamArrayUtils {
* @param array - the array
*/
public static void printArray(int[][] array) {
if (array==null) System.out.println("null");
for (int j=0; j<array.length; j++) {
System.out.println("");
for (int i=0; i<array[j].length; i++) {
@ -750,11 +756,20 @@ public class PamArrayUtils {
System.out.println("");
}
public static void printArray(boolean[] boolArray) {
if (boolArray==null) System.out.println("null");
for (int i=0; i<boolArray.length; i++) {
System.out.println(i + ": " + boolArray[i]);
}
}
/**
* Print a Long array
* @param array - the array to print.
*/
public static void printArray(Long[] array) {
if (array==null) System.out.println("null");
for (int i=0; i<array.length; i++) {
System.out.println(i + ": " + array[i]);
}
@ -1070,6 +1085,9 @@ public class PamArrayUtils {

View File

@ -8,7 +8,7 @@ import PamguardMVC.PamDataUnit;
import PamguardMVC.superdet.SuperDetection;
/**
* CPOD click.
* CPOD or FPOD click.
*/
public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implements AcousticDataUnit {
@ -21,6 +21,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
private long iciSamples;
private short[] rawData;
/**
* The amplitude in dB.
*/
@ -44,6 +45,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
short slope = shortData[8];
CPODClick cpodClick = new CPODClick(baseData.getTimeMilliseconds(), baseData.getStartSample(),
nCyc, bw, kHz, endF, spl, slope, shortData);
// cpodClick.setDurationInMilliseconds(baseData.getMillisecondDuration());
return cpodClick;
}
@ -55,6 +57,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
* @param shortData
* @return
*/
@Deprecated
public static CPODClick makeClick(CPODControl cpodControl, long minuteMillis, short[] shortData) {
int t = shortData[0]<<16 |
@ -76,33 +79,25 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
short endF = shortData[6];
short spl = shortData[7];
short slope = shortData[8];
CPODClick cpodClick = new CPODClick(tMillis, fileSamples, nCyc, bw, kHz, endF, spl, slope, shortData);
// //estimate the duration in millis - not accurate but gives an idea.
// double duration = (nCyc/(double) kHz);
// cpodClick.setDurationInMilliseconds(duration);
return cpodClick;
}
/**
* Create a CPOD click. This is usually called whenever the CPOD click is imported from a CSV file.
*
* @param minuteMillis The time in milliseconds of the minute block preceding the
* current click.
* @param shortData
* @return
* Make a FPOD click. This called whenever click has been imported from a FP1 or FP3 file
* @param tMillis - the time in milliseconds datenum.
* @param fileSamples - the number of samples into the file the CPOD click is at - this is calculated from CPODClickDataBlock.CPOD_SR
* @param shortData - the raw data from the CPOD click. This can be 8 bytes or 30 bytes if a click train clcik
* @return a CPODClick object.
*/
public static CPODClick makeClick(CPODControl2 cpodControl, long minuteMillis, short[] shortData) {
int t = shortData[0]<<16 |
shortData[1]<<8 |
shortData[2]; // 5 microsec intervals !
long tMillis = minuteMillis + t/200;
public static CPODClick makeFPODClick(long tMillis, long fileSamples, short[] shortData) {
// now a bit of time stretching. Need to get the start time and see how
// different this is, then it's a linear stretch.
tMillis = cpodControl.stretchClicktime(tMillis);
// do a sample number within the file as 5us intervals
long fileSamples = t + minuteMillis * 200;
// int micros = t%200;
short nCyc = shortData[3];
short bw = shortData[4];
short kHz = shortData[5];
@ -110,11 +105,42 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
short spl = shortData[7];
short slope = shortData[8];
CPODClick cpodClick = new CPODClick(tMillis, fileSamples, nCyc, bw, kHz, endF, spl, slope, shortData);
return cpodClick;
}
/**
* Make a CPOD click. This called whenever click has been imported from a CP1 or CP3 file
* @param tMillis - the time in milliseconds datenum.
* @param fileSamples - the number of samples into the file the CPOD click is at - this is calculated from CPODClickDataBlock.CPOD_SR
* @param shortData - the raw data from the CPOD click. This can be 8 bytes or 40 bytes if a click train clcik
* @return a CPODClick object.
*/
public static CPODClick makeCPODClick(long tMillis, long fileSamples, short[] shortData) {
short nCyc = shortData[3];
short bw = shortData[4];
short kHz = shortData[5];
short endF = shortData[6];
short spl = shortData[7];
short slope = shortData[8];
CPODClick cpodClick = new CPODClick(tMillis, fileSamples, nCyc, bw, kHz, endF, spl, slope, shortData);
// //estimate the duration in millis - not accurate but gives an idea.
double duration = (nCyc/(double) kHz);
cpodClick.setDurationInMilliseconds(duration);
//TODO
//add classification info.
return cpodClick;
}
/**
* Constructor for a CPOD click.
* Constructor for a CPOD click. This adds all basic information that is required for a CPOD or FPOD click
* @param tMillis - the time in millis.
* @param fileSamples - the file samples
* @param nCyc - the number of cycles
@ -135,13 +161,14 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
this.spl = spl;
this.slope = slope;
double[] f = new double[2];
f[0] = Math.min(kHz, endF)*1000;
f[1] = Math.max(kHz, endF)*1000;
f[0] = (kHz - bw/2.)*1000.;
f[1] = (kHz + bw/2.)*1000.;
setFrequency(f);
//estimate the duration in millis - not accurate but gives an idea.
double duration = (nCyc/(double) kHz);
this.setDurationInMilliseconds(duration);
setDurationInMilliseconds(duration);
if (shortData!=null) {
//only CPOD
@ -260,6 +287,7 @@ public class CPODClick extends PamDataUnit<PamDataUnit,SuperDetection> implement
}
return amplitudedB;
}
/* (non-Javadoc)
* @see PamDetection.AcousticDataUnit#getSummaryString()

View File

@ -30,7 +30,8 @@ import PamguardMVC.dataOffline.OfflineDataLoadInfo;
* @author Doug Gillespie
* @author Jamie Macaulay
*
*/
*/
@Deprecated
public class CPODControl extends OfflineFileControl implements PamSettings {
private CPODClickDataBlock cp1DataBlock, cp3DataBlock;

View File

@ -27,7 +27,7 @@ import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
/**
* CPOD control. Loads and manages CPOD and FPOD data into
* PAMGaurd.
*PAMGaurd.
* <p>
* Note that this module (CPODControl) originally used a folder of CP1 files as it's file store but
* this version now converts CP1/CP3 etc. into binary files instead in order to integrate into PAMGuard's
@ -38,8 +38,6 @@ import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
*/
public class CPODControl2 extends PamControlledUnit implements PamSettings {
private static final float CPOD_SAMPLE_RATE = 200000;
private CPODClickDataBlock cp1DataBlock, cp3DataBlock;
/**
@ -111,7 +109,7 @@ public class CPODControl2 extends PamControlledUnit implements PamSettings {
cp3DataBlock.setOverlayDraw(new PamDetectionOverlayGraphics(cp3DataBlock, new PamSymbol()));
PamSettingManager.getInstance().registerSettings(this);
cpodProcess.setSampleRate(CPOD_SAMPLE_RATE, false);
cpodProcess.setSampleRate(CPODClickDataBlock.CPOD_SR, false);
cpodImporter = new CPODImporter(this);

View File

@ -24,7 +24,17 @@ public class CPODDataGramProvider implements DatagramProvider {
@Override
public int addDatagramData(PamDataUnit dataUnit, float[] dataGramLine) {
CPODClick cpodClick = (CPODClick) dataUnit;
dataGramLine[cpodClick.getkHz()] ++;
int minKhz = cpodClick.getkHz()- cpodClick.getBw()/2;
int maxkHz = cpodClick.getkHz()- cpodClick.getBw()/2;
//each datagram line is a 1kHz bin
for (int i=0; i<dataGramLine.length; i++) {
if(i>=minKhz && i<=maxkHz) {
dataGramLine[i] ++;
}
}
// dataGramLine[cpodClick.getkHz()] ++;
return 1;
}

View File

@ -17,6 +17,7 @@ import java.util.concurrent.Executors;
import org.apache.commons.io.FilenameUtils;
import PamController.PamController;
import PamUtils.PamArrayUtils;
import PamUtils.PamCalendar;
import PamView.dialog.warn.WarnOnce;
import binaryFileStorage.BinaryDataSource;
@ -251,12 +252,22 @@ public class CPODImporter {
data[7]=spl;
data[8]=slope;
//these are the basic data
CPODClick cpodClick = new CPODClick(fpoDdata.getTimeMillis(),
fileSamples, nCyc, bw,
kHz, endF, spl, slope, data);
if (fpoDdata.HasWave) {
int[] waveform = FPODReader.makeResampledWaveform(fpoDdata);
System.out.println("FPOD click waveform: " + kHz);
PamArrayUtils.printArray(waveform);
}
// cpodClick.setDurationInMilliseconds((fpoDdata.duration*5.)/1000.);
//does the click have a waveform?
//TODO
return cpodClick;
}
@ -345,10 +356,25 @@ public class CPODImporter {
private CPODClick processClick(int nMinutes, short[] shortData) {
long minuteMillis = fileStart + nMinutes * 60000L;
int t = shortData[0]<<16 |
shortData[1]<<8 |
shortData[2]; // 5 microsec intervals !
long tMillis = minuteMillis + t/200;
// now a bit of time stretching. Need to get the start time and see how
// different this is, then it's a linear stretch.
tMillis = cpodControl.stretchClicktime(tMillis);
// do a sample number within the file as 5us intervals
long fileSamples = t + minuteMillis * 200;
/*
*
*/
return CPODClick.makeClick(cpodControl, fileStart + nMinutes * 60000L, shortData);
return CPODClick.makeCPODClick(tMillis, fileSamples, shortData);
}

View File

@ -17,6 +17,7 @@ import fileOfflineData.OfflineFileMapPoint;
* @author Doug Gillespie
*
*/
@Deprecated
public class CPODLoader {
private CPODControl cpodControl;

View File

@ -9,17 +9,38 @@ import java.util.ArrayList;
/**
* Functions for importing FPOD files. Noe this class is independent of any PAMGuard functionality.
* Functions for importing FPOD files.
* <p>
* Note this class should be independent of any PAMGuard functionality.
* <p>
* Although some anming has changed a lot of the variable names are consistent with Pascal code
* used in FPOD.exe software from whihc this is absed.
*
* @author Jamie Macaulay
*/
public class FPODReader {
/**
* Look up array to convert byte values to linear sound level
*/
private static int[] LinearPkValsArr;
/**
* Look up array to convert byte values to linear sound level if using extended amps.
*/
private static int[][] ClippedPkArr;
/**
* Look up sine array fro reconstructing waveforms.
*/
private static double[] SineArr = new double[2000];
/**
* Look up sine array for converting IPI (inter-pulse-interval) to kHz values
*/
private static int[] IPItoKHZ = new int[257];
/**
* Length of the FPOD header in bytes.
*/
@ -37,6 +58,7 @@ public class FPODReader {
*/
private static final int FP3_FPOD_DATA_LEN = 32;
/**
* Import an FPOD file.
* @param cpFile - the FP1 file.
@ -48,6 +70,7 @@ public class FPODReader {
public static int importFile(File cpFile, ArrayList<FPODdata> fpodData, int from, int maxNum ) throws IOException {
populateRawToRealPkArrays();
populateIPIArray();
BufferedInputStream bis = null;
int bytesRead;
@ -175,7 +198,8 @@ public class FPODReader {
fpodClick.EndIPI = bufPosN[15] & 254 + 1; // + 1 on all IPIs because counts from the POD start at
}
fpodClick.duration = ((bufPosN[13] & 240) << 4 | bufPosN[14]);
//the duration is in 5us units.
fpodClick.duration = ((bufPosN[13] & 240)*16 + toUnsigned(bufPosN[14]));
///rm...can't exactly explain this but it's translated from FPOD Pascal code - calculates bandwidth
int ampDfSum = Math.abs(fpodClick.Pkminus1Extnd - fpodClick.MaxPkRaw);
@ -233,7 +257,7 @@ public class FPODReader {
if (nClicks%100000==0) {
System.out.println("Pod data: " + nClicks + " " +fpodClick.getTimeMillis() + " " +fpodClick.dataString());
System.out.println("Pod data: " + nClicks + " " +fpodClick.getTimeMillis() + " " +fpodClick.dataString() + " " +toUnsigned(bufPosN[13]) + " " + toUnsigned(bufPosN[14]));
}
@ -377,7 +401,24 @@ public class FPODReader {
* @return the kHz value
*/
public static int IPItoKhz(int IPI) {
return 4000/IPI;
return IPItoKHZ[IPI];
}
/**
* Ppulate the IPI array
*/
public static void populateIPIArray() {
for (int count = 0; count < 16; count++) {
IPItoKHZ[count] = 255;
}
for (int count = 16; count < 256; count++) {
IPItoKHZ[count] = Math.round(4000 / count);
}
IPItoKHZ[64] = 63; // Smoothes an uncomfortable step here
IPItoKHZ[256] = 1; // An 'indicative' value
}
@ -883,7 +924,7 @@ public class FPODReader {
/**
* Holds FPOD wav data. Note this is not actually wav data
* but the amplitue and inter pule interval of successive peaks
* but the amplitude and inter pulse interval of successive peaks
* in the waveform.
*/
public static class FPODWavData {
@ -1068,14 +1109,92 @@ public class FPODReader {
}
public static void BuildSineArray() {
final double constPiFrac = Math.PI / 1000;
double S;
for (int count = 0; count < 2000; count++) {
S = Math.sin(constPiFrac * count);
SineArr[count] = S;
}
}
/**
* Reconstructs sinusoidal waveform from the peaks which have been sampled at 4MHz
*
* @param click - FPOD click with waveform information.
*/
public static int[] makeResampledWaveform(FPODdata click) {
if (SineArr==null) {
BuildSineArray();
}
int[] MhzSampledArr = new int[23];
int count, cyc, SinePtsPerUs, SinePtr, FirstClkCyc, IPIsum, NewIPIx, OldIPIx;
// MhzSampledArr initialization (assuming it's an array)
// Read back from end of WavIPIarr to find start of continuous sound data
int RawStartPtr = 21;
while (RawStartPtr > 0 && click.getWavData().getWavValsIPI()[RawStartPtr] < 255) {
click.getWavData().getWavValsSPL()[RawStartPtr] = (short) LinearPkValsArr[click.getWavData().getWavValsSPL()[RawStartPtr]];
RawStartPtr--;
}
RawStartPtr = Math.min(21, RawStartPtr + 1);
FirstClkCyc = 21 - click.Ncyc;
// Construct each cycle in MhzSampledArr
SinePtr = 0;
int MHzArrPtr = 0;
int MaxSPLval = 0;
IPIsum = 0;
cyc = RawStartPtr;
do {
// Populate MhzSampledArr
SinePtsPerUs = Math.round(4000 / click.getWavData().getWavValsIPI()[cyc]);
do {
MhzSampledArr[MHzArrPtr] = (int) Math.round(SineArr[SinePtr] * click.getWavData().getWavValsSPL()[cyc]);
MHzArrPtr++;
SinePtr += SinePtsPerUs;
} while (SinePtr <= 1999 && MHzArrPtr < MhzSampledArr.length);
if (MHzArrPtr >= MhzSampledArr.length) {
break; // Fix: extend this array if needed
}
SinePtr -= 2000;
if (cyc == FirstClkCyc) {
int StartOfClickHighRes = MHzArrPtr;
}
IPIsum += click.getWavData().getWavValsIPI()[cyc];
cyc++;
} while (cyc < 22);
// Bring line up to zero
if (MHzArrPtr < MhzSampledArr.length) {
MhzSampledArr[MHzArrPtr] = 0;
}
return MhzSampledArr;
}
/**
* Test the program
* @param args
*/
public static void main(String[] args) {
String filePath = "/Users/au671271/Library/CloudStorage/GoogleDrive-macster110@gmail.com/My Drive/PAMGuard_dev/CPOD/FPOD_NunBank/0866 NunBankB 2023 06 27 FPOD_6480 file0.FP1";
// String filePath = "/Users/au671271/Library/CloudStorage/GoogleDrive-macster110@gmail.com/My Drive/PAMGuard_dev/CPOD/FPOD_NunBank/0866 NunBankB 2023 06 27 FPOD_6480 file0.FP1";
String filePath = "D:\\My Drive\\PAMGuard_dev\\CPOD\\FPOD_NunBank\\0866 NunBankB 2023 06 27 FPOD_6480 file0.FP1";
File fpfile = new File(filePath);
ArrayList<FPODdata> fpodData = new ArrayList<FPODdata>();

View File

@ -3,6 +3,7 @@ package cpod.dataPlotFX;
import java.awt.geom.Path2D;
import PamController.PamControlledUnit;
import PamUtils.PamArrayUtils;
import PamUtils.PamUtils;
import PamView.HoverData;
import PamView.GeneralProjector.ParameterType;
@ -124,45 +125,98 @@ public class CPODPlotInfoFX extends GenericDataPlotInfo {
public Polygon drawDataUnit(int plotNumber, PamDataUnit pamDataUnit, GraphicsContext g, double scrollStart, TDProjectorFX tdProjector, int type) {
// if (getScaleInfoIndex()==getScaleInfos().indexOf(frequencyInfo)) drawClickFFT( plotNumber, pamDataUnit,g , scrollStart, tdProjector, type);
//System.out.println("ClickPlotInfo: Draw data unit: " + pamDataUnit.getUID());
//draw special data units.
Path2D path2D = null;
ParameterType paramType = getCurrentScaleInfo().getDataType();
// if (getScaleInfoIndex()==getScaleInfos().indexOf(stemScaleInfo))
if (getCurrentScaleInfo().getDataType() == ParameterType.AMPLITUDE_STEM){
//draw on a stem plot.
switch (getCurrentScaleInfo().getDataType()) {
case AMPLITUDE_STEM:
case NCYCLES:
case AMPLITUDE_LIN:
case BANDWIDTH:
case FREQUENCY:
path2D = drawStemClick( plotNumber, pamDataUnit,g , scrollStart, tdProjector, type, paramType);
break;
default:
return super.drawDataUnit(plotNumber, pamDataUnit, g, scrollStart, tdProjector, type);
}
else if (getCurrentScaleInfo().getDataType() == ParameterType.NCYCLES){
//draw CPOD cycles.
path2D = drawStemClick( plotNumber, pamDataUnit,g , scrollStart, tdProjector, type, paramType);
}
else if (getCurrentScaleInfo().getDataType() == ParameterType.AMPLITUDE_LIN){
//draw cpod SPL.
path2D = drawStemClick( plotNumber, pamDataUnit,g , scrollStart, tdProjector, type, paramType);
}
else if (getCurrentScaleInfo().getDataType() == ParameterType.BANDWIDTH){
//draw cpod SPL.
path2D = drawStemClick( plotNumber, pamDataUnit,g , scrollStart, tdProjector, type, paramType);
}
else return super.drawDataUnit(plotNumber, pamDataUnit, g, scrollStart, tdProjector, type);
//add to hover list if special data units.
if (path2D!=null && type!=TDSymbolChooserFX.HIGHLIGHT_SYMBOL && type!=TDSymbolChooserFX.HIGHLIGHT_SYMBOL_MARKED ){
tdProjector.addHoverData(new HoverData(path2D, pamDataUnit, 0, plotNumber));
return null;
}
return null;
}
/**
* Draw a frequency line
* @param plotNumber
* @param pamDataUnit
* @param g
* @param scrollStart
* @param tdProjector
* @param type
* @return
*/
@Override
public Polygon drawFrequencyData(int plotNumber, PamDataUnit pamDataUnit, GraphicsContext g, double scrollStart,
TDProjectorFX tdProjector, int type) {
g.setLineDashes(null);
g.setLineWidth(2);
double[] f = pamDataUnit.getFrequency();
if (f == null) {
return null;
}
if (f.length == 1) {
System.out.println("CPODPlot: Single frequency measure in data unit " + pamDataUnit.toString());
}
// draw a frequency box.
double y0 = tdProjector.getYPix(f[0]);
double y1 = tdProjector.getYPix(f[1]);
double x0 = tdProjector.getTimePix(pamDataUnit.getTimeMilliseconds()-scrollStart);
double x1 = tdProjector.getTimePix(pamDataUnit.getEndTimeInMilliseconds()-scrollStart);
System.out.println("CPODPlotInfoFX: Draw freq data unit: x: " + x0 + " y " + " y1: " + y1 + " to " + y0 + " cpod_data " + ((CPODClick) pamDataUnit).getBw());
PamArrayUtils.printArray(f);
g.setStroke(getSymbolChooser().getPamSymbol(pamDataUnit, type).getLineColor());
Color fillCol = getSymbolChooser().getPamSymbol(pamDataUnit, type).getFillColor();
g.setFill(Color.color(fillCol.getRed(), fillCol.getGreen(), fillCol.getBlue(), 0.4)); //add alpha
g.strokeLine(x0, y0, x0, y1);
//create the polygon.
Path2D path2D= new Path2D.Double(0,1);
// if (Math.abs(x1-x0)>50) {
//
// System.out.println("Generic Data Plot: " + "x0: " + x0 + " x1: " + x1 + " y1: " + y1 + " y: " + y0);
// }
path2D.moveTo(x0, y0);
path2D.lineTo(x0, y1);
tdProjector.addHoverData(new HoverData(path2D, pamDataUnit, 0, plotNumber));
return null;
}
/**
* Specific ways to plot CPOD data as NYCLES, AMPLITUDE_LIN and AMPLITUDE_STEM.
* @param plotNumber - the plot on which the FFT is drawing.
@ -219,17 +273,26 @@ public class CPODPlotInfoFX extends GenericDataPlotInfo {
y1=tdProjector.getYPix(1);
x2=tC;
y2= tdProjector.getYPix(pamDataUnit.getAmplitudeDB());
break;
case AMPLITUDE_LIN:
double spl = ((CPODClick) pamDataUnit).getSpl()/255.0;
x1=tC;
y1=tdProjector.getYPix(-spl);
x2=tC;
y2= tdProjector.getYPix(spl);
break;
case FREQUENCY:
double[] freq = pamDataUnit.getFrequency();
x1=tC;
y1=tdProjector.getYPix(freq[0]);
x2=tC;
y2= tdProjector.getYPix(freq[1]);
break;
case NCYCLES:
case BANDWIDTH:
double nycl = ((CPODClick) pamDataUnit).getnCyc();

View File

@ -8,6 +8,8 @@ import javafx.scene.control.Labeled;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxGlyphs.PamSVGIcon;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
@ -70,9 +72,8 @@ public class MLExportOverlayMenu extends ExportOverlayMenu {
private PamButton createButton() {
PamButton button = new PamButton("");
if (svgsprite==null) {
try {
// if (svgsprite==null) {
// try {
//
// // load the svg file
// InputStream svgFile =
@ -84,20 +85,21 @@ public class MLExportOverlayMenu extends ExportOverlayMenu {
//
// button.setGraphic(svgImage);
PamSVGIcon svgIconMaker = new PamSVGIcon();
// PamSVGIcon svgIconMaker = new PamSVGIcon();
// svgsprite = svgIconMaker.create(getClass().getResource("/Resources/matlab_icon2.svg").toURI().toURL(), Color.WHITE, 1);
//// "-fx-fill: white; -fx-stroke-width: 2;");
// svgsprite.setFitHeight(standardIconSize+7);
// svgsprite.setFitWidth(standardIconSize+7);
Text matlabIcon=PamGlyphDude.createPamIcon("file-matlab", standardIconSize+7);
svgsprite = svgIconMaker.create(getClass().getResource("/Resources/matlab_icon2.svg").toURI().toURL(), Color.WHITE, 1);
// "-fx-fill: white; -fx-stroke-width: 2;");
svgsprite.setFitHeight(standardIconSize+7);
svgsprite.setFitWidth(standardIconSize+7);
button.setGraphic(svgsprite.getSpriteNode());
button.setGraphic(matlabIcon);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
return button;
}

View File

@ -22,6 +22,8 @@ import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxGlyphs.PamSVGIcon;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
@ -65,29 +67,31 @@ public class RExportOverlayMenu extends ExportOverlayMenu {
// return button;
PamButton button = new PamButton();
Text matlabIcon=PamGlyphDude.createPamIcon("file-r", standardIconSize+7);
button.setGraphic(matlabIcon);
PamSVGIcon svgsprite;
try {
// System.out.println("START SVG load R");
PamSVGIcon svgIconMaker = new PamSVGIcon();
svgsprite = svgIconMaker.create(getClass().getResource("/Resources/r-project.svg").toURI().toURL(), Color.WHITE, 1);
// svgsprite = PamSVGIcon.create(new File(getClass().getResource("/Resources/r-project.svg").toURI()),
// "-fx-fill: white; -fx-stroke-width: 2;");
svgsprite.setFitHeight(standardIconSize+7);
svgsprite.setFitWidth(standardIconSize+7);
button.setGraphic(svgsprite.getSpriteNode());
// System.out.println("END SVG load R");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// PamSVGIcon svgsprite;
// try {
//
//// System.out.println("START SVG load R");
//
// PamSVGIcon svgIconMaker = new PamSVGIcon();
//
// svgsprite = svgIconMaker.create(getClass().getResource("/Resources/r-project.svg").toURI().toURL(), Color.WHITE, 1);
//
//// svgsprite = PamSVGIcon.create(new File(getClass().getResource("/Resources/r-project.svg").toURI()),
//// "-fx-fill: white; -fx-stroke-width: 2;");
// svgsprite.setFitHeight(standardIconSize+7);
// svgsprite.setFitWidth(standardIconSize+7);
// button.setGraphic(svgsprite.getSpriteNode());
//
//// System.out.println("END SVG load R");
//
//
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
return button;
}

View File

@ -4,6 +4,7 @@ import javafx.stage.Stage;
import javafx.stage.StageStyle;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxStyles.PamStylesManagerFX;
import PamController.PamController;
import PamController.SettingsPane;
@ -21,11 +22,11 @@ public class SettingsDialog<T> extends PamDialogFX<T>{
public SettingsDialog(SettingsPane<T> settingsPane){
super(PamGuiManagerFX.getInstance().getPrimaryStage() /*TODO - add stage*/, settingsPane.getName(), StageStyle.DECORATED);
this.getDialogPane().getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
this.setResizable(true);
this.settingsPane=settingsPane;
this.setContent(settingsPane.getContentNode());
// this.getDialogPane().getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
this.getDialogPane().getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamDialogCSS());
Stage stage = (Stage) this.getDialogPane().getScene().getWindow();
stage.toFront();

View File

@ -36,9 +36,8 @@ import rawDeepLearningClassifier.dlClassification.DLClassifyProcess;
import rawDeepLearningClassifier.dlClassification.animalSpot.SoundSpotClassifier;
import rawDeepLearningClassifier.dlClassification.archiveModel.ZipModelClassifier;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericDLClassifier;
import rawDeepLearningClassifier.dlClassification.ketos.KetosClassifier;
import rawDeepLearningClassifier.dlClassification.ketos.KetosClassifier2;
import rawDeepLearningClassifier.dlClassification.koogu.KooguClassifier;
import rawDeepLearningClassifier.layoutFX.DLModelSelectPane;
import rawDeepLearningClassifier.layoutFX.DLSidePanelSwing;
import rawDeepLearningClassifier.layoutFX.DLSymbolManager;
import rawDeepLearningClassifier.layoutFX.PredictionSymbolManager;
@ -255,7 +254,7 @@ public class DLControl extends PamControlledUnit implements PamSettings {
/***** Add new deep learning models here ****/
dlModels.add(new SoundSpotClassifier(this));
dlModels.add(new KetosClassifier(this));
dlModels.add(new KetosClassifier2(this));
dlModels.add(new KooguClassifier(this));
dlModels.add(new ZipModelClassifier(this));
//it is important the Generic Model is last because we need to check
@ -408,7 +407,6 @@ public class DLControl extends PamControlledUnit implements PamSettings {
settingsPane = new DLSettingsPane(this);
}
System.out.println("Get DL raw settings pane...");
return settingsPane;
}
@ -423,8 +421,6 @@ public class DLControl extends PamControlledUnit implements PamSettings {
* @param parentFrame - the frame.
*/
public void showSettingsDialog(Frame parentFrame) {
System.out.println("Get DL raw settings pane BAD...");
if (settingsDialog == null || parentFrame != settingsDialog.getOwner()) {
SettingsPane<RawDLParams> setPane = (SettingsPane<RawDLParams>) getSettingsPane();
setPane.setParams(this.rawDLParmas);

View File

@ -533,6 +533,7 @@ public class DLClassifyProcess extends PamInstantProcess {
@Override
public void pamStart() {
// TODO Auto-generated method stub
System.out.println("PREP MODEL:");
this.dlControl.getDLModel().prepModel();
}

View File

@ -100,7 +100,7 @@ public abstract class StandardClassifierModel implements DLClassiferModel, PamSe
@Override
public void prepModel() {
//System.out.println("PrepModel! !!!");
// System.out.println("STANDARD CLASSIFIER MODEL PREP MODEL! !!!");
StandardModelParams oldParams = getDLParams().clone();
getDLWorker().prepModel(getDLParams(), dlControl);

View File

@ -121,7 +121,7 @@ public class StandardAdvModelPane extends SettingsPane<StandardModelParams> {
@Override
public void setParams(StandardModelParams params) {
//System.out.println("Set advanced pane params: " + params.useDefaultTransfroms);
// System.out.println("Set advanced pane params: " + params.dlTransfroms.size());
if (params.dlTransfroms==null) {
mainPane.setTop(null);
mainPane.setCenter(new Label("A model must be loaded before \n "

View File

@ -6,6 +6,7 @@ import org.controlsfx.control.PopOver;
import org.controlsfx.control.ToggleSwitch;
import PamController.SettingsPane;
import PamUtils.PamArrayUtils;
import PamView.dialog.warn.WarnOnce;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
@ -143,6 +144,10 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
usedefaultSeg = new ToggleSwitch ();
usedefaultSeg.selectedProperty().addListener((obsval, oldval, newval)->{
defaultSegmentLenChanged();
//only set the hop if the user physically changes the toggle switch. This is not included in defaultSegmentLenChanged
//becuase defaultSegmentLenChanged can be called from elsewhere
int defaultsamples = getDefaultSamples();
dlClassifierModel.getDLControl().getSettingsPane().getHopLenSpinner().getValueFactory().setValue((int) defaultsamples/2);
});
usedefaultSeg.setPadding(new Insets(0,0,0,0));
//there is an issue with the toggle switch which means that it has dead space to the left if
@ -212,13 +217,13 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
// int defaultsamples = (int) this.soundSpotClassifier.millis2Samples(paramsClone.defaultSegmentLen);
float sR = dlClassifierModel.getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
// float sR = dlClassifierModel.getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
int defaultsamples = (int) (paramsClone.defaultSegmentLen.doubleValue()*sR/1000.0);
int defaultsamples = getDefaultSamples();
//work out the window length in samples
dlClassifierModel.getDLControl().getSettingsPane().getSegmentLenSpinner().getValueFactory().setValue(defaultsamples);
dlClassifierModel.getDLControl().getSettingsPane().getHopLenSpinner().getValueFactory().setValue((int) defaultsamples/2);
// dlClassifierModel.getDLControl().getSettingsPane().getHopLenSpinner().getValueFactory().setValue((int) defaultsamples/2);
dlClassifierModel.getDLControl().getSettingsPane().getSegmentLenSpinner().setDisable(true);
}
@ -226,6 +231,12 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
dlClassifierModel.getDLControl().getSettingsPane().getSegmentLenSpinner().setDisable(false);
}
}
private int getDefaultSamples() {
float sR = dlClassifierModel.getDLControl().getSettingsPane().getSelectedParentDataBlock().getSampleRate();
int defaultsamples = (int) (paramsClone.defaultSegmentLen.doubleValue()*sR/1000.0);
return defaultsamples;
}
/**
* Called whenever a new model has been selected
@ -325,6 +336,7 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
return currParams;
}
@SuppressWarnings("unchecked")
@Override
public void setParams(StandardModelParams currParams) {
try {
@ -338,18 +350,19 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
//set the params on the advanced pane.
// System.out.println("SET PARAMS ADV PANE: " + (paramsClone.classNames == null ? null : paramsClone.classNames.length));
this.getAdvSettingsPane().setParams(paramsClone);
//System.out.println("SET advanced params: " + paramsClone.dlTransfroms);
if (paramsClone.modelPath!=null) {
//this might
currentSelectedFile = new File(paramsClone.modelPath);
//this might change the paramsClone values if the model contains pamguard compatible metadata
newModelSelected(currentSelectedFile);
}
setClassNames(paramsClone);
setClassNames(currParams);
usedefaultSeg.setSelected(currParams.useDefaultSegLen);
usedefaultSeg.setSelected(paramsClone.useDefaultSegLen);
defaultSegmentLenChanged();
}
@ -357,7 +370,6 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
catch (Exception e) {
e.printStackTrace();
}
//updatePathLabel();
}
@ -369,7 +381,7 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
private void setClassNames(StandardModelParams currParams) {
speciesIDBox.getItems().clear();
System.out.println("SET CLASS NAMES: currParams.classNames: " + currParams.classNames + " " + (currParams.classNames!=null ? currParams.classNames.length: 0) + " " + currParams.numClasses);
// System.out.println("SET CLASS NAMES: currParams.classNames: " + currParams.classNames + " " + (currParams.classNames!=null ? currParams.classNames.length: 0) + " " + currParams.numClasses);
int classNamesLen = 0;
@ -384,7 +396,9 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
speciesIDBox.getItems().add("Class: " + i);
}
}
// System.out.println("Binary classification: set: " + speciesIDBox.getItems().size());
// PamArrayUtils.printArray(currParams.binaryClassification);
for (int i=0; i<speciesIDBox.getItems().size(); i++) {
if (currParams.binaryClassification!=null && i<currParams.binaryClassification.length) {
@ -392,7 +406,6 @@ public abstract class StandardModelPane extends SettingsPane<StandardModelParams
}
else {
speciesIDBox.getItemBooleanProperty(i).set(true);
}
}
}

View File

@ -150,6 +150,7 @@ public class StandardModelParams implements Serializable, Cloneable {
@Override
public String toString() {
super.toString();
String string = "-------Transforms------\n";
if (dlTransfromParams==null) {
string+="There are no transform params\n";

View File

@ -8,12 +8,15 @@ import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.DLClassiferModel;
import rawDeepLearningClassifier.dlClassification.StandardClassifierModel;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericPrediction;
import rawDeepLearningClassifier.dlClassification.ketos.KetosDLParams;
import rawDeepLearningClassifier.dlClassification.ketos.KetosUI;
import rawDeepLearningClassifier.layoutFX.DLCLassiferModelUI;
/**
@ -31,7 +34,7 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
/**
* The file extensions
*/
private String[] fileExtensions = new String[] {"zip"};
private String[] fileExtensions = new String[] {"*.zip"};
/**
* Parameters for a Ketos classifier.
@ -51,7 +54,13 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
public ArchiveModelClassifier(DLControl dlControl) {
super(dlControl);
// TODO Auto-generated constructor stub
this.standardDLParams = makeParams();
this.archiveModelUI= new ArchiveModelUI(this);
//load the previous settings
PamSettingManager.getInstance().registerSettings(this);
}
@ -73,7 +82,7 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
@Override
public DLModelWorker<GenericPrediction> getDLWorker() {
return getKetosWorker();
return getModelWorker();
}
@ -100,7 +109,7 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
* Get the KetosWorker. this handles loading and running the Ketos model.
* @return the Ketos worker.
*/
public ArchiveModelWorker getKetosWorker() {
public ArchiveModelWorker getModelWorker() {
if (archiveModelWorker==null) {
archiveModelWorker= new ArchiveModelWorker();
}
@ -123,7 +132,7 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
@Override
public Serializable getSettingsReference() {
if (standardDLParams==null) {
standardDLParams = new StandardModelParams();
standardDLParams = makeParams();
}
ArrayList<DLTransfromParams> dlTransformParams = DLClassiferModel.getDLTransformParams(standardDLParams.dlTransfroms);
@ -153,9 +162,18 @@ public abstract class ArchiveModelClassifier extends StandardClassifierModel {
.makeDLTransforms((ArrayList<DLTransfromParams>) standardDLParams.dlTransfromParams);
}
} else
standardDLParams = new StandardModelParams();
standardDLParams = makeParams();
return true;
}
/**
* Create the parameters class for the model. This can be overridden for bespoke parameters.
*classes.
* @return a new parameters class object.
*/
public StandardModelParams makeParams() {
return new StandardModelParams();
}
@Override
public boolean isModelType(URI uri) {

View File

@ -18,6 +18,8 @@ public class ArchiveModelPane extends StandardModelPane {
@Override
public void newModelSelected(File file) {
//the model has to set some of the parameters for the UI .
//A ketos model contains information on the transforms, duration and the class names.
this.setCurrentSelectedFile(file);
@ -27,7 +29,7 @@ public class ArchiveModelPane extends StandardModelPane {
}
StandardModelParams params = getParams(getParamsClone());
StandardModelParams params = getParamsClone();
// if (params.dlTransfromParams!=null) {
@ -44,20 +46,17 @@ public class ArchiveModelPane extends StandardModelPane {
* model or to use the existing transforms in the settings.
*/
archiveModelClassifier.getDLWorker().prepModel(params, archiveModelClassifier.getDLControl());
//get the model transforms calculated from the model by SoundSpoyWorker and apply them to our temporary params clone.
// System.out.println("Ketos transforms 1: " + this.ketosClassifier.getKetosWorker().getModelTransforms());
//get the model transforms calculated from the model by the worker and apply them to our temporary params clone.
getParamsClone().dlTransfroms = this.archiveModelClassifier.getDLWorker().getModelTransforms();
// if (getParamsClone().defaultSegmentLen!=null) {
// usedefaultSeg.setSelected(true);
// }
// System.out.println("Ketos: new model selected " + getParamsClone().dlTransfroms.size());
///set the advanced pane parameters.
getAdvSettingsPane().setParams(getParamsClone());
}
}

View File

@ -12,12 +12,12 @@ import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams
import rawDeepLearningClassifier.layoutFX.DLCLassiferModelUI;
public class ArchiveModelUI implements DLCLassiferModelUI {
/**
* Pane containing controls to set up the OrcaSPot classifier.
*/
private StandardModelPane standardSettingsPane;
/**
* The sound spot classifier.
*/
@ -27,22 +27,19 @@ public class ArchiveModelUI implements DLCLassiferModelUI {
* The extension filter.
*/
private ArrayList<ExtensionFilter> extensionFilters;
/**
* SondSpot classifier.
* @param soundSpotClassifier
*/
public ArchiveModelUI(ArchiveModelClassifier archiveClassifier) {
this.archiveModel=archiveClassifier;
extensionFilters = new ArrayList<ExtensionFilter>();
String[] fileExt = archiveModel.getFileExtensions();
for (int i=0; i<fileExt.length; i++) {
//import the settings holder
extensionFilters.add(new ExtensionFilter((fileExt[i] + " Model"), "*." + fileExt[i]));
}
// extensionFilters = new ArrayList<ExtensionFilter>();
//
// String[] fileExt = archiveModel.getFileExtensions();
//
// extensionFilters.add(new ExtensionFilter(archiveClassifier.getName(), fileExt));
}
@ -60,25 +57,29 @@ public class ArchiveModelUI implements DLCLassiferModelUI {
archiveModel.setDLParams(params);
}
@Override
public void setParams() {
// System.out.println("Set model params: " + genericModelClassifier.getGenericDLParams().dlTransfromParams.size());
// System.out.println("Set model params: " + genericModelClassifier.getGenericDLParams().dlTransfromParams.size());
getSettingsPane().setParams(archiveModel.getDLParams());
}
@Override
public JPanel getSidePanel() {
//no side pane for Ketos just now.
return null;
}
@Override
public List<ExtensionFilter> getModelFileExtensions() {
if (extensionFilters == null) {
extensionFilters = new ArrayList<ExtensionFilter>();
extensionFilters.add(new ExtensionFilter(archiveModel.getName(), archiveModel.getFileExtensions()));
}
return extensionFilters;
}
}

View File

@ -1,12 +1,12 @@
package rawDeepLearningClassifier.dlClassification.archiveModel;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import org.jamdev.jdl4pam.ArchiveModel;
import org.jamdev.jdl4pam.genericmodel.GenericModelParams;
import org.jamdev.jdl4pam.ketos.KetosModel;
import org.jamdev.jdl4pam.transforms.DLTransform;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.jsonfile.DLTransformParser2;
@ -14,224 +14,240 @@ import org.jamdev.jdl4pam.transforms.jsonfile.DLTransformsParser;
import org.json.JSONObject;
import PamView.dialog.warn.WarnOnce;
import ai.djl.MalformedModelException;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericPrediction;
/**
*
* Runs a Ketos deep learning model and performs feature extraction.
* <p>
*
* @author Jamie Macaulay
*
*/
public class ArchiveModelWorker extends DLModelWorker<GenericPrediction> {
/**
*
* Runs a Ketos deep learning model and performs feature extraction.
* <p>
*
* @author Jamie Macaulay
*
* The ketos model
*/
public class ArchiveModelWorker extends DLModelWorker<GenericPrediction> {
private ArchiveModel dlModel;
/**
* Thelast loaded model path.,
*/
private String currentPath;
/**
* The ketos model
*/
private ArchiveModel dlModel;
/**
* Thelast loaded model path.,
*/
private String currentPath;
/**
* SoundSpotWorker constructor.
*/
public ArchiveModelWorker() {
this.setEnableSoftMax(false);
}
/**
* Prepare the model
*/
public void prepModel(StandardModelParams dlParams, DLControl dlControl) {
//ClassLoader origCL = Thread.currentThread().getContextClassLoader();
try {
// get the plugin class loader and set it as the context class loader
// NOTE THAT THIS IS REQUIRED TO MAKE THIS MODULE RUN AS A PLUGIN WHEN THE CLASS FILES
// ARE BUNDLED INTO A FATJAR, HOWEVER THIS WILL STOP THE PLUGIN FROM RUNNING AS A SEPARATE
// PROJECT IN ECLIPSE. So while testing the code and debugging, make sure the
// if (DLControl.PLUGIN_BUILD) {
// PluginClassloader newCL = PamModel.getPamModel().getClassLoader();
// Thread.currentThread().setContextClassLoader(newCL);
// }
//first open the model and get the correct parameters.
//21/11/2022 - Added a null and filename check here to stop the mdoel reloading everytime PAMGuard hits a new file or
//is stopped or started - this was causing a memory leak.
if (dlModel==null || currentPath ==null || !Paths.get(currentPath).equals(Paths.get(dlParams.modelPath))) {
/**
* SoundSpotWorker constructor.
*/
public ArchiveModelWorker() {
this.setEnableSoftMax(false);
//TODO
// if (ketosModel!=null && ketosModel.getModel()!=null) {
// ketosModel.getModel().close();
// }
//System.out.println(Paths.get(genericParams.modelPath));
this.currentPath = dlParams.modelPath;
dlModel = loadModel(currentPath);
//System.out.println("LOAD A NEW MODEL: ");
//System.out.println(genericModel.getModel().getModelPath().getFileName());
}
}
catch (Exception e) {
e.printStackTrace();
//WarnOnce.showWarning(null, "Model Load Error", "There was an error loading the model file.", WarnOnce.OK_OPTION);
}
/**
* Prepare the model
*/
public void prepModel(StandardModelParams dlParams, DLControl dlControl) {
//ClassLoader origCL = Thread.currentThread().getContextClassLoader();
try {
try {
// get the plugin class loader and set it as the context class loader
// NOTE THAT THIS IS REQUIRED TO MAKE THIS MODULE RUN AS A PLUGIN WHEN THE CLASS FILES
// ARE BUNDLED INTO A FATJAR, HOWEVER THIS WILL STOP THE PLUGIN FROM RUNNING AS A SEPARATE
// PROJECT IN ECLIPSE. So while testing the code and debugging, make sure the
// if (DLControl.PLUGIN_BUILD) {
// PluginClassloader newCL = PamModel.getPamModel().getClassLoader();
// Thread.currentThread().setContextClassLoader(newCL);
// }
//first open the model and get the correct parameters.
//21/11/2022 - Added a null and filename check here to stop the mdoel reloading everytime PAMGuard hits a new file or
//is stopped or started - this was causing a memory leak.
if (dlModel==null || currentPath ==null || !Paths.get(currentPath).equals(Paths.get(dlParams.modelPath))) {
//TODO
// if (ketosModel!=null && ketosModel.getModel()!=null) {
// ketosModel.getModel().close();
// }
//read the JSON string from the the file.
String jsonString = DLTransformsParser.readJSONString(new File(dlModel.getAudioReprFile()));
//System.out.println(Paths.get(genericParams.modelPath));
this.currentPath = dlParams.modelPath;
dlModel = new ArchiveModel(new File(dlParams.modelPath));
//System.out.println("LOAD A NEW MODEL: ");
//System.out.println(genericModel.getModel().getModelPath().getFileName());
}
}
catch (Exception e) {
e.printStackTrace();
//WarnOnce.showWarning(null, "Model Load Error", "There was an error loading the model file.", WarnOnce.OK_OPTION);
//convert the JSON string to a parameters object.
GenericModelParams modelParams = makeModelParams( jsonString);
//important to add this for Ketos models because the JSON string does not necessarily contain and output shape.
//System.out.println("----Default output shape: " + ketosParams.defaultOutputShape + " " + ketosModel.getOutShape());
if (modelParams.defaultOutputShape==null) {
modelParams.defaultOutputShape = dlModel.getOutShape();
}
try {
//read the JSON string from the the file.
String jsonString = DLTransformsParser.readJSONString(new File(dlModel.getAudioReprFile()));
//convert the JSON string to a parameters object.
GenericModelParams modelParams = makeModelParams( jsonString);
//important to add this for Ketos models because the JSON string does not necessarily contain and output shape.
//System.out.println("----Default output shape: " + ketosParams.defaultOutputShape + " " + ketosModel.getOutShape());
if (modelParams.defaultOutputShape==null) {
modelParams.defaultOutputShape = dlModel.getOutShape();
}
//HACK there seems to be some sort of bug in ketos where the params input shape is correct but the model input shape is wrong.
if (dlModel.getInputShape()==null || !dlModel.getInputShape().equals(modelParams.defaultInputShape)) {
WarnOnce.showWarning("Model shape", "The model shape does not match the model metadata. \n Metadata shape will be used used.", WarnOnce.OK_OPTION);
dlModel.setInputShape(modelParams.defaultInputShape);
}
// ///HACK here for now to fix an issue with dB and Ketos transforms having zero length somehow...
// for (int i=0; i<ketosParams.dlTransforms.size(); i++) {
// if (ketosParams.dlTransforms.get(i).dltransfromType == DLTransformType.SPEC2DB) {
// ketosParams.dlTransforms.get(i).params = null;
// //System.out.println("Set dB transform to null: " + ketosParams.dlTransforms.get(i).params);
// }
// }
//generate the transforms from the KetosParams objects.
ArrayList<DLTransform> transforms = DLTransformsFactory.makeDLTransforms(modelParams.dlTransforms);
///HACK here for now to fix an issue with dB and Ketos transforms having zero length somehow...
for (int i=0; i<modelParams.dlTransforms.size(); i++) {
System.out.println(modelParams.dlTransforms.get(i));
}
//only load new transforms if defaults are selected
if (getModelTransforms()==null || dlParams.dlTransfroms==null || dlParams.useDefaultTransfroms) {
System.out.println(" " + transforms);
//System.out.println("SET MODEL TRANSFORMS: " + ketosDLParams.dlTransfroms + " " + ketosDLParams.useDefaultTransfroms);
//only set the transforms if they are null - otherwise handled elsewhere.
setModelTransforms(transforms);
dlParams.useDefaultTransfroms = true;
}
else {
//System.out.println("SET CURRENT TRANSFORMS: " + ketosDLParams.dlTransfroms + " " + ketosDLParams.useDefaultTransfroms);
//use the old transforms.
setModelTransforms(dlParams.dlTransfroms);
}
//ketosDLParams.dlTransfroms = transforms; //this is done after prep model in the settings pane.
dlParams.defaultSegmentLen = modelParams.segLen*1000.; //the segment length in microseconds.
//ketosParams.classNames = new String[] {"Noise", "Right Whale"}; // FIXME;
//ok 0 the other values are not user selectable but this is. If we relaod the same model we probably want to keep it....
//So this is a little bt of a hack but will probably be OK in most cases.
if (dlParams.binaryClassification==null || dlParams.binaryClassification.length!=dlParams.numClasses) {
dlParams.binaryClassification = new boolean[dlParams.numClasses];
for (int i=0; i<dlParams.binaryClassification.length; i++) {
dlParams.binaryClassification[i] = true; //set default to true.
}
}
if (modelParams.classNames!=null) {
dlParams.classNames = dlControl.getClassNameManager().makeClassNames(modelParams.classNames);
}
// if (dlParams.classNames!=null) {
// for (int i = 0; i<dlParams.classNames.length; i++) {
// System.out.println("Class name " + i + " " + dlParams.classNames[i]);
// }
// }
// ketosDLParams.classNames = dlControl.getClassNameManager().makeClassNames(ketosParams.classNames);
// if (ketosParams.classNames!=null) {
// for (int i = 0; i<ketosDLParams.classNames.length; i++) {
// System.out.println("Class name " + i + " " + ketosDLParams.classNames[i].className + " ID " + ketosDLParams.classNames[i].ID );
// }
// }
//HACK there seems to be some sort of bug in ketos where the params input shape is correct but the model input shape is wrong.
if (dlModel.getInputShape()==null || !dlModel.getInputShape().equals(modelParams.defaultInputShape)) {
WarnOnce.showWarning("Model shape", "The model shape does not match the model metadata. \n Metadata shape will be used used.", WarnOnce.OK_OPTION);
dlModel.setInputShape(modelParams.defaultInputShape);
}
catch (Exception e) {
dlModel=null;
e.printStackTrace();
//WarnOnce.showWarning(null, "Model Metadata Error", "There was an error extracting the metadata from the model.", WarnOnce.OK_OPTION);
// ///HACK here for now to fix an issue with dB and Ketos transforms having zero length somehow...
// for (int i=0; i<ketosParams.dlTransforms.size(); i++) {
// if (ketosParams.dlTransforms.get(i).dltransfromType == DLTransformType.SPEC2DB) {
// ketosParams.dlTransforms.get(i).params = null;
// //System.out.println("Set dB transform to null: " + ketosParams.dlTransforms.get(i).params);
// }
// }
//generate the transforms from the KetosParams objects.
ArrayList<DLTransform> transforms = DLTransformsFactory.makeDLTransforms(modelParams.dlTransforms);
// ///HACK here for now to fix an issue with dB and Ketos transforms having zero length somehow...
// for (int i=0; i<modelParams.dlTransforms.size(); i++) {
// System.out.println(modelParams.dlTransforms.get(i));
// }
//only load new transforms if defaults are selected
if (getModelTransforms()==null || dlParams.dlTransfroms==null || dlParams.useDefaultTransfroms) {
System.out.println(" " + transforms);
//System.out.println("SET MODEL TRANSFORMS: " + ketosDLParams.dlTransfroms + " " + ketosDLParams.useDefaultTransfroms);
//only set the transforms if they are null - otherwise handled elsewhere.
setModelTransforms(transforms);
dlParams.useDefaultTransfroms = true;
}
//Thread.currentThread().setContextClassLoader(origCL);
else {
//System.out.println("SET CURRENT TRANSFORMS: " + ketosDLParams.dlTransfroms + " " + ketosDLParams.useDefaultTransfroms);
//use the old transforms.
setModelTransforms(dlParams.dlTransfroms);
}
//ketosDLParams.dlTransfroms = transforms; //this is done after prep model in the settings pane.
dlParams.defaultSegmentLen = modelParams.segLen*1000.; //the segment length in microseconds.
//ketosParams.classNames = new String[] {"Noise", "Right Whale"}; // FIXME;
//ok 0 the other values are not user selectable but this is. If we relaod the same model we probably want to keep it....
//So this is a little bt of a hack but will probably be OK in most cases.
if (dlParams.binaryClassification==null || dlParams.binaryClassification.length!=dlParams.numClasses) {
dlParams.binaryClassification = new boolean[dlParams.numClasses];
for (int i=0; i<dlParams.binaryClassification.length; i++) {
dlParams.binaryClassification[i] = true; //set default to true.
}
}
if (modelParams.classNames!=null) {
dlParams.classNames = dlControl.getClassNameManager().makeClassNames(modelParams.classNames);
}
else {
//set the number of class names from the default output shape
dlParams.numClasses = (int) modelParams.defaultOutputShape.get(1);
}
// if (dlParams.classNames!=null) {
// for (int i = 0; i<dlParams.classNames.length; i++) {
// System.out.println("Class name " + i + " " + dlParams.classNames[i]);
// }
// }
// ketosDLParams.classNames = dlControl.getClassNameManager().makeClassNames(ketosParams.classNames);
// if (ketosParams.classNames!=null) {
// for (int i = 0; i<ketosDLParams.classNames.length; i++) {
// System.out.println("Class name " + i + " " + ketosDLParams.classNames[i].className + " ID " + ketosDLParams.classNames[i].ID );
// }
// }
}
/**
* Create the parameters from a JSON string.
* @param jsonString - the json string.
* @return the paramters.
*/
public GenericModelParams makeModelParams(String jsonString) {
//Need to figure out if this is the new or old format.
JSONObject jsonObject = new JSONObject(jsonString);
boolean isParamsV2 =DLTransformParser2.isParamsV2(jsonObject);
//standard format.
GenericModelParams params = DLTransformParser2.readJSONParams(jsonObject);
return params;
catch (Exception e) {
dlModel=null;
e.printStackTrace();
//WarnOnce.showWarning(null, "Model Metadata Error", "There was an error extracting the metadata from the model.", WarnOnce.OK_OPTION);
}
//Thread.currentThread().setContextClassLoader(origCL);
}
/**
* Load a model from a file
* @param currentPath- the path to the model.
* @return- the loaded model object.
* @throws MalformedModelException
* @throws IOException
*/
public ArchiveModel loadModel(String currentPath2) throws MalformedModelException, IOException {
return new SimpleArchiveModel(new File(currentPath2));
}
/**
* Create the parameters from a JSON string.
* @param jsonString - the json string.
* @return the paramters.
*/
public GenericModelParams makeModelParams(String jsonString) {
//Need to figure out if this is the new or old format.
JSONObject jsonObject = new JSONObject(jsonString);
boolean isParamsV2 =DLTransformParser2.isParamsV2(jsonObject);
//standard format.
GenericModelParams params = DLTransformParser2.readJSONParams(jsonObject);
return params;
}
@Override
public float[] runModel(float[][][] transformedDataStack) {
System.out.println("Model input: " + transformedDataStack.length + " " + transformedDataStack[0].length + " " + transformedDataStack[0][0].length);
return dlModel.runModel(transformedDataStack);
}
@Override
public float[] runModel(float[][][] transformedDataStack) {
System.out.println("Model input: " + transformedDataStack.length + " " + transformedDataStack[0].length + " " + transformedDataStack[0][0].length);
return dlModel.runModel(transformedDataStack);
}
@Override
public GenericPrediction makeModelResult(float[] prob, double time) {
GenericPrediction soundSpotResult = new GenericPrediction(prob);
soundSpotResult.setAnalysisTime(time);
return soundSpotResult;
}
@Override
public GenericPrediction makeModelResult(float[] prob, double time) {
GenericPrediction soundSpotResult = new GenericPrediction(prob);
soundSpotResult.setAnalysisTime(time);
return soundSpotResult;
}
/**
* Destroy the model.
*/
public void closeModel() {
this.currentPath = null;
}
/**
* Destroy the model.
*/
public void closeModel() {
this.currentPath = null;
}
/**
* Get the currently loaded mode.
* @return - the currently loaded mode.
*/
public ArchiveModel getModel() {
return dlModel;
}
/**
* Get the currently loaded mode.
* @return - the currently loaded mode.
*/
public ArchiveModel getModel() {
return dlModel;
}
@Override
public boolean isModelNull() {
return dlModel==null;
}
@Override
public boolean isModelNull() {
return dlModel==null;
}
}
}

View File

@ -0,0 +1,39 @@
package rawDeepLearningClassifier.dlClassification.archiveModel;
import java.io.File;
import java.io.IOException;
import org.jamdev.jdl4pam.ArchiveModel;
import ai.djl.MalformedModelException;
/**
* A Tensorflow model packaged with a jar file.
* @author Jamie Macaulay
*
*/
public class SimpleArchiveModel extends ArchiveModel {
public SimpleArchiveModel(File file) throws MalformedModelException, IOException {
super(file);
// TODO Auto-generated constructor stub
}
@Override
public String getAudioReprRelPath(String zipFolder) {
// settings are in parent directory
return "audio_repr_pg.json";
}
@Override
public String getModelRelPath(String zipFolder) {
// model is in parent directory
return "model/saved_model.pb";
}
@Override
public String getModelFolderName() {
return "zip_model";
}
}

View File

@ -0,0 +1,66 @@
package rawDeepLearningClassifier.dlClassification.ketos;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelClassifier;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelWorker;
/**
* Classifier which uses deep learning models from Meridian's Ketos framework.
* <p>
* Ketos uses TensorFlow models and packages them inside a zipped .ktpb file
* which contains a JSON file for the transforms and a .pb model. Users can
* select a .ktpb file - PAMGaurd will decompress it, find the JSON file, set up
* the transforms and load the model.
* <p>
* Details on Meridians framework can be found at https://meridian.cs.dal.ca/2015/04/12/ketos/
* <p>
* KetosClassifier2 is a more abstracted version of KetosClassifer which inherits most functionality from ArchiveModel
* @author Jamie Macaulay
*
*/
public class KetosClassifier2 extends ArchiveModelClassifier {
public static String MODEL_NAME = "Ketos";
/**
* The file extensions
*/
private String[] fileExtensions = new String[] {"*.ktpb"};
private KetosWorker2 ketosWorker;
public KetosClassifier2(DLControl dlControl) {
super(dlControl);
}
@Override
public String[] getFileExtensions() {
return fileExtensions;
}
@Override
public String getName() {
return MODEL_NAME;
}
@Override
public ArchiveModelWorker getModelWorker() {
if (ketosWorker==null) {
ketosWorker= new KetosWorker2();
}
return ketosWorker;
}
/**
* Create the parameters class for the model. This can be overridden for bespoke parameters.
*classes.
* @return a new parameters class object.
*/
public StandardModelParams makeParams() {
return new KetosDLParams();
}
}

View File

@ -38,7 +38,7 @@ public class KetosModelPane extends StandardModelPane {
this.setParamsClone(new KetosDLParams());
}
//set the current paramters for the clone
StandardModelParams params = getParams(getParamsClone());
@ -59,17 +59,17 @@ public class KetosModelPane extends StandardModelPane {
//get the model transforms calculated from the model by SoundSpoyWorker and apply them to our temporary params clone.
// System.out.println("Ketos transforms 1: " + this.ketosClassifier.getKetosWorker().getModelTransforms());
getParamsClone().dlTransfroms = this.ketosClassifier.getKetosWorker().getModelTransforms();
// if (getParamsClone().defaultSegmentLen!=null) {
// usedefaultSeg.setSelected(true);
// }
// System.out.println("---------------------------- ");
// System.out.println("KETOS: new model selected " +getParamsClone().dlTransfromParams.size() + " \n " + getParamsClone());
// System.out.println("Ketos: new model selected " + getParamsClone().dlTransfroms.size());
///set the advanced pane parameters.
getAdvSettingsPane().setParams(getParamsClone());
}
}

View File

@ -123,7 +123,7 @@ public class KetosWorker extends DLModelWorker<GenericPrediction> {
//only load new transforms if defaults are selected
if (getModelTransforms()==null || ketosDLParams.dlTransfroms==null || ketosDLParams.useDefaultTransfroms) {
System.out.println(" " + transforms);
//System.out.println(" " + transforms);
//System.out.println("SET MODEL TRANSFORMS: " + ketosDLParams.dlTransfroms + " " + ketosDLParams.useDefaultTransfroms);
//only set the transforms if they are null - otherwise handled elsewhere.
@ -152,7 +152,13 @@ public class KetosWorker extends DLModelWorker<GenericPrediction> {
if (ketosParams.classNames!=null) {
ketosDLParams.classNames = dlControl.getClassNameManager().makeClassNames(ketosParams.classNames);
ketosDLParams.numClasses = ketosDLParams.classNames.length;
}
else {
//set the number of class names from the default output shape
ketosDLParams.numClasses = (int) ketosParams.defaultOutputShape.get(1);
}
// if (dlParams.classNames!=null) {
// for (int i = 0; i<dlParams.classNames.length; i++) {

View File

@ -0,0 +1,37 @@
package rawDeepLearningClassifier.dlClassification.ketos;
import java.io.File;
import java.io.IOException;
import org.jamdev.jdl4pam.ArchiveModel;
import org.jamdev.jdl4pam.genericmodel.GenericModelParams;
import org.jamdev.jdl4pam.ketos.KetosModel;
import org.jamdev.jdl4pam.ketos.KetosParams;
import ai.djl.MalformedModelException;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelWorker;
public class KetosWorker2 extends ArchiveModelWorker {
/**
* Load a model from a file
* @param currentPath- the path to the model.
* @return- the loaded model object.
* @throws MalformedModelException
* @throws IOException
*/
public ArchiveModel loadModel(String currentPath2) throws MalformedModelException, IOException {
return new KetosModel(new File(currentPath2));
}
/**
* Create the parameters from a JSON string.
* @param jsonString - the json string.
* @return the paramters.
*/
public GenericModelParams makeModelParams(String jsonString) {
//ketos parameters are non standard and need a bit of extra work to get right.
//This also deal with legacy paramters.
return new KetosParams(jsonString);
}
}

View File

@ -2,6 +2,9 @@ package rawDeepLearningClassifier.dlClassification.koogu;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelClassifier;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.GenericPrediction;
/**
* Classifier which uses deep learning models from Koogus' framework.
@ -23,7 +26,9 @@ public class KooguClassifier extends ArchiveModelClassifier {
/**
* The file extensions
*/
private String[] fileExtensions = new String[] {"kgu"};
private String[] fileExtensions = new String[] {"*.kgu"};
private KooguModelWorker kooguWorker;
public KooguClassifier(DLControl dlControl) {
@ -39,4 +44,15 @@ public class KooguClassifier extends ArchiveModelClassifier {
public String getName() {
return MODEL_NAME;
}
@Override
public ArchiveModelWorker getModelWorker() {
if (kooguWorker==null) {
kooguWorker= new KooguModelWorker();
}
return kooguWorker;
}
}

View File

@ -0,0 +1,25 @@
package rawDeepLearningClassifier.dlClassification.koogu;
import java.io.File;
import java.io.IOException;
import org.jamdev.jdl4pam.ArchiveModel;
import org.jamdev.jdl4pam.koogu.KooguModel;
import ai.djl.MalformedModelException;
import rawDeepLearningClassifier.dlClassification.archiveModel.ArchiveModelWorker;
public class KooguModelWorker extends ArchiveModelWorker {
/**
* Load a model from a file
* @param currentPath- the path to the model.
* @return- the loaded model object.
* @throws MalformedModelException
* @throws IOException
*/
public ArchiveModel loadModel(String currentPath2) throws MalformedModelException, IOException {
return new KooguModel(new File(currentPath2));
}
}

View File

@ -44,7 +44,8 @@ import rawDeepLearningClassifier.layoutFX.defaultModels.DefaultModelPane;
/**
* A pane which allows users to select a model.
* A pane which allows users to select a model and then loads the model on
* on a different thread, showing a progress indicator.
*
* Models could be potentially selected from
* 1) A file (implemented)
@ -479,8 +480,11 @@ public class DLModelSelectPane extends PamBorderPane {
ArrayList<String> extensionFilters = new ArrayList<String>();
for (DLClassiferModel dlModel: dlControl.getDLModels()) {
//System.out.println("Model: " + dlModel.getModelUI());
if (dlModel.getModelUI()!=null) {
for (ExtensionFilter extFilter: dlModel.getModelUI().getModelFileExtensions()){
//System.out.println("Extensions: " + extFilter.getExtensions());
extensionFilters.addAll(extFilter.getExtensions());
}
}

View File

@ -367,9 +367,6 @@ public class DLSettingsPane extends SettingsPane<RawDLParams>{
*/
protected void setClassifierPane() {
//set the classifier Pane.class
System.out.println("Set CLASSIFIER PANE: " + modelSelectPane.currentClassifierModel);
if (modelSelectPane.currentClassifierModel!=null && modelSelectPane.currentClassifierModel.getModelUI()!=null) {
classifierPane.setCenter(modelSelectPane.currentClassifierModel.getModelUI().getSettingsPane().getContentNode());

View File

@ -166,7 +166,7 @@ public class DLTransformsPane extends PamBorderPane {
transformPane = DataTransformPaneFactory.getSettingsPane(dlTransforms.get(i));
System.out.println("Set DL transfroms: " + dlTransforms.get(i).getDLTransformType() + " " + ((SimpleTransform) dlTransforms.get(i)).getParams());
//System.out.println("Set DL transfroms: " + dlTransforms.get(i).getDLTransformType() + " " + ((SimpleTransform) dlTransforms.get(i)).getParams());
//there must be a transform pane or else this will break.