Koogu working

Koogu now working...
This commit is contained in:
Jamie Mac 2024-01-17 07:00:06 +00:00
parent 7f1524267e
commit 37fe953474
19 changed files with 959 additions and 281 deletions

View File

@ -8,7 +8,6 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>

View File

@ -842,6 +842,13 @@ C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2-->
<artifactId>atlantafx-base</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Extra 3D bits for JavaFX -->
<dependency>
<groupId>org.fxyz3d</groupId>
<artifactId>fxyz3d</artifactId>
<version>0.6.0</version>
</dependency>
</dependencies>
</project>

View File

@ -4,24 +4,24 @@ import pamViewFX.fxNodes.PamBorderPane;
import java.util.ArrayList;
import org.fxyz3d.geometry.Point3D;
import org.fxyz3d.shapes.composites.PolyLine3D;
import Array.Hydrophone;
import Array.PamArray;
import Array.Streamer;
import javafx.event.EventHandler;
import javafx.scene.AmbientLight;
import javafx.scene.DepthTest;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.geometry.Point3D;
import javafx.scene.shape.Sphere;
import javafx.scene.text.Text;
@ -60,6 +60,7 @@ public class Array3DPane extends PamBorderPane {
private double scaleFactor=20;
private double axisSize=10*scaleFactor;
//keep track of mouse positions
@ -92,7 +93,10 @@ public class Array3DPane extends PamBorderPane {
private Rotate rotateX;
private Translate translate;
/**
* The size of the hydrophone for the 3D display.
*/
private double hydrophoneSize = 0.5;
public Array3DPane(){
@ -113,13 +117,13 @@ public class Array3DPane extends PamBorderPane {
root3D.getChildren().add(arrayGroup);
root3D.getChildren().add(axisGroup);
AmbientLight light = new AmbientLight();
light.setColor(Color.WHITE);
Group lightGroup = new Group();
lightGroup.getChildren().add(light);
root3D.getChildren().add(lightGroup);
AmbientLight light = new AmbientLight();
light.setColor(Color.WHITE);
Group lightGroup = new Group();
lightGroup.getChildren().add(light);
root3D.getChildren().add(lightGroup);
//Use a SubScene to mix 3D and 2D stuff.
//note- make sure depth buffer in sub scene is enabled.
@ -136,7 +140,7 @@ public class Array3DPane extends PamBorderPane {
//handle mouse events for sub scene
handleMouse(subScene);
//create new group to add sub scene to
Group group = new Group();
@ -230,8 +234,8 @@ public class Array3DPane extends PamBorderPane {
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
axisGroup.getChildren().addAll(xText, yText, zText);
axisGroup.getChildren().addAll(xSphere, ySphere, zSphere);
return axisGroup;
}
@ -295,98 +299,146 @@ public class Array3DPane extends PamBorderPane {
* @param array - the hydrophone array to draw.
*/
public void drawArray(PamArray array) {
System.out.println("Draw array: " + array);
System.out.println("DRAW ARRAY: " + array);
//clear the array
arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
ArrayList<Hydrophone> hydrophones = array.getHydrophoneArray();
//draw hydrophones
Sphere sphere;
Streamer streamer;
for (int i=0; i<hydrophones.size(); i++){
//get the streamer for the hydrophone
streamer = array.getStreamer(hydrophones.get(i).getStreamerId());
double x = hydrophones.get(i).getX() + hydrophones.get(i).getStreamerId();
double y = hydrophones.get(i).getY() + hydrophones.get(i).getStreamerId();
double z = hydrophones.get(i).getZ() + hydrophones.get(i).getStreamerId();
sphere=new Sphere(hydrophoneSize*scaleFactor);
sphere.setTranslateX(x*scaleFactor);
sphere.setTranslateY(z*scaleFactor);
sphere.setTranslateZ(y*scaleFactor);
Color col = Color.RED;
final PhongMaterial aMaterial = new PhongMaterial();
aMaterial.setDiffuseColor(col);
aMaterial.setSpecularColor(col.brighter());
sphere.setMaterial(aMaterial);
// System.out.println("Add hydrophone: " + x + " " + y + " " +z);
arrayGroup.getChildren().add(sphere);
ArrayList<Point3D> streamerPoints=new ArrayList<Point3D>();
//now plot a line from the streamer to the hydrophone
Point3D newPoint;
newPoint=new Point3D(x*scaleFactor, z*scaleFactor, y*scaleFactor);
streamerPoints.add(newPoint);
newPoint =new Point3D(streamer.getCoordinate(0)*scaleFactor, streamer.getCoordinate(2)*scaleFactor, streamer.getCoordinate(1)*scaleFactor);
streamerPoints.add(newPoint);
System.out.println("Streamer points: " + streamerPoints.size());
PolyLine3D polyLine3D=new PolyLine3D(streamerPoints, 4f, Color.DODGERBLUE);
arrayGroup.getChildren().add(polyLine3D);
}
}
// /**
// * Draw the entire array
// * @param pos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
// */
// public void drawArrays(ArrayList<ArrayList<ArrayPos>> pos){
//
// arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
//
// if (pos==null){
// System.err.println("Array3DPane: Hydrophone positions are null");
// return;
// }
//
// for (int i=0; i< pos.size(); i++){
// for (int j=0; j<pos.get(i).size(); j++){
// drawArray(pos.get(i).get(j));
// }
// }
//
// //System.out.println("Draw 3D hydrophone array");
// }
// /**
// * Draw the entire array
// * @param pos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
// */
// public void drawArrays(ArrayList<ArrayList<ArrayPos>> pos){
//
// arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
//
// if (pos==null){
// System.err.println("Array3DPane: Hydrophone positions are null");
// return;
// }
//
// for (int i=0; i< pos.size(); i++){
// for (int j=0; j<pos.get(i).size(); j++){
// drawArray(pos.get(i).get(j));
// }
// }
//
// //System.out.println("Draw 3D hydrophone array");
// }
// /**
// * Draw an array.
// * @param arrayPos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
// */
// private void drawArray(ArrayPos arrayPos){
//
// final PhongMaterial redMaterial = new PhongMaterial();
// redMaterial.setDiffuseColor(DEFAULT_HYDRO_COL);
// redMaterial.setSpecularColor(DEFAULT_HYDRO_COL.brighter());
//
// final PhongMaterial greenMaterial = new PhongMaterial();
// greenMaterial.setDiffuseColor(DEFAULT_SENSOR_COL);
// greenMaterial.setSpecularColor(DEFAULT_SENSOR_COL.brighter());
//
// //draw hydrophones
// Sphere sphere;
// for (int i=0; i<arrayPos.getTransformHydrophonePos().size(); i++){
// sphere=new Sphere(settings.hydrophoneSize*scaleFactor);
// sphere.setTranslateX(arrayPos.getTransformHydrophonePos().get(i)[0]*scaleFactor);
// sphere.setTranslateY(-arrayPos.getTransformHydrophonePos().get(i)[2]*scaleFactor);
// sphere.setTranslateZ(arrayPos.getTransformHydrophonePos().get(i)[1]*scaleFactor);
//
// Color hydroCol = settings.hydrophoneColours[arrayPos.getHArray().getHydrophones().get(i).channel.get()];
//
// if (hydroCol == null) {
// sphere.setMaterial(redMaterial);
// }
// else {
// final PhongMaterial aMaterial = new PhongMaterial();
// aMaterial.setDiffuseColor(hydroCol);
// aMaterial.setSpecularColor(hydroCol.brighter());
// sphere.setMaterial(aMaterial);
//
// }
// arrayGroup.getChildren().add(sphere);
//
// }
//
//
//
// //draw streamer
// PolyLine3D polyLine3D;
// ArrayList<Point3D> streamerPoints;
//
// for (int i=0; i<arrayPos.getTransformStreamerPositions().size(); i++){
// if (arrayPos.getTransformStreamerPositions().get(i)==null) return;
// streamerPoints=new ArrayList<Point3D>();
// for (int j=0; j<arrayPos.getTransformStreamerPositions().get(i).size(); j++){
//
// //TODO- use cylinder for line
// // Cylinder cylinder=createConnection(arrayPos.getTransformStreamerPositions().get(i).get(j).multiply(scaleFactor), arrayPos.getTransformStreamerPositions().get(i).get(j+1).multiply(scaleFactor),0.2*scaleFactor);
// // arrayGroup.getChildren().add(cylinder);
//
// //need to convert to fxyz 3D point - stupid but no work around.
// Point3D newPoint=new Point3D((float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getX()*scaleFactor),
// (float) (-arrayPos.getTransformStreamerPositions().get(i).get(j).getZ()*scaleFactor), (float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getY()*scaleFactor));
// streamerPoints.add(newPoint);
// }
// polyLine3D=new PolyLine3D(streamerPoints, 4, Color.BLUE);
// arrayGroup.getChildren().add(polyLine3D);
// }
//
// }
// /**
// * Draw an array.
// * @param arrayPos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
// */
// private void drawArray(ArrayPos arrayPos){
//
// final PhongMaterial redMaterial = new PhongMaterial();
// redMaterial.setDiffuseColor(DEFAULT_HYDRO_COL);
// redMaterial.setSpecularColor(DEFAULT_HYDRO_COL.brighter());
//
// final PhongMaterial greenMaterial = new PhongMaterial();
// greenMaterial.setDiffuseColor(DEFAULT_SENSOR_COL);
// greenMaterial.setSpecularColor(DEFAULT_SENSOR_COL.brighter());
//
// //draw hydrophones
// Sphere sphere;
// for (int i=0; i<arrayPos.getTransformHydrophonePos().size(); i++){
// sphere=new Sphere(settings.hydrophoneSize*scaleFactor);
// sphere.setTranslateX(arrayPos.getTransformHydrophonePos().get(i)[0]*scaleFactor);
// sphere.setTranslateY(-arrayPos.getTransformHydrophonePos().get(i)[2]*scaleFactor);
// sphere.setTranslateZ(arrayPos.getTransformHydrophonePos().get(i)[1]*scaleFactor);
//
// Color hydroCol = settings.hydrophoneColours[arrayPos.getHArray().getHydrophones().get(i).channel.get()];
//
// if (hydroCol == null) {
// sphere.setMaterial(redMaterial);
// }
// else {
// final PhongMaterial aMaterial = new PhongMaterial();
// aMaterial.setDiffuseColor(hydroCol);
// aMaterial.setSpecularColor(hydroCol.brighter());
// sphere.setMaterial(aMaterial);
//
// }
// arrayGroup.getChildren().add(sphere);
//
// }
//
//
//
// //draw streamer
// PolyLine3D polyLine3D;
// ArrayList<Point3D> streamerPoints;
//
// for (int i=0; i<arrayPos.getTransformStreamerPositions().size(); i++){
// if (arrayPos.getTransformStreamerPositions().get(i)==null) return;
// streamerPoints=new ArrayList<Point3D>();
// for (int j=0; j<arrayPos.getTransformStreamerPositions().get(i).size(); j++){
//
// //TODO- use cylinder for line
// // Cylinder cylinder=createConnection(arrayPos.getTransformStreamerPositions().get(i).get(j).multiply(scaleFactor), arrayPos.getTransformStreamerPositions().get(i).get(j+1).multiply(scaleFactor),0.2*scaleFactor);
// // arrayGroup.getChildren().add(cylinder);
//
// //need to convert to fxyz 3D point - stupid but no work around.
// Point3D newPoint=new Point3D((float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getX()*scaleFactor),
// (float) (-arrayPos.getTransformStreamerPositions().get(i).get(j).getZ()*scaleFactor), (float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getY()*scaleFactor));
// streamerPoints.add(newPoint);
// }
// polyLine3D=new PolyLine3D(streamerPoints, 4, Color.BLUE);
// arrayGroup.getChildren().add(polyLine3D);
// }
//
// }

View File

@ -5,14 +5,19 @@ import PamController.PamController;
import PamController.SettingsPane;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.layout.VBox;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamHBox;
/**
* The main settings pane for settings up a hydrophone array.
@ -98,14 +103,14 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
// });
streamerPane.addStreamerListener((x,y)->{
System.out.println("Streamer changed!");
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
System.out.println("Streamer changed!");
array3DPane.drawArray(array);
});
hydrophonePane.addStreamerListener((x,y)->{
System.out.println("Hydrophone changed!");
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
System.out.println("Hydrophone changed!" + array.getHydrophoneCount());
array3DPane.drawArray(array);
});
@ -173,6 +178,37 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
arrayLabel.setPadding(new Insets(5,5,5,5));
PamGuiManagerFX.titleFont1style(arrayLabel);
//holds the array label and also some button for import and export.
PamHBox arrayImportExportBox = new PamHBox();
arrayImportExportBox.setSpacing(5);
arrayImportExportBox.setAlignment(Pos.CENTER_LEFT);
arrayImportExportBox.setPadding(new Insets(5,0,0,0));
PamButton importButton = new PamButton("Import...");
importButton.setOnAction((action)->{
importArray();
});
importButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-import", PamGuiManagerFX.iconSize));
importButton.setTooltip(new Tooltip("Import array settings from a .pgaf file"));
PamButton exportButton = new PamButton("Export...");
exportButton.setOnAction((action)->{
exportArray();
});
exportButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-export", PamGuiManagerFX.iconSize));
exportButton.setTooltip(new Tooltip("Export array settings to a .pgaf file"));
//balnk region to make it look nicer
Region blank = new Region();
blank.setPrefWidth(70);
arrayImportExportBox.getChildren().addAll(importButton, exportButton, blank);
PamBorderPane titleHolder = new PamBorderPane();
titleHolder.setLeft(arrayLabel);
titleHolder.setRight(arrayImportExportBox);
//the streamer pane for changing streamer settings.
streamerPane = new StreamersPane();
streamerPane.setMaxWidth(Double.MAX_VALUE);
@ -196,12 +232,28 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
PamVBox vBox = new PamVBox();
vBox.setSpacing(5);
vBox.getChildren().addAll(arrayLabel, streamerPane, hydrophoneLabel,
vBox.getChildren().addAll(titleHolder, streamerPane, hydrophoneLabel,
hydrophonePane);
return vBox;
}
/**
* Select a file to export array settings to.
*/
private void exportArray() {
// TODO Auto-generated method stub
}
/**
* Select a file to import array settings
*/
private void importArray() {
// TODO Auto-generated method stub
}
/**
* Set correct text for the receiver in the current medium (e.g. air or water);
*/
@ -233,6 +285,9 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
hydrophonePane.setParams(input);
streamerPane.setParams(input);
environmentalPane.setParams(input);
//draw the array
array3DPane.drawArray(input);
}
@Override

View File

@ -77,6 +77,15 @@ public class HydrophoneProperty {
}
public Hydrophone getHydrophone() {
//incase table data changes.
this.hydrophone.setID(this.id.get());
this.hydrophone.setX(x.get());
this.hydrophone.setY(y.get());
this.hydrophone.setZ(z.get());
this.hydrophone.setdX(xErr.get());
this.hydrophone.setdY(yErr.get());
this.hydrophone.setdZ(xErr.get());
return hydrophone;
}

View File

@ -1,9 +1,6 @@
package Array.layoutFX;
import javax.swing.JTextField;
import Array.Hydrophone;
import PamController.SettingsPane;
import javafx.scene.Node;
import javafx.scene.control.Label;
import Array.PamArray;
@ -21,8 +18,10 @@ import javafx.scene.layout.Region;
import net.synedra.validatorfx.Validator;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.validator.PamValidator;
@ -32,7 +31,7 @@ import pamViewFX.validator.PamValidator;
* @author Jamie Macaulay
*
*/
public class HydrophoneSettingsPane extends SettingsPane<Hydrophone> {
public class HydrophoneSettingsPane extends DynamicSettingsPane<Hydrophone> {
private static final double COLUMN_0_WIDTH = 120;
@ -102,7 +101,7 @@ public class HydrophoneSettingsPane extends SettingsPane<Hydrophone> {
*/
private PamBorderPane mainPane;
private InterpSettingsPane interpPane;
private InterpChoicePane interpPane;
private ComboBox<String> defaultHydro;
@ -123,9 +122,14 @@ public class HydrophoneSettingsPane extends SettingsPane<Hydrophone> {
Label interpLabel = new Label("Interpolation");
PamGuiManagerFX.titleFont2style(interpLabel);
interpPane = new InterpSettingsPane();
interpPane = new InterpChoicePane();
PamHBox interpHolder = new PamHBox();
interpHolder.setSpacing(5);
interpHolder.setAlignment(Pos.CENTER);
interpHolder.getChildren().addAll(new Label("Method"), interpPane);
holderPane.getChildren().addAll(recieverIDLabel, createGeneralPane(), coOrdLabel, createPositionPane(), interpLabel, interpPane);
holderPane.getChildren().addAll(recieverIDLabel, createGeneralPane(), coOrdLabel, createPositionPane(), interpLabel, interpHolder);
mainPane = new PamBorderPane();
mainPane.setCenter(holderPane);
@ -343,13 +347,25 @@ public class HydrophoneSettingsPane extends SettingsPane<Hydrophone> {
double maxWidth =10;
xPos=new TextField();
xPos.textProperty().addListener((obsVal, oldVal, newVal)->{
notifySettingsListeners();
});
xPos.setMaxWidth(maxWidth);
addTextValidator(xPos, "x position", validator);
yPos=new TextField();
yPos.setMaxWidth(maxWidth);
addTextValidator(yPos, "y position", validator);
yPos.textProperty().addListener((obsVal, oldVal, newVal)->{
notifySettingsListeners();
});
zPos=new TextField();
zPos.setMaxWidth(maxWidth);
zPos.textProperty().addListener((obsVal, oldVal, newVal)->{
notifySettingsListeners();
});
addTextValidator(zPos, "z position", validator);
depthLabel = new Label("Depth");
depthLabel.setAlignment(Pos.CENTER);

View File

@ -1,6 +1,7 @@
package Array.layoutFX;
import java.util.ArrayList;
import java.util.List;
import Array.Hydrophone;
import Array.PamArray;
@ -10,8 +11,13 @@ import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Dialog;
import javafx.scene.control.TableCell;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.util.Callback;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.IntegerStringConverter;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import pamViewFX.fxNodes.table.TableSettingsPane;
@ -23,8 +29,8 @@ import pamViewFX.fxNodes.table.TableSettingsPane;
*
*/
public class HydrophonesPane extends PamBorderPane {
static final double defaultx = 0.;
static final double defaulty = 0.;
static final double defaultz = 0.;
@ -33,7 +39,7 @@ public class HydrophonesPane extends PamBorderPane {
static final double defaultzErr = 0.;
static final String defaulttype = "Unknown";
static final double defaultsensitivity = -201;
/**
* Reference to the current array
*/
@ -49,77 +55,77 @@ public class HydrophonesPane extends PamBorderPane {
* A list of all the current hydrophones.
*/
ObservableList<HydrophoneProperty> hydrophoneList = FXCollections.observableArrayList();
/**
* The hydrophone array table.
*/
private HydrophoneTable tableArrayPane;
private PamFlipPane pamFlipePane;
/**
* Settings pane for a single hydrophone.
*/
private HydrophoneSettingsPane hydrophonePane = new HydrophoneSettingsPane();
/**
* A list of listeners which are called whenever a hydrophone is added removed or changed.
*/
public ArrayList<ArrayChangeListener> hydrophoneChangeListeners = new ArrayList<ArrayChangeListener>();
public HydrophonesPane() {
tableArrayPane = new HydrophoneTable(hydrophoneList);
tableArrayPane.setPadding(new Insets(5,5,5,5));
pamFlipePane = new PamFlipPane();
pamFlipePane.getAdvLabel().setText("Hydrophone Settings");
// pamFlipePane.minWidthProperty().bind(this.widthProperty());
// pamFlipePane.setStyle("-fx-background-color: green;");
tableArrayPane = new HydrophoneTable(hydrophoneList);
tableArrayPane.setPadding(new Insets(5,5,5,5));
pamFlipePane = new PamFlipPane();
pamFlipePane.getAdvLabel().setText("Hydrophone Settings");
// pamFlipePane.minWidthProperty().bind(this.widthProperty());
// pamFlipePane.setStyle("-fx-background-color: green;");
((Pane) hydrophonePane.getContentNode()).setPadding(new Insets(5,5,5,15));
pamFlipePane.setAdvPaneContent(hydrophonePane.getContentNode());
pamFlipePane.setFrontContent(tableArrayPane);
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
pamFlipePane.backButtonProperty().addListener((obsval, oldVal, newVal)->{
// System.out.println("Hello back button pressed: " + newVal.intValue());
//the flip pane
if (newVal.intValue()==PamFlipPane.OK_BACK_BUTTON) {
Hydrophone hydro = hydrophonePane.getParams(currentHydrophoneData.getHydrophone());
if (hydro==null) {
//the warning dialog is shown in the streamer settings pane
return;
}
// System.out.println("Hydro: " + currentHydrophoneData.getX().get()+ " " + currentHydrophoneData.getY().get() + " " + currentHydrophoneData.getZ().get() + " ID: " +hydro.getID());
// System.out.println("Hydro err: " + currentHydrophoneData.getXErr().get()+ " " + currentHydrophoneData.getYErr().get() + " " + currentHydrophoneData.getZErr().get());
((Pane) hydrophonePane.getContentNode()).setPadding(new Insets(5,5,5,15));
currentHydrophoneData.setHydrophone(hydro);
notifyHydrophoneListeners(currentHydrophoneData);
pamFlipePane.setAdvPaneContent(hydrophonePane.getContentNode());
pamFlipePane.setFrontContent(tableArrayPane);
//need to refresh table to show symbol.
tableArrayPane.getTableView().refresh();
//
// System.out.println("Table size: " + tableArrayPane.getTableView().getItems().size());
// for (int i=0; i<tableArrayPane.getTableView().getItems().size(); i++) {
// System.out.println("Item : " + tableArrayPane.getTableView().getItems().get(i) + " " + currentHydrophoneData);
// }
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
pamFlipePane.backButtonProperty().addListener((obsval, oldVal, newVal)->{
// System.out.println("Hello back button pressed: " + newVal.intValue());
//the flip pane
if (newVal.intValue()==PamFlipPane.OK_BACK_BUTTON) {
Hydrophone hydro = hydrophonePane.getParams(currentHydrophoneData.getHydrophone());
if (hydro==null) {
//the warning dialog is shown in the streamer settings pane
return;
}
});
this.setCenter(pamFlipePane);
// System.out.println("Hydro: " + currentHydrophoneData.getX().get()+ " " + currentHydrophoneData.getY().get() + " " + currentHydrophoneData.getZ().get() + " ID: " +hydro.getID());
// System.out.println("Hydro err: " + currentHydrophoneData.getXErr().get()+ " " + currentHydrophoneData.getYErr().get() + " " + currentHydrophoneData.getZErr().get());
currentHydrophoneData.setHydrophone(hydro);
notifyHydrophoneListeners(currentHydrophoneData);
//need to refresh table to show symbol.
tableArrayPane.getTableView().refresh();
//
// System.out.println("Table size: " + tableArrayPane.getTableView().getItems().size());
// for (int i=0; i<tableArrayPane.getTableView().getItems().size(); i++) {
// System.out.println("Item : " + tableArrayPane.getTableView().getItems().get(i) + " " + currentHydrophoneData);
// }
}
});
this.setCenter(pamFlipePane);
}
/**
* Notify the hydrophone listeners of a change
* @param streamer - the changed streamer
@ -129,63 +135,106 @@ public class HydrophonesPane extends PamBorderPane {
listener.arrayChanged(ArrayChangeListener.HYDROPHONE_CHANGE, hydrophone);
}
}
/**
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
* @author Jamie Macaulay
*
*/
class HydrophoneTable extends TableSettingsPane<HydrophoneProperty> {
/**
* The z table
*/
private TableColumn<HydrophoneProperty, Number> z;
public HydrophoneTable(ObservableList<HydrophoneProperty> hydrophoneData) {
super(hydrophoneData);
z = new TableColumn<HydrophoneProperty,Number>("depth");
z = new TableColumn<HydrophoneProperty,Number>("depth");
z.setCellValueFactory(cellData -> cellData.getValue().getZ());
z.setEditable(false);
z.setEditable(true);
//need to set up all the rows.
TableColumn<HydrophoneProperty,Number> hydroID = new TableColumn<HydrophoneProperty,Number>("ID");
hydroID.setCellValueFactory(cellData -> cellData.getValue().getID());
TableColumn<HydrophoneProperty,Integer> hydroID = new TableColumn<HydrophoneProperty,Integer>("ID");
hydroID.setCellValueFactory(cellData -> cellData.getValue().getID().asObject());
hydroID.setEditable(false);
// Default cell factory provides text field for editing and converts text in text field to int.
Callback<TableColumn<HydrophoneProperty, Integer>, TableCell<HydrophoneProperty, Integer>> defaultCellFactory =
TextFieldTableCell.forTableColumn(new IntegerStringConverter());
// Cell factory implementation that uses default cell factory above, and augments the implementation
// by updating the value of the looked-up color cell-selection-color for the cell when the item changes:
Callback<TableColumn<HydrophoneProperty, Integer>, TableCell<HydrophoneProperty, Integer>> cellFactory = col -> {
TableCell<HydrophoneProperty, Integer> cell = defaultCellFactory.call(col);
cell.itemProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("Hello set colour: " + newValue);
if (newValue == null) {
cell.setStyle("cell-selection-color: -fx-selection-bar ;");
} else {
Color color = createColor(newValue.intValue());
String formattedColor = formatColor(color);
// cell.setStyle("cell-selection-color: "+ formattedColor + " ;");
cell.setStyle("-fx-background: "+ formattedColor + " ;");
cell.setStyle("-fx-background-color: "+ formattedColor + " ;");
System.out.println("Hello set style: " + formattedColor);
}
});
return cell;
};
hydroID.setCellFactory(cellFactory);
TableColumn<HydrophoneProperty,Number> x = new TableColumn<HydrophoneProperty,Number>("x");
x.setCellValueFactory(cellData -> cellData.getValue().getX());
x.setEditable(false);
x.setEditable(true);
TableColumn<HydrophoneProperty,Number> y = new TableColumn<HydrophoneProperty,Number>("y");
y.setCellValueFactory(cellData -> cellData.getValue().getY());
y.setEditable(false);
y.setEditable(true);
TableColumn posColumn=new TableColumn("Position (m)");
posColumn.getColumns().addAll(x, y, z);
TableColumn<HydrophoneProperty,Number> xErr = new TableColumn<HydrophoneProperty,Number>("x");
xErr.setCellValueFactory(cellData -> cellData.getValue().getXErr());
xErr.setEditable(false);
xErr.setEditable(true);
TableColumn<HydrophoneProperty,Number> yErr = new TableColumn<HydrophoneProperty,Number>("y");
yErr.setCellValueFactory(cellData -> cellData.getValue().getYErr());
yErr.setEditable(false);
yErr.setEditable(true);
TableColumn<HydrophoneProperty,Number> zErr = new TableColumn<HydrophoneProperty,Number>("z");
zErr.setCellValueFactory(cellData -> cellData.getValue().getZErr());
zErr.setEditable(false);
zErr.setEditable(true);
TableColumn errorColumn=new TableColumn("Errors (m)");
errorColumn.getColumns().addAll(xErr, yErr, zErr);
getTableView().getColumns().addAll(hydroID, posColumn, errorColumn);
}
// Create color based on int value. Just use value as hue, full saturation and brightness:
private Color createColor(int x) {
return Color.hsb(x, 1.0, 1.0);
}
// Format color as string for CSS (#rrggbb format, values in hex).
private String formatColor(Color c) {
int r = (int) (255 * c.getRed());
int g = (int) (255 * c.getGreen());
int b = (int) (255 * c.getBlue());
return String.format("#%02x%02x%02x", r, g, b);
}
@Override
public void dialogClosed(HydrophoneProperty data) {
@ -197,25 +246,25 @@ public class HydrophonesPane extends PamBorderPane {
@Override
public Dialog<HydrophoneProperty> createSettingsDialog(HydrophoneProperty data) {
//we do not use dialogs here- sliding pane instead.
// setClassifierPane(data);
// setClassifierPane(data);
pamFlipePane.flipToBack();
return null;
}
@Override
public void editData(HydrophoneProperty data){
// setClassifierPane(data);
// setClassifierPane(data);
pamFlipePane.getAdvLabel().setText("Hydrophone " + data.getID().get() + " Settings");
hydrophonePane.setCurrentArray(currentArray);
hydrophonePane.setParams(data.getHydrophone());
currentHydrophoneData = data;
pamFlipePane.flipToBack();
}
private PamArray getCurrentArray() {
return currentArray;
@ -231,34 +280,84 @@ public class HydrophonesPane extends PamBorderPane {
@Override
public void createNewData(){
HydrophoneProperty hydrophone = createDefaultHydrophoneProperty(hydrophoneList.size());
//create a new classifier.
hydrophoneList.add(createDefaultHydrophoneProperty(hydrophoneList.size()));
hydrophoneList.add(hydrophone);
notifyHydrophoneListeners(hydrophone);
}
@Override
public void deleteData(HydrophoneProperty data){
super.deleteData(data);
//the ID number for hydrophone sis actually important for where they are in the list. Bit a legacy issue but no
//point in messes everything up to fix. So, when a hydrophone is deleted must update all the ID numbers.
updateIDNumbers();
notifyHydrophoneListeners(data);
}
/**
* Update the ID numbers.
*/
private void updateIDNumbers() {
for (int i=0; i<getData().size(); i++){
getData().get(i).id.set(i);
}
}
private HydrophoneProperty createDefaultHydrophoneProperty(int id) {
return new HydrophoneProperty(new Hydrophone(id, defaultx, defaulty,defaultz, defaultxErr, defaultyErr, defaultzErr, defaulttype, defaultsensitivity,
null, 0. ));
null, 0. ));
}
public TableColumn<HydrophoneProperty, Number> getZColumn() {
return z;
}
/**
* Get the current streamers.
* @return the current streamers.
*/
public ObservableList<HydrophoneProperty> getHydrophones() {
return getData();
}
}
public void setParams(PamArray currentArray) {
//TODO
this.currentArray=currentArray;
tableArrayPane.getHydrophones().clear();
for (int i=0; i<currentArray.getHydrophoneCount(); i++) {
tableArrayPane.getHydrophones().add(new HydrophoneProperty(currentArray.getHiddenHydrophone(i)));
}
//update ID numbers just incase.
tableArrayPane.updateIDNumbers();
}
public PamArray getParams(PamArray currParams) {
//TODO
public synchronized PamArray getParams(PamArray currParams) {
currParams.clearArray();
Hydrophone hydrophone;
for (int i=0; i<tableArrayPane.getHydrophones().size(); i++) {
hydrophone = tableArrayPane.getHydrophones().get(i).getHydrophone();
hydrophone.setID(i);
currParams.addHydrophone(hydrophone);
}
return currParams;
}
/**
* Get the current hydrophone list.
* @return the current hydrophone list.
@ -275,14 +374,14 @@ public class HydrophonesPane extends PamBorderPane {
tableArrayPane.getZColumn().setText(PamController.getInstance().getGlobalMediumManager().getZString());
hydrophonePane.setRecieverLabels();
}
/**
* Add a listener which is called whenever a hydrophone is added, removed or changed.
* @param e - the listener to add
*/
public void addStreamerListener(ArrayChangeListener e) {
hydrophoneChangeListeners.add(e);
}
}

View File

@ -41,10 +41,15 @@ public class PropogationPane extends SettingsPane<PamArray> {
validator.createCheck()
.dependsOn("speed_of_sound", speedOfSound.textProperty())
.withMethod(c -> {
try {
String posVal = c.get("speed_of_sound");
if (posVal.isEmpty() || Double.valueOf(posVal)==null) {
c.error("The input for speed of sound is invalid");
}
}
catch (Exception e) {
c.error("The input for speed of sound is invalid");
}
})
.decorates(speedOfSound).immediate();
@ -55,10 +60,15 @@ public class PropogationPane extends SettingsPane<PamArray> {
validator.createCheck()
.dependsOn("speed_of_sound_error", speedOfSoundError.textProperty())
.withMethod(c -> {
try {
String posVal = c.get("speed_of_sound_error");
if (posVal.isEmpty() || Double.valueOf(posVal)==null) {
c.error("The input for speed of sound error is invalid");
}
}
catch (Exception e) {
c.error("The input for speed of sound is invalid");
}
})
.decorates(speedOfSoundError).immediate();

View File

@ -221,6 +221,15 @@ public class StreamersPane extends PamBorderPane {
//add to the current array.
currentArray.addStreamer(newStreamer.getStreamer());
System.out.println("Create new streamer: " + currentArray.getNumStreamers());
notifyStreamerListeners(newStreamer);
}
@Override
public void deleteData(StreamerProperty data){
super.deleteData(data);
notifyStreamerListeners(data);
}
private StreamerProperty createDefaultStreamerProperty() {
@ -263,21 +272,21 @@ public class StreamersPane extends PamBorderPane {
for (int i=0; i<tableArrayPane.getStreamers().size(); i++) {
if (i<currentArray.getStreamerCount()) {
currentArray.updateStreamer(i,tableArrayPane.getStreamers().get(i).getStreamer());
currParams.updateStreamer(i,tableArrayPane.getStreamers().get(i).getStreamer());
}
else {
currentArray.addStreamer(tableArrayPane.getStreamers().get(i).getStreamer());
currParams.addStreamer(tableArrayPane.getStreamers().get(i).getStreamer());
}
}
while (currentArray.getStreamerCount()>tableArrayPane.getStreamers().size()) {
currentArray.removeStreamer(currentArray.getStreamerCount()-1);
currParams.removeStreamer(currParams.getStreamerCount()-1);
}
// currentArray.updateStreamer(tableArrayPane.getStreamers().indexOf(currentStreamerData), streamer);
System.out.println("Get params streamer: " + currentArray.getNumStreamers());
return currentArray;
return currParams;
}
public void setRecieverLabels() {

View File

@ -749,6 +749,16 @@ public class PamArrayUtils {
}
System.out.println("");
}
/**
* Print a Long array
* @param array - the array to print.
*/
public static void printArray(Long[] array) {
for (int i=0; i<array.length; i++) {
System.out.println(i + ": " + array[i]);
}
}
/**
@ -1058,6 +1068,8 @@ public class PamArrayUtils {

Binary file not shown.

View File

@ -255,4 +255,9 @@ public class SimpleFilterPaneFX extends DynamicSettingsPane<FFTFilterParams>{
freqPane.setSampleRate(sampleRate);
}
public void addValueChangeListener(Object object) {
// TODO Auto-generated method stub
}
}

View File

@ -1,6 +1,7 @@
package rawDeepLearningClassifier.dlClassification.genericModel;
import PamController.SettingsPane;
import PamUtils.PamArrayUtils;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@ -51,10 +52,10 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
*/
private GridPane classNameHolder;
// /**
// * The text field names.
// */
// private TextField[] classNameFields;
// /**
// * The text field names.
// */
// private TextField[] classNameFields;
/**
* The DL transform pane.
@ -182,14 +183,35 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
defualtShapeSwitch = new PamToggleSwitch("Use model default shape");
defualtShapeSwitch.selectedProperty().addListener((obsval, oldval, newval)->{
System.out.println("Hello: deafult shape: " + newval);
PamArrayUtils.printArray( currentInput.defaultShape);
if (newval) {
//set the correct model shape.
if (currentInput!=null && currentInput.defaultShape!=null) {
for (int i=0; i<currentInput.defaultShape.length; i++) {
shapeSpinners[i].getValueFactory().setValue(currentInput.defaultShape[i].intValue());
for (int i=0; i<shapeSpinners.length; i++) {
//the spinner lengths.
if (i<currentInput.defaultShape.length) {
shapeSpinners[i].setDisable(true);
shapeSpinners[i].setVisible(true);
shapeSpinners[i].getValueFactory().setValue(currentInput.defaultShape[i].intValue());
}
else {
shapeSpinners[i].setVisible(false);
shapeSpinners[i].getValueFactory().setValue(1);
}
}
}
//disable the shapes.
shapeHolder.setDisable(newval);
}
else {
//reset for user input
for (int i=0; i<shapeSpinners.length; i++) {
shapeSpinners[i].setVisible(true);
shapeSpinners[i].setDisable(false);
}
}
});
@ -200,7 +222,7 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
outShapeSpinners= new Spinner[2]; //set at for now but could be different in future?
for (int i=0; i<outShapeSpinners.length; i++) {
outShapeSpinners[i] = new Spinner<Integer>(-1, Integer.MAX_VALUE, 10, 1);
outShapeSpinners[i] .setPrefWidth(80);
outShapeSpinners[i] .getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
@ -211,25 +233,25 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
defualtOutSwitch = new PamToggleSwitch("Use model default out");
defualtOutSwitch.selectedProperty().addListener((obsval, oldval, newval)->{
if (!newval) {
PamDialogFX.showWarning("This is generally a very bad idea. If the output shape is not that specified by the model then PAMGuard may through an index out of bounds exception");
}
// System.out.println("DEFAULT OUTPUT" + currentInput);
// System.out.println("DEFAULT OUTPUT" + currentInput);
//set the correct model shape.
if (currentInput!=null && currentInput.defualtOuput!=null) {
///just use the max number?
for (int i=0; i<currentInput.defualtOuput.length; i++) {
outShapeSpinners[i].getValueFactory().setValue(currentInput.defualtOuput[i].intValue());
}
//settings the numbr of classes is not a good idea becuase it's difficult to know how output shape tranlsates to class number.
// System.out.println("Set the class number default to " + currentInput.defualtOuput[1].intValue());
// classNumber.getValueFactory().setValue(currentInput.defualtOuput[1].intValue());
// System.out.println("Set the class number default to " + currentInput.defualtOuput[1].intValue());
// classNumber.getValueFactory().setValue(currentInput.defualtOuput[1].intValue());
}
//disable the shapes.
outShapeHolder.setDisable(newval);
//classNumber.setDisable(newval);
});
//defualtOutSwitch.setSelected(true);
@ -277,7 +299,7 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
if (setParams) return;
genericClassifier.getModelUI().getSettingsPane().setParams(this.getParams(currentInput));
}
/**
* Populate the class name fields.
*/
@ -304,8 +326,8 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
else {
textFields[i].setText(("Class " + i));
}
classNameHolder.add(new Label(("Class " + i)), 0, i);
classNameHolder.add(textFields[i], 1, i);
}
@ -321,7 +343,7 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
@Override
public GenericModelParams getParams(GenericModelParams currParams) {
// System.out.println("Generic Adv Pane GET PARAMS:");
// System.out.println("Generic Adv Pane GET PARAMS:");
if (setParams) return null;
@ -336,11 +358,11 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
String[] classNames= new String[textFields.length];
boolean[] binaryClassification = new boolean[currParams.numClasses];
// if (currParams.binaryClassification!=null) {
// System.out.println("Current classification: " + currParams.binaryClassification.length
// + " new: " + binaryClassification.length) ;
// }
// if (currParams.binaryClassification!=null) {
// System.out.println("Current classification: " + currParams.binaryClassification.length
// + " new: " + binaryClassification.length) ;
// }
for (int i=0; i<textFields.length; i++) {
classNames[i]=textFields[i].getText();
@ -353,8 +375,15 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
}
int nSpinner=0;
for (int i =0; i<outShapeSpinners.length; i++) {
if (outShapeSpinners[i].isVisible()) nSpinner++;
}
//set the model shape
Long[] outShape = new Long[outShapeSpinners.length];
Long[] outShape = new Long[nSpinner];
for (int i=0; i<outShape.length; i++) {
// System.out.println("Input shape: " + currentInput.shape[i].intValue());
outShape[i]=Long.valueOf(outShapeSpinners[i].getValue());
@ -368,17 +397,17 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
//System.out.println("Input shape: V " + shapeSpinners[i].getValue().intValue());
}
currParams.outputShape = outShape;
currParams.shape = inShape;
currParams.classNames = this.getDLControl().getClassNameManager().makeClassNames(classNames);
// System.out.println("GenericAdvPane: Class names");
// for (int i=0; i<currParams.classNames.length; i++) {
// System.out.println("Class " + i + " " + currParams.classNames[i].className);
// }
// System.out.println("GenericAdvPane: Class names");
// for (int i=0; i<currParams.classNames.length; i++) {
// System.out.println("Class " + i + " " + currParams.classNames[i].className);
// }
currParams.binaryClassification = binaryClassification;
@ -395,11 +424,11 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
this.currentInput = input.clone();
//System.out.println("Generic Adv Pane SET PARAMS: " +currentInput );
// System.out.println("GenericAdvPane: Class names " + currentInput.numClasses);
// for (int i=0; i<currentInput.classNames.length; i++) {
// System.out.println("Class " + i + " " +currentInput.classNames[i].className);
// }
// System.out.println("GenericAdvPane: Class names " + currentInput.numClasses);
// for (int i=0; i<currentInput.classNames.length; i++) {
// System.out.println("Class " + i + " " +currentInput.classNames[i].className);
// }
if (input.defaultShape==null) {
defualtShapeSwitch.setSelected(false);
@ -411,15 +440,15 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
//
classNumber.getValueFactory().setValue(currentInput.numClasses);
//populate the class names field.
populateClassNameFields(currentInput.numClasses, input);
//set the model shape
if (currentInput.shape!=null) {
for (int i=0; i<currentInput.shape.length; i++) {
// System.out.println("Input shape: " + currentInput.shape[i].intValue());
// System.out.println("Input shape: " + currentInput.shape[i].intValue());
shapeSpinners[i].getValueFactory().setValue(currentInput.shape[i].intValue());
//System.out.println("Input shape: V " + shapeSpinners[i].getValue().intValue());
@ -428,7 +457,7 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
if (currentInput.outputShape!=null) {
for (int i=0; i<currentInput.outputShape.length; i++) {
// System.out.println("Output shape: " + currentInput.outputShape[i].intValue());
// System.out.println("Output shape: " + currentInput.outputShape[i].intValue());
outShapeSpinners[i].getValueFactory().setValue(currentInput.outputShape[i].intValue());
}
}
@ -437,10 +466,10 @@ public class GenericAdvPane extends SettingsPane<GenericModelParams> {
//System.out.println("Set transforms: " + currentInput.dlTransfroms.size());
transfromPane.setExampleSoundIndex(currentInput.exampleSoundIndex);
transfromPane.setTransforms(currentInput.dlTransfroms);
// for (int i=0; i<currentInput.classNames.length; i++) {
// System.out.println("Textfield: Class " + i + " " +textFields[i].getText());
// }
// for (int i=0; i<currentInput.classNames.length; i++) {
// System.out.println("Textfield: Class " + i + " " +textFields[i].getText());
// }
setParams=false;

View File

@ -71,7 +71,7 @@ public class GenericModelParser {
// System.out.println(jsonObject);
writeJSONToFile(file, jsonObject.toString(), false);
writeJSONToFile(file, jsonObject.toString(1), false);
return true;
}

View File

@ -113,10 +113,10 @@ public class GenericModelWorker extends DLModelWorker<GenericPrediction> {
this.setEnableSoftMax(true);
}
GenericModelParams genericModelParams = new GenericModelParams();
// GenericModelParams genericModelParams = new GenericModelParams();
genericModelParams.defaultShape = longArr2Long(genericModel.getInputShape().getShape());
genericModelParams.defualtOuput = longArr2Long(genericModel.getOutShape().getShape());
((GenericModelParams) genericParams).defaultShape = longArr2Long(genericModel.getInputShape().getShape());
((GenericModelParams) genericParams).defualtOuput = longArr2Long(genericModel.getOutShape().getShape());
}

View File

@ -4,11 +4,16 @@ import java.util.ArrayList;
import java.util.Arrays;
import org.controlsfx.control.RangeSlider;
import org.controlsfx.control.decoration.Decorator;
import org.controlsfx.control.decoration.GraphicDecoration;
import org.controlsfx.control.decoration.StyleClassDecoration;
import org.jamdev.jdl4pam.transforms.DLTransform;
import org.jamdev.jdl4pam.transforms.DLTransform.DLTransformType;
import org.jamdev.jdl4pam.transforms.FreqTransform;
import org.jamdev.jdl4pam.transforms.SimpleTransform;
import org.jamdev.jdl4pam.transforms.WaveTransform;
import org.jamdev.jpamutils.wavFiles.AudioData;
import org.jamdev.jpamutils.wavFiles.FilterParams;
import PamUtils.PamArrayUtils;
import javafx.collections.FXCollections;
@ -16,16 +21,20 @@ import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.util.StringConverter;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.sliders.ColourRangeSlider;
import pamViewFX.fxNodes.utilsFX.ColourArray;
import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType;
import pamViewFX.fxPlotPanes.PlotPane;
import pamViewFX.validator.PamValidator;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSound;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory;
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
@ -106,7 +115,12 @@ public abstract class DLTransformImage extends PamBorderPane{
/**
* The time label.
*/
private Label timeLabel;
private Label timeLabel;
/**
* The error label.
*/
private Label errorLabel;
public DLTransformImage() {
@ -133,8 +147,8 @@ public abstract class DLTransformImage extends PamBorderPane{
transformschoiceBox = new ChoiceBox<DLTransform>();
transformschoiceBox.valueProperty().addListener((obsval, oldval, newval)->{
updateTransformImage();
calcTimeBins(transformsR);
plotPane.repaint();
// calcTimeBins(transformsR);
// plotPane.repaint();
});
transformschoiceBox.setConverter(new DLTransformConverter());
transformschoiceBox.setPrefWidth(170);
@ -194,11 +208,18 @@ public abstract class DLTransformImage extends PamBorderPane{
timeSlider.maxWidthProperty().bind(plotPane.getPlotCanvas().widthProperty().add(5));
//create an error label
errorLabel = new Label();
Node decoration = PamGlyphDude.createPamIcon("mdi2c-close-circle-outline", Color.RED, 10);
errorLabel.setGraphic(decoration);
// Decorator.addDecoration(errorLabel, new GraphicDecoration(decoration, Pos.CENTER_RIGHT));
BorderPane.setAlignment(timeLabel, Pos.CENTER);
this.setBottom(timeLabel);
}
/**
* Get the species choice box.
* @return - the species choice box.
@ -212,7 +233,7 @@ public abstract class DLTransformImage extends PamBorderPane{
* Calculate the sample time bins.
*/
private void calcTimeBins(float sampleRate) {
timeBins[0] = (int) (sampleRate*(timeSlider.getLowValue()/1000.0));
timeBins[1] = (int) (sampleRate*(timeSlider.getHighValue()/1000.0));
@ -221,9 +242,8 @@ public abstract class DLTransformImage extends PamBorderPane{
long[] shape = calcShape();
double nSamples = this.exampleSound.getSampleRate()*((timeSlider.getHighValue()-timeSlider.getLowValue())/1000.0);
if (shape!=null && shape.length==2) {
int timeShape = (int) (shape[0]*(nSamples/(double) exampleSound.getWave().length));
@ -238,6 +258,7 @@ public abstract class DLTransformImage extends PamBorderPane{
}
}
/**
* Calculate the output shape.
*/
@ -247,24 +268,30 @@ public abstract class DLTransformImage extends PamBorderPane{
if (this.exampleSound==null) return null;
ArrayList<DLTransform> transforms = getDLTransforms();
if (transforms==null) return null;
long[] shape;
if (transforms.get(transforms.size()-1) instanceof FreqTransform) {
FreqTransform freqTransform = ((FreqTransform) transforms.get(transforms.size()-1));
if (freqTransform.getSpecTransfrom()==null) return null;
double[][] data2D = freqTransform.getSpecTransfrom().getTransformedData();
shape = new long[] {data2D.length, data2D[0].length};
}
else {
WaveTransform waveTransform = ((WaveTransform) transforms.get(transforms.size()-1));
double[] data = waveTransform.getWaveData().getScaledSampleAmplitudes();
// System.out.println("Get wave data: " + waveTransform.getDLTransformType() + " " + waveTransform.getWaveData());
if (waveTransform.getWaveData()==null) {
return null;
}
double[] data = waveTransform.getWaveData().getScaledSampleAmplitudes();
shape = new long[] {data.length};
}
@ -301,6 +328,7 @@ public abstract class DLTransformImage extends PamBorderPane{
return this.exampleSound.getSampleRate();
}
/**
* Update the example sound.
* @param exampleSoundType - the example sound type.
@ -310,6 +338,7 @@ public abstract class DLTransformImage extends PamBorderPane{
updateExampleSound(exampleSound);
}
/**
* Update the example sound.
* @param exampleSound - the new example sound.
@ -332,12 +361,19 @@ public abstract class DLTransformImage extends PamBorderPane{
updateTransformImage();
}
/**
* Update the transform image to the latest selected transform and data params.
*/
public void updateTransformImage() {
public boolean updateTransformImage() {
if (this.exampleSound==null) return;
setErrorMessage(null);
if (this.exampleSound==null) {
System.err.println("DLTRanfromImage.updateTransformImage: the example sound is null");
return false;
}
specImage=null;
data1D=null;
@ -347,12 +383,20 @@ public abstract class DLTransformImage extends PamBorderPane{
((WaveTransform) getDLTransforms().get(0)).setWaveData(soundData);
DLTransform currentTransform = getDLTransforms().get(0);
for (int i=1; i<transformschoiceBox.getSelectionModel().getSelectedIndex(); i++) {
currentTransform = getDLTransforms().get(i).transformData(currentTransform);
}
// System.out.println("Current transfrom: " + currentTransform.getDLTransformType() + " index: " + transformschoiceBox.getSelectionModel().getSelectedIndex());
int i = 0;
String errCheck;
//update all the transforms with the transformed data
for (i=0; i<transformschoiceBox.getSelectionModel().getSelectedIndex()+1; i++) {
errCheck = checkTransform(getDLTransforms().get(i), currentTransform);
if (errCheck!=null) {
setErrorMessage("Error in " + getDLTransforms().get(i).getDLTransformType() + " - " + errCheck);
return false;
}
// System.out.println("TRANSFROM IMAGE 1: " + currentTransform.getDLTransformType() + " index: " + i + " " + ((WaveTransform) currentTransform).getWaveData().getSampleAmplitudes().length);
currentTransform = getDLTransforms().get(i).transformData(currentTransform);
// System.out.println("TRANSFROM IMAGE 2: " + currentTransform.getDLTransformType() + " index: " + i + " " + ((WaveTransform) currentTransform).getWaveData().getSampleAmplitudes().length);
}
if (currentTransform instanceof FreqTransform) {
if (((FreqTransform) currentTransform).getSpecTransfrom()!=null) {
@ -392,10 +436,15 @@ public abstract class DLTransformImage extends PamBorderPane{
specImage = new SpectrogramImage(data2D, colArray, PamArrayUtils.minmax(data2D), false);
transformsR = ((FreqTransform) currentTransform).getSpecTransfrom().getSpectrgram().getSampleRate();
}
else {
//error
setErrorMessage("Error in " + currentTransform.getDLTransformType());
return false;
}
}
if (currentTransform instanceof WaveTransform) {
if (((WaveTransform) currentTransform).getWaveData()!=null) {
if (((WaveTransform) currentTransform).getWaveData()!=null && ((WaveTransform) currentTransform).getWaveData().getSampleAmplitudes().length>0) {
plotPane.getAxis(Side.LEFT).setLabel("Amplitude");
colRangeSlider.setDisable(true);
@ -409,10 +458,125 @@ public abstract class DLTransformImage extends PamBorderPane{
transformsR = ((WaveTransform) currentTransform).getWaveData().getSampleRate();
//System.out.println("Spec wave data: " + ((WaveTransform) currentTransform).getWaveData().getScaledSampleAmpliudes()[10]);
}
else {
setErrorMessage("Error in " + currentTransform.getDLTransformType());
return false;
}
}
calcTimeBins(transformsR);
plotPane.repaint();
return true;
}
/**
* Set an error message in the plit
* @param string
*/
public void setErrorMessage(String string) {
if (string==null) {
this.setCenter(plotPane);
return;
}
plotPane.getPlotCanvas().getGraphicsContext2D().clearRect(0, 0, plotPane.getPlotCanvas().getWidth(),
plotPane.getPlotCanvas().getHeight());
errorLabel.setText(string);
this.setCenter(errorLabel);
// getPlotCanvas().getGraphicsContext2D().setStroke(Color.RED);
// getPlotCanvas().getGraphicsContext2D().setFill(Color.RED);
// getPlotCanvas().getGraphicsContext2D().strokeText(string, 10, getPlotCanvas().getHeight()/2);
}
/**
* Check for error in a transform and return the transform if true;
* @param dlTransform - the new transform
* @param currentTransform - the data t be transformed
* @return a string error message.
*/
private String checkTransform(DLTransform dlTransform, DLTransform currentTransform) {
String error = null;
SimpleTransform simpleTransform = ((SimpleTransform) dlTransform);
float sampleRate;
switch (dlTransform.getDLTransformType()) {
case DECIMATE:
case DECIMATE_SCIPY:
//decimation sampleRate
sampleRate = simpleTransform.getParams()[0].floatValue();
double seconds = ((WaveTransform) currentTransform).getWaveData().getLengthInSeconds();
if (seconds < 3/sampleRate) {
//only three samples left
error = "The decimation Nyquist is too low for the sample sound. Use a different example species";
}
break;
case ENHANCE:
break;
case FILTER:
FilterParams params = WaveTransform.transform2FilterParams(simpleTransform.getParams());
sampleRate = ((WaveTransform) currentTransform).getWaveData().getSampleRate();
if (params.filterType==AudioData.BANDPASS || params.filterType== AudioData.LOWPASS) {
//filter cutoff must be within sample rate.
if (params.highCut>=sampleRate) {
error = "The upper filter frequency cannnot be greater than or equal to Nyquist";
}
}
if (params.filterType==AudioData.BANDPASS || params.filterType== AudioData.HIGHPASS) {
if (params.lowCut>=sampleRate) {
error = "The lower filter frequency cannnot be greater than or equal to Nyquist";
}
}
break;
case FILTER_ISOLATED_SPOTS:
break;
case GAUSSIAN_FILTER:
break;
case MEDIANFILTER:
break;
case NORMALISE_WAV:
break;
case PREEMPHSIS:
break;
case REDUCETONALNOISE_MEAN:
break;
case REDUCETONALNOISE_MEDIAN:
break;
case SPEC2DB:
break;
case SPECCLAMP:
break;
case SPECCROPINTERP:
break;
case SPECNORMALISE:
break;
case SPECNORMALISEROWSUM:
break;
case SPECNORMALISESTD:
break;
case SPECNORMALISE_MINIMAX:
break;
case SPECTROGRAM:
break;
case SPECTROGRAMKETOS:
break;
case TRIM:
break;
default:
break;
}
return error;
}
@ -453,6 +617,8 @@ public abstract class DLTransformImage extends PamBorderPane{
y1= ((dataTrim[i]- data1DminMax[0])/(dataRange))*getPlotCanvas().getHeight();
y2= ((dataTrim[i+1]- data1DminMax[0])/(dataRange))*getPlotCanvas().getHeight();
getPlotCanvas().getGraphicsContext2D().setStroke(Color.BLACK);
getPlotCanvas().getGraphicsContext2D().setFill(Color.BLACK);
getPlotCanvas().getGraphicsContext2D().strokeLine(x1, y1, x2, y2);
}
}

View File

@ -60,6 +60,11 @@ public class DataTransformPaneFactory {
case NORMALISE_WAV:
settingsPane = new LabelTransfromPane(dlTransfrom, DLTransformType.NORMALISE_WAV.toString());
settingsPane.setPadding(new Insets(0,0,0,20));
break;
case FILTER:
settingsPane = new FilterTransformPane(dlTransfrom);
settingsPane.setParams(dlTransfrom);
break;
case SPEC2DB:
// settingsPane = new LabelTransfromPane(dlTransfrom, DLTransformType.SPEC2DB.toString());
// settingsPane.setPadding(new Insets(0,0,0,20));

View File

@ -0,0 +1,199 @@
package rawDeepLearningClassifier.layoutFX.dlTransfroms;
import org.jamdev.jdl4pam.transforms.DLTransform;
import org.jamdev.jdl4pam.transforms.SimpleTransform;
import org.jamdev.jdl4pam.transforms.WaveTransform;
import org.jamdev.jpamutils.wavFiles.AudioData;
import org.jamdev.jpamutils.wavFiles.FilterParams;
import Filters.FilterBand;
import fftFilter.FFTFilterParams;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.Pane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.utilityPanes.SimpleFilterPaneFX;
/**
* Pane for a waveform filter.
*/
public class FilterTransformPane extends DLTransformPane {
/**
* The transform associated with the settings pane.
*/
private DLTransform simpleTransfrom;
/**
* Controls for changing filter settings.
*/
private SimpleFilterPaneFX filterPane;
/**
* Choice box for changing the filter type - e.g. Butterworth
*/
private ComboBox<String> filterMethodBox;
/**
* Spinner for changing the filter order.
*/
private Spinner<Integer> orderSpinner;
public FilterTransformPane(DLTransform dlTransfrom) {
super();
this.simpleTransfrom= dlTransfrom;
this.setCenter(createFilterPane());
// this.setStyle("-fx-background-color:orangered;");
}
private Node createFilterPane() {
PamVBox mainPane = new PamVBox();
mainPane.setSpacing(5);
filterMethodBox = new ComboBox<String>();
filterMethodBox.getItems().add(AudioData.BUTTERWORTH, "Butterworth");
filterMethodBox.getItems().add(AudioData.CHEBYSHEV, "Chebyshev");
filterMethodBox.valueProperty().addListener((obsVal, oldVal, newVal)->{
this.notifySettingsListeners();
});
//spinner for changing filter order.
orderSpinner = new Spinner<Integer>(1,50,4,1);
orderSpinner.valueProperty().addListener((obsVal, oldVal, newVal)->{
this.notifySettingsListeners();
});
orderSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
PamHBox filterTypeHolder = new PamHBox();
filterTypeHolder.setSpacing(5);
filterTypeHolder.setAlignment(Pos.CENTER_LEFT);
filterTypeHolder.getChildren().addAll(filterMethodBox, new Label("Order"), orderSpinner);
//create the filter pane - use the standard pG one - a bit of hack but no point in basically replicating
//this whole pane again.
filterPane = new SimpleFilterPaneFX();
filterPane.addSettingsListener(()->{
this.notifySettingsListeners();
});
mainPane.getChildren().addAll(new Label("Filter Type"), filterTypeHolder, filterPane.getContentNode());
TitledPane titledPane = new TitledPane(simpleTransfrom.getDLTransformType().toString(), mainPane);
// PamBorderPane borderPane = new PamBorderPane();
// borderPane.setTop(new Label(simpleTransfrom.getDLTransformType().toString()));
// borderPane.setCenter(hBox);
titledPane.setExpanded(false);
return titledPane;
}
/**
* Convert parameters array to filter parameters.
* @param params - the parameters to set.
* @return the FFTfilterParams object with params from fileParams
*/
private FFTFilterParams transform2FilterParams(FilterParams filtParams) {
FFTFilterParams filtParamsPG = new FFTFilterParams();
switch (filtParams.filterType) {
case AudioData.LOWPASS:
filtParamsPG.filterBand = FilterBand.LOWPASS;
break;
case AudioData.HIGHPASS:
filtParamsPG.filterBand = FilterBand.HIGHPASS;
break;
case AudioData.BANDPASS:
filtParamsPG.filterBand = FilterBand.BANDPASS;
break;
}
filtParamsPG.lowPassFreq = filtParams.highCut;
filtParamsPG.highPassFreq = filtParams.lowCut;
return filtParamsPG;
}
private FilterParams getFFTFilterSettings(FilterParams params) {
FFTFilterParams paramsFFT = filterPane.getParams(new FFTFilterParams());
switch (paramsFFT.filterBand) {
case BANDPASS:
params.filterType = AudioData.BANDPASS;
break;
case BANDSTOP:
break;
case HIGHPASS:
params.filterType = AudioData.HIGHPASS;
break;
case LOWPASS:
params.filterType = AudioData.LOWPASS;
break;
}
params.highCut = paramsFFT.lowPassFreq;
params.lowCut = paramsFFT.highPassFreq;
return params;
}
@Override
public DLTransform getDLTransform() {
return this.getParams(simpleTransfrom) ;
}
@Override
public DLTransform getParams(DLTransform dlTransform) {
// System.out.println("GET PARAMS: FILTER");
SimpleTransform simpleTransform = (SimpleTransform) dlTransform;
//create filter params object.
FilterParams filtParams = new FilterParams();
filtParams = getFFTFilterSettings(filtParams);
filtParams.filterMethod = filterMethodBox.getSelectionModel().getSelectedIndex();
filtParams.order = orderSpinner.getValue();
simpleTransform.setParams(WaveTransform.filterParams2transform(filtParams));
return simpleTransform;
}
@Override
public void setParams(DLTransform dlTransform) {
// System.out.println("SET PARAMS: FILTER");
SimpleTransform simpleTransform = (SimpleTransform) dlTransform;
//get filter params as an object to try and make less mistakes!
FilterParams filtParams = WaveTransform.transform2FilterParams(simpleTransform.getParams());
//get the selection model.
filterMethodBox.getSelectionModel().select(filtParams.filterMethod);
orderSpinner.getValueFactory().setValue(filtParams.order);
//bit of a hack but otherwise have to rewrite filter GUI.
filterPane.setParams(transform2FilterParams(filtParams));
}
}

View File

@ -38,7 +38,9 @@ public class ExampleSoundFactory {
MINKE_WHALE("Minke Whale (Balaenoptera spp.)", ExampleSoundCategory.MYSTICETES),
HUMPBACK_WHALE("Humpback whale (Megaptera novaeangliae) ", ExampleSoundCategory.MYSTICETES);
HUMPBACK_WHALE("Humpback whale (Megaptera novaeangliae) ", ExampleSoundCategory.MYSTICETES),
BLUE_WHALE("Blue whale (Balaenoptera musculus) ", ExampleSoundCategory.MYSTICETES);
private final String text;
@ -267,6 +269,10 @@ public class ExampleSoundFactory {
case DOLPHIN:
exampleSound = new SimpleExampleSound(dolphin1, 192000);
break;
case BLUE_WHALE:
path = getClass().getResource("/Resources/exampleSounds/Blue_whale.wav");
exampleSound = new SimpleExampleSound(path);
break;
default:
break;