Fix merge

Merged in a single commit from Jamies fork that had updates to the
template classifier. Then had to make a few changes to get it working
with other changes J had made that must have been in other commits.
This commit is contained in:
Douglas Gillespie 2023-12-18 14:58:24 +00:00
parent 1b9d80b0eb
commit 2f41c986f4
5 changed files with 16 additions and 1008 deletions

View File

@ -1,88 +0,0 @@
package Array.layoutFX;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import javafx.scene.control.ChoiceBox;
import javafx.util.StringConverter;
/**
* Choice box which allows selection of interpolation options.
*
* @author Jamie Macaulay
*
*/
public class InterpChoicePane extends InterpSettingsPane {
/**
* Interp choice box.
*/
private ChoiceBox<Integer> interpChoiceBox;
public InterpChoicePane() {
interpChoiceBox = new ChoiceBox<Integer>();
interpChoiceBox.getItems().addAll(interpChoice);
interpChoiceBox.setMaxWidth(Double.MAX_VALUE);
interpChoiceBox.setConverter(new StringConverter<>() {
@Override
public String toString(Integer item) {
if (item ==null) return "null";
return getInterpString(item);
}
@Override
public Integer fromString(String unused) {
throw new UnsupportedOperationException();
}
});
this.setCenter(interpChoiceBox);
}
public void setSelection(int option) {
interpChoiceBox.getSelectionModel().select(Integer.valueOf(option));
// useLatest.setSelected(option == PamArray.ORIGIN_USE_LATEST);
// useInterpolate.setSelected(option == PamArray.ORIGIN_INTERPOLATE);
// usePrevious.setSelected(option == PamArray.ORIGIN_USE_PRECEEDING);
}
public int getSelection() {
int sel = getSelectedInterpType();
if (((1<<sel) & allowedValues) == 0) {
PamDialogFX.showWarning("The selected interpolation is not available with the selected reference position");
return -1;
}
else {
return sel;
}
}
@Override
protected void enableControls() {
interpChoiceBox.getItems().clear();
for (int i=0; i<interpChoice.length ; i++) {
if ((allowedValues & (1<<interpChoice[i])) != 0){
interpChoiceBox.getItems().add(interpChoice[i]);
}
}
}
@Override
protected int getSelectedInterpType() {
Integer choice = interpChoiceBox.getSelectionModel().getSelectedItem();
if (choice == null) {
return -1;
}
else return choice;
}
}

View File

