Work on the data selector for the deep learning module.

This commit is contained in:
Jamie Mac 2024-07-15 15:25:16 +01:00
parent d2ba95f500
commit edd9df426f
9 changed files with 238 additions and 52 deletions

View File

@ -101,7 +101,7 @@
<exclude>META-INF/*.SF</exclude> <!-- get rid of manifests from library jars - also done in orig ant build file -->
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>test/resources/**</exclude>
<exclude>test/resources/**</exclude><!-- get rid of deep learning moduels and wav files used for unit tests -->
</excludes>
</filter>
</filters>

View File

@ -39,8 +39,16 @@ public class CompoundDialogPaneFX extends DynamicSettingsPane<Boolean> {
DataSelectorDialogPaneFX dsp = new DataSelectorDialogPaneFX(ds, panel, ind++);
selectorPanels.add(dsp);
//need to add a listener for settings changes to these panes so it can be passed to this pane
dsp.addSettingsListener(()->{
//notify any listeners to this pane that the sub pane has changed.
notifySettingsListeners();
});
mainPanel.getChildren().add(dsp.getContentNode());
}
}

View File

@ -109,6 +109,12 @@ public class DataSelectorDialogPaneFX extends DynamicSettingsPane<Boolean> {
dsPane.getChildren().add(contentPane);
//need to add a listener for settings changes to these panes so it can be passed to this pane
innerPanel.addSettingsListener(()->{
notifySettingsListeners();
});
orButton.setVisible(setIndex > 0);
if (dataSelector instanceof CompoundDataSelector || setIndex < 0) {
buttonPane.setVisible(false);

View File

@ -189,11 +189,6 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane {
dataSelectHolder.setPadding(new Insets(5,5,5,5));
dataSelectPane = createDataSelectPane();
dataSelectPane.addSettingsListener(()->{
//dynamic settings pane so have to repaint whenever a control is selected.
getParams();
clickPlotInfo.getTDGraph().repaint(0);
});
dataSelectPane.setParams(true);
@ -232,6 +227,12 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane {
setFreqType();
setParams();
dataSelectPane.addSettingsListener(()->{
//dynamic settings pane so have to repaint whenever a control is selected.
getParams();
clickPlotInfo.getTDGraph().repaint(0);
});
this.setCenter(tabPane);
this.setPrefHeight(PREF_HEIGHT);

View File

@ -97,7 +97,7 @@ public class DLDataSelector extends AnnotationDataSelector<DLAnnotation> {
//set paramters for all data filters.
for (int i=0; i<dlDataSelectParams.dataSelectorParams.length; i++) {
dataFilters.get(i).setParams((DLDataSelectorParams) dataSelectParams);
dataFilters.get(i).setParams((DataSelectParams) dlDataSelectParams.dataSelectorParams[i]);
}
}
@ -117,7 +117,9 @@ public class DLDataSelector extends AnnotationDataSelector<DLAnnotation> {
}
@Override
public DataSelectParams getParams() {
public DLDataSelectorParams getParams() {
//get the paramters from the pane.
for (int i=0; i<dlDataSelectParams.dataSelectorParams.length; i++) {
dlDataSelectParams.dataSelectorParams[i] = dataFilters.get(i).getParams();
}

View File

@ -7,6 +7,7 @@ import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.DLDetection;
import rawDeepLearningClassifier.dlClassification.PredictionResult;
import rawDeepLearningClassifier.logging.DLAnnotation;
/**
* A data filter which filters data by the maximum prediction value
@ -26,6 +27,8 @@ public class DLPredictionFilter implements DLDataFilter {
*/
private DLPredictionFilterParams filterParams = new DLPredictionFilterParams();
private DLPredictonPane dlPredictonPane;
public DLPredictionFilter(DLControl dlcontrol) {
this.dlcontrol = dlcontrol;
checkParamsClass() ;
@ -35,7 +38,10 @@ public class DLPredictionFilter implements DLDataFilter {
@Override
public int scoreDLData(PamDataUnit dataUnit) {
DLDetection dlDetection = (DLDetection) dataUnit;
DLAnnotation annotation = (DLAnnotation) dataUnit. findDataAnnotation(DLAnnotation.class) ;
if (annotation==null) return -1;
//iterate through all results and check that at least one class passes data selection.
float[] results;
@ -43,7 +49,7 @@ public class DLPredictionFilter implements DLDataFilter {
int maxPred = -1;
//get the maximum prediction index which passes the minimum threshold
for (PredictionResult modelResult: dlDetection.getModelResults()) {
for (PredictionResult modelResult: annotation.getModelResults()) {
results = modelResult.getPrediction();
for (int j=0; j<results.length; j++) {
if (filterParams.classSelect[j] && results[j]>filterParams.minClassPredicton[j]) {
@ -84,10 +90,18 @@ public class DLPredictionFilter implements DLDataFilter {
@Override
public DynamicSettingsPane<DataSelectParams> getSettingsPane() {
// TODO Auto-generated method stub
return null;
public DynamicSettingsPane getSettingsPane() {
if (dlPredictonPane ==null) {
dlPredictonPane = new DLPredictonPane(this);
}
return dlPredictonPane;
}
public DLControl getDLControl() {
return this.dlcontrol;
}
// /**
// * Get the index of the highest prediciton value a list of results.

View File

@ -5,7 +5,7 @@ import PamguardMVC.dataSelector.DataSelectParams;
/**
* Parameters for filtering by the minimum prediciton value.
*/
public class DLPredictionFilterParams extends DataSelectParams {
public class DLPredictionFilterParams extends DataSelectParams implements Cloneable{
private static final long serialVersionUID = 1L;
@ -22,6 +22,7 @@ public class DLPredictionFilterParams extends DataSelectParams {
/**
* Clone the parameters.
*/
@Override
public DLPredictionFilterParams clone() {
try {
return (DLPredictionFilterParams) super.clone();

View File

@ -1,11 +1,24 @@
package rawDeepLearningClassifier.dataSelector;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.Priority;
import javafx.scene.text.TextAlignment;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxGlyphs.PamGlyphDude;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.sliders.PamSlider;
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
import rawDeepLearningClassifier.dlClassification.DLClassName;
/**
* Settings pane for filtering deep learning results by class prediciton.
@ -14,50 +27,165 @@ public class DLPredictonPane extends DynamicSettingsPane<DLPredictionFilterParam
private DLPredictionFilter predicitonFilter;
private PamVBox mainPane;
private PamBorderPane mainPane;
private PamVBox contentPane;
private ClassDataSelector[] classPanes;
private ToggleButton toggelButton;
public DLPredictonPane(DLPredictionFilter predicitonFilter) {
super(null);
this.predicitonFilter=predicitonFilter;
createPane();
}
private void createPane() {
mainPane = new PamVBox();
mainPane.setSpacing(5);
mainPane = new PamBorderPane();
PamBorderPane topPane = new PamBorderPane();
Label label = new Label("Select classes to show");
PamBorderPane.setAlignment(label, Pos.BOTTOM_LEFT);
// label.setTextAlignment(TextAlignment.LEFT);
label.setAlignment(Pos.BOTTOM_LEFT);
topPane.setLeft(label);
toggelButton = new ToggleButton();
toggelButton.setTooltip(new Tooltip("Lock sliders together so one slider changes all values"));
toggelButton.setGraphic(PamGlyphDude.createPamIcon("mdi2l-lock-open", PamGuiManagerFX.iconSize));
toggelButton.selectedProperty().addListener((onsVal, oldVal,newVal)->{
if (newVal) {
toggelButton.setGraphic(PamGlyphDude.createPamIcon("mdi2l-lock", PamGuiManagerFX.iconSize));
}
else {
toggelButton.setGraphic(PamGlyphDude.createPamIcon("mdi2l-lock-open", PamGuiManagerFX.iconSize));
}
});
toggelButton.setSelected(false);
topPane.setRight(toggelButton);
// topPane.setAlignment(Pos.CENTER_RIGHT);
contentPane = new PamVBox();
contentPane.setSpacing(5);
mainPane.setTop(topPane);
mainPane.setCenter(contentPane);
PamBorderPane.setMargin(topPane, new Insets(0,0,5.,0));
}
class ClassDataSelector extends PamHBox {
PamSpinner<Double> spinner;
Slider slider;
CheckBox enable;
Label valueLabel;
ClassDataSelector(String classType, int index) {
enable = new CheckBox(classType);
spinner = new PamSpinner<Double>(0., 1., 0.7, 0.1);
spinner.setEditable(true);
enable.setPrefWidth(80);
enable.setTooltip(new Tooltip(classType));
enable.setOnAction((a)->{
//disable if the class is unticked.
slider.setDisable(!enable.isSelected());
valueLabel.setDisable(!enable.isSelected());
notifySettingsListeners();
});
this.getChildren().addAll(getChildrenUnmodifiable());
slider = new Slider();
slider.setShowTickMarks(true);
slider.setMinorTickCount(10);
slider.setShowTickLabels(false);
slider.setMajorTickUnit(0.5);
slider.valueProperty().addListener((obsval, oldval, newval)->{
valueLabel.setText(String.format("%.2f", newval));
//if the lock button has been sleected then change all the sliders
//so that they are the same value as this slide (unless the class is disabled)
if (toggelButton.isSelected()) {
for (int i=0; i<classPanes.length; i++) {
if (classPanes[i].enable.isSelected() && i!=index) {
classPanes[i].slider.setValue(newval.doubleValue());
}
};
}
notifySettingsListeners();
});
slider.setMin(0.);
slider.setMax(1.);
PamHBox.setHgrow(slider, Priority.ALWAYS);
valueLabel = new Label();
valueLabel.setMinWidth(30);
valueLabel.setText(String.format("%.2f", slider.getValue()));
this.getChildren().addAll(enable, slider, valueLabel);
}
}
@Override
public DLPredictionFilterParams getParams(DLPredictionFilterParams currParams) {
// TODO Auto-generated method stub
for (int i=0; i<classPanes.length ; i++) {
currParams.classSelect[i] = classPanes[i].enable.isSelected();
currParams.minClassPredicton[i] = classPanes[i].slider.getValue();
}
return currParams;
}
@Override
public void setParams(DLPredictionFilterParams input) {
//set the parameters. Note that class numbers should have been checked already.
setClassPane(input);
}
private void setClassPane(DLPredictionFilterParams input) {
DLClassName[] classNames = predicitonFilter.getDLControl().getDLModel().getClassNames();
contentPane.getChildren().clear();
classPanes = new ClassDataSelector[input.classSelect.length];
ClassDataSelector classPane;
for (int i=0; i<input.classSelect.length ; i++) {
classPane = new ClassDataSelector(classNames[i].className, i);
classPanes[i] = classPane;
contentPane.getChildren().add(classPane);
classPane.enable.setSelected(input.classSelect[i]);
classPane.slider.setValue(input.minClassPredicton[i]);
if (i==input.classSelect.length-1) {
classPane.slider.setShowTickLabels(true);
}
}
}
// /**
// * Check the class numbers are correct
// * @param input
// */
// private void checkSpeciesClassNumbers(DLPredictionFilterParams input) {
// this.predicitonFilter.getSpeciesClassList();
//
// }
@Override
public String getName() {
return "Deep learning prediciton filter";

View File

@ -1,28 +1,30 @@
package rawDeepLearningClassifier.dataSelector;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamSpinner;
import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.PamBorderPane;
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
/**
* JavaFX pane for the deep learning data selector. This simply selects the rype
* of filter to use and sets that as the controls.
* <p>
* Note that at the moment this only implements one type of data filter and so
* essentially all controls etc. for changing filters are invisible to the user.
*
* @author Jamie Macaulay
*/
public class DLSelectPaneFX extends DynamicSettingsPane<Boolean>{
private PamVBox mainPane;
private PamBorderPane mainPane;
/**
* Refrence to the deep learning data selector.
* Reference to the deep learning data selector.
*/
private DLDataSelector dlDataSelector;
/**
* The current index selected by the user - not in the params.
*/
private int currentIndex = 0;
public DLSelectPaneFX(DLDataSelector dlDataSelector) {
@ -38,23 +40,47 @@ public class DLSelectPaneFX extends DynamicSettingsPane<Boolean>{
}
private void createPane() {
mainPane = new PamVBox();
mainPane.setSpacing(5);
mainPane = new PamBorderPane();
//need to add a settings listener to the filter panes to pass on any notification this settings listener.
for (int i=0; i<dlDataSelector.getDataSelectors().size(); i++) {
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPane().addSettingsListener(()->{
//notify any listeners to this pane that a filter pane has changed.
notifySettingsListeners();
});
}
}
@Override
public Boolean getParams(Boolean currParams) {
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPane().getParams(null);
public Boolean getParams(Boolean input) {
// System.out.println("Get params DL data selector!");
DLDataSelectorParams currParams = dlDataSelector.getParams();
//TODO - maybe should grab settings from all filters or just the selected one?
currParams.dataSelectorParams[currentIndex] = dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPane().getParams(currParams.dataSelectorParams[currentIndex]);
return currParams;
dlDataSelector.setParams(currParams);
return true;
}
@Override
public void setParams(Boolean input) {
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPane().getParams(null);
DLDataSelectorParams currParams = dlDataSelector.getParams();
this.currentIndex = currParams.dataSelectorIndex;
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPane().setParams(currParams.dataSelectorParams[currentIndex]);
setDataFilterPane(currentIndex);
}
private void setDataFilterPane(int index) {
DLDataFilter dlFilter = dlDataSelector.getDataSelectors().get(index);
mainPane.setCenter(dlFilter.getSettingsPane().getContentNode());
}
@Override
@ -64,7 +90,7 @@ public class DLSelectPaneFX extends DynamicSettingsPane<Boolean>{
@Override
public Node getContentNode() {
return new Label("Hello DL data selector");
return mainPane;
}
@Override