Merge branch 'PAMGuard:main' into main

This commit is contained in:
Douglas Gillespie 2022-04-28 13:48:41 +01:00 committed by GitHub
commit f9787a9633
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 512 additions and 107 deletions

View File

@ -421,7 +421,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
}
}
protected String getCurrentFolder() {
public String getCurrentFolder() {
if (folderInputParameters.recentFiles.size() == 0) {
return null;
}

View File

@ -145,6 +145,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
public AcquisitionPaneFX(AcquisitionControl aquisitionControl){
super(null);
mainPane = new PamBorderPane();
mainPane.setPrefWidth(400);
this.acquisitionControl=aquisitionControl;
this.acquisitionParameters=acquisitionControl.getAcquisitionParameters();
@ -153,7 +154,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
flipPane=new FlipPane();
flipPane.setFlipDirection(Orientation.HORIZONTAL);
flipPane.setFlipTime(250); //default is 700ms- way too high
//flipPane.prefWidthProperty().bind(mainPane.widthProperty());
if (aquisitionControl.isViewer()){
this.mainPane.setCenter(createViewerModePane());
@ -166,9 +167,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
//create the advanced flip pane.
advancedSettingPane = createAdvSettingsPane();
flipPane.getBack().getChildren().add(advancedSettingPane);
System.out.println("MAKE PANE: " + acquisitionParameters.getDaqSystemType());
//System.out.println("MAKE PANE: " + acquisitionParameters.getDaqSystemType());
}
@ -194,7 +193,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
buttonHolder.setAlignment(Pos.CENTER_LEFT);
buttonHolder.getChildren().addAll(back, advLabel = new Label("Adv. Settings"));
advLabel.setAlignment(Pos.CENTER);
advLabel.setMaxWidth(Double.MAX_VALUE); //nneed ot make sure label is in center.
advLabel.setMaxWidth(Double.MAX_VALUE); //need to make sure label is in center.
PamGuiManagerFX.titleFont2style(advLabel);
advLabel.setAlignment(Pos.CENTER);
@ -264,7 +263,6 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
//TODO- this is a bit CUMBERSOME and maybe fixed in new version of JavaFX
//need to get stage and resize because new controls may have been added.
if (mainPane!=null && mainPane.getScene()!=null) {
Stage stage = (Stage) mainPane.getScene().getWindow();
stage.sizeToScene();
@ -498,7 +496,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
acquisitionControl.getOfflineFileServer().setOfflineFileParameters(ofp);
}
System.out.println("Get Params: Open Aquisition dialog: " + acquisitionParameters.getDaqSystemType());
//System.out.println("Get Params: Open Aquisition dialog: " + acquisitionParameters.getDaqSystemType());
return acquisitionParameters;
}

View File

@ -0,0 +1,273 @@
package Acquisition.layoutFX;
import java.io.File;
import java.util.ArrayList;
import Acquisition.AudioFileFuncs;
import Acquisition.FolderInputSystem;
import Acquisition.WavFileFuncs;
import PamUtils.PamAudioFileFilter;
import javafx.geometry.Insets;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox;
/**
* Pane with controls to fix wave file headers.
* @author Jamie Macaulay
*
*/
public class CheckWavHeadersPane extends PamBorderPane {
/**
* The text area.
*/
private TextArea textArea;
/**
* The folder name label.
*/
private Label folderName;
/**
* Progress bar showing progress of file write.
*/
private ProgressBar progressBar;
private boolean running, ran;
/**
* Check file workers.
*/
private CheckFiles checkFilesWorker;
/**
* The files.
*/
private ArrayList<File> allFiles = new ArrayList<File>();
/**
* The folder input system.
*/
private FolderInputSystem folderInputSystem;
/**
* Look at sub folders.
*/
private boolean subFolders;
/**
* The folder.
*/
private File folder;
/**
* The number of files.
*/
private int nFiles;
private int doneFiles;
private int nErrors;
/**
* Simple double property.
*/
private SimpleDoubleProperty progressProperty = new SimpleDoubleProperty(0);
/**
* Constructor for the CheckWavHeadersPane
* @param folderInputSystem - the folder input system.
*/
public CheckWavHeadersPane(FolderInputSystem folderInputSystem) {
//this.setCenter(new Label("Hello fix wav pane"));
PamVBox mainPane = new PamVBox();
mainPane.setSpacing(5);
this.folderInputSystem=folderInputSystem;
folderName = new Label(" ");
PamGuiManagerFX.titleFont2style(folderName);
textArea = new TextArea();
textArea.setEditable(false);
ScrollPane scrollPane = new ScrollPane(textArea);
scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
//scrollPane.setPrefSize(322, 300);
this.setCenter(scrollPane);
PamHBox pamHBox = new PamHBox();
pamHBox.setAlignment(Pos.CENTER_LEFT);
pamHBox.setSpacing(5);
PamButton runButton = new PamButton();
runButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play"));
runButton.setOnAction((action)->{
checkFiles();
});
progressBar = new ProgressBar();
PamHBox.setHgrow(progressBar, Priority.ALWAYS);
progressBar.prefHeightProperty().bind(runButton.heightProperty());
pamHBox.getChildren().addAll(runButton, progressBar);
progressBar.setMaxWidth(Double.MAX_VALUE);
mainPane.getChildren().addAll(folderName, textArea, pamHBox);
this.setPadding(new Insets(5,0,5,15));
}
private void setParams() {
running = ran = false;
subFolders = folderInputSystem.getFolderInputParameters().subFolders;
if (subFolders) {
folderName.setText(folderInputSystem.getCurrentFolder() + " + sub folders");
}
else {
folderName.setText(folderInputSystem.getCurrentFolder());
}
folder = new File(folderInputSystem.getCurrentFolder());
textArea.setText(" ");
allFiles.clear();
nFiles = countFiles(folder);
progressBar.setProgress(0);
progressBar.progressProperty().bind(progressProperty);
//progressBar.setMaximum(Math.max(nFiles, 1));
enableControls();
}
private int countFiles(File folder) {
int nF = 0;
File[] files = folder.listFiles(new PamAudioFileFilter());
if (files == null) return 0;
File file;
for (int i = 0; i < files.length; i++) {
file = files[i];
if (file.isDirectory() && subFolders) {
System.out.println(file.getAbsoluteFile());
nF += countFiles(file.getAbsoluteFile());
}
else if (file.isFile()) {
allFiles.add(file);
nF++;
}
}
return nF;
}
/**
* Return true if there is an error
* @param aFile file to check, aif or wav
* @return true if there is an error
*/
private int checkFile(File aFile) {
if (aFile.exists() == false || aFile.isDirectory() == true) {
return AudioFileFuncs.FILE_DOESNTEXIST;
}
String fileName = aFile.getName();
// get the bit after the dot
int dotPos = fileName.lastIndexOf('.');
if (dotPos < 0) {
return AudioFileFuncs.FILE_UNKNOWNTYPE;
}
String fileEnd = fileName.substring(dotPos+1);
if (fileEnd.equalsIgnoreCase("wav")) {
return checkWavFile(aFile);
}
else if (fileEnd.equalsIgnoreCase("aif")) {
return checkAifFile(aFile);
}
return AudioFileFuncs.FILE_UNKNOWNTYPE;
}
private void enableControls() {
//getOkButton().setEnabled(nFiles > 0 & running == false && ran == false);
//getCancelButton().setEnabled(running == false);
}
private void checkFiles() {
running = true;
textArea.setText(String.format("Checking %d files ...\n", nFiles));
doneFiles = 0;
nErrors = 0;
enableControls();
checkFilesWorker = new CheckFiles();
}
private void jobDone() {
running = false;
ran = true;
enableControls();
textArea.appendText(String.format("\n\n%d file headers contained errors", nErrors));
}
private int checkAifFile(File file) {
return AudioFileFuncs.FILE_CANTOPEN;
}
private int checkWavFile(File aFile) {
return WavFileFuncs.checkHeader(aFile, true);
}
private class CheckFiles extends Task<Integer> {
@Override
protected Integer call() throws Exception {
try {
/*
* need to loop over files again
* for each file, report on progress with it's name and
* whether or not it had an error
*/
int error;
File aFile;
for (int i = 0; i < allFiles.size(); i++) {
error = checkFile(aFile = allFiles.get(i));
//progressBar.progressProperty().bind(null);
progressProperty.setValue(100*i/(double) allFiles.size());
}
return null;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void done() {
super.done();
jobDone();
}
}
}

View File

@ -1,19 +0,0 @@
package Acquisition.layoutFX;
import Acquisition.FolderInputSystem;
import javafx.scene.control.Label;
import pamViewFX.fxNodes.PamBorderPane;
/**
* Pane with controls to fix wave file headers.
* @author Jamie Macaulay
*
*/
public class FixWavPane extends PamBorderPane {
public FixWavPane(FolderInputSystem folderInputSystem) {
this.setCenter(new Label("Hello fix wav pane"));
}
}

View File

@ -143,7 +143,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
/**
* Pane to fix the headers of wave files.
*/
private FixWavPane fixWavPane;
private CheckWavHeadersPane fixWavPane;
/**
* Toggle button for merging contigious files
@ -166,6 +166,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
this.folderInputSystem=folderInputSystem2;
this.acquisitionPaneFX = acquisitionPaneFX;
this.mainPane=createDAQPane();
this.mainPane.setPrefWidth(300);
}
/**
@ -198,7 +199,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
browseFileButton.setGraphic(Glyph.create("FontAwesome|FILES_ALT").
size(PamGuiManagerFX.iconSize).color(Color.WHITE.darker()));
browseFileButton.prefHeightProperty().bind(fileSelectBox.heightProperty()); //make browse button same height as combo box.
browseFileButton.setMinWidth(30);
browseFileButton.setMinWidth(35);
browseFileButton.setOnAction( (action) ->{
selectFolder(false);
});
@ -208,7 +209,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
browseFolderButton.setGraphic(Glyph.create("FontAwesome|FOLDER").
size(PamGuiManagerFX.iconSize).color(Color.WHITE.darker()));
browseFolderButton.prefHeightProperty().bind(fileSelectBox.heightProperty()); //make browse button same height as combo box.
browseFolderButton.setMinWidth(30);
browseFolderButton.setMinWidth(35);
browseFolderButton.setOnAction( (action) ->{
selectFolder(true);
});
@ -244,7 +245,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
fileDateStrip.prefWidthProperty().bind(pamVBox.widthProperty());
fixWavPane = new FixWavPane(folderInputSystem);
fixWavPane = new CheckWavHeadersPane(folderInputSystem);
Label utilsLabel=new Label("Sound file utilities");
PamGuiManagerFX.titleFont2style(utilsLabel);
@ -323,10 +324,11 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
table.setEditable(true);
TableColumn<WavFileType, Boolean > useWavFileColumn = new TableColumn<>( "Use file" );
TableColumn<WavFileType, Boolean > useWavFileColumn = new TableColumn<>( "Use" );
useWavFileColumn.setCellValueFactory(cellData -> cellData.getValue().useWavFileProperty());
useWavFileColumn.setCellFactory( tc -> new CheckBoxTableCell<>());
useWavFileColumn.setEditable(true);
useWavFileColumn.setMaxWidth(40);
TableColumn<WavFileType, String > fileNameColumn = new TableColumn<WavFileType, String >("File Name");
fileNameColumn.setCellValueFactory( f -> new SimpleStringProperty(f.getValue().getName()));
@ -342,12 +344,13 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
TableColumn<WavFileType, Float > durationColumn = new TableColumn<WavFileType, Float > ("Duration");
durationColumn.setCellValueFactory(cellData -> new SimpleFloatProperty(cellData.getValue().getDurationInSeconds()).asObject());
TableColumn<WavFileType, Float > sampleRateColumn = new TableColumn<WavFileType, Float > ("Sample Rate");
TableColumn<WavFileType, Float > sampleRateColumn = new TableColumn<WavFileType, Float > ("sR");
sampleRateColumn.setCellValueFactory(cellData -> new SimpleFloatProperty(cellData.getValue().getAudioInfo().getSampleRate()).asObject());
//
TableColumn<WavFileType, Integer > chanColumn = new TableColumn<WavFileType, Integer > ("No. Channels");
TableColumn<WavFileType, Integer > chanColumn = new TableColumn<WavFileType, Integer > ("Chan");
chanColumn.setCellValueFactory(cellData -> new SimpleIntegerProperty(cellData.getValue().getAudioInfo().getChannels()).asObject());
useWavFileColumn.setPrefWidth(70);
TableColumn<WavFileType, String > typeColumn = new TableColumn<WavFileType, String > ("Type");

View File

@ -62,6 +62,7 @@ public class RawOrFFTPane extends SettingsPane<RawOrFFTParamsInterface> {
// BorderPane.setMargin(fftSourcePane, new Insets(15, 0, 0, 0));
beamDataSourcePane = new SourcePaneFX(FFTDataUnit.class, false, false);
beamDataSourcePane.addSourceType(RawDataUnit.class, false);
beamDataSourcePane.setMaxWidth(Double.POSITIVE_INFINITY);
/*
*
sourceList.setMaxWidth(Double.MAX_VALUE);

View File

@ -10,6 +10,7 @@ import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import PamUtils.PamArrayUtils;
import PamView.GeneralProjector;
import PamView.GeneralProjector.ParameterType;
import PamView.dialog.GenericSwingDialog;
@ -63,7 +64,8 @@ public class StandardSymbolChooser extends PamSymbolChooser {
ArrayList<SymbolModifier> modifiers = getSymbolModifiers();
// System.out.println("StandardSymbolChooser: " + modifiers.size() + " Defualt shape: " + options.symbolData.symbol);
// System.out.println("StandardSymbolOptions: " + options);
// System.out.println("StandardSymbolOptions: " + mord.length + " " + this.getSymbolManager() + " " + options);
// PamArrayUtils.printArray(mord);
if (modifiers == null || modifiers.size() == 0) {
return symbolData;

View File

@ -4,6 +4,7 @@ import java.awt.Color;
import java.io.Serializable;
import java.util.HashMap;
import PamUtils.PamArrayUtils;
import PamView.symbol.modifier.SymbolModifier;
import PamView.symbol.modifier.SymbolModifierParams;
@ -138,7 +139,7 @@ public class StandardSymbolOptions extends PamSymbolOptions implements Serializa
* @return the modifierOrder
*/
public int[] getModifierOrder(StandardSymbolChooser symbolChooser) {
if (modifierOrder == null || modifierOrder.length != symbolChooser.getSymbolModifiers().size()) {
if (modifierOrder == null || modifierOrder.length != symbolChooser.getSymbolModifiers().size() || PamArrayUtils.contains(modifierOrder, -1)) {
modifierOrder = new int[symbolChooser.getSymbolModifiers().size()];
for (int i = 0; i < modifierOrder.length; i++) {
modifierOrder[i] = i;

View File

@ -40,9 +40,6 @@ import javax.swing.Timer;
import networkTransfer.receive.BuoyStatusDataUnit;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import PamController.PamControlledUnit;
import PamController.PamController;
import PamController.PamControllerInterface;

View File

@ -21,6 +21,7 @@ import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
@ -41,7 +42,7 @@ public class BearLocAlgorithmPane extends SettingsPane<BearingLocaliserParams> {
this.bfLocControl = bfLocControl;
algoPane = new GridPane();
algoPane.setVgap(2);
algoPane.setHgap(12);
algoPane.setHgap(5);
// algoPane.setPadding(new Insets(2, 12, 2, 12));
mainPane = new PamBorderPane(new PamTitledBorderPane("Algorithm selection", algoPane));
mainPane.setPadding(new Insets(10, 5, 10, 5));
@ -140,6 +141,9 @@ public class BearLocAlgorithmPane extends SettingsPane<BearingLocaliserParams> {
algoPane.add(idLab = new Label(String.format("%d", i)), 0, iRow);
GridPane.setHalignment(idLab, HPos.CENTER);
algoSelection[i] = new ChoiceBox<>();
algoSelection[i].setMaxWidth(Double.POSITIVE_INFINITY);
algoSelection[i].setPrefWidth(150);
GridPane.setHgrow(algoSelection[i], Priority.ALWAYS); //stop the choice box from changing size on selection
for (BearingAlgorithmProvider anAlgo:allAlgorithms) {
algoSelection[i].getItems().add(anAlgo.getStaticProperties().getName());
}

View File

@ -74,6 +74,7 @@ public class BearLocGroupPane extends SettingsPane<BearingLocaliserParams> {
@Override
public void setParams(BearingLocaliserParams params) {
System.out.println("Bearing Localiser: params: " + params.getChannelBitmap());
groupedChannelPanel.setParams(params.getRawOrFFTSourceParameters());
doAllGroups.setSelected(params.doAllGroups);
}

View File

@ -26,6 +26,7 @@ import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamTextField;
@ -50,6 +51,8 @@ public class BearLocSourcePane extends SettingsPane<BearingLocaliserParams> {
// sourcePane.setVgap(3);
// sourcePane.setHgap(4);
detSourcePane = new SourcePaneFX(PamDetection.class, false, true);
detSourcePane.setMaxWidth(Double.POSITIVE_INFINITY);
GridPane.setHgrow(detSourcePane, Priority.ALWAYS);
// sourcePane.add(detSourcePane, 0, 2);
sourcePane.add(detSourcePane, 0, 0);
mainPane.setTop(new PamTitledBorderPane("Detection Source", sourcePane));

View File

@ -118,8 +118,7 @@ public class CTClassificationProcess extends PamInstantProcess {
@Override
public void pamStart() {
System.out.println("-----||||| This parent block: " + this.getParentDataBlock() + " " + this.getParentProcess());
//System.out.println("-----||||| This parent block: " + this.getParentDataBlock() + " " + this.getParentProcess());
}
@Override

View File

@ -66,6 +66,11 @@ public class ClickTrainControl extends PamControlledUnit implements PamSettings
*/
public static final int NEW_PARENT_DATABLOCK= 3;
/**
* The PAMGuard clock has been updated.
*/
public static final int CLOCK_UPDATE = 4;
/**
* Reference to the click train process.
*/
@ -233,7 +238,7 @@ public class ClickTrainControl extends PamControlledUnit implements PamSettings
}
for (int i=0; i<this.clickTrainAlgorithms.size(); i++) {
clickTrainAlgorithms.get(i).update(ClickTrainControl.NEW_PARAMS);
clickTrainAlgorithms.get(i).update(ClickTrainControl.NEW_PARAMS, null);
}
//set up the classifier parameters
@ -326,7 +331,7 @@ public class ClickTrainControl extends PamControlledUnit implements PamSettings
*/
public void update(int flag) {
for (int i=0; i<this.clickTrainAlgorithms.size(); i++) {
clickTrainAlgorithms.get(i).update(flag);
clickTrainAlgorithms.get(i).update(flag, null);
}
}
@ -537,6 +542,7 @@ public class ClickTrainControl extends PamControlledUnit implements PamSettings
return clAlgorithmInfoManager;
}

View File

@ -182,6 +182,13 @@ public class ClickTrainProcess extends PamInstantProcess {
public ClickTrainControl getClickTrainControl() {
return this.clickTrainControl;
}
@Override
public void masterClockUpdate(long timeMilliseconds, long sampleNumber) {
super.masterClockUpdate(timeMilliseconds, sampleNumber);
this.clickTrainControl.getCurrentCTAlgorithm().update(ClickTrainControl.CLOCK_UPDATE, Long.valueOf(timeMilliseconds));
}
// /**

View File

@ -32,9 +32,10 @@ public interface ClickTrainAlgorithm {
/**
* Send update flag to the algorithm
* @param object - an object to add to update
* @param flag - the flag.
*/
public void update(int i);
public void update(int i, Object object);
/**
* Get logging class for click algorithm specific information.

View File

@ -44,7 +44,7 @@ public class RatioClickTrainAlgorithm implements ClickTrainAlgorithm {
}
@Override
public void update(int i) {
public void update(int i, Object data) {
// TODO Auto-generated method stub
}

View File

@ -15,7 +15,7 @@ public class MHTChi2Params implements Cloneable, Serializable, ManagedParameters
*/
private static final long serialVersionUID = 1L;
/**
* The absolute maximum ICI for a click train
* The absolute maximum ICI for a click train in seconds!
*/
public double maxICI = 0.4;

View File

@ -217,6 +217,25 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
}
}
}
/**
* Check for garbage collection based on the current time. This is used when, for example, no click are detected for a
* long period.
* @param timeMillis - the time in millis
* @param mhtAlgorithm - the channel based MHTAlgorithm.
*/
private void checkCTGarbageCollect(long timeMillis, MHTAlgorithm mhtAlgorithm) {
boolean isGarbage = this.mhtGarbageBot.checkCTGarbageCollect(timeMillis, mhtAlgorithm.getMHTKernal());
if (isGarbage) {
//grab tracks
mhtAlgorithm.getMHTKernal().confirmRemainingTracks();
grabDoneTrains(mhtAlgorithm);
//reset the kernel;
mhtAlgorithm.getMHTKernal().clearKernel();
}
}
// /**
// * Get the interval between the new unit and the last unit.
@ -396,7 +415,7 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
* Update the algorithm
* @param flag- flag indicating the update type.
*/
public void update(int flag) {
public void update(int flag, Object info) {
switch (flag) {
case ClickTrainControl.PROCESSING_START:
@ -437,10 +456,16 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
case ClickTrainControl.NEW_PARAMS:
setupAlgorithm();
break;
case ClickTrainControl.CLOCK_UPDATE:
for (int i=0; i<this.mHTAlgorithms.size(); i++) {
checkCTGarbageCollect((Long) info, mHTAlgorithms.get(i));
}
break;
}
}
/**
* Set up the algorithm.
*/
@ -547,13 +572,12 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
*/
public void printSettings() {
System.out.println("/********MHT PARAMS*******/");
pamMHTChi2.printSettings();
mhtKernal.getMHTParams().printSettings();
System.out.println("/*************************/");
Debug.out.println("/********MHT PARAMS*******/");
if (Debug.isPrintDebug()) {
pamMHTChi2.printSettings();
mhtKernal.getMHTParams().printSettings();
}
Debug.out.println("/*************************/");
// //MHT kernel params
// System.out.println("npruneback: " + mhtKernal.getMHTParams().nPruneback);

View File

@ -59,8 +59,8 @@ public class MHTGarbageBot {
* then the possibility matrix will simply keep resizing and click train
* detector will run indefinitely.
*
* @param - the new data unit
* @param -the channel based MHTAlgorithm.
* @param dataUnit - the new data unit
* @param mhtKernel - the current MHT Kernel.
* @return - true if a garbage collection task was executed.
*/
public boolean checkCTGarbageCollect(PamDataUnit dataUnit, MHTKernel<PamDataUnit> mhtKernel) {
@ -126,6 +126,25 @@ public class MHTGarbageBot {
return false;
}
/**
* Check whether a garbage collection of the hypothesis matrix is required based on current time rather than the current data unit.
* @param currentTimemillis - the current time in millis
* @param mhtKernel - the MHT kernel
* @return true if a garbage collect is required.
*/
public boolean checkCTGarbageCollect(long currentTimemillis, MHTKernel<PamDataUnit> mhtKernel) {
if (mhtKernel.getLastDataUnit()==null) return false;
if ((currentTimemillis - mhtKernel.getLastDataUnit().getTimeMilliseconds())
>mhtKernel.getMHTParams().maxCoast*mhtKernel.getMHTChi2Provider().getChi2Params().maxICI*1000.) {
return true;
}
return false;
}
/**
* Get the interval between the new unit and the last unit.
* @param dataUnit - get the data units.

View File

@ -263,7 +263,7 @@ public class ClickTrainAlgorithmPaneFX extends SettingsPane<ClickTrainParams> {
clickTrainControl.createDataSelector(sourcePane.getSource());
System.out.println("ClickTrainAlgorithmPaneFX: Detection Selector: " + clickTrainControl.getDataSelector() + " " + sourcePane.getSource());
//System.out.println("ClickTrainAlgorithmPaneFX: Detection Selector: " + clickTrainControl.getDataSelector() + " " + sourcePane.getSource());
if (clickTrainControl.getDataSelector()!=null) {
Label dataSelectorLabel = new Label("Detection Selector");
@ -557,8 +557,8 @@ public class ClickTrainAlgorithmPaneFX extends SettingsPane<ClickTrainParams> {
this.ctClassifierHolder.setParams(clickTrainParams);
//notify the algorithm of updates.
System.out.println("getSelectedCTAlgorithm(): " + getSelectedCTAlgorithm());
System.out.println("getSelectedCTAlgorithm().getClickTrainGraphics(): " + getSelectedCTAlgorithm().getClickTrainGraphics());
// System.out.println("getSelectedCTAlgorithm(): " + getSelectedCTAlgorithm());
// System.out.println("getSelectedCTAlgorithm().getClickTrainGraphics(): " + getSelectedCTAlgorithm().getClickTrainGraphics());
getSelectedCTAlgorithm().getClickTrainGraphics().notifyUpdate(ClickTrainControl.NEW_PARENT_DATABLOCK,
sourcePane.getDataBlockBox().getSelectionModel().getSelectedItem());

View File

@ -571,13 +571,17 @@ public class Scrolling2DPlotDataFX {
/****Some useful variables used all the time**/
//Note - "imageXX" indicates that the number refers to pixels in the writable images
// - "screenXX" indicates the number refers to pixels on the screen.
//time axis
private double tScale; // the time scale in pixels per millisecond.
// private long wrapLengthMillis; //the length of the left wrap section in millis
private double wrapScreenPix; //the number of screen pixels the wrap takes up
private double wrapImagePixdw; //the length of the wrap section in spectrogram image pixels (not time display pixels)
private double imagePixdw; // the width of the screen in image pixels.
private double imagestart; //the start of time image
private double imageStart1; //the start of time image
private double imageStart2; //the start of the image for the second wrap segment
private double endScreenPix; //the end of the screen in pixels. This s not just timePixels
private double nImagePixs;//the number of pixels on image in memory, from zero to current location of pointer.
//the number of screen pixels corresponding to the current position on the writable image to zero.
@ -585,10 +589,19 @@ public class Scrolling2DPlotDataFX {
private double scrollEndTime; //the current time.
//location to start drawing image on screen from.
private double screenStartPix;
//freq axis
/**Frequency (vertical) axis***/
private double freqPixels;
private double imageFP1, imageFP2;
private double freqWidth;
/*
* The maximum pixel jitter allowed. The calculated image start position can jitter because
* of rounding errors. MAX_PIXEL_JITTER ensures that the image location is kep constant for
* different frames by assumin that any chnage below MAX_PIXEL_JITTER is a rounding error and not
* a change in the display.
*/
private double MAX_PIXEL_JITTER = 3; //pixels
public double drawSpectrogramWrap(GraphicsContext g2d, double timePixels, double freqPixels, PamAxisFX timeAxis,
@ -609,69 +622,89 @@ public class Scrolling2DPlotDataFX {
//the length of the wrap section in spectrogram image pixels (not time display pixels)
wrapImagePixdw=wrapScreenPix/(timeScale * 1000. * tScale * timeCompression);
imagePixdw = timePixels/(timeScale * 1000. * tScale * timeCompression);
// System.out.println(String.format(" timeScale %.3f timeCompression %d timePixels %.3f wrapImagePixdw %.3f",
// timeScale, timeCompression, timePixels, wrapImagePixdw));
imagePixdw= timePixels/(timeScale * 1000. * tScale * timeCompression);
//the start of time image
imagestart=imageXPos+1-wrapImagePixdw;
/**
* Because everything related to pixel measurements is a double in JavaFX we sometimes
* get a rounding issue which means the wrap display. The way to get around this is to only
* change the imageStart whenever the displays finishes wrapping. It's a bit of a HACK but it
* works.
*/
double imageStart=imageXPos+1-wrapImagePixdw;
if (Math.abs(imageStart-this.imageStart1)>=MAX_PIXEL_JITTER) {
//System.out.println("Reset image start: " + imageStart + " " + this.imageStart1);
this.imageStart1=imageStart;
}
//location to start drawing image on screne from.
screenStartPix=0;
if (imagestart<-1){
if (this.imageStart1<-1){
//gotta shift the start of the screen a bit if there is not enough image
screenStartPix=(Math.abs(imagestart))*timeScale * 1000. * tScale * timeCompression;
screenStartPix=(Math.abs(imageStart1))*timeScale * 1000. * tScale * timeCompression;
}
// System.out.println("imageXPos: "+imageXPos+"wrapLengthMillis: "+wrapLengthMillis+ " wrapScreenPix "+wrapScreenPix+
// " wrapScreenPixdw: "+wrapScreenPix+ " wrapImagePixdw: "+wrapImagePixdw+ " imagestart: "+
// imagestart + "nScreenPix: "+nScreenPix);
//System.out.println(String.format(" imageStart %.4f imageXPos %.4f imagePixdw %.4f", imageStart1,imageXPos, imagePixdw ));
/**
* Lift as much as possible into first section
*/
g2d.drawImage(writableImage, Math.max(0,imagestart), freqBinRange[1], wrapImagePixdw, freqWidth,
g2d.drawImage(writableImage, Math.max(0,this.imageStart1), freqBinRange[1], wrapImagePixdw, freqWidth,
screenStartPix, imageFP1, wrapScreenPix, imageFP2);
if (imagestart<-1){
if (imageStart1<-1){
/**
* If this occurs, the image is negative, i.e. we have to go back and fill a bit in from the end of the image in the wrap section.
*/
g2d.drawImage(writableImage, writableImage.getWidth()+imagestart, freqBinRange[1], Math.abs(imagestart), freqWidth,
g2d.drawImage(writableImage, writableImage.getWidth()+ imageStart1, freqBinRange[1], Math.abs(imageStart1), freqWidth,
0, imageFP1, screenStartPix, imageFP2);
}
//System.out.println(String.format(" totalXDraw %d wrapImagePixdw %.2f", totalXDraw,wrapImagePixdw ));
if (totalXDraw>imagePixdw){
imagestart=imageXPos+1-imagePixdw;
/**
* Because imageStart1 has remained clamped to prevent jitter in the image, we have to add a compensation factor
* to prevent jitter on the other half of the image. The compensation factor is the difference between the clamped
* start of the image (imageStart1) and the true image start (imagesStart)
*/
imageStart2= imageXPos +1 - imagePixdw- (imageStart-this.imageStart1);
//System.out.println(String.format(" imageStart %.4f imageXPos %.4f imagePixdw %.4f", imageStart,imageXPos, imagePixdw ));
screenStartPix= wrapScreenPix;
imagePixdw=imagePixdw-wrapImagePixdw;
if (imagestart<-1){
imagePixdw=imagePixdw - wrapImagePixdw;
if (imageStart2<-1){
/**
* Cannot fill the entire area in one go without going into negative parts of the image.
*/
screenStartPix=wrapScreenPix+(Math.abs(imagestart))*timeScale * 1000. * tScale * timeCompression;
imagePixdw=imagePixdw+imagestart;
screenStartPix=wrapScreenPix+(Math.abs(imageStart2))*timeScale * 1000. * tScale * timeCompression;
imagePixdw=imagePixdw+imageStart2;
}
//System.out.println(String.format(" imagestart %.3f imagePixdw %.3f screenstart %.3f", imagestart, imagePixdw,(timePixels-(endScreenPix-timePixels)+wrapScreenPix)));
//System.out.println(String.format(" imagestart %.3f imagePixdw %.3f screenStartPix %.3f imageXPos %.3f", imageStart2, imagePixdw, screenStartPix, imageXPos));
/**
* Now draw the data after the wrap line. i.e. the older part of the image
*/
g2d.drawImage(writableImage, Math.max(0,imagestart), freqBinRange[1], imagePixdw, freqWidth,
g2d.drawImage(writableImage, Math.max(0,imageStart2), freqBinRange[1], imagePixdw, freqWidth,
screenStartPix, imageFP1, timePixels-screenStartPix, imageFP2);
if (imagestart<-1){
if (imageStart2<-1){
/**
* Fill the remaining section with the negative parts of the image
*/
g2d.drawImage(writableImage, writableImage.getWidth()+imagestart, freqBinRange[1], Math.abs(imagestart), freqWidth,
g2d.drawImage(writableImage, writableImage.getWidth()+imageStart2, freqBinRange[1], Math.abs(imageStart2), freqWidth,
wrapScreenPix, imageFP1, screenStartPix-wrapScreenPix, imageFP2);
}

View File

@ -207,11 +207,11 @@ public class GroupedChannelPaneFX {
}
protected void showChannels(int channels) {
//remove all channels from vertical box pane.
channelListPane.getChildren().removeAll(channelListPane.getChildren());
channelListPane.getChildren().remove(selectAll);
channelListPane.getChildren().remove(selectAll);
channelListPane.add(selectAll,0,0);
for (int i = 0; i < Math.min(PamConstants.MAX_CHANNELS, channelBoxes.length); i++) {
@ -306,13 +306,16 @@ public class GroupedChannelPaneFX {
}
public void setParams(GroupedSourceParameters params) {
/**
* First try to find the source datablock and from there set up
* the panel.
*/
*/
PamController pamController = PamController.getInstance();
sourceDataBlock = pamController.getDataBlockByLongName(params.getDataSource());
setSourceDataBlock(sourceDataBlock);
if (sourceDataBlock != null) {
// showChannels(sourceDataBlock.getChannelMap());
showChannels(sourceDataBlock.getSequenceMap());

View File

@ -2,6 +2,7 @@ package pamViewFX.fxNodes.utilityPanes;
import java.io.Serializable;
import javafx.geometry.Pos;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
@ -57,6 +58,7 @@ public class MinMaxPane<T extends Number> extends PamBorderPane {
PamHBox pamHBox = new PamHBox();
pamHBox.setSpacing(5);
pamHBox.setAlignment(Pos.CENTER_LEFT);
//e
checkBox = new CheckBox(varName);

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.controlsfx.control.ToggleSwitch;
import PamUtils.PamArrayUtils;
import PamView.symbol.ManagedSymbolData;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
@ -248,6 +249,10 @@ public class StandardSymbolOptionsPane extends FXSymbolOptionsPane<StandardSymbo
for (int i=0; i<modifierorder.length; i++ ) {
modifierorder[i] = getWhichChooser().getSymbolModifiers().indexOf(sortedPanelist.get(i).getSymbolModifier());
}
// System.out.println("Modifier Order: " + standardSymbolManager);
// PamArrayUtils.printArray(modifierorder);
return modifierorder;
}

View File

@ -14,6 +14,7 @@ import PamguardMVC.PamObservable;
import PamguardMVC.PamProcess;
import binaryFileStorage.DataUnitFileInformation;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.RawDLParams;
import rawDeepLearningClassifier.layoutFX.DLDetectionGraphics;
import rawDeepLearningClassifier.layoutFX.DLGraphics;
import rawDeepLearningClassifier.logging.DLAnnotation;
@ -127,7 +128,7 @@ public class DLClassifyProcess extends PamInstantProcess {
*/
private void setupClassifierProcess() {
System.out.println("Setup raw deep learning classiifer process: ");
//System.out.println("Setup raw deep learning classiifer process: ");
if (dlControl.getDLParams()==null) {
System.err.println("SegmenterProcess.setupSegmenter: The DLParams are null???");
@ -138,6 +139,11 @@ public class DLClassifyProcess extends PamInstantProcess {
System.err.println("Raw Deep Learning Classifier: The grouped source parameters were null."
+ " A new instance has been created: Possible de-serialization error.");
}
//important for downstream processes such as the bearing localiser.
dlModelResultDataBlock.setChannelMap(dlControl.getDLParams().groupedSourceParams.getChannelBitmap());
dlDetectionDataBlock.setChannelMap(dlControl.getDLParams().groupedSourceParams.getChannelBitmap());
int[] chanGroups = dlControl.getDLParams().groupedSourceParams.getChannelGroups();
@ -159,6 +165,20 @@ public class DLClassifyProcess extends PamInstantProcess {
public void prepareProcess() {
setupClassifierProcess();
}
/**
* called for every process once the system model has been created.
* this is a good time to check out and find input data blocks and
* similar tasks.
*
*/
@Override
public void setupProcess() {
setupClassifierProcess();
super.setupProcess();
}
/*
@ -233,7 +253,6 @@ public class DLClassifyProcess extends PamInstantProcess {
//1) It's over a max time
//2) Contains different parent data units (if not from raw data).
GroupedRawData lastUnit = classificationBuffer2.get(classificationBuffer2.size()-1);
if (!(lastUnit.getParentDataUnit() instanceof RawDataUnit) && lastUnit.getParentDataUnit()!=rawDataUnit.getParentDataUnit()) {
@ -255,7 +274,7 @@ public class DLClassifyProcess extends PamInstantProcess {
// if (timeDiff>=this.dlControl.getDLParams().maxBufferTime) {
//we are over the max buffer size.
System.out.println("DLClassifyProcess: warning: buffer is over max time gap");
//System.out.println("DLClassifyProcess: warning: buffer is over max time gap");
return true;
}
@ -280,7 +299,8 @@ public class DLClassifyProcess extends PamInstantProcess {
}
/**
* Create a data unit form a model result.
* Create a data unit form a model result. This is called whenever data passes a prediction threshold.
*
* @param modelResult - the model result.
* @param pamRawData - the raw data unit which the model result came from.
*/
@ -288,7 +308,7 @@ public class DLClassifyProcess extends PamInstantProcess {
//the model result may be null if the classifier uses a new thread.
//System.out.println("New segment: parent UID: " + pamRawData.getParentDataUnit().getUID() + " Prediciton: " + modelResult.getPrediction()[4]);
//System.out.println("New segment: parent UID: " + pamRawData.getParentDataUnit().getUID() + " Prediciton: " + modelResult.getPrediction()[0]+ " " + getSourceParams().countChannelGroups());
//create a new data unit - always add to the model result section.
DLDataUnit dlDataUnit = new DLDataUnit(pamRawData.getTimeMilliseconds(), pamRawData.getChannelBitmap(),
@ -303,11 +323,14 @@ public class DLClassifyProcess extends PamInstantProcess {
//need to implement multiple groups.
for (int i=0; i<getSourceParams().countChannelGroups(); i++) {
// System.out.println("RawDataIn: chan: " + pamRawData.getChannelBitmap()+ " " +
// PamUtils.hasChannel(getSourceParams().getGroupChannels(i), pamRawData.getChannelBitmap()) +
// " grouped source: " +getSourceParams().getGroupChannels(i));
// System.out.println("RawDataIn: chan: " + pamRawData.getChannelBitmap()+ " " +
// PamUtils.hasChannel(getSourceParams().getGroupChannels(i), pamRawData.getChannelBitmap()) +
// " grouped source: " +getSourceParams().getGroupChannels(i) + " Channels OK? "
// +PamUtils.hasChannel(getSourceParams().getGroupChannels(i), PamUtils.getSingleChannel(pamRawData.getChannelBitmap()))
// + " groupchan: " + getSourceParams().getGroupChannels(i) + " " + PamUtils.getLowestChannel(pamRawData.getChannelBitmap())
// + " chan bitmap: " + pamRawData.getChannelBitmap());
if (PamUtils.hasChannel(getSourceParams().getGroupChannels(i), PamUtils.getSingleChannel(pamRawData.getChannelBitmap()))) {
if (PamUtils.hasChannel(getSourceParams().getGroupChannels(i), PamUtils.getLowestChannel(pamRawData.getChannelBitmap()))) {
/***
* The are two options here.
@ -316,6 +339,8 @@ public class DLClassifyProcess extends PamInstantProcess {
* 2) Annotated an existing data unit with a deep learning annotation.
*/
if (pamRawData.getParentDataUnit() instanceof RawDataUnit) {
/****Make our own data units****/
if (dlDataUnit.getPredicitionResult().isBinaryClassification()) {
//if the model result has a binary classification then it is added to the data buffer unless the data
//buffer has reached a maximum size. In that case the data is saved.
@ -345,9 +370,11 @@ public class DLClassifyProcess extends PamInstantProcess {
}
}
else {
//need to go by the parent data unit for merging data not the segments.
/****Add annotation to existing data unit (e.g. click, clip or other RawDataHolder)****/
//Need to go by the parent data unit for merging data not the segments. Note that we may still add multiple
//predicitions to a single data unit depending on how many segments it contains.
//System.out.println("New model data " + pamRawData.getParentDataUnit().getUID() + " " + groupDataBuffer[i].size() + " " + modelResultDataBuffer[i].size());
System.out.println("New model data " + pamRawData.getParentDataUnit().getUID() + " " + groupDataBuffer[i].size() + " " + modelResultDataBuffer[i].size());
if (pamRawData.getParentDataUnit()!=lastParentDataUnit[i]) {
//save any data
@ -371,7 +398,6 @@ public class DLClassifyProcess extends PamInstantProcess {
lastParentDataUnit[i]=pamRawData.getParentDataUnit();
groupDataBuffer[i].add(pamRawData);
modelResultDataBuffer[i].add(modelResult);
//System.out.println("Buffer click annotation to " + lastParentDataUnit[i].getUID() + " " + groupDataBuffer[i].size());
}
}
@ -558,4 +584,12 @@ public class DLClassifyProcess extends PamInstantProcess {
return dlAnnotationType;
}
/**
* Get the parameters for the raw deep learning module.
* @return the parameters object for the raw deep learning classifier.
*/
public RawDLParams getDLParams() {
return this.dlControl.getDLParams();
}
}

View File

@ -1,8 +1,8 @@
package rawDeepLearningClassifier.dlClassification;
import PamView.GroupedDataSource;
import PamView.GroupedSourceParameters;
import PamguardMVC.AcousticDataBlock;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
/**
* Holds classified data units from deep learning model.
@ -10,11 +10,18 @@ import PamguardMVC.PamProcess;
* @author Jamie Macaulay
*
*/
public class DLDetectionDataBlock extends AcousticDataBlock<DLDetection> {
public class DLDetectionDataBlock extends AcousticDataBlock<DLDetection> implements GroupedDataSource {
public DLDetectionDataBlock(String dataName, PamProcess parentProcess, int channelMap) {
private DLClassifyProcess dlClassifyProcess;
public DLDetectionDataBlock(String dataName, DLClassifyProcess parentProcess, int channelMap) {
super(DLDetection.class, dataName, parentProcess, channelMap);
this.dlClassifyProcess = parentProcess;
}
@Override
public GroupedSourceParameters getGroupSourceParameters() {
return dlClassifyProcess.getDLParams().groupedSourceParams;
}

View File

@ -375,7 +375,7 @@ public class SegmenterProcess extends PamProcess {
if (currentRawChunks[i]==null) {
//create a new data unit - should only be called once after initial start.
currentRawChunks[i] = new GroupedRawData(timeMilliseconds, getSourceParams() .getGroupChannels(i),
currentRawChunks[i] = new GroupedRawData(timeMilliseconds, getSourceParams().getGroupChannels(i),
startSampleTime, dlControl.getDLParams().rawSampleSize, dlControl.getDLParams().rawSampleSize);
currentRawChunks[i].setParentDataUnit(unit);;
}
@ -388,7 +388,7 @@ public class SegmenterProcess extends PamProcess {
//current time milliseconds is referenced from the first chunk with samples added. But, this can mean, especially for long period of times and multiple
//chunks that things get a bit out of sync. So make a quick check to ensure that time millis is roughly correct. If not then fix.
if (Math.abs(((double) currentRawChunks[i].getTimeMilliseconds() + 1000.*currentRawChunks[i].getRawDataPointer()[0]/this.getSampleRate()) - timeMilliseconds)>MAX_MILLIS_DRIFT) {
Debug.out.println("DL SEGMENTER: RESETTING TIME: ");
//Debug.out.println("DL SEGMENTER: RESETTING TIME: ");
currentRawChunks[i].setTimeMilliseconds((long) (timeMilliseconds - 1000.*currentRawChunks[i].getRawDataPointer()[0]/this.getSampleRate()));
currentRawChunks[i].setStartSample(startSampleTime-currentRawChunks[i].getRawDataPointer()[0]);
}
@ -690,6 +690,7 @@ public class SegmenterProcess extends PamProcess {
for (int i =0; i<rawData.length; i++) {
rawData[i] = new double[samplesize];
}
}
/**