@ -1,698 +0,0 @@
package Array.layoutFX;
import org.controlsfx.control.PopOver;
import Array.HydrophoneLocator;
import Array.HydrophoneLocators;
import Array.PamArray;
import Array.Streamer;
import Array.sensors.ArrayParameterType;
import Array.sensors.ArraySensorFieldType;
import Array.streamerOrigin.HydrophoneOriginMethod;
import Array.streamerOrigin.HydrophoneOriginMethods;
import Array.streamerOrigin.HydrophoneOriginSystem;
import Array.streamerOrigin.OriginDialogComponent;
import Array.streamerOrigin.OriginSettings;
import PamController.PamController;
import PamController.SettingsPane;
import PamUtils.LatLong;
import PamguardMVC.PamDataBlock;
import javafx.geometry.Pos;
import javafx.scene.Node;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamButton;
import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.validator.PamValidator;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import net.synedra.validatorfx.Validator;
/**
* A JavaFX settings pane for a streamer.
*
* @author Jamie Macaulay
*
*/
public class StreamerSettingsPane extends SettingsPane<Streamer> {
private final static double MAX_TEXTFIELD_WIDTH = 80;
public PamBorderPane mainPane;
private ComboBox<HydrophoneOriginSystem> originMethod;
private PamBorderPane originPanel;
/**
* The default streamer
*/
public Streamer defaultStreamer;
/**
* The current array
*/
private PamArray currentArray;
/**
* The current origin methods
*/
private HydrophoneOriginMethod currentOriginMethod;
/*
* The current origin method pane.
*/
private Pane currentOriginComponent;
/**
* Interpolation panel
*/
private InterpChoicePane interpPane;
private TextField xPos;
private Validator validator = new PamValidator();
private TextField yPos;
private TextField zPos;
private TextField zPosErr;
private TextField xPosErr;
private Label depthLabel;
private TextField yPosErr;
private Label depthLabel2;
private TextField heading;
private TextField roll;
private TextField pitch;
private ComboBox localiserMethod;
private SensorSourcePane[] sensorComponents;
private Label depthSensorLabel;
/**
* Button for extra origin params.
*/
private PamButton originButton;
public StreamerSettingsPane() {
super(null);
mainPane = new PamBorderPane();
mainPane.setCenter(getStreamerPane());
}
/**
* Create the streamer pane
* @return get the pane.
*/
private Pane getStreamerPane(){
String reciever = PamController.getInstance().getGlobalMediumManager().getRecieverString();
Label label = new Label("Geo-reference Position");
PamGuiManagerFX.titleFont2style(label);
//holds advanced setings for new origin methods.
originPanel = new PamBorderPane();
PopOver popOver = new PopOver();
popOver.setContentNode(originPanel);
originMethod = new ComboBox<HydrophoneOriginSystem>();
originButton = new PamButton();
originButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-crosshairs-gps"));
originButton.setOnAction((a)->{
popOver.show(originButton);
});
originMethod.setMaxWidth(Double.MAX_VALUE);
PamHBox originHolder = new PamHBox();
originHolder.setSpacing(5);
originHolder.setAlignment(Pos.CENTER_LEFT);
originHolder.getChildren().addAll(originMethod,originButton);
originHolder.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(originMethod, Priority.ALWAYS);
int n = HydrophoneOriginMethods.getInstance().getCount();
for (int i = 0; i < n; i++) {
originMethod.getItems().add(HydrophoneOriginMethods.getInstance().getMethod(i));
}
Label hydroMovementLabel = new Label(reciever +" Movement Model");
//listener for when a new origin method is called.
originMethod.setOnAction((action)->{
newOriginMethod();
});
interpPane = new InterpChoicePane();
Label inteprlabel = new Label("Interpolation");
PamGuiManagerFX.titleFont2style(inteprlabel);
PamHBox interpBox = new PamHBox();
interpBox.setSpacing(5);
Label interpMethodLabel = new Label("Method");
Region spacer = new Region();
spacer.prefWidthProperty().bind(originButton.widthProperty());
interpBox.getChildren().addAll(interpMethodLabel, interpPane, spacer);
interpBox.setAlignment(Pos.CENTER_LEFT);
interpBox.setMaxWidth(Double.MAX_VALUE);
interpPane.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(interpPane, Priority.ALWAYS);
//add all stuff to the holder
PamVBox holder = new PamVBox();
holder.getChildren().addAll(label, originHolder, hydroMovementLabel, createLocatorPane(), inteprlabel, interpBox);
holder.setSpacing(5);
return holder;
}
/**
* Create the locator pane.
* @return the pane containing controls.
*/
public Pane createLocatorPane() {
//craet data sources for sensors.
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
sensorComponents = new SensorSourcePane[sensorFields.length];
//EnableOrientation eo = new EnableOrientation();
for (int i = 0; i < sensorFields.length; i++) {
sensorComponents[i] = new SensorSourcePane(sensorFields[i], true, sensorFields[i] != ArraySensorFieldType.HEIGHT);
//sensorComponents[i].addActionListenr(eo);
}
localiserMethod = new ComboBox<>();
int n = HydrophoneLocators.getInstance().getCount();
for (int i = 0; i < n; i++) {
localiserMethod.getItems().add(HydrophoneLocators.getInstance().getSystem(i));
}
localiserMethod.setMaxWidth(Double.MAX_VALUE);
PamHBox loclaiserMethodHolder = new PamHBox();
loclaiserMethodHolder.setSpacing(5);
loclaiserMethodHolder.setAlignment(Pos.CENTER_LEFT);
Label spacer = new Label();
spacer.prefWidthProperty().bind(originButton.widthProperty());
loclaiserMethodHolder.getChildren().addAll(localiserMethod, spacer);
loclaiserMethodHolder.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(localiserMethod, Priority.ALWAYS);
//hydrophone position and
PamGridPane positionPane = new PamGridPane();
positionPane.setHgap(5);
positionPane.setVgap(5);
ColumnConstraints rc = new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, MAX_TEXTFIELD_WIDTH);
//this sets all text fields to the correct width - but of naff hack but what grid pane needs to work.
for (int i=1; i<5; i++) {
positionPane.getColumnConstraints().add(rc);
}
xPos=new TextField();
xPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(xPos, "x position", validator);
yPos=new TextField();
yPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(yPos, "y position", validator);
zPos=new TextField();
zPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(zPos, "z position", validator);
depthLabel = new Label("Depth");
depthLabel.setAlignment(Pos.CENTER);
depthSensorLabel = new Label("Depth Sensor");
depthSensorLabel.setAlignment(Pos.CENTER);
xPosErr=new TextField();
xPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(xPosErr, "x error", validator);
yPosErr=new TextField();
yPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(yPosErr, "y error", validator);
zPosErr=new TextField();
zPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
depthLabel2 = new Label(""); //changes with air or water mode.
depthLabel2.setAlignment(Pos.CENTER);
HydrophoneSettingsPane.addTextValidator(zPosErr, "z error", validator);
int col=0;
int row=0;
Label xLabel = new Label("x");
xLabel.setAlignment(Pos.CENTER);
Label yLabel = new Label("y");
yLabel.setAlignment(Pos.CENTER);
//Orientations
String degsLab = LatLong.deg + " ";
col=1;
positionPane.add(xLabel, col++, row);
positionPane.add(yLabel, col++, row);
positionPane.add(depthLabel, col++, row);
col++;
positionPane.add(depthSensorLabel, col++, row);
col=0;
row++;
Label positionLabel = new Label("Position");
positionPane.add(positionLabel, col++, row);
positionPane.add(xPos, col++, row);
positionPane.add(yPos, col++, row);
positionPane.add(zPos, col++, row);
positionPane.add(new Label("(m)"), col++, row);
positionPane.add(sensorComponents[ArraySensorFieldType.HEIGHT.ordinal()].getPane(), col++, row);
col=0;
row++;
Label errLabel = new Label("Error");
positionPane.add(errLabel, col++, row);
positionPane.add(xPosErr, col++, row);
positionPane.add(yPosErr, col++, row);
positionPane.add(zPosErr, col++, row);
positionPane.add(new Label("(m)"), col++, row);
//Orientation
col=1;
row++;
Label headingLabel = new Label("Heading");
headingLabel.setAlignment(Pos.CENTER);
Label pitchLabel = new Label("Pitch");
pitchLabel.setAlignment(Pos.CENTER);
Label rolllabel = new Label("Roll");
rolllabel.setAlignment(Pos.CENTER);
positionPane.add(headingLabel, col++, row);
positionPane.add(pitchLabel, col++, row);
positionPane.add(rolllabel, col++, row);
row++;
heading = new TextField();
heading.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(heading, "heading", validator);
pitch = new TextField();
pitch.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(pitch, "pitch", validator);
roll = new TextField();
roll.setMaxWidth(MAX_TEXTFIELD_WIDTH);
HydrophoneSettingsPane.addTextValidator(roll, "roll", validator);
col=0;
Label orientation = new Label("Orientation");
positionPane.add(orientation, col++, row);
positionPane.add(heading, col++, row);
positionPane.add(pitch, col++, row);
positionPane.add(roll, col++, row);
positionPane.add(new Label(degsLab), col++, row);
PamButton button = new PamButton("Sensors");
button.setGraphic(PamGlyphDude.createPamIcon("mdi2c-compass-outline", PamGuiManagerFX.iconSize));
PopOver popOver = new PopOver(createSensorPane());
popOver.setDetachable(true);
button.setOnAction((a)->{
popOver.show(button);
});
positionPane.add(button, col++, row);
PamVBox holder= new PamVBox();
holder.setSpacing(5);
holder.getChildren().addAll(loclaiserMethodHolder, positionPane);
return holder;
}
/**
* Create a pane to set where sensor data comes from
* @return the sensor pane.
*/
private Pane createSensorPane() {
PamBorderPane pane = new PamBorderPane();
//hydrophone position and
PamGridPane positionPane = new PamGridPane();
positionPane.setHgap(5);
positionPane.setVgap(5);
int col=0;
int row=0;
positionPane.add(new Label("Heading"), col++, row);
positionPane.add(sensorComponents[ArraySensorFieldType.HEADING.ordinal()].getPane(), col++, row);
row++;
col=0;
positionPane.add(new Label("Pitch"), col++, row);
positionPane.add(sensorComponents[ArraySensorFieldType.PITCH.ordinal()].getPane(), col++, row);
row++;
col=0;
positionPane.add(new Label("Roll"), col++, row);
positionPane.add(sensorComponents[ArraySensorFieldType.ROLL.ordinal()].getPane(), col++, row);
Label orientLabel = new Label("Orientation Data");
PamGuiManagerFX.titleFont2style(orientLabel);
pane.setTop(orientLabel);
pane.setCenter(positionPane);
return pane;
}
/**
* Create a new origin method.
*/
public void newOriginMethod() {
int methInd = originMethod.getSelectionModel().getSelectedIndex();
if (methInd < 0) {
return;
}
HydrophoneOriginSystem currentSystem = HydrophoneOriginMethods.getInstance().getMethod(this.originMethod.getSelectionModel().getSelectedIndex());
currentOriginMethod = currentSystem.createMethod(currentArray, defaultStreamer);
try {
OriginSettings os = defaultStreamer.getOriginSettings(currentOriginMethod.getClass());
if (os != null) {
currentOriginMethod.setOriginSettings(os);
}
}
catch (Exception e) {
// will throw if it tries to set the wrong type of settings.
e.printStackTrace();
}
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
if (mthDialogComponent == null) {
originPanel.getChildren().clear();
currentOriginComponent = null;
this.originButton.setDisable(true);
}
else {
this.originButton.setDisable(false);
Pane newComponent = mthDialogComponent.getSettingsPane();
if (currentOriginComponent != newComponent) {
originPanel.setCenter(newComponent);
currentOriginComponent = newComponent;
mthDialogComponent.setParams();
}
}
enableControls();
}
private void enableControls() {
if (currentOriginMethod != null) {
interpPane.setAllowedValues(currentOriginMethod.getAllowedInterpolationMethods());
}
}
@Override
public Streamer getParams(Streamer currParams) {
try {
defaultStreamer.setX(Double.valueOf(xPos.getText()));
defaultStreamer.setY(Double.valueOf(yPos.getText()));
defaultStreamer.setZ(-Double.valueOf(zPos.getText()));
defaultStreamer.setDx(Double.valueOf(xPosErr.getText()));
defaultStreamer.setDy(Double.valueOf(yPosErr.getText()));
defaultStreamer.setDz(Double.valueOf(zPosErr.getText()));
}
catch (NumberFormatException e) {
System.err.println("Streamer getParams: There is a problem with one of the position parameters in the streamer panel");
return null;
}
defaultStreamer.setStreamerName(currParams.getStreamerName());
int im = interpPane.getSelection();
if (im < 0) {
System.err.println("Streamer getParams: There is an index problem with the interpolation selection streamer panel: index = " + im);
}
currentArray.setOriginInterpolation(im);
// try {
// streamer.setBuoyId1(Integer.valueOf(buoyId.getText()));
// }
// catch (NumberFormatException e) {
// streamer.setBuoyId1(null);
// }
HydrophoneLocator locator = HydrophoneLocators.getInstance().
getSystem(localiserMethod.getSelectionModel().getSelectedIndex()).getLocator(currentArray, defaultStreamer);
if (originPanel != null)
// MasterLocator masterLocator = currentArray.getMasterLocator();
// int streamerIndex = currentArray.indexOfStreamer(streamer);
// if (streamerIndex < 0) {
// streamerIndex = currentArray.getNumStreamers();
// }
// masterLocator.setHydrophoneLocator(streamerIndex, locator);
if (currentOriginMethod == null) {
System.err.println("Streamer getParams: No hydrophoneorigin method selected in streamer panel");
}
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
if (mthDialogComponent != null) {
if (mthDialogComponent.getParams() == false) {
return null;
}
}
// defaultStreamer.setEnableOrientation(enableOrientation.isSelected());
// if (enableOrientation.isSelected()) {
defaultStreamer.setHeading(getDoubleValue(heading));
defaultStreamer.setPitch(getDoubleValue(pitch));
defaultStreamer.setRoll(getDoubleValue(roll));
// }
if (!heading.isDisable() && defaultStreamer.getHeading() == null) {
System.err.println("Streamer getParams: You must enter a fixed value for the streamer heading");
}
if (!pitch.isDisable() && defaultStreamer.getPitch() == null) {
System.err.println("Streamer getParams: You must enter a fixed value for the streamer pitch");
}
if (!roll.isDisable() && defaultStreamer.getRoll() == null) {
System.err.println("Streamer getParams: You must enter a fixed value for the streamer roll");
}
/**
* We may have large lists of the streamers which we mwant to use the orientation data from or not. The enable orientation check box will
* enable or disable orientation for ALL streamers which are loaded into memory.
*/
// setEnableRotation(enableOrientation.isSelected(), defaultStreamer.getStreamerIndex());
defaultStreamer.setHydrophoneOrigin(currentOriginMethod);
defaultStreamer.setHydrophoneLocator(locator);
defaultStreamer.setOriginSettings(currentOriginMethod.getOriginSettings());
defaultStreamer.setLocatorSettings(locator.getLocatorSettings());
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
for (int i = 0; i < sensorFields.length; i++) {
ArrayParameterType fieldType = sensorComponents[i].getParameterType();
defaultStreamer.setOrientationTypes(sensorFields[i], fieldType);
if (fieldType == ArrayParameterType.SENSOR) {
PamDataBlock dataBlock = sensorComponents[i].getDataBlock();
defaultStreamer.setSensorDataBlocks(sensorFields[i], dataBlock == null ? null : dataBlock.getLongDataName());
}
}
return defaultStreamer;
}
@Override
public void setParams(Streamer input) {
if (input==null) {
System.out.print("Streamer setParams: The input streamer is null");
}
this.defaultStreamer=input;
// origin methods
// MasterLocator masterLocator = currentArray.getMasterLocator();
// int streamerIndex = currentArray.indexOfStreamer(streamer);
HydrophoneLocator hLocator = defaultStreamer.getHydrophoneLocator();
if (hLocator != null) {
int locatorIndex = HydrophoneLocators.getInstance().indexOfClass(hLocator.getClass());
localiserMethod.getSelectionModel().select(locatorIndex);
HydrophoneOriginMethod originMethod = defaultStreamer.getHydrophoneOrigin();
if (originMethod != null) {
int originIndex = HydrophoneOriginMethods.getInstance().indexOfClass(originMethod.getClass());
this.originMethod.getSelectionModel().select(originIndex);
}
}
else {
localiserMethod.getSelectionModel().select(0);
}
// streamerName.setText(defaultStreamer.getStreamerName());
xPos.setText(String.valueOf(defaultStreamer.getX()));
yPos.setText(String.valueOf(defaultStreamer.getY()));
zPos.setText(String.valueOf(PamController.getInstance().getGlobalMediumManager().getZCoeff()*defaultStreamer.getZ()));
xPosErr.setText(String.valueOf(defaultStreamer.getDx()));
yPosErr.setText(String.valueOf(defaultStreamer.getDy()));
zPosErr.setText(String.valueOf(defaultStreamer.getDz()));
// if (streamer.getBuoyId1() != null) {
// buoyId.setText(streamer.getBuoyId1().toString());
// }
// else {
// buoyId.setText("");
// }
HydrophoneOriginMethod mth = defaultStreamer.getHydrophoneOrigin();
if (mth==null) {
originMethod.getSelectionModel().select(0);
newOriginMethod();
mth = currentOriginMethod;
//defaultStreamer.setHydrophoneOrigin(HydrophoneOriginMethods.getInstance().getMethod(0).createMethod(currentArray, defaultStreamer));
}
OriginDialogComponent mthDialogComponent = mth.getDialogComponent();
if (mthDialogComponent != null) {
System.out.println("Streamer setParams: Set origin component: ");
mthDialogComponent.setParams();
}
System.out.println("Streamer setParams: Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll());
heading .setText(orientation2Text(defaultStreamer.getHeading()));
pitch .setText(orientation2Text(defaultStreamer.getPitch()));
roll .setText(orientation2Text(defaultStreamer.getRoll()));
System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation());
if (currentArray.getOriginInterpolation()<0) {
interpPane.setSelection(0);
}
else {
interpPane.setSelection(currentArray.getOriginInterpolation());
}
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
for (int i = 0; i < sensorFields.length; i++) {
ArrayParameterType fieldType = defaultStreamer.getOrientationTypes(sensorFields[i]);
String fieldDataBlock = defaultStreamer.getSensorDataBlocks(sensorFields[i]);
sensorComponents[i].setParameterType(fieldType);
if (fieldType == ArrayParameterType.SENSOR && fieldDataBlock != null) {
sensorComponents[i].setDataBlock(PamController.getInstance().getDataBlockByLongName(fieldDataBlock));
}
}
setRecieverLabels() ;
enableControls();
}
private String orientation2Text(Double ang) {
if (ang == null) return String.valueOf(0.0);
else return String.format("%3.1f", defaultStreamer.getHeading());
}
@Override
public String getName() {
return "Streamer Pane";
}
@Override
public Node getContentNode() {
return mainPane;
}
@Override
public void paneInitialized() {
}
public void setRecieverLabels() {
// TODO Auto-generated method stub
}
private Double getDoubleValue(TextField textField) {
String txt = textField.getText();
if (txt == null || txt.length() == 0) {
return null;
}
Double val;
try {
val = Double.valueOf(txt);
return val;
}
catch (NumberFormatException e) {
System.err.println("Invalid orientation information: " + txt);
return null;
}
}
public void setCurrentArray(PamArray currentArray2) {
this.currentArray=currentArray2;
}
}

