Swing symbol modifiers for DL and peak freq

This commit is contained in:
Jamie Mac 2024-07-17 22:58:49 +01:00
parent 6ba9efbbae
commit 12bf8cb5f7
11 changed files with 433 additions and 55 deletions

View File

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

View File

@ -159,4 +159,29 @@ public class PamAWTUtils {
return bestPoint;
}
/**
* Convert a colour to an int.
* @param c - the colour to change.
* @return the int representation of the colour
*/
public static int colorToInt(java.awt.Color c) {
int r = (int) Math.round(c.getRed());
int g = (int) Math.round(c.getGreen());
int b = (int) Math.round(c.getBlue());
return (r << 16) | (g << 8) | b;
}
/**
* Convert an int encoded with a colour to a Color object.
* @param value - the int to convert to colour
* @return the Color object for the int
*/
public static java.awt.Color intToColor(int value) {
int r = (value >>> 16) & 0xFF;
int g = (value >>> 8) & 0xFF;
int b = value & 0xFF;
return new java.awt.Color(r,g,b);
}
}

View File

@ -5,6 +5,7 @@ import java.awt.Color;
import PamUtils.PamUtils;
import PamView.GeneralProjector;
import PamView.PamSymbolType;
import PamView.dialog.PamDialogPanel;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
@ -45,7 +46,15 @@ public class PeakFreqModifier extends SymbolModifier {
*/
private ColourArrayType colourArrayType;
private PeakFreqOptionsPane peakFreqOptions;
/**
* JavaFX pane for frequency symbol options.
*/
private PeakFreqOptionsPane peakFreqOptionsPaneFX;
/**
* Swing panel for frequency symbol options
*/
private PamDialogPanel peakFreqOptionsPanel;
public PeakFreqModifier(PamSymbolChooser symbolChooser) {
super(PEAK_FREQ_MODIFIER_NAME, symbolChooser, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR );
@ -130,11 +139,20 @@ public class PeakFreqModifier extends SymbolModifier {
@Override
public SymbolModifierPane getOptionsPane() {
//System.out.println("PEAK FREQ COLOUR ARRAY2: " + peakFreqSymbolOptions.freqColourArray);
if (this.peakFreqOptions==null) {
peakFreqOptions = new PeakFreqOptionsPane(this);
peakFreqOptions.setParams();
if (this.peakFreqOptionsPaneFX==null) {
peakFreqOptionsPaneFX = new PeakFreqOptionsPane(this);
peakFreqOptionsPaneFX.setParams();
}
return peakFreqOptions;
return peakFreqOptionsPaneFX;
}
public PamDialogPanel getDialogPanel() {
//System.out.println("PEAK FREQ COLOUR ARRAY2: " + peakFreqSymbolOptions.freqColourArray);
if (this.peakFreqOptionsPanel==null) {
peakFreqOptionsPanel = new PeakFreqOptionsPanel(this);
peakFreqOptionsPanel.setParams();
}
return peakFreqOptionsPanel;
}
@Override

View File

@ -0,0 +1,203 @@
package PamView.symbol.modifier;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;
import PamView.ColourComboBox;
import PamView.dialog.PamDialogPanel;
import PamView.panel.PamPanel;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
/**
* Swing panel for changing parameters for the peak frequency symbol chooser.
*
* @author Jamie Macaulay
*/
public class PeakFreqOptionsPanel implements PamDialogPanel {
private PeakFreqModifier freqSymbolModifer;
private PamPanel mainPanel;
private JSpinner minFreq;
private JSpinner maxFreq;
private ColourComboBox colourBox;
public PeakFreqOptionsPanel(PeakFreqModifier symbolModifer) {
this.freqSymbolModifer=symbolModifer;
mainPanel = createFreqPaneL();
}
/**
* Pane which changes the frequency limits.
* @return pane with controls to change freq. limits.
*/
private PamPanel createFreqPaneL(){
PamPanel holder = new PamPanel();
holder.setLayout(new GridBagLayout());
holder.setBorder(new TitledBorder("Peak frequency colour map"));
GridBagConstraints c = new GridBagConstraints();
c.gridy=0;
c.gridx=0;
//doesn't seem to work so added spaces in labels instead
c.ipadx = 5;
c.anchor =GridBagConstraints.EAST;
holder.add(new JLabel("Min. freq"), c);
c.gridx++;
c.anchor =GridBagConstraints.WEST;
minFreq = new JSpinner(new SpinnerNumberModel(0., 0., 10000000., 1000.));
//make the lock button the same height as the spinner
Dimension prefSize = minFreq.getPreferredSize();
minFreq.setPreferredSize(new Dimension(90, prefSize.height));
holder.add(minFreq, c);
c.gridx++;
c.ipadx = 5;
c.anchor =GridBagConstraints.EAST;
holder.add(new JLabel(" Max. freq"), c);
c.gridx++;
c.ipadx = 5;
c.anchor =GridBagConstraints.WEST;
maxFreq =new JSpinner(new SpinnerNumberModel(1000., 1., Math.max(1000.,freqSymbolModifer.getSymbolChooser().getPamDataBlock().getSampleRate()/2.), 1000.));
maxFreq.setPreferredSize(new Dimension(90, prefSize.height));
holder.add(maxFreq, c);
c.gridx++;
c.ipadx = 5;
c.anchor =GridBagConstraints.WEST;
holder.add(new JLabel(" Hz"), c);
c.gridy++;
c.ipadx = 5;
c.gridwidth=2;
c.gridx=0;
c.anchor =GridBagConstraints.EAST;
holder.add(new JLabel("Freq. colour map"), c);
c.gridx=2;
c.gridwidth=3;
colourBox = new ColourComboBox();
c.anchor =GridBagConstraints.WEST;
prefSize = colourBox.getPreferredSize();
colourBox.setPreferredSize(new Dimension(200, prefSize.height));
holder.add(colourBox, c);
return holder;
}
@Override
public JComponent getDialogComponent() {
return mainPanel;
}
@Override
public boolean getParams(){
//bit messy but works /
// PeakFreqSymbolOptions symbolOptions = (PeakFreqSymbolOptions) standardSymbolOptions.getModifierParams(this.getSymbolModifier().getName());
PeakFreqSymbolOptions symbolOptions = (PeakFreqSymbolOptions)freqSymbolModifer.getSymbolModifierParams().clone();
//must make sure we do not call get parameters during a set parameters - the listeners on the controls call getParams so all goes
//haywire if the setParams is not set properly.
//System.out.println("GETPARAMS: " + ColourArray.getColorArrayType(this.colourBox.getSelectionModel().getSelectedItem()) + " " + setParams);
symbolOptions.freqLimts=new double[] {(double) minFreq.getValue(), (double) maxFreq.getValue()};
symbolOptions.freqColourArray = PamUtilsFX.swingColArray2FX(this.colourBox.getSelectedColourMap());
//System.out.println("StandardSymbolModifierPane : getParams(): new mod: " +mod);
freqSymbolModifer.setSymbolModifierParams(symbolOptions);
System.out.println("Get freq limits: 1: " + symbolOptions.freqLimts[0] + " " + symbolOptions.freqLimts[1] + " " + (double) maxFreq.getValue());
return true;
}
@Override
public void setParams() {
// StandardSymbolOptions standardSymbolOptions = (StandardSymbolOptions) getSymbolModifier().getSymbolChooser().getSymbolOptions();
// PeakFreqSymbolOptions symbolOptions = (PeakFreqSymbolOptions) standardSymbolOptions.getModifierParams(this.getSymbolModifier().getName());
PeakFreqSymbolOptions symbolOptions = (PeakFreqSymbolOptions)freqSymbolModifer.getSymbolModifierParams();
//now set frequency parameters;
checkFreqLimits( symbolOptions ) ;
minFreq.setValue(symbolOptions.freqLimts[0]);
maxFreq.setValue(symbolOptions.freqLimts[1]);
colourBox.setSelectedColourMap((PamUtilsFX.fxColArray2Swing(symbolOptions.freqColourArray)));
}
/**
* Check the frequency limits make sense for the given datablock
* @param symbolOptions - the peak frequency options.
*/
private void checkFreqLimits(PeakFreqSymbolOptions symbolOptions ) {
System.out.println("Check freq limits: 1: " + symbolOptions.freqLimts[0] + " " + symbolOptions.freqLimts[1]);
SpinnerNumberModel spinnerValFact = (SpinnerNumberModel) maxFreq.getModel();
spinnerValFact.setMaximum(getSampleRate() /2.);
//for some reason also need to set this
spinnerValFact.setMinimum(1.);
//set reasonable step sizes
if (getSampleRate()>=10000) {
spinnerValFact.setStepSize(1000.);
}
else if (getSampleRate()>=2000){
spinnerValFact.setStepSize(200.);
}
else {
spinnerValFact.setStepSize(50.);
}
if (symbolOptions.freqLimts==null) {
symbolOptions.freqLimts= new double[] {0, getSampleRate() /2};
}
System.out.println("Check freq limits: 2: " + symbolOptions.freqLimts[0] + " " + symbolOptions.freqLimts[1]);
//check nyquist for upper limit
if (symbolOptions.freqLimts[1]>getSampleRate() /2) {
symbolOptions.freqLimts[1]=getSampleRate() /2;
}
//check nyquist for lower limit
if (symbolOptions.freqLimts[0]>getSampleRate() /2) {
symbolOptions.freqLimts[0]=0;
}
}
private float getSampleRate() {
return freqSymbolModifer.getSymbolChooser().getPamDataBlock().getSampleRate();
}
}

View File

@ -6,6 +6,11 @@ import PamView.ColourArray;
import PamView.ColourArray.ColourArrayType;
import PamView.sliders.PamRangeSlider;
/**
* A range slider which shows a colour gradient between two thumbs.
*
* @author Jamie Macaulay
*/
public class ColourRangeSlider extends PamRangeSlider {
/**
@ -15,23 +20,32 @@ public class ColourRangeSlider extends PamRangeSlider {
public ColourRangeSlider(){
super(JSlider.VERTICAL);
// this.orientation = JSlider.VERTICAL;
}
public ColourRangeSlider(int min, int max){
super(JSlider.VERTICAL);
// this.orientation = JSlider.HORIZONTAL;
super(min, max,JSlider.VERTICAL);
}
public ColourRangeSlider(int min, int max, int orientation){
super(min, max,orientation);
}
public ColourRangeSlider(int orientation){
super(orientation);
// this.orientation = JSlider.HORIZONTAL;
}
/**
* Set the colour map type to show between the two thumbs.
* @param colourMap - the colour map to show.
*/
public void setColourMap(ColourArrayType colourMap){
((ColourRangeSliderUI) getUI()).setColourMap(colourMap);
}
/**
* Set a custom colour map type to show between the two thumbs.
* @param colourMap - the colour map to show.
*/
public void setColourMap(ColourArray colourMap){
((ColourRangeSliderUI) getUI()).setColourMap(colourMap);
}

View File

@ -253,7 +253,7 @@ public class ClickControlPane2 extends PamBorderPane implements TDSettingsPane {
* @return the data select pane.
*/
private DynamicSettingsPane<Boolean> createDataSelectPane(){
System.out.println("DATA SELECTOR: " + clickPlotInfo.getClickDataSelector());
// System.out.println("DATA SELECTOR: " + clickPlotInfo.getClickDataSelector());
return clickPlotInfo.getClickDataSelector().getDialogPaneFX();
}

View File

@ -16,12 +16,10 @@ import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JPopupMenu.Separator;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;
import PamView.ColourArray.ColourArrayType;
import PamView.PamSymbol;
import PamView.PamView;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
@ -56,13 +54,26 @@ import pamViewFX.fxNodes.PamSymbolFX;
*/
public class PamUtilsFX {
/**
* Convert an FX based ColourArrayType to Swing. Note that swing options that do not exist in FX and vice versa will return null.
* @param arrayFX - the FX ColourArrayType.
* @return the Swing ColourArrayType;
*/
public static ColourArrayType fxColArray2Swing(pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType arrayFX) {
ColourArrayType type = ColourArrayType.valueOf(arrayFX.toString());
return type;
}
/**
* Convert an Swing based ColourArrayType to FX. Note that swing options that do not exist in FX and vice versa will return null.
* @param arraySwing - the Swing ColourArrayType.
* @return the FX ColourArrayType.
*/
public static pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType swingColArray2FX(ColourArrayType arraySwing) {
pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType type = pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType.valueOf(arraySwing.toString());
return type;
}
/**
*
* @param awtColor
@ -673,5 +684,4 @@ public class PamUtilsFX {
return Color.rgb(r,g,b);
}
}

View File

@ -180,6 +180,17 @@ public class PeakFreqOptionsPane extends StandardSymbolModifierPane {
DoubleSpinnerValueFactory spinnerValFact = (DoubleSpinnerValueFactory) maxFreq.getValueFactory();
spinnerValFact.maxProperty().set(getSampleRate() /2);
//set reasonable step sizes
if (getSampleRate()>=10000) {
spinnerValFact.amountToStepByProperty().set(1000.);
}
else if (getSampleRate()>=2000){
spinnerValFact.amountToStepByProperty().set(200.);
}
else {
spinnerValFact.amountToStepByProperty().set(50.);
}
if (symbolOptions.freqLimts==null) {
symbolOptions.freqLimts= new double[] {0, getSampleRate() /2};

View File

@ -9,6 +9,7 @@ import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
@ -25,12 +26,15 @@ import javax.swing.JToggleButton;
import javax.swing.border.TitledBorder;
import PamView.ColourComboBox;
import PamView.PamAWTUtils;
import PamView.dialog.GenericSwingDialog;
import PamView.dialog.PamButton;
import PamView.dialog.PamDialogPanel;
import PamView.panel.PamPanel;
import PamView.symbol.StandardSymbolOptions;
import PamView.symbol.modifier.SymbolModifier;
import Spectrogram.ColourRangeSlider;
import pamViewFX.fxNodes.utilsFX.ColourArray;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
import rawDeepLearningClassifier.dlClassification.DLClassName;
@ -95,6 +99,10 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
private PamPanel mainPanel;
private int[] classColours;
private AbstractButton colourButton;
public DLSymbolOptionPanel(SymbolModifier symbolModifer) {
this.dlSymbolModifier = (DLSymbolModifier) symbolModifer;
@ -222,6 +230,11 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
*/
private void setClassColParams(DLSymbolModifierParams symbolOptions) {
//create a temporary array to save different class colours in - this needs to be
//before other params are set.
this.classColours = symbolOptions.classColors;
int nClass = checkClassNamesBox( symbolOptions, classNameBox2);
symbolOptions.classIndex = Math.min(symbolOptions.classIndex, nClass-1);
@ -229,21 +242,81 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
classNameBox2.setSelectedIndex(Math.max(symbolOptions.classIndex2, 0));
int index = symbolOptions.classIndex2>=0 ? symbolOptions.classIndex2 : 0;
// int index = symbolOptions.classIndex2>=0 ? symbolOptions.classIndex2 : 0;
if (symbolOptions.classColors==null) {
symbolOptions.setDefaultClassColors(nClass);
}
if (classNameBox2.getSelectedIndex()>=0) {
colourButton.setBackground(PamAWTUtils.intToColor(classColours[classNameBox2.getSelectedIndex()]));
colourButton.repaint();
}
// //set the correct colour
// colorPicker.setColor(symbolOptions.classColors[index]);
}
/**
* get parameters for colouring by class.
* @param symbolOptions - the symbol options.
* @return
*/
public DLSymbolModifierParams getClassColParams(DLSymbolModifierParams symbolOptions ) {
// int index = classNameBox2.getSelectedIndex()>=0 ? classNameBox2.getSelectedIndex():0;
symbolOptions.classColors = classColours;
symbolOptions.classIndex2 = classNameBox2.getSelectedIndex();
return symbolOptions;
}
/**
*
* @param symbolOptions
* @return
*/
public DLSymbolModifierParams getPredictionColParams(DLSymbolModifierParams symbolOptions ) {
symbolOptions.clims=new double[] {((double) colorRangeSlider.getValue())/100., ((double) colorRangeSlider.getUpperValue())/100.};
symbolOptions.colArray = PamUtilsFX.swingColArray2FX(this.colorComboBox.getSelectedColourMap());
symbolOptions.classIndex = classNameBox.getSelectedIndex();
return symbolOptions;
}
@Override
public boolean getParams() {
// TODO Auto-generated method stub
return false;
//bit messy but works
DLSymbolModifierParams symbolOptions = dlSymbolModifier.getSymbolModifierParams().clone();
//need to check this here.
//checkClassNamesBox(symbolOptions);
if (b1.isSelected()) symbolOptions.colTypeSelection = DLSymbolModifierParams.PREDICITON_COL;
if (b2.isSelected()) symbolOptions.colTypeSelection = DLSymbolModifierParams.CLASS_COL;
//get parameters for colouring
symbolOptions = getClassColParams(symbolOptions);
//get parameters for colouring by prediction value
symbolOptions = getPredictionColParams(symbolOptions) ;
symbolOptions.showOnlyBinary = showOnlyBinary.isSelected();
dlSymbolModifier.checkColourArray();
//set the paratmers.
dlSymbolModifier.setSymbolModifierParams(symbolOptions);
return true;
}
@ -254,10 +327,8 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
if (b1.isSelected()) {
holder.add(probPane, BorderLayout.CENTER);
System.out.println("Set probPane pane");
} else if (b2.isSelected()) {
holder.add(classPane, BorderLayout.CENTER);
System.out.println("Set class pane");
}
holder.validate();
@ -273,16 +344,25 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
private JPanel createClassPane() {
classNameBox2 = new JComboBox<>();
classNameBox2.addActionListener(this);
classNameBox2.addActionListener((action)->{
//make sure the setting button shows the colour
if (classNameBox2.getSelectedIndex()>=0) {
colourButton.setBackground(PamAWTUtils.intToColor(classColours[classNameBox2.getSelectedIndex()]));
}
setSettingsPane();
});
classNameBox2.setPreferredSize(new Dimension((int) CLASS_NAME_BOX_WIDTH, 25));
// colorPicker.setPreferredSize(new Dimension(60, 25));
PamButton colourButton = new PamButton("Color");
colourButton = new PamButton("Color");
colourButton.addActionListener((action)->{
Color color = JColorChooser.showDialog(colourButton, "Pick colour for class", Color.black);
Color color = JColorChooser.showDialog(colourButton, "Pick colour for class", PamAWTUtils.intToColor(classColours[classNameBox2.getSelectedIndex()]));
if (color!=null) {
colourButton.setBackground(color);
// colourButton.setForeground(color);
classColours[classNameBox2.getSelectedIndex()]=PamAWTUtils.colorToInt(color);
}
});
JPanel classHolder = new JPanel();
@ -318,13 +398,19 @@ public class DLSymbolOptionPanel implements PamDialogPanel, ActionListener {
c.gridx++;
colorComboBox = new ColourComboBox();
colorComboBox.addActionListener((action)->{
colorRangeSlider.setColourMap(colorComboBox.getSelectedColourMap());
colorRangeSlider.repaint();
});
holder.add(colorComboBox, c);
c.gridx = 0;
c.gridy++;
c.gridwidth =2;
colorRangeSlider = new ColourRangeSlider(JSlider.HORIZONTAL); // Min 0, Max 1 for probabilities
colorRangeSlider = new ColourRangeSlider(0, 100, JSlider.HORIZONTAL); // Min 0, Max 1 for probabilities
colorRangeSlider.setPaintTicks(true);
colorRangeSlider.setMinorTickSpacing(20);
holder.add(colorRangeSlider, c);
return holder;

View File

@ -4,6 +4,7 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
@ -100,6 +101,10 @@ public class DLPredictionPanel implements PamDialogPanel {
GridBagConstraints c = new PamGridBagContraints();
c.ipadx =5;
c.gridwidth=2;
contentPanel.add(new Label("Min. prediciton for each class"), c);
c.gridwidth=1;
c.gridy++;
for (int i=0; i<input.classSelect.length ; i++) {

View File

@ -64,8 +64,9 @@ public class DLSelectPanel implements PamDialogPanel {
DLDataSelectorParams currParams = dlDataSelector.getParams();
//dialog has a reference to the data filter and will change params.
dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPanel().getParams();
boolean dataFilterOK = dlDataSelector.getDataSelectors().get(currentIndex).getSettingsPanel().getParams();
if (dataFilterOK) {
//TODO - maybe should grab settings from all filters or just the selected one?
currParams.dataSelectorParams[currentIndex] = dlDataSelector.getDataSelectors().get(currentIndex).getParams();
@ -73,6 +74,10 @@ public class DLSelectPanel implements PamDialogPanel {
return true;
}
else {
return false;
}
}
}