Updates to exporter and data map in FX GUI

This commit is contained in:
Jamie Mac 2024-08-21 12:53:53 +01:00
parent 791dad9439
commit 2c11ff435b
28 changed files with 1310 additions and 809 deletions

View File

@ -6,7 +6,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-21.0.2.13-hotspot">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/Amazon Coretto 21">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>

View File

@ -65,7 +65,7 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
/**
* Pane which allows users to change scale on datamap.
*/
private ScalePaneFX scalePane;
private DataMapSettingsPane dataMapSettingsPane;
private PamVBox settingsPane;
@ -87,14 +87,14 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
//create all the different panes,
summaryPane = new SummaryPaneFX(dataMapControl, this);
scalePane=new ScalePaneFX(dataMapControl,this);
scrollingDataPanel= new ScrollingDataPaneFX(dataMapControl, this);
dataMapSettingsPane=new DataMapSettingsPane(dataMapControl,this);
//create the setting spane
settingsPane=new PamVBox();
// settingsPane.getChildren().add(summaryPane);
settingsPane.getChildren().add(scalePane);
settingsPane.getChildren().add(dataMapSettingsPane.getContentNode());
settingsPane.setPadding(new Insets(40,10,10,10));
settingsPane.setPrefWidth(HIDE_PANE_WIDTH);
@ -178,12 +178,11 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
* Called from ScalePanel when anything
* to do with scaling changes.
*/
@Deprecated
public void scaleChanged() {
if (scalePane == null || scrollingDataPanel == null) {
if (dataMapSettingsPane == null || scrollingDataPanel == null) {
return;
}
scalePane.getParams(dataMapControl.dataMapParameters);
dataMapSettingsPane.getParams(dataMapControl.dataMapParameters);
//scrollingDataPanel.scaleChange();
}
@ -228,24 +227,30 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
switch (changeType) {
case PamControllerInterface.INITIALIZATION_COMPLETE:
scrollingDataPanel.updateScrollBar();
scalePane.checkDataGramPane();
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
this.repaintAll();
break;
case PamControllerInterface.CHANGED_OFFLINE_DATASTORE:
scrollingDataPanel.updateScrollBar();
scalePane.checkDataGramPane();
dataMapSettingsPane.checkDataGramPane();
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
break;
case PamControllerInterface.ADD_CONTROLLEDUNIT:
scalePane.checkDataGramPane();
case PamControllerInterface.REMOVE_CONTROLLEDUNIT:
scalePane.checkDataGramPane();
dataMapSettingsPane.checkDataGramPane();
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
break;
case PamControllerInterface.INITIALIZE_LOADDATA:
case PamControllerInterface.EXTERNAL_DATA_IMPORTED:
scrollingDataPanel.updateScrollBar();
scalePane.checkDataGramPane();
dataMapSettingsPane.checkDataGramPane();
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
this.repaintAll();
break;
case PamControllerInterface.OFFLINE_DATA_LOADED:
scrollingDataPanel.updateScrollBar();
scalePane.checkDataGramPane();
dataMapSettingsPane.checkDataGramPane();
dataMapSettingsPane.setParams(dataMapControl.dataMapParameters);
this.repaintAll();
break;
case PamControllerInterface.DATA_LOAD_COMPLETE:
@ -304,4 +309,22 @@ public class DataMapPaneFX extends PamBorderPane implements UserDisplayNodeFX {
return null;
}
/**
* Get the current number of data stream panes
* @return the number of data stream panes
*/
public int getNumDataStreamPanes() {
return this.scrollingDataPanel.getNumDataStreamPanes();
}
/**
* Get a data stream pane.
* @param n - the index of the data stream pane
* @return the data stream pane or null if the index is out of bounds.
*/
public DataStreamPaneFX getDataStreamPane(int n) {
return this.scrollingDataPanel.getDataSyreamPane( n);
}
}

View File

@ -0,0 +1,489 @@
package dataMap.layoutFX;
import dataGram.DatagramManager;
import dataGram.DatagramScaleInformation;
import dataGram.DatagramSettings;
import dataMap.DataMapControl;
import dataMap.DataMapParameters;
import PamController.PamController;
import PamUtils.PamCalendar;
import binaryFileStorage.BinaryStore;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.comboBox.ColorComboBox;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxNodes.sliders.ColourRangeSlider;
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
import pamViewFX.fxNodes.utilsFX.ColourArray;
import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType;
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
/**
* Settings pane which allows users to change settings for data maps.
*
* @author Jamie Macaulay
*
*/
public class DataMapSettingsPane extends DynamicSettingsPane<DataMapParameters> {
/*
* Reference to the data map control.
*/
private DataMapControl dataMapControl;
/**
* Reference to the dataMapPane.
*/
private DataMapPaneFX dataMapPane;
// /**
// * The slider which determines time scale.
// */
// private Slider timeSlider;
/**
* Shows the time scale in pix/hour
*/
private Label timeScaleLabel;
/**
* Selects unit count on vertical scale
*/
private ComboBox<String> scaleBox;
/**
* Check box for log vertical scale.
*/
private PamToggleSwitch logScaleToggle;
// /**
// * The chosen time values.
// */
// private double[] timeScaleChoices = DataMapParameters.hScaleChoices;
/**
* Combo box holding options to channge the datargam bin size
*/
private ComboBox<String> datagramBox;
/**
* Holds a list of times for the datagram bin size.
*/
private ComboBox<String> dataGramComboBox;
/**
* Holds everything.
*/
private PamVBox holder;
/**
* Grid pane with settings for the data scales
*/
private PamGridPane scaleSettingsPane;
private Label dataGramLabel;
private ComboBox<String> dataGramBox;
/**
* Holdes datagram settings.
*/
private PamVBox dataGramSettingsPane;
private DataGramColPane dataGramColPane;
private PamBorderPane mainPain;
public DataMapSettingsPane(DataMapControl dataMapControl, DataMapPaneFX dataMapPane) {
super(null);
this.dataMapControl = dataMapControl;
this.dataMapPane = dataMapPane;
// //create the holder pane.
// PamVBox vBoxHolder=new PamVBox();
// vBoxHolder.setSpacing(5);
// Label title=new Label("Scales");
// PamGuiManagerFX.titleFont2style(title);
// vBoxHolder.getChildren().addAll(title, controlPane);
//add the scale
holder=new PamVBox();
holder.setSpacing(5);
Label scaleLabel = new Label("Data Scale");
PamGuiManagerFX.titleFont2style(scaleLabel);
holder.getChildren().add(scaleLabel);
holder.getChildren().add(scaleSettingsPane = createScalePane());
//adds the datagram settings pane which is dependent on binary storage.
checkDataGramPane();
mainPain = new PamBorderPane();
mainPain.setCenter(holder);
//set params for the pane
setParams(dataMapControl.dataMapParameters);
checkDataGramPane(); // create datagram pane if a binary store already added.
sayHScale();
}
/**
* Adds a settings pane for the data gram if a binary store is present.
*/
public void checkDataGramPane(){
if (BinaryStore.findBinaryStoreControl()!=null){
DatagramManager dataGramManager=BinaryStore.findBinaryStoreControl().getDatagramManager();
if (dataGramManager!=null && dataGramSettingsPane==null) {
PamVBox datagramholder = new PamVBox();
datagramholder.setSpacing(5);
Label datagramLabel = new Label("Datagrams");
PamGuiManagerFX.titleFont2style(datagramLabel);
datagramholder.getChildren().add(datagramLabel);
datagramholder.getChildren().add(createDatagramPane(dataGramManager));
holder.getChildren().add(this.dataGramSettingsPane = datagramholder);
}
}
else {
holder.getChildren().remove(this.dataGramSettingsPane);
datagramBox=null;
}
}
/**
* Create the a datagram combo box to change the size of the datagram
* @param dataGramManager - the datagram manager for the current biinary store.
* @return a combo box with datagram bin sizes.
*/
private ComboBox<String> createDataGramBinPane(DatagramManager dataGramManager){
dataGramComboBox=new ComboBox<String>(createDurationList(dataGramManager));
dataGramComboBox.getSelectionModel().select(durationToString(dataGramManager.getDatagramSettings().datagramSeconds*1000L));
dataGramComboBox.valueProperty().addListener(( ov, t, t1) -> {
if (t==t1) return;
else {
PamController.getInstance();
boolean ans=PamDialogFX.showWarning(PamController.getMainStage(), "Warning", "Recalculating the datagram for a large dataset may take a long time" +
"Are you sure you want to continue");
if (ans){
int index=dataGramComboBox.getSelectionModel().getSelectedIndex();
//messy- datagramSeconfds should be in millis but left for backwards compatibility.
dataGramManager.getDatagramSettings().datagramSeconds=(int) (DatagramSettings.defaultDatagramSeconds[index]/1000);
dataGramManager.updateDatagrams();
dataMapPane.repaintAll();
}
}
});
return dataGramComboBox;
}
/**
* Convert duration to string.
* @param duration in millis.
*/
private String durationToString(long duration){
return (" " + PamCalendar.formatDuration(duration));
}
/**
* Create list of load times.
* @return list of load times duration.
*/
private ObservableList<String> createDurationList(DatagramManager dataGramManager){
ObservableList<String> loadTimeList=FXCollections.observableArrayList();
for (int i=0; i<DatagramSettings.defaultDatagramSeconds.length; i++){
loadTimeList.add(durationToString(DatagramSettings.defaultDatagramSeconds[i]));
}
return loadTimeList;
}
private Pane createDatagramPane(DatagramManager dataGramManager) {
dataGramLabel= new Label("Datagram bin size");
ComboBox<String> datagramBinsBox = createDataGramBinPane(dataGramManager);
//Pane for colouring datagrams.
dataGramBox=new ComboBox<String> ();
//find all datagrams.
updateDataStreamBox();
dataGramBox.setOnAction((action)->{
dataGramColPane.setDataStreamPanel(dataMapPane.getDataStreamPane(dataGramBox.getSelectionModel().getSelectedIndex()));
});
//holds settings for the datagram
dataGramColPane = new DataGramColPane();
PamGridPane holder = new PamGridPane();
holder.setHgap(5);
holder.setVgap(5);
//holder.setGridLinesVisible(true);
int row = 0;
holder.add(dataGramLabel, 0,row);
holder.add(datagramBinsBox, 1, row);
row++;
holder.add(new Label("Select datagram"), 0, row);
holder.add(dataGramBox, 1, row);
row++;
GridPane.setHgrow(dataGramColPane, Priority.ALWAYS);
holder.add(dataGramColPane, 0, row);
//dunno why this always had to be set after the child has been added to work.
GridPane.setColumnSpan(dataGramColPane, 3);
//hack to make sure the third column of the gris expands to fit the pane
ColumnConstraints rightCol = new ColumnConstraints();
rightCol.setHgrow(Priority.ALWAYS);
holder.getColumnConstraints().addAll(new ColumnConstraints(), new ColumnConstraints(), rightCol);
return holder;
}
private void updateDataStreamBox() {
System.out.println("UPDATE DATA STREAM BOX: " + this.dataMapPane.getNumDataStreamPanes());
for (int i=0; i<this.dataMapPane.getNumDataStreamPanes(); i++) {
if (dataMapPane.getDataStreamPane(i).getScaleType() == DatagramScaleInformation.PLOT_3D) {
dataGramBox.getItems().add(dataMapPane.getDataStreamPane(i).getDataName().getName());
}
}
}
/**
* Allows the user to change datagram colours.
*
*/
public class DataGramColPane extends PamBorderPane {
private ColourRangeSlider colourSlider;
private Label ampLabel;
private ColorComboBox colorBox;
private ColourArrayType colorArray = ColourArrayType.HSV;
private DataStreamPaneFX dataStreamPane;
public DataGramColPane() {
//create colour slider
//colour slider
colourSlider=new ColourRangeSlider();
colourSlider.setShowTickMarks(false);
colourSlider.setShowTickLabels(false);
colourSlider.setOrientation(Orientation.HORIZONTAL);
//amplifier label
// String dBRef = GlobalMedium.getdBRefString(PamController.getInstance().getGlobalMediumManager().getCurrentMedium());
Label ampLabel = new Label("Colour scale");
colorBox=new ColorComboBox(ColorComboBox.COLOUR_ARRAY_BOX);
colorBox.setPrefWidth(80);
colourSlider.highValueProperty().addListener((obsVal, oldVal, newVal)->{
});
//Change the colour of the colour slider when combo box is changed.
colorBox.valueProperty().addListener(new ChangeListener<String>() {
@Override public void changed(ObservableValue<? extends String> ov, String t, String t1) {
//change the colour of the colour range slider.
setColours();
}
});
colorBox.setValue(ColourArray.getName(getColourArrayType()));
//need to set up alignment properly. //FIXME- a bit messy
BorderPane.setAlignment(colorBox, Pos.CENTER);
//sliderPane.setPadding(new Insets(10,0,0,0));
BorderPane.setMargin(colorBox, new Insets(0,5,0,5));
this.setCenter(colourSlider);
this.setRight(colorBox);
//set up so the correct color
colorBox.setValue(ColourArray.getName(getColourArrayType()));
colourSlider.setColourArrayType(getColourArrayType());
}
public void setDataStreamPanel(DataStreamPaneFX selectedItem) {
this.dataStreamPane=selectedItem;
//TODO - set the colours here.
}
/**
* Set colours depending on current colour selection in combo box.
*/
private void setColours(){
this.setColourArrayType(ColourArray.getColourArrayType(colorBox.getValue()));
colourSlider.setColourArrayType(getColourArrayType());
}
public ColourArrayType getColourArrayType() {
return colorArray;
}
public void setColourArrayType(ColourArrayType colourArrayType) {
this.colorArray = colourArrayType;
}
}
/**
* Create a pane to change vertical scales.
* @return pamne with controls to change vertical scales.
*/
private PamGridPane createScalePane() {
PamGridPane controlPane=new PamGridPane();
controlPane.setHgap(5);
controlPane.setVgap(5);
// //create time scale controls
// controlPane.add(new Label("Time window"),0,1);
//
// //create time slider
// timeSlider=new Slider(0, timeScaleChoices.length-1, 1);
// timeSlider.setShowTickLabels(true);
// timeSlider.setShowTickMarks(true);
// timeSlider.setMajorTickUnit(1);
//
// timeSlider.setLabelFormatter(new ScaleStringConverter());
//
//// PamGridPane.setHalignment(timeSlider, Pos.BOTTOM_CENTER);
//
// controlPane.add(timeSlider,1,1);
// //add listener to time slider to change datamap.
// timeSlider.valueProperty().addListener((ov, oldVal, newVal)->{
// sayHScale();
// dataMapPane.scaleChanged();
// });
//
// controlPane.add(timeScaleLabel=new Label(""),3,1);
//create vertical scale controls
scaleBox=new ComboBox<String> ();
scaleBox.getItems().add("No Scaling");
scaleBox.getItems().add("per Second");
scaleBox.getItems().add("per Minute");
scaleBox.getItems().add("per Hour");
scaleBox.getItems().add("per Day");
controlPane.add(new Label("Show detections "),0,0);
controlPane.add(scaleBox,1,0);
// scaleBox.setPrefWidth(200);
scaleBox.valueProperty().addListener((ov, oldVal, newVal)->{
dataMapPane.scaleChanged();
});
logScaleToggle=new PamToggleSwitch("Log Scale");
logScaleToggle.selectedProperty().addListener((obsVal, oldVal, newVal)->{
dataMapPane.scaleChanged();
});
controlPane.add(logScaleToggle,0,1);
return controlPane;
}
/**
* Show the horizontal scale.
*/
private void sayHScale() {
// double hChoice = timeScaleChoices[this.];
// timeScaleLabel.setText(String.format("%s pixs/hour", new Double(timeScaleChoices[(int) hChoice]).toString()));
}
//HACK use setting flag to avoid immediate callback which overwrites changes 2 and 3 !
boolean setting = false;
public void setParams(DataMapParameters dataMapParameters) {
setting = true;
// timeSlider.setValue(dataMapParameters.hScaleChoice);
scaleBox.getSelectionModel().select(dataMapParameters.vScaleChoice);
logScaleToggle.setSelected(dataMapParameters.vLogScale);
//make sure the combo box has correct datastreams
updateDataStreamBox();
setting = false;
}
public DataMapParameters getParams(DataMapParameters dataMapParameters) {
if (setting) return dataMapParameters;
// dataMapParameters.hScaleChoice = (int) timeSlider.getValue();
dataMapParameters.vScaleChoice = scaleBox.getSelectionModel().getSelectedIndex();
dataMapParameters.vLogScale = logScaleToggle.isSelected();
return dataMapParameters;
}
@Override
public String getName() {
return "Datamap settings";
}
@Override
public Node getContentNode() {
// TODO Auto-generated method stub
return mainPain;
}
@Override
public void paneInitialized() {
// TODO Auto-generated method stub
}
}

View File

@ -138,6 +138,7 @@ public class DataStreamPaneFX extends PamBorderPane {
dataGraph = new DataGraphFX();
dataGraph.setupAxis();
dataName = new DataName();
dataName.setName(dataBlock.getDataName());
this.setTop(topPane=createTopPane());
this.setCenter(dataGraph);
@ -991,6 +992,16 @@ public class DataStreamPaneFX extends PamBorderPane {
public class DataName {
private String name;
public String getName() {
return name;
}
public void setName(String dataName) {
this.name=dataName;
}
}
/**

View File

@ -1,293 +0,0 @@
package dataMap.layoutFX;
import dataGram.DatagramManager;
import dataGram.DatagramSettings;
import dataMap.DataMapControl;
import dataMap.DataMapParameters;
import PamController.PamController;
import PamUtils.PamCalendar;
import binaryFileStorage.BinaryStore;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.util.StringConverter;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxNodes.sliders.PamSlider;
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
/**
* Allows uses to change the horizontal and vertical scales on the data map.
*
* @author Jamie Macaulay
*
*/
public class ScalePaneFX extends PamBorderPane {
/*
* Reference to the data map control.
*/
private DataMapControl dataMapControl;
/**
* Reference to the dataMapPane.
*/
private DataMapPaneFX dataMapPane;
/**
* The slider which determines time scale.
*/
private Slider timeSlider;
/**
* Shows the time scale in pix/hour
*/
private Label timeScaleLabel;
/**
* Selects unit count on vertical scale
*/
private ComboBox<String> scaleBox;
/**
* Check box for log vertical scale.
*/
private PamToggleSwitch logScaleBox;
/**
* The chosen time values.
*/
private double[] timeScaleChoices = DataMapParameters.hScaleChoices;
/**
* Combo box holding options to channge the datargam bin size
*/
private ComboBox<String> datagramBox;
/**
* Holds a list of times for the datagram bin size.
*/
private ComboBox<String> dataGramComboBox;
/**
* Holds everything.
*/
private PamVBox holder;
/**
* Grid pane with settings for the data scales
*/
private PamGridPane scaleSettingsPane;
private Label dataGramLabel;
public ScalePaneFX(DataMapControl dataMapControl, DataMapPaneFX dataMapPane) {
this.dataMapControl = dataMapControl;
this.dataMapPane = dataMapPane;
// //create the holder pane.
// PamVBox vBoxHolder=new PamVBox();
// vBoxHolder.setSpacing(5);
// Label title=new Label("Scales");
// PamGuiManagerFX.titleFont2style(title);
// vBoxHolder.getChildren().addAll(title, controlPane);
holder=new PamVBox();
holder.setSpacing(20);
holder.getChildren().add(scaleSettingsPane = createScalePane());
this.setCenter(holder);
//set params for the pane
setParams(dataMapControl.dataMapParameters);
checkDataGramPane(); // create datagram pane if a binary store already added.
sayHScale();
}
/**
* Adds a settings pane for the datagram if a binary store is present.
*/
public void checkDataGramPane(){
if (BinaryStore.findBinaryStoreControl()!=null){
DatagramManager dataGramManager=BinaryStore.findBinaryStoreControl().getDatagramManager();
if (dataGramManager!=null && datagramBox==null) {
datagramBox=createDatagramPane(dataGramManager);
scaleSettingsPane.add(dataGramLabel= new Label("Datagram bin size"), 0, 2);
scaleSettingsPane.add(dataGramComboBox, 1, 2);
}
}
else {
scaleSettingsPane.getChildren().remove(dataGramLabel);
scaleSettingsPane.getChildren().remove(dataGramComboBox);
datagramBox=null;
}
}
/**
* Create the a datagram combo box to change the size of the datagram
* @param dataGramManager - the datagram manager for the current biinary store.
* @return a combo box with datagram bin sizes.
*/
private ComboBox<String> createDatagramPane(DatagramManager dataGramManager){
dataGramComboBox=new ComboBox<String>(createDurationList(dataGramManager));
dataGramComboBox.getSelectionModel().select(durationToString(dataGramManager.getDatagramSettings().datagramSeconds*1000L));
dataGramComboBox.valueProperty().addListener(( ov, t, t1) -> {
if (t==t1) return;
else {
PamController.getInstance();
boolean ans=PamDialogFX.showWarning(PamController.getMainStage(), "Warning", "<html>Recalculating the datagram for a large dataset may take a long time<br>" +
"Are you sure you want to continue ?</html>");
if (ans){
int index=dataGramComboBox.getSelectionModel().getSelectedIndex();
//messy- datagramSeconfds should be in millis but left for backwards compatibility.
dataGramManager.getDatagramSettings().datagramSeconds=(int) (DatagramSettings.defaultDatagramSeconds[index]/1000);
dataGramManager.updateDatagrams();
dataMapPane.repaintAll();
}
}
});
return dataGramComboBox;
}
/**
* Convert duration to string.
* @param duration in millis.
*/
private String durationToString(long duration){
return (" " + PamCalendar.formatDuration(duration));
}
/**
* Create list of load times.
* @return list of load times duration.
*/
private ObservableList<String> createDurationList(DatagramManager dataGramManager){
ObservableList<String> loadTimeList=FXCollections.observableArrayList();
for (int i=0; i<DatagramSettings.defaultDatagramSeconds.length; i++){
loadTimeList.add(durationToString(DatagramSettings.defaultDatagramSeconds[i]));
}
return loadTimeList;
}
private PamGridPane createScalePane() {
PamGridPane controlPane=new PamGridPane();
controlPane.setHgap(5);
controlPane.setVgap(5);
//create time scale controls
controlPane.add(new Label("Time window"),0,1);
//create time slider
timeSlider=new Slider(0, timeScaleChoices.length-1, 1);
timeSlider.setShowTickLabels(true);
timeSlider.setShowTickMarks(true);
timeSlider.setMajorTickUnit(1);
timeSlider.setLabelFormatter(new ScaleStringConverter());
// PamGridPane.setHalignment(timeSlider, Pos.BOTTOM_CENTER);
controlPane.add(timeSlider,1,1);
//add listener to time slider to change datamap.
timeSlider.valueProperty().addListener((ov, oldVal, newVal)->{
sayHScale();
dataMapPane.scaleChanged();
});
controlPane.add(timeScaleLabel=new Label(""),3,1);
//create vertical scale controls
controlPane.add(new Label("Data counts"),0,0);
scaleBox=new ComboBox<String> ();
scaleBox.getItems().add("No Scaling");
scaleBox.getItems().add("per Second");
scaleBox.getItems().add("per Minute");
scaleBox.getItems().add("per Hour");
scaleBox.getItems().add("per Day");
controlPane.add(scaleBox,1,0);
scaleBox.setPrefWidth(200);
scaleBox.valueProperty().addListener((ov, oldVal, newVal)->{
dataMapPane.scaleChanged();
});
logScaleBox=new PamToggleSwitch("Log Scale");
logScaleBox.selectedProperty().addListener((obsVal, oldVal, newVal)->{
dataMapPane.scaleChanged();
});
controlPane.add(logScaleBox,3,0);
return controlPane;
}
class ScaleStringConverter extends StringConverter<Double> {
@Override
public String toString(Double object) {
return String.valueOf(timeScaleChoices[object.intValue()]);
}
@Override
public Double fromString(String string) {
return Double.valueOf(string);
}
}
/**
* Show the horizontal scale.
*/
private void sayHScale() {
double hChoice = timeSlider.getValue();
timeScaleLabel.setText(String.format("%s pixs/hour", new Double(timeScaleChoices[(int) hChoice]).toString()));
}
//HACK use setting flag to avoid immediate callback which overwrites changes 2 and 3 !
boolean setting = false;
public void setParams(DataMapParameters dataMapParameters) {
setting = true;
timeSlider.setValue(dataMapParameters.hScaleChoice);
scaleBox.getSelectionModel().select(dataMapParameters.vScaleChoice);
logScaleBox.setSelected(dataMapParameters.vLogScale);
setting = false;
}
public void getParams(DataMapParameters dataMapParameters) {
if (setting) return;
dataMapParameters.hScaleChoice = (int) timeSlider.getValue();
dataMapParameters.vScaleChoice = scaleBox.getSelectionModel().getSelectedIndex();
dataMapParameters.vLogScale = logScaleBox.isSelected();
}
}

View File

@ -28,7 +28,7 @@ public class ScrollingDataPaneFX extends PamBorderPane {
/**
* Standard millis to wait for repaint.
* Do not ake this too high i.e. above 50 or the display gets very jerky
* Do not make this too high i.e. above 50 or the display gets very jerky
*/
public static final long REPAINTMILLIS = 50;
@ -496,4 +496,24 @@ public class ScrollingDataPaneFX extends PamBorderPane {
// this.notifyScrollChange();
// }
/**
* Get the current number of data stream panes
* @return the number of data stream panes
*/
public int getNumDataStreamPanes() {
return this.dataStreamPanels.size();
}
/**
* Get a data stream pane.
* @param n - the index of the data stream pane
* @return the data stream pane or null if the index is out of bounds.
*/
public DataStreamPaneFX getDataSyreamPane(int n) {
if (n<this.dataStreamPanels.size()) {
return dataStreamPanels.get(n);
}
else return null;
}
}

View File

@ -7,16 +7,13 @@ import PamView.paneloverlay.overlaymark.OverlayMark;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamRawDataBlock;
import detectiongrouplocaliser.DetectionGroupSummary;
import export.wavExport.WavFileExportManager;
import javafx.animation.Timeline;
import export.wavExport.WavDetExport;
import javafx.application.Platform;
import javafx.scene.control.Labeled;
import javafx.scene.control.Tooltip;
import javafx.scene.effect.ColorInput;
import javafx.scene.text.Text;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamButton;
import wavFiles.WavFileWriter;
/**
* Export a .wav clip.
@ -27,27 +24,27 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
private Text wavFileGlyph;
/**
* The wav file write
*/
private WavFileWriter wavFile;
// /**
// * The wav file write
// */
// private WavFileWriter wavFile;
//
// private String defaultPath;
//
// private String currentFolder;
private String defaultPath;
private WavDetExport wavExportManager;
private String currentFolder;
private WavFileExportManager wavExportManager;
private ColorInput shadow;
private Timeline timline;
// private ColorInput shadow;
//
// private Timeline timline;
private PamButton pamButton;
public WavExportOverlayMenu(){
// wavFileGlyph=PamGlyphDude.createPamGlyph(MaterialDesignIcon.FILE_MUSIC, standardIconSize);
wavFileGlyph=PamGlyphDude.createPamIcon("mdi2f-file-music", standardIconSize+14);
wavExportManager= new WavFileExportManager();
wavExportManager= new WavDetExport();
//set a callback when saving is finsihed.
wavExportManager.setOnWavSaved((saveFile, flag)->{
@ -132,7 +129,7 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
*/
private void writeWavFile(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
// animateButton() ; //start button animation.
wavExportManager.dataUnits2Wav(foundDataUnits, selectedIndex, mark);
wavExportManager.writeOverlayMarkWav(foundDataUnits, selectedIndex, mark);
}
@ -148,7 +145,7 @@ public class WavExportOverlayMenu extends ExportOverlayMenu {
rawDataBlock=foundDataUnits.getDataList().get(0).getParentDataBlock().getRawSourceDataBlock();
}
//is there available raw data
if (mark!=null && WavFileExportManager.haveRawData(rawDataBlock, (long) mark.getLimits()[0], (long) mark.getLimits()[1])) {
if (mark!=null && WavDetExport.haveRawData(rawDataBlock, (long) mark.getLimits()[0], (long) mark.getLimits()[1])) {
return true;
}

View File

@ -12,7 +12,7 @@ import dataPlotsFX.layout.TDGraphFX.TDPlotPane;
import dataPlotsFX.overlaymark.menuOptions.OverlayMenuItem;
import dataPlotsFX.overlaymark.menuOptions.OverlayMenuManager;
import detectiongrouplocaliser.DetectionGroupSummary;
import export.wavExport.WavFileExportManager;
import export.wavExport.WavDetExport;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
@ -546,7 +546,7 @@ public class TDMenuPane extends PamBorderPane {
PamRawDataBlock pamRawBlock = findRawSourceBlock();
// System.out.println("Pam raw data block: " + pamRawBlock);
if (WavFileExportManager.haveRawData(pamRawBlock, (long) overlayMarker.getCurrentMark().getLimits()[0], (long) overlayMarker.getCurrentMark().getLimits()[1])) {
if (WavDetExport.haveRawData(pamRawBlock, (long) overlayMarker.getCurrentMark().getLimits()[0], (long) overlayMarker.getCurrentMark().getLimits()[1])) {
//System.out.println("Overaly Marker start X: " + overlayMarker.getCurrentMark().getLimits()[0] + " end: " + overlayMarker.getCurrentMark().getLimits()[1]);
//System.out.println("Overlay Marker start Y: " + overlayMarker.getCurrentMark().getLimits()[2] + " end: " + overlayMarker.getCurrentMark().getLimits()[3]);
groupDetectionDisplay.showRawData(pamRawBlock, overlayMarker.getCurrentMark().getLimits(), overlayMarker.getCurrentMark().getMarkChannels());

View File

@ -926,6 +926,8 @@ public class Scrolling2DPlotDataFX {
//reset transform in case of other drawings on base canvas.
if (orientation == Orientation.VERTICAL) g2d.setTransform(horzAffine);
}
/**

View File

@ -22,9 +22,13 @@ import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
/**
* A general pane with a frequency slider, colour bar slider and colour combo box. These nodes are interconnected so when colour combo box is changed colours change.
* Other than that this pane does nothing but all slider value properties are available to be used in another class or subclass. This means this control pane should be
* available to be used for any spectrogram/3D colour image.
* A general pane with a frequency slider, colour bar slider and colour combo
* box. These nodes are interconnected so when colour combo box is changed
* colours change. Other than that this pane does nothing but all slider value
* properties are available to be used in another class or subclass. This means
* this control pane should be available to be used for any spectrogram/3D
* colour image.
*
* @author Jamie Macaulay
*
*/

View File

@ -48,8 +48,12 @@ public abstract class MLDataUnitExport<T extends PamDataUnit<?, ?>> {
//UID for the detection.
Matrix UID = Mat5.newScalar(dataUnit.getUID());
Matrix startSample = Mat5.newScalar(0);
if (dataUnit.getStartSample()!=null) {
//the start sample.
Matrix startSample = Mat5.newScalar(dataUnit.getStartSample());
startSample = Mat5.newScalar(dataUnit.getStartSample());
}
//the duration of the detection in samples.
Matrix sampleDuration = Mat5.newScalar(dataUnit.getSampleDuration());

View File

@ -11,7 +11,7 @@ import PamguardMVC.PamDataUnit;
import export.CSVExport.CSVExportManager;
import export.MLExport.MLDetectionsManager;
import export.RExport.RExportManager;
import export.wavExport.WavFileExportManager;
import export.wavExport.WavDetExportManager;
/**
* Exports data to external files. Manages the file sizes and creates data buffers for
@ -61,7 +61,7 @@ public class PamExporterManager {
//add the MATLAB export
pamExporters.add(new MLDetectionsManager());
pamExporters.add(new RExportManager(this));
pamExporters.add(new WavFileExportManager());
pamExporters.add(new WavDetExportManager());
// pamExporters.add(new CSVExportManager());
}

View File

@ -37,6 +37,7 @@ import PamguardMVC.PamDataBlock;
import export.ExportParams;
import export.PamExporterManager;
import offlineProcessing.OLProcessDialog;
import offlineProcessing.OLProcessDialog.OLMonitor;
import offlineProcessing.OfflineTaskGroup;
import offlineProcessing.TaskMonitor;
import offlineProcessing.TaskMonitorData;
@ -359,7 +360,7 @@ public class ExportProcessDialog {
public void setParams(ExportParams params) {
System.out.println("EXPORT: SET PARAMS: " +params);
// System.out.println("EXPORT: SET PARAMS: " +params);
if (params ==null) currentParams = new ExportParams();
currentParams = params.clone();
@ -367,7 +368,7 @@ public class ExportProcessDialog {
buttonGroup.clearSelection();
exportButtons[params.exportChoice].setSelected(true);
System.out.println("EXPORT: SET PARAMS: " +currentParams.folder);
// System.out.println("EXPORT: SET PARAMS: " +currentParams.folder);
exportTo.setText(currentParams.folder);
spinner.setValue(currentParams.maximumFileSize);
@ -376,10 +377,12 @@ public class ExportProcessDialog {
}
}
class ExportTaskMonitor implements TaskMonitor {
/**
* Ok, this is a bit of a hack but because we run tasks for multiple data blocks
* we have to run a new task whenever the previous task is finished. So we use a task monitor
* to deetct when the task is finsihed and then, instead of finishing we run a new task.
*/
class ExportTaskMonitor extends OLMonitor {
private int taskIndex;
@ -387,25 +390,64 @@ public class ExportProcessDialog {
private boolean started = false;
private int activeTasks;
public ExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
super();
this.taskIndex = i;
this.exportTaskGroup = exportTaskGroup;
this.activeTasks = 0;
for (int i1=0; i1<exportTaskGroup.getNTasks(); i1++) {
if (exportTaskGroup.getTask(i1).isDoRun()) {
activeTasks++;
}
}
}
@Override
public void setTaskStatus(TaskMonitorData taskMonitorData) {
if (taskMonitorData.taskStatus== TaskStatus.COMPLETE && !started) {
System.out.println(" TASK COMPLETE:");
if (taskIndex<exportTaskGroup.getNTasks()) {
switch (taskMonitorData.taskStatus) {
case COMPLETE:
if (taskIndex<exportTaskGroup.getNTasks() && !started) {
exportTaskGroup.runTaskFrom(taskIndex+1);
started = true;
}
break;
default:
super.setTaskStatus(taskMonitorData);
}
//A hack which sets the global
switch (taskMonitorData.taskActivity) {
case LINKING:
case LOADING:
//the progress of one datablocks
double progress = ((double) taskMonitorData.progValue)/taskMonitorData.progMaximum;
double totalProgress = ((double) taskIndex)/activeTasks + progress/activeTasks;
// System.out.println("Total progress: " + taskMonitorData.progValue + " of " + taskMonitorData.progMaximum + " - " + totalProgress + "%" + " " + progress + " " + activeTasks + " " + taskIndex);
//needs to be added to the overall progress
int max = getGlobalProgress().getMaximum();
getGlobalProgress().setValue((int) (totalProgress*max));
default:
break;
}
}
}
public ExportTaskMonitor newExportTaskMonitor(int i, ExportTaskGroup exportTaskGroup) {
return new ExportTaskMonitor(i, exportTaskGroup);
}
}
/**
* Export task
@ -428,12 +470,12 @@ public class ExportProcessDialog {
* @param i - the index
*/
public void runTaskFrom(int i) {
System.out.println("RUN TASK FROM :" + i);
//sets the porimary datablock to that of the relevent task.
this.setPrimaryDataBlock(getTask(i).getDataBlock());
if (i<getNTasks()-1) {
//will start a new thread after this one has finished
this.setTaskMonitor(new ExportTaskMonitor(i, this));
this.setTaskMonitor(mtOfflineDialog.newExportTaskMonitor(i, this));
}
super.runTasks();
}

View File

@ -56,7 +56,7 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
//System.out.println("Data selector null: " + this.getDataBlock().getDataName() + " " + dataUnit);
exporter.exportDataUnit(dataUnit, false);
}
else if (dataSelector.scoreData(dataUnit)>0 && dataSelector.getParams().getCombinationFlag() != DataSelectParams.DATA_SELECT_DISABLE) {
else if (dataSelector.scoreData(dataUnit)>0 || dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) {
//System.out.println("Data selector OK: " + this.getDataBlock().getDataName() + " " + dataUnit);
exporter.exportDataUnit(dataUnit, false);
}
@ -73,7 +73,7 @@ public class ExportTask extends OfflineTask<PamDataUnit<?,?>>{
@Override
public void loadedDataComplete() {
System.out.println("EXPORTER: loaded data complete");
// System.out.println("EXPORTER: loaded data complete");
//force the exporter so save any renaming data units in the buffer
exporter.exportDataUnit(null, true);
exporter.close();

View File

@ -1,6 +1,5 @@
package export.wavExport;
import java.awt.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@ -20,46 +19,36 @@ import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
import PamguardMVC.PamObserverAdapter;
import PamguardMVC.PamRawDataBlock;
import PamguardMVC.RawDataHolder;
import PamguardMVC.dataOffline.OfflineDataLoading;
import dataMap.OfflineDataMapPoint;
import detectiongrouplocaliser.DetectionGroupSummary;
import export.PamDataUnitExporter;
import javafx.scene.layout.Pane;
import wavFiles.Wav16AudioFormat;
import wavFiles.WavFileWriter;
/**
* Manages .wav file writing based on what type of data unit is selected and whether raw data is available.
* <p>
* There are two primary use cases;
* <br>
* 1) Order raw data from an overlay mark and save as a wav file
* <br>
* 2) Save a list of data units to wav files - either a single file with zero pads, a concatonated file or seperate files.
*
* @author Jamie Macaulay
*
*/
public class WavFileExportManager implements PamDataUnitExporter {
public class WavDetExport {
/**
* Successful writing of .wav file.
*/
public static final int SUCCESS_WAV=0;
// public static final int SUCCESS_WAV=0;
/**
* Successful writing of .wav file from data contained in detections.
*/
public static final int SUCCESS_DET_WAV=1;
// public static final int SUCCESS_DET_WAV=1;
/**
* General failure in wav file writing
*/
public static final int FAILURE_WAV=2;
// public static final int FAILURE_WAV=2;
public static final int LOADING_WAV=2;
// public static final int LOADING_WAV=2;
/**
* The maximum allowed size
*/
private static final double MAX_ZEROPAD_SIZE_MEGABYTES = 1024; //MB
/**
* The default path to write files to
@ -80,7 +69,7 @@ public class WavFileExportManager implements PamDataUnitExporter {
private WavOptionsPanel wavOptionsPanel;
public WavFileExportManager() {
public WavDetExport() {
wavDataUnitExports.add(new RawHolderWavExport());
defaultPath=FileSystemView.getFileSystemView().getDefaultDirectory().getPath();
@ -179,7 +168,7 @@ public class WavFileExportManager implements PamDataUnitExporter {
* @param selectedIndex - the currently selected data unit.
* @param mark - overlay mark.
*/
public int dataUnits2Wav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
public int writeOverlayMarkWav(DetectionGroupSummary foundDataUnits, int selectedIndex, OverlayMark mark) {
System.out.println("Data units 2 wav");
//this order for .wav files.
//if there is a mark then save limits of mark. If there is one data unit then set limits of data units
@ -224,15 +213,18 @@ public class WavFileExportManager implements PamDataUnitExporter {
int flag=-1;
String currentFileS = createFileName(foundDataUnits.getFirstTimeMillis());
File file = new File(currentFileS);
if (hasAllWavClips) {
flag = saveDataUnitWav(foundDataUnits);
flag = writeDetGroupWav(foundDataUnits, file, false);
}
else if (!hasAllWavClips && haveRawData) {
//no raw data
flag = saveRawWav(start, end, rawDataBlock);
}
else {
flag = saveDataUnitWav(foundDataUnits);
flag = writeDetGroupWav(foundDataUnits, file, false);
}
return flag;
@ -263,47 +255,129 @@ public class WavFileExportManager implements PamDataUnitExporter {
/**
* Save wav data from a data unit instead of from the raw file store.
* @param foundDataUnits - the list of found data units.
* @param currentFile - path to current file to save to.
* @param zeroPad - if true will zeroPad detections.
* @return the number of data units that were saved.
*/
private int saveDataUnitWav(DetectionGroupSummary foundDataUnits) {
return saveDataUnitWav(foundDataUnits.getDataList());
public int writeDetGroupWav(DetectionGroupSummary foundDataUnits, File filename, boolean zeroPad) {
return writeDataUnitWav(foundDataUnits.getDataList(), filename, zeroPad);
}
/**
* Save data units which contain raw data to a wav file. Note that this assumed
* the data units all contain raw data and are in order.
*
* @param foundDataUnits - data units containing raw data.
* @return the number of data units saved - this should be the same as the size
* of the data unit list.
* Save data units which contain raw data to individual wav files within a folder.
* @param foundDataUnits - list of data units to save.
* @param currentFile - the current folder. If this is a file name the parent directory will be used.
* @return the number of data units saved
*/
private int saveDataUnitWav(List<PamDataUnit> foundDataUnits) {
public int writeDataUnitWavs(List<PamDataUnit> foundDataUnits, File currentFile) {
int n=0;
WavFileWriter wavWrite = null;
for (PamDataUnit fnDataUnit: foundDataUnits){
String currentFile = createFileName(fnDataUnit.getTimeMilliseconds());
AudioFormat audioFormat = new Wav16AudioFormat(fnDataUnit.getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(fnDataUnit.getChannelBitmap()));
System.out.println("Save detection wav." + foundDataUnits.size());
String currentFileS = createFileName(fnDataUnit.getTimeMilliseconds());
//System.out.println("Save detection wav." + foundDataUnits.size());
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
wavWrite= new WavFileWriter(currentFile, audioFormat);
wavWrite= new WavFileWriter(currentFileS, audioFormat);
System.out.println("Append wav." + foundDataUnits.size());
System.out.println("Write individual wav." + foundDataUnits.size());
//save the wav file of detection
wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit));
n++;
wavWrite.close();
break;
}
}
}
return n;
}
/**
* Save data units which contain raw data to a wav file. Note that this assumed
* the data units all contain raw data, the raw data is at the same sample rate and number of channels
* and the data units are in order. This will APPEND to the wav file if it currently exists.
*
* @param foundDataUnits - data units containing raw data.
* @param currentFile - path to current file to save to.
* @param zeroPad - if true will zeroPad detections.
* @return the number of data units saved - this should be the same as the size
* of the data unit list.
*/
public int writeDataUnitWav(List<PamDataUnit> foundDataUnits, File currentFile, boolean zeroPad) {
int n=0;
WavFileWriter wavWrite = null;
PamDataUnit lastfnDataUnit = null;
if (foundDataUnits==null || foundDataUnits.size()<=0) {
return 0;
}
//System.out.println("Save detection wav." + foundDataUnits.size());
AudioFormat audioFormat = new Wav16AudioFormat(foundDataUnits.get(0).getParentDataBlock().getSampleRate(), PamUtils.getNumChannels(foundDataUnits.get(0).getChannelBitmap()));
wavWrite= new WavFileWriter(currentFile.getAbsolutePath(), audioFormat);
for (PamDataUnit fnDataUnit: foundDataUnits){
for (int i=0; i<wavDataUnitExports.size(); i++) {
if (wavDataUnitExports.get(i).getUnitClass().isAssignableFrom(fnDataUnit.getClass())) {
System.out.println("Append wav. data unit: " + n + " samples: " + wavDataUnitExports.get(i).getWavClip(fnDataUnit)[0].length + " zeroPad: " + zeroPad);
if (zeroPad && lastfnDataUnit!=null) {
//we need to append zero samples between the detections.
long timeMillisDiff = fnDataUnit.getTimeMilliseconds() - lastfnDataUnit.getTimeMilliseconds();
long sampleDiff = fnDataUnit.getStartSample() - lastfnDataUnit.getStartSample();
int samplesPad;
//are the two similar? - are they within 5 milliseconds
if (Math.abs(((sampleDiff/audioFormat.getSampleRate())*1000.) - timeMillisDiff)<5){
//use the sample diff
samplesPad = (int) sampleDiff;
}
else {
//use time millis for padding. May indicate that data units are from different wav files.
samplesPad = (int) ((((double) timeMillisDiff)/1000.)*audioFormat.getSampleRate());
}
//now safety check - is this more than one GB of data. Each sample is 16bits but the input double array is 64 bits each.
double size = samplesPad*16*audioFormat.getChannels()/1024/1024;
//
if (size>MAX_ZEROPAD_SIZE_MEGABYTES) {
wavWrite.close();
System.err.println(String.format("WavExportManager: A zero padding of %.2f MB was requested. The maximum allowed size is %.2f - "
+ "the .wav file was closed and any additional data units have not been written %s", size, MAX_ZEROPAD_SIZE_MEGABYTES, currentFile));
return n;
}
System.out.println("Append wav. zero pad" + samplesPad);
wavWrite.append(new double[audioFormat.getChannels()][samplesPad]);
}
//save the wav file of detection
if (wavWrite.append(wavDataUnitExports.get(i).getWavClip(fnDataUnit))) {
n++;
}
lastfnDataUnit = fnDataUnit;
break;
}
}
}
wavWrite.close();
//send a message that the wav file has saved
if (wavWrite!=null && saveCallback!=null) saveCallback.wavSaved(wavWrite.getFileName(), 0);
@ -340,85 +414,6 @@ public class WavFileExportManager implements PamDataUnitExporter {
}
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
// boolean implementsInterface = Arrays.stream(dataUnitType.getInterfaces()).anyMatch(i -> i == RawDataHolder.class);
if ( RawDataHolder.class.isAssignableFrom(dataUnitType)) return true;
return false;
}
@Override
public boolean exportData(File fileName,
List<PamDataUnit> dataUnits, boolean append) {
//should we zeropad?
saveDataUnitWav(dataUnits);
return true;
}
@Override
public String getFileExtension() {
return "wav";
}
@Override
public String getIconString() {
return "mdi2f-file-music";
}
@Override
public String getName() {
return "raw sound";
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public boolean isNeedsNewFile() {
return false;
}
@Override
public Component getOptionsPanel() {
if (this.wavOptionsPanel==null) {
this.wavOptionsPanel = new WavOptionsPanel();
}
return wavOptionsPanel;
}
@Override
public Pane getOptionsPane() {
// TODO Auto-generated method stub
return null;
}
/**
* Observes incoming raw data and saves to a wav file
*
@ -528,70 +523,4 @@ public class WavFileExportManager implements PamDataUnitExporter {
}
// hello(){
//
//
// if (mark==null) {
// start= foundDataUnits.getFirstTimeMillis();
// end= foundDataUnits.getLastTimeMillis();
// }
//
// File folder = new File(currentFolder);
//
// //save a .wav file clip.
// if (!folder.exists()){
// if (!folder.mkdir()){
// //TODO- warning message.
// return;
// }
// }
//
// String currentPath = PamCalendar.formatFileDateTime();
// //add data types to the filen,ae
// for (int i=0 ;i<mlData.size(); i++ ){
// currentPath=currentPath + "_" + mlData.get(i).getName();
// }
// //add correct file type.
// currentPath = currentPath + ".mat";
// currentPath = currentFolder+"\\"+currentPath;
//
//
// if (append && clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
// wavFile.append(rawData);
// lastClipDataUnit.setSampleDuration(rawEnd-lastClipDataUnit.getStartSample());
// clipDataBlock.updatePamData(lastClipDataUnit, dataUnit.getTimeMilliseconds());
// // System.out.println(String.format("%d samples added to file", rawData[0].length));
// }
// else {
// ClipDataUnit clipDataUnit;
// long startMillis = dataUnit.getTimeMilliseconds() - (long) (clipGenSetting.preSeconds*1000.);
// if (clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
// String folderName = getClipFileFolder(dataUnit.getTimeMilliseconds(), true);
// String fileName = getClipFileName(startMillis);
// AudioFormat af = new Wav16AudioFormat(getSampleRate(), rawData.length);
// wavFile = new WavFileWriter(folderName+fileName, af);
// wavFile.write(rawData);
// wavFile.close();
// // make a data unit to go with it.
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
// (int)(rawEnd-rawStart), channelMap, fileName, dataBlock.getDataName(), rawData, getSampleRate());
// }
// else {
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
// (int)(rawEnd-rawStart), channelMap, "", dataBlock.getDataName(), rawData, getSampleRate());
// }
// clipDataUnit.setFrequency(dataUnit.getFrequency());
// lastClipDataUnit = clipDataUnit;
// if (bearingLocaliser != null) {
// localiseClip(clipDataUnit, bearingLocaliser, hydrophoneMap);
// }
// clipDataBlock.addPamData(clipDataUnit);
// }
//
// return 0; // no error.
// }
//
// }
// }
}

View File

@ -0,0 +1,229 @@
package export.wavExport;
import java.awt.Component;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.swing.filechooser.FileSystemView;
import PamController.PamController;
import PamDetection.RawDataUnit;
import PamUtils.PamCalendar;
import PamUtils.PamUtils;
import PamView.paneloverlay.overlaymark.OverlayMark;
import PamguardMVC.LoadObserver;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
import PamguardMVC.PamObserverAdapter;
import PamguardMVC.PamRawDataBlock;
import PamguardMVC.RawDataHolder;
import PamguardMVC.dataOffline.OfflineDataLoading;
import dataMap.OfflineDataMapPoint;
import detectiongrouplocaliser.DetectionGroupSummary;
import export.PamDataUnitExporter;
import javafx.scene.layout.Pane;
import wavFiles.Wav16AudioFormat;
import wavFiles.WavFileWriter;
/**
* Writes data units and/or ordered raw data to a wav file. Has functions to
* handle .wav file writing based on overlay marks and detection groups with
* functions to make decisions based on what type of data unit is selected and
* whether raw data is available.
* <p>
* There are two primary use cases; <br>
* 1) Order raw data from an overlay mark and save as a wav file <br>
* 2) Save a list of data units to wav files - either a single file with zero
* pads, a concatenated file or separate files.
*
* @author Jamie Macaulay
*
*/
public class WavDetExportManager implements PamDataUnitExporter {
/**
* Options for exporting wav files.
*/
private WavExportOptions wavFileoptions = new WavExportOptions();
/**
* Settings panel for wav file exporting
*/
private WavOptionsPanel wavOptionsPanel;
/**
* Exporter of wav files.
*/
private WavDetExport wavDetExport = new WavDetExport();
public WavDetExportManager() {
}
@Override
public boolean hasCompatibleUnits(Class dataUnitType) {
// boolean implementsInterface = Arrays.stream(dataUnitType.getInterfaces()).anyMatch(i -> i == RawDataHolder.class);
if ( RawDataHolder.class.isAssignableFrom(dataUnitType)) return true;
return false;
}
@Override
public boolean exportData(File fileName,
List<PamDataUnit> dataUnits, boolean append) {
//make sure we have the latest options.
if (wavOptionsPanel!=null) {
//means the options panel has been opened.
wavFileoptions = wavOptionsPanel.getParams(wavFileoptions);
}
//should we zeropad?
//saveDataUnitWav(dataUnits);
switch (wavFileoptions.wavSaveChoice) {
case WavExportOptions.SAVEWAV_CONCAT:
wavDetExport.writeDataUnitWav(dataUnits, fileName, false);
break;
case WavExportOptions.SAVEWAV_INDIVIDUAL:
//here the filename will not be used but the parent folder will be used instead to write
//lots of wav files to.
wavDetExport.writeDataUnitWavs(dataUnits, fileName);
break;
case WavExportOptions.SAVEWAV_ZERO_PAD:
wavDetExport.writeDataUnitWav(dataUnits, fileName, true);
break;
}
return true;
}
@Override
public String getFileExtension() {
return "wav";
}
@Override
public String getIconString() {
return "mdi2f-file-music";
}
@Override
public String getName() {
return "raw sound";
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public boolean isNeedsNewFile() {
return false;
}
@Override
public Component getOptionsPanel() {
if (this.wavOptionsPanel==null) {
this.wavOptionsPanel = new WavOptionsPanel();
}
wavOptionsPanel.setParams(this.wavFileoptions) ;
return wavOptionsPanel;
}
@Override
public Pane getOptionsPane() {
// TODO - make FX version of settings.
return null;
}
// hello(){
//
//
// if (mark==null) {
// start= foundDataUnits.getFirstTimeMillis();
// end= foundDataUnits.getLastTimeMillis();
// }
//
// File folder = new File(currentFolder);
//
// //save a .wav file clip.
// if (!folder.exists()){
// if (!folder.mkdir()){
// //TODO- warning message.
// return;
// }
// }
//
// String currentPath = PamCalendar.formatFileDateTime();
// //add data types to the filen,ae
// for (int i=0 ;i<mlData.size(); i++ ){
// currentPath=currentPath + "_" + mlData.get(i).getName();
// }
// //add correct file type.
// currentPath = currentPath + ".mat";
// currentPath = currentFolder+"\\"+currentPath;
//
//
// if (append && clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
// wavFile.append(rawData);
// lastClipDataUnit.setSampleDuration(rawEnd-lastClipDataUnit.getStartSample());
// clipDataBlock.updatePamData(lastClipDataUnit, dataUnit.getTimeMilliseconds());
// // System.out.println(String.format("%d samples added to file", rawData[0].length));
// }
// else {
// ClipDataUnit clipDataUnit;
// long startMillis = dataUnit.getTimeMilliseconds() - (long) (clipGenSetting.preSeconds*1000.);
// if (clipControl.clipSettings.storageOption == ClipSettings.STORE_WAVFILES) {
// String folderName = getClipFileFolder(dataUnit.getTimeMilliseconds(), true);
// String fileName = getClipFileName(startMillis);
// AudioFormat af = new Wav16AudioFormat(getSampleRate(), rawData.length);
// wavFile = new WavFileWriter(folderName+fileName, af);
// wavFile.write(rawData);
// wavFile.close();
// // make a data unit to go with it.
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
// (int)(rawEnd-rawStart), channelMap, fileName, dataBlock.getDataName(), rawData, getSampleRate());
// }
// else {
// clipDataUnit = new ClipDataUnit(startMillis, dataUnit.getTimeMilliseconds(), rawStart,
// (int)(rawEnd-rawStart), channelMap, "", dataBlock.getDataName(), rawData, getSampleRate());
// }
// clipDataUnit.setFrequency(dataUnit.getFrequency());
// lastClipDataUnit = clipDataUnit;
// if (bearingLocaliser != null) {
// localiseClip(clipDataUnit, bearingLocaliser, hydrophoneMap);
// }
// clipDataBlock.addPamData(clipDataUnit);
// }
//
// return 0; // no error.
// }
//
// }
// }
}

View File

@ -25,7 +25,7 @@ public class WavExportOptions implements Serializable, Cloneable {
public static final int SAVEWAV_INDIVIDUAL = 2;
/**
* Flag to indicuate how to save files
* Flag to indicate how to save files
*/
public int wavSaveChoice = SAVEWAV_CONCAT;

View File

@ -38,17 +38,17 @@ public class WavOptionsPanel extends PamPanel {
this.setLayout((new GridBagLayout()));
addComponent(this, zeroPad = new JRadioButton("Concat"), c);
addComponent(this, zeroPad = new JRadioButton("Zero Pad"), c);
c.gridx++;
addComponent(this, noZeroPad = new JRadioButton("Zero pad"), c);
addComponent(this, noZeroPad = new JRadioButton("Concatonate"), c);
c.gridx++;
addComponent(this, indvidualWav = new JRadioButton("Individual"), c);
c.gridx++;
addComponent(this, new JLabel(" wav"), c);
// c.gridx++;
// addComponent(this, new JLabel(" wav"), c);
// Initialization of object of "ButtonGroup" class.
ButtonGroup buttonGroup = new ButtonGroup();
@ -97,8 +97,8 @@ public class WavOptionsPanel extends PamPanel {
public WavExportOptions getParams(WavExportOptions wavExportOptions) {
if (zeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
if (noZeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
if (indvidualWav.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_ZERO_PAD;
if (noZeroPad.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_CONCAT;
if (indvidualWav.isSelected()) wavExportOptions.wavSaveChoice = WavExportOptions.SAVEWAV_INDIVIDUAL;
return wavExportOptions;
}

View File

@ -63,6 +63,7 @@ public class OLProcessDialog extends PamDialog {
private JButton[] settingsButton;
private JLabel status, currFile;
private JProgressBar globalProgress; // file by file progress 1: nFiles
private JProgressBar loadedProgress; // progress throgh loaded data
private JCheckBox deleteOldData;
private JLabel dataInfo;
@ -723,7 +724,7 @@ public class OLProcessDialog extends PamDialog {
* @author Doug Gillespie
*
*/
class OLMonitor implements TaskMonitor {
public class OLMonitor implements TaskMonitor {
@Override
public void setTaskStatus(TaskMonitorData taskMonitorData) {
@ -734,6 +735,7 @@ public class OLProcessDialog extends PamDialog {
else {
currFile.setText(taskMonitorData.fileOrStatus);
}
switch (taskMonitorData.taskActivity) {
case LINKING:
case LOADING:
@ -755,6 +757,7 @@ public class OLProcessDialog extends PamDialog {
default:
break;
}
switch (taskMonitorData.taskStatus) {
case COMPLETE:
globalProgress.setValue(100);
@ -879,6 +882,11 @@ public class OLProcessDialog extends PamDialog {
this.isNeedaNote = isNeedaNote;
}
public JProgressBar getGlobalProgress() {
return globalProgress;
}
}

View File

@ -472,13 +472,35 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
this.pamGuiTab=pamGuiTab;
PamHBox analysisControls=new PamHBox();
analysisControls.setSpacing(10);
analysisControls.setPadding(new Insets(0,10,0,20));
// playControls.getStyleClass().add("pane-opaque");
analysisControls.setPrefHeight(prefHeight);
analysisControls.setAlignment(Pos.CENTER);
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
//in PMAGUard viewer mode we want a reporcess button
PamButton reProcessButton=new PamButton("Reprocess...");
reProcessButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog-transfer", PamGuiManagerFX.iconSize));
reProcessButton.setOnAction((action->{
}));
analysisControls.getChildren().addAll(reProcessButton);
}
else {
//real time mode
//create record and play buttons.
PamHBox playControls=new PamHBox();
recordButton=new PamButton();
// recordButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.CIRCLE, Color.LIMEGREEN, PamGuiManagerFX.iconSize));
recordButton.setGraphic(PamGlyphDude.createPamIcon("mdi2r-record-circle", Color.RED, PamGuiManagerFX.iconSize));
recordButton.getStyleClass().add("transparent-button");
recordButton.setStyle("-fx-padding: 0 10 0 10;");
//recordButton.setStyle(" -fx-background-radius: 50;");
recordButton.setOnAction((action)->{
@ -489,28 +511,23 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
else {
PamController.getInstance().pamStart();
pamGuiManagerFX.setPamRunning(true);
}
});
playButton=new PamButton();
// playButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.PLAY, Color.BLACK, PamGuiManagerFX.iconSize));
playButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play", Color.BLACK, PamGuiManagerFX.iconSize));
playButton.getStyleClass().add("transparent-button");
//playButton.setStyle(" -fx-background-radius: 50;");
playButton.setOnAction((action)->{
//TODO
//start pamguard
//PamController.getInstance().pamStart();
});
// playButton=new PamButton();
//// playButton.setGraphic(PamGlyphDude.createPamGlyph(FontAwesomeIcon.PLAY, Color.BLACK, PamGuiManagerFX.iconSize));
// playButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-play", Color.BLACK, PamGuiManagerFX.iconSize));
// playButton.getStyleClass().add("transparent-button");
// //playButton.setStyle(" -fx-background-radius: 50;");
// playButton.setOnAction((action)->{
// //TODO
// //start pamguard
// //PamController.getInstance().pamStart();
// });
analysisControls.getChildren().addAll(recordButton);
playControls.getChildren().addAll(recordButton,playButton);
playControls.setSpacing(10);
playControls.setPadding(new Insets(0,10,0,20));
// playControls.getStyleClass().add("pane-opaque");
playControls.setPrefHeight(prefHeight);
playControls.setAlignment(Pos.CENTER);
}
//create window editing button. This holds a toggle to edit windows and options.
rightHBox=new PamHBox();
@ -563,7 +580,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
centerHBox.setPrefHeight(prefHeight);
this.setCenter(centerHBox);
this.setLeft(playControls);
this.setLeft(analysisControls);
this.setRight(rightHBox);
this.setPrefHeight(prefHeight);
@ -616,7 +633,7 @@ public class PamGuiFX extends StackPane implements PamViewInterface {
/**
* Show the controls which allows manula resizing of the pane.
* Show the controls which allows manual resizing of the pane.
* @param resize.
*/
public void showResizableControl(boolean resize) {

View File

@ -1,15 +1,9 @@
package pamViewFX;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import atlantafx.base.controls.ToggleSwitch;
import atlantafx.base.theme.PrimerDark;
import atlantafx.base.theme.PrimerLight;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
@ -96,7 +90,16 @@ public class PamLauncherPane extends PamBorderPane {
// this.getStylesheets().add(getClass().getResource(primerPAMGuard).toExternalForm());
// this.getStylesheets().add(getClass().getResource(new PrimerDark().getUserAgentStylesheet()).toExternalForm());
PamStylesManagerFX.getPamStylesManagerFX().setCurStyle(new PamDefaultStyle());
}
private void setStyle(boolean PAMGuardFX) {
this.getStylesheets().clear();
if (PAMGuardFX) {
PamStylesManagerFX.getPamStylesManagerFX().setCurStyle(new PamAtlantaStyle());
this.getStylesheets().addAll(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
this.setStyle("-fx-background-color: -fx-darkbackground");
}
}

View File

@ -42,7 +42,6 @@ import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
/**
* Pane which holds settings menu. All primary settings are accessed from this pane which sits in a hiding pane to the right

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import PamView.ColourScheme;
import PamView.PamColors;
import atlantafx.base.theme.CupertinoDark;
import atlantafx.base.theme.CupertinoLight;
import atlantafx.base.theme.PrimerDark;
import atlantafx.base.theme.PrimerLight;
@ -53,6 +55,7 @@ public class PamAtlantaStyle extends PamDefaultStyle {
// private String guiCSS = new NordDark().getUserAgentStylesheet();
// protected String primerlight = "/Resources/css/primer-light.css";
protected String primerlight = new PrimerLight().getUserAgentStylesheet();
// protected String primerlight = new CupertinoLight().getUserAgentStylesheet();
/**
* Relative location of the CSS style sheet to be used for the Pamguard standard
@ -62,6 +65,7 @@ public class PamAtlantaStyle extends PamDefaultStyle {
// private String dialogCSS = new PrimerDark().getUserAgentStylesheet();
// protected String primerdark = "/Resources/css/primer-dark.css";
protected String primerdark = new PrimerDark().getUserAgentStylesheet();
// protected String primerdark = new CupertinoDark().getUserAgentStylesheet();
/**

View File

@ -7,6 +7,7 @@ import java.util.ArrayList;
import org.jamdev.jdl4pam.transforms.DLTransformsFactory;
import org.jamdev.jdl4pam.transforms.DLTransfromParams;
import org.jamdev.jdl4pam.transforms.SimpleTransformParams;
import org.jamdev.jpamutils.wavFiles.AudioData;
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import org.junit.jupiter.api.Test;
@ -31,7 +32,7 @@ public class ClickDLTest {
System.out.println("*****Click classification Deep Learning C*****");
//relative paths to the resource folders.
String relModelPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/updated_model/saved_model.pb";
String relModelPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/uniform_model/saved_model.pb";
String clicksPath = "./src/test/resources/rawDeepLearningClassifier/Generic/risso_click/clicks.mat";
Path path = Paths.get(relModelPath);
@ -45,14 +46,17 @@ public class ClickDLTest {
//create the transforms.
ArrayList<DLTransfromParams> dlTransformParamsArr = new ArrayList<DLTransfromParams>();
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV));
//waveform transforms.
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.DECIMATE_SCIPY, 248000.));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.PEAK_TRIM, 128, 1));
dlTransformParamsArr.add(new SimpleTransformParams(DLTransformType.NORMALISE_WAV, 0., 1, AudioData.ZSCORE));
genericModelParams.dlTransfromParams = dlTransformParamsArr;
genericModelParams.dlTransfroms = DLTransformsFactory.makeDLTransforms((ArrayList<DLTransfromParams>)genericModelParams.dlTransfromParams);
//create the clicks.
path = Paths.get(clicksPath);
ArrayList<GroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
ArrayList<PredGroupedRawData> clicks = importClicks(path.toAbsolutePath().normalize().toString(), SAMPLE_RATE);
//prep the model
genericModelWorker.prepModel(genericModelParams, null);
@ -61,28 +65,30 @@ public class ClickDLTest {
ArrayList<GroupedRawData> groupedData = new ArrayList<GroupedRawData>();
int i=0;
for (int i=0; i<1; i++) {
float prediction = 0;
float prediction = (float) clicks.get(i).getPrediction()[0];
groupedData.add(clicks.get(i)); //TODO for loop
System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
//System.out.println("Waveform input: " + groupedData.get(i).getRawData().length + " " + groupedData.get(i).getRawData()[0].length);
ArrayList<StandardPrediction> genericPrediction = genericModelWorker.runModel(groupedData,SAMPLE_RATE, 0);
float[] output = genericPrediction.get(0).getPrediction();
float[] output = genericPrediction.get(i).getPrediction();
System.out.println(String.format("Click %d Predicted output: %.2f true output: %.2f passed: %b", clicks.get(i).getUID(),
output[0], prediction, output[0]>prediction*0.9 && output[0]<prediction*1.1));
}
}
/**
* Import a bunch of clicks from a .mat file
*/
public static ArrayList<GroupedRawData> importClicks(String filePath, float sR) {
public static ArrayList<PredGroupedRawData> importClicks(String filePath, float sR) {
try {
Mat5File mfr = Mat5.readFromFile(filePath);
@ -91,9 +97,9 @@ public class ClickDLTest {
Struct mlArrayRetrived = mfr.getStruct( "clickpreds" );
int numClicks= mlArrayRetrived.getNumCols();
ArrayList<GroupedRawData> clicks = new ArrayList<GroupedRawData>(numClicks);
ArrayList<PredGroupedRawData> clicks = new ArrayList<PredGroupedRawData>(numClicks);
GroupedRawData clickData;
PredGroupedRawData clickData;
for (int i=0; i<numClicks; i++) {
Matrix clickWav= mlArrayRetrived.get("wave", i);
@ -107,10 +113,12 @@ public class ClickDLTest {
Matrix channelMap= mlArrayRetrived.get("channelMap", i);
Matrix startSample= mlArrayRetrived.get("startSample", i);
Matrix sampleDuration= mlArrayRetrived.get("sampleDuration", i);
Matrix pred= mlArrayRetrived.get("pred", i);
clickData = new GroupedRawData(clickmillis.getLong(0), channelMap.getInt(0), startSample.getLong(0), sampleDuration.getLong(0), sampleDuration.getInt(0));
clickData = new PredGroupedRawData(clickmillis.getLong(0), channelMap.getInt(0), startSample.getLong(0), sampleDuration.getLong(0), sampleDuration.getInt(0));
clickData.setUID(clickUID.getLong(0));
clickData.setRawData(clickwaveform);
clickData.setPrediction(new double[] {pred.getDouble(0), pred.getDouble(1)});
clicks.add(clickData);
}
@ -124,5 +132,25 @@ public class ClickDLTest {
}
}
public static class PredGroupedRawData extends GroupedRawData {
private double[] prediction;
public double[] getPrediction() {
return prediction;
}
public void setPrediction(double[] prediction) {
this.prediction = prediction;
}
public PredGroupedRawData(long timeMilliseconds, int channelBitmap, long startSample, long duration, int samplesize) {
super(timeMilliseconds, channelBitmap, startSample, duration, samplesize);
}
}
}

View File

@ -218,8 +218,7 @@ public class DelphinIDTest {
//the values for the whistle detector.
double[][] pamguardWhistleImage = whistleScatter2Image(whistleValues);
System.out.println("Size python: " + compressedWhistleImage.length + " x " + compressedWhistleImage[0].length);
//System.out.println("Size python: " + compressedWhistleImage.length + " x " + compressedWhistleImage[0].length);
float[][][] input = new float[1][][];
input[0] = JamArr.doubleToFloat(compressedWhistleImage);
@ -255,7 +254,6 @@ public class DelphinIDTest {
System.out.println("DelphinID mode test end");
}

View File

@ -1,23 +1,10 @@
package wavFiles;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.swing.JOptionPane;
//import org.kc7bfi.jflac.util.ByteData;
import org.jflac.util.ByteData;
import clickDetector.WindowsFile;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
public class WavFile {