View File

@ -1,208 +0,0 @@
package Array.layoutFX;
import Array.PamArray;
import Array.Streamer;
import PamController.PamController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Dialog;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.flipPane.PamFlipPane;
import pamViewFX.fxNodes.table.TableSettingsPane;
import javafx.scene.control.TableColumn;
import javafx.scene.layout.Pane;
import javafx.geometry.Insets;
/**
* A pane for setting up hydrophones. Note that this is entirely separate from PAMGuard so can be used in
* other projects.
*
* @author Jamie Macaulay
*
*/
public class StreamersPane extends PamBorderPane {
BasicArrayTable tableArrayPane;
ObservableList<StreamerProperty> streamerData = FXCollections.observableArrayList();
/**
* The current hydrophone array
*/
private PamArray currentArray;
/**
* The pam flip pane.
*/
private PamFlipPane pamFlipePane;
/**
* The current streamer data.
*/
private StreamerProperty currentStreamerData;
/**
* Settings pane for a single hydrophone.
*/
private StreamerSettingsPane streamerPane = new StreamerSettingsPane();
public StreamersPane() {
tableArrayPane = new BasicArrayTable(streamerData);
tableArrayPane.setPadding(new Insets(5,5,5,5));
this.setCenter(tableArrayPane);
pamFlipePane = new PamFlipPane();
pamFlipePane.getAdvLabel().setText("Streamer");
((Pane) streamerPane.getContentNode()).setPadding(new Insets(5,5,5,15));
pamFlipePane.setAdvPaneContent(streamerPane.getContentNode());
pamFlipePane.setFrontContent(tableArrayPane);
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
pamFlipePane.setAdvLabelEditable(true);
pamFlipePane.getPostAdvLabel().setText("Settings");
pamFlipePane.flipFrontProperty().addListener((obsval, oldVal, newVal)->{
//the flip pane
if (newVal) {
Streamer streamer = streamerPane.getParams(currentStreamerData.getStreamer());
if (streamer==null) {
//the warning dialog is shown in the streamer settings pane
return;
}
streamer.setStreamerName(pamFlipePane.getAdvLabel().getText());
currentStreamerData.setStreamer(streamer);
//need to refresh table to show symbol.
tableArrayPane.getTableView().refresh();
}
});
this.setCenter(pamFlipePane);
}
/**
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
* @author Jamie Macaulay
*
*/
class BasicArrayTable extends TableSettingsPane<StreamerProperty> {
private TableColumn<StreamerProperty, Number> z;
public BasicArrayTable(ObservableList<StreamerProperty> data) {
super(data);
//need to set up all the rows.
TableColumn<StreamerProperty,Number> streamerID = new TableColumn<StreamerProperty,Number>("ID");
streamerID.setCellValueFactory(cellData -> cellData.getValue().getID());
streamerID.setEditable(false);
TableColumn<StreamerProperty,String> name = new TableColumn<StreamerProperty,String>("Name");
name.setCellValueFactory(cellData -> cellData.getValue().getName());
name.setEditable(true);
TableColumn<StreamerProperty,Number> x = new TableColumn<StreamerProperty,Number>("x");
x.setCellValueFactory(cellData -> cellData.getValue().getX());
x.setEditable(false);
TableColumn<StreamerProperty,Number> y = new TableColumn<StreamerProperty,Number>("y");
y.setCellValueFactory(cellData -> cellData.getValue().getY());
y.setEditable(false);
z = new TableColumn<StreamerProperty,Number>("depth");
z.setCellValueFactory(cellData -> cellData.getValue().getZ());
z.setEditable(false);
TableColumn posColumn=new TableColumn("Position (m)");
posColumn.getColumns().addAll(x, y, z);
TableColumn<StreamerProperty,String> reference = new TableColumn<StreamerProperty,String>("Reference");
reference.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
reference.setEditable(true);
TableColumn<StreamerProperty,String> locator = new TableColumn<StreamerProperty,String>("Locator");
locator.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
locator.setEditable(true);
TableColumn geoColumn=new TableColumn("Geo-reference");
geoColumn.getColumns().addAll(reference, locator);
getTableView().getColumns().addAll(streamerID, name, posColumn, geoColumn);
}
@Override
public void dialogClosed(StreamerProperty data) {
Streamer hydro = streamerPane.getParams(data.getStreamer());
data.setStreamer(hydro);
}
@Override
public Dialog<StreamerProperty> createSettingsDialog(StreamerProperty data) {
//we do not use dialogs here- sliding pane instead.
// setClassifierPane(data);
// showFlipPane(true);
pamFlipePane.flipToBack();
return null;
}
@Override
public void editData(StreamerProperty data){
if (data.getName() == null){
pamFlipePane.getAdvLabel().setText("Streamer " + data.getID().get());
}
streamerPane.setCurrentArray(currentArray);
streamerPane.setParams(data.getStreamer());
currentStreamerData = data;
pamFlipePane.flipToBack();
}
@Override
public void createNewData(){
//create a new classifier.
streamerData.add(createDefaultStreamerProperty());
}
private StreamerProperty createDefaultStreamerProperty() {
Streamer streamer = new Streamer(1, 0.,0.,0.,0.,0.,0.);
return new StreamerProperty(streamer);
}
public TableColumn<StreamerProperty, Number> getZColumn() {
return z;
}
}
public void setParams(PamArray currentArray) {
this.currentArray=currentArray;
}
public PamArray getParams(PamArray currParams) {
return currParams;
}
public void setRecieverLabels() {
tableArrayPane.getZColumn().setText(PamController.getInstance().getGlobalMediumManager().getZString());
streamerPane.setRecieverLabels();
}
}

View File

@ -22,19 +22,19 @@ public class PamArrayUtils {
/** /**
* Calculate the mean of one dimension within a list of points. <i>e.g.</i> the points might be a list of [x y z] co-ordinates in * Calculate the mean of one dimension within a list of points. <i>e.g.</i> the points might be a list of [x y z] co-ordinates in
* which case the dim=0 would return the mean of all x points. * which case the dim=0 would return the mean of all x points.
* @param array - a list of points * @param successJump - a list of points
* @param InitialtoIgnorePercentage: ignore the first percentage of results * @param InitialtoIgnorePercentage: ignore the first percentage of results
* @param dim - the dimension of the point to calculate the average for * @param dim - the dimension of the point to calculate the average for
* @return the mean of one dimension of the list of the points. * @return the mean of one dimension of the list of the points.
*/ */
public static double mean(ArrayList<float[]> array, double InitialtoIgnorePercentage, int dim){ public static double mean(ArrayList<double[]> successJump, double InitialtoIgnorePercentage, int dim){
double meanTotal=0; double meanTotal=0;
int n=0; int n=0;
int forStart=(int) Math.round((InitialtoIgnorePercentage)*array.size()); int forStart=(int) Math.round((InitialtoIgnorePercentage)*successJump.size());
for (int i=forStart; i<array.size();i++){ for (int i=forStart; i<successJump.size();i++){
meanTotal+= array.get(i)[dim]; meanTotal+= successJump.get(i)[dim];
n++; n++;
} }
@ -46,21 +46,21 @@ public class PamArrayUtils {
/** /**
* Calculate the standard deviation of an array of doubles, ignoring an 'initialtoIgnorePercentage' percentage of jumps * Calculate the standard deviation of an array of doubles, ignoring an 'initialtoIgnorePercentage' percentage of jumps
* @param array * @param successJump
* @param initialtoIgnorePercentage- percentage of initial values to ignore. * @param initialtoIgnorePercentage- percentage of initial values to ignore.
* @return standard deviation of array. * @return standard deviation of array.
*/ */
public static double std(ArrayList<float[]> array, double initialtoIgnorePercentage, int dim){ public static double std(ArrayList<double[]> successJump, double initialtoIgnorePercentage, int dim){
double std=0.0; double std=0.0;
int n=0; int n=0;
int forStart=(int) Math.round((initialtoIgnorePercentage)*array.size()); int forStart=(int) Math.round((initialtoIgnorePercentage)*successJump.size());
double meanTotal= mean(array, initialtoIgnorePercentage, dim); double meanTotal= mean(successJump, initialtoIgnorePercentage, dim);
//calculate standard deviation //calculate standard deviation
for (int k=forStart;k<array.size(); k++){ for (int k=forStart;k<successJump.size(); k++){
std+=Math.pow((array.get(k)[dim]-meanTotal),2); std+=Math.pow((successJump.get(k)[dim]-meanTotal),2);
} }
//standard deviation //standard deviation
@ -1058,6 +1058,8 @@ public class PamArrayUtils {
@ -1070,5 +1072,4 @@ public class PamArrayUtils {
} }

View File

@ -52,7 +52,8 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
getFlipPane().getAdvLabel().textProperty().unbind(); getFlipPane().getAdvLabel().textProperty().unbind();
getFlipPane().getAdvLabel().textProperty().bind(sweepPane.getNameTextProperty()); getFlipPane().getAdvLabel().textProperty().bind(sweepPane.getNameTextProperty());
getFlipPane().getPreAdvLabel().graphicProperty().bind(sweepPane.getNameGraphicProperty()); // removed DG 2023 12 14 since not everything was in this merge that was required Needs to be put back.
// getFlipPane().getPreAdvLabel().graphicProperty().bind(sweepPane.getNameGraphicProperty());
sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType()); sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType());