From 8b5b5b2f18da88d5aa33206966d6a61e2861420e Mon Sep 17 00:00:00 2001 From: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:14:28 +0100 Subject: [PATCH] Updated data selectors for BT display Merging old status bar and new DataSelector options so that they work more consistently on the BT display. --- .../dataSelector/DataSelectDialog.java | 16 ++ src/clickDetector/BTAmplitudeSelector.java | 14 +- src/clickDetector/BTDisplayParameters.java | 82 +++++----- src/clickDetector/ClickBTDisplay.java | 142 +++++++++++++----- .../alarm/ClickAlarmParameters.java | 33 +++- .../dataSelector/ClickDataSelector.java | 44 +++--- .../dataSelector/ClickSelectPanel.java | 69 +++++++-- .../dialogs/ClickDisplayDialog.java | 45 +++--- .../offlineFuncs/OfflineToolbar.java | 45 ++++-- src/clickDetector/tdPlots/ClickPlotInfo.java | 11 +- 10 files changed, 347 insertions(+), 154 deletions(-) diff --git a/src/PamguardMVC/dataSelector/DataSelectDialog.java b/src/PamguardMVC/dataSelector/DataSelectDialog.java index 5fd7f81f..9cb541e1 100644 --- a/src/PamguardMVC/dataSelector/DataSelectDialog.java +++ b/src/PamguardMVC/dataSelector/DataSelectDialog.java @@ -76,6 +76,22 @@ public class DataSelectDialog extends PamDialog { // } } + public boolean setTab(int tabIndex) { + if (tabPane == null) { + return false; + } + if (tabIndex < 0 || tabIndex >= tabPane.getTabCount()) { + return false; + } + try { + tabPane.setSelectedIndex(tabIndex); + } + catch (Exception e) { + return false; + } + return true; + } + public boolean showDialog() { if (dataPanel != null) { dataPanel.setParams(); diff --git a/src/clickDetector/BTAmplitudeSelector.java b/src/clickDetector/BTAmplitudeSelector.java index ba020596..fac92954 100644 --- a/src/clickDetector/BTAmplitudeSelector.java +++ b/src/clickDetector/BTAmplitudeSelector.java @@ -29,6 +29,7 @@ import PamView.PamSymbolType; import PamView.dialog.PamDialog; import PamView.dialog.PamDialogPanel; import PamView.dialog.PamGridBagContraints; +import clickDetector.dataSelector.ClickDataSelector; import pamMaths.HistogramDisplay; import pamMaths.HistogramGraphicsLayer; import pamMaths.PamHistogram; @@ -59,6 +60,7 @@ public class BTAmplitudeSelector implements PamDialogPanel { private JCheckBox amplitudeSelect; private JTextField minAmplitude; private JFrame ownerFrame; + private ClickDataSelector dataSelector; /** * @param btDisplay */ @@ -66,6 +68,7 @@ public class BTAmplitudeSelector implements PamDialogPanel { super(); this.clickControl = clickControl; this.btDisplay = btDisplay; + dataSelector = btDisplay.getDataSelector(); clickDataBlock = clickControl.getClickDataBlock(); histoPlot = new HistogramDisplay(); histoPlot.setGraphicsOverLayer(histoOverLayer = new HistoOverLayer()); @@ -125,7 +128,8 @@ public class BTAmplitudeSelector implements PamDialogPanel { axMin = allHistogram.getScaleMinVal(); axMax = allHistogram.getScaleMaxVal(); plotRectangle = g.getClipBounds(); - double dx = (btDisplayParameters.minAmplitude - axMin) / (axMax-axMin) * plotRectangle.width; +// double dx = (btDisplayParameters.minAmplitude - axMin) / (axMax-axMin) * plotRectangle.width; + double dx = (dataSelector.getParams().minimumAmplitude - axMin) / (axMax-axMin) * plotRectangle.width; int x = (int) Math.round(dx); g.setColor(Color.RED); g.drawLine(x, 0, x, plotRectangle.height); @@ -151,7 +155,7 @@ public class BTAmplitudeSelector implements PamDialogPanel { double newAmp = (double) mouseEvent.getX() / histoOverLayer.plotRectangle.width * (histoOverLayer.axMax-histoOverLayer.axMin) + histoOverLayer.axMin; BTDisplayParameters btDisplayParameters = btDisplay.getBtDisplayParameters(); - btDisplayParameters.minAmplitude = newAmp; + dataSelector.getParams().minimumAmplitude = newAmp; ampCtrlPanel.setParams(btDisplayParameters); redrawHisto(); // @@ -173,7 +177,7 @@ public class BTAmplitudeSelector implements PamDialogPanel { if (btDisplayParameters.amplitudeSelect == false) { return false; } - double dx = (btDisplayParameters.minAmplitude - histoOverLayer.axMin) / + double dx = (dataSelector.getParams().minimumAmplitude - histoOverLayer.axMin) / (histoOverLayer.axMax-histoOverLayer.axMin) * histoOverLayer.plotRectangle.width; int x = (int) Math.round(dx); if (Math.abs(e.getX()-x) > 10) { @@ -213,14 +217,14 @@ public class BTAmplitudeSelector implements PamDialogPanel { } private void setParams(BTDisplayParameters btParams) { amplitudeSelect.setSelected(btParams.amplitudeSelect); - minAmplitude.setText(String.format("%3.1f", btParams.minAmplitude)); + minAmplitude.setText(String.format("%3.1f", dataSelector.getParams().minimumAmplitude)); enableControls(); } private boolean getParams(BTDisplayParameters btParams) { btParams.amplitudeSelect = amplitudeSelect.isSelected(); try { - btParams.minAmplitude = Double.valueOf(minAmplitude.getText()); + dataSelector.getParams().minimumAmplitude = Double.valueOf(minAmplitude.getText()); } catch (NumberFormatException e) { return false; diff --git a/src/clickDetector/BTDisplayParameters.java b/src/clickDetector/BTDisplayParameters.java index bf9604f7..925f0b74 100644 --- a/src/clickDetector/BTDisplayParameters.java +++ b/src/clickDetector/BTDisplayParameters.java @@ -44,17 +44,17 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara public int nBearingGridLines = 1; public int nAmplitudeGridLines = 0; public int nICIGridLines = 0; - public boolean showEchoes = true; +// public boolean showEchoes = true; public int minClickLength = 2, maxClickLength = 12; public int minClickHeight = 2, maxClickHeight = 12; private double timeRange = 10; public int displayChannels = 0; public boolean view360; public boolean amplitudeSelect = false; - public double minAmplitude = 0; +// public double minAmplitude = 0; public boolean showUnassignedICI = false; - public boolean showEventsOnly = false; - public boolean showANDEvents = true; +// public boolean showEventsOnly = false; +// public boolean showANDEvents = true; public boolean logICIScale; public int angleRotation = ROTATE_TOARRAY; @@ -65,7 +65,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara /* * Show identified species */ - private boolean[] showSpeciesList; +// private boolean[] showSpeciesList; public int colourScheme = COLOUR_BY_TRAIN; @@ -83,7 +83,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara } catch (CloneNotSupportedException Ex) { Ex.printStackTrace(); } - showSpeciesList = null; +// showSpeciesList = null; return null; } @@ -107,49 +107,49 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara /** * @return the showSpeciesList */ - public boolean getShowSpecies(int speciesIndex) { - if (showSpeciesList != null && showSpeciesList.length > speciesIndex) { - return showSpeciesList[speciesIndex]; - } - makeShowSpeciesList(speciesIndex); - return true; - } - private void makeShowSpeciesList(int maxIndex) { - if (showSpeciesList == null) { - showSpeciesList = new boolean[0]; - } - else if (showSpeciesList.length > maxIndex) { - return; - } - int oldLength = showSpeciesList.length; - showSpeciesList = Arrays.copyOf(showSpeciesList, maxIndex + 1); - for (int i = oldLength; i <= maxIndex; i++) { - showSpeciesList[i] = true; - } - } +// public boolean getShowSpecies(int speciesIndex) { +// if (showSpeciesList != null && showSpeciesList.length > speciesIndex) { +// return showSpeciesList[speciesIndex]; +// } +// makeShowSpeciesList(speciesIndex); +// return true; +// } +// private void makeShowSpeciesList(int maxIndex) { +// if (showSpeciesList == null) { +// showSpeciesList = new boolean[0]; +// } +// else if (showSpeciesList.length > maxIndex) { +// return; +// } +// int oldLength = showSpeciesList.length; +// showSpeciesList = Arrays.copyOf(showSpeciesList, maxIndex + 1); +// for (int i = oldLength; i <= maxIndex; i++) { +// showSpeciesList[i] = true; +// } +// } /** * @param showSpeciesList the showSpeciesList to set */ - public void setShowSpecies(int speciesIndex, boolean showSpecies) { - makeShowSpeciesList(speciesIndex); - showSpeciesList[speciesIndex] = showSpecies; - } +// public void setShowSpecies(int speciesIndex, boolean showSpecies) { +// makeShowSpeciesList(speciesIndex); +// showSpeciesList[speciesIndex] = showSpecies; +// } @Override public PamParameterSet getParameterSet() { PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); - try { - Field field = this.getClass().getDeclaredField("showSpeciesList"); - ps.put(new PrivatePamParameterData(this, field) { - @Override - public Object getData() throws IllegalArgumentException, IllegalAccessException { - return showSpeciesList; - } - }); - } catch (NoSuchFieldException | SecurityException e) { - e.printStackTrace(); - } +// try { +// Field field = this.getClass().getDeclaredField("showSpeciesList"); +// ps.put(new PrivatePamParameterData(this, field) { +// @Override +// public Object getData() throws IllegalArgumentException, IllegalAccessException { +// return showSpeciesList; +// } +// }); +// } catch (NoSuchFieldException | SecurityException e) { +// e.printStackTrace(); +// } return ps; } diff --git a/src/clickDetector/ClickBTDisplay.java b/src/clickDetector/ClickBTDisplay.java index 637d9578..ebf0ca07 100644 --- a/src/clickDetector/ClickBTDisplay.java +++ b/src/clickDetector/ClickBTDisplay.java @@ -34,6 +34,7 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; @@ -115,9 +116,12 @@ import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.PamObservable; import PamguardMVC.PamObserver; +import PamguardMVC.dataSelector.DataSelectDialog; import PamguardMVC.superdet.SuperDetection; import clickDetector.ClickClassifiers.ClickIdInformation; import clickDetector.ClickClassifiers.ClickIdentifier; +import clickDetector.alarm.ClickAlarmParameters; +import clickDetector.dataSelector.ClickDataSelector; import clickDetector.dialogs.ClickDisplayDialog; import clickDetector.offlineFuncs.OfflineEventDataBlock; import clickDetector.offlineFuncs.OfflineEventDataUnit; @@ -2244,7 +2248,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett PamDataBlock clickData = clickControl.getClickDataBlock(); int nAll = clickData.getUnitsCount(); String txt = String.format("%d of %d loaded clicks will not be displayed because their amplitude is < %3.1fdB", - n, nAll, btDisplayParameters.minAmplitude); + n, nAll, getDataSelector().getParams().minimumAmplitude); Insets insets = getInsets(); int x = insets.left; int y = getHeight()-5; @@ -2383,19 +2387,33 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett } menuItem = new JMenuItem("Settings ..."); + menuItem.setToolTipText("Display options"); menuItem.addActionListener(new SettingsMenuAction()); menu.add(menuItem); + menuItem = new JMenuItem("Click data selector ..."); + menuItem.setToolTipText("Detailed data selection options"); + menuItem.addActionListener(new DataSelectorAction()); + menu.add(menuItem); menuItem = new JMenuItem("Show amplitude selector ..."); + menuItem.setToolTipText("Graphical amplitude selector display"); menuItem.addActionListener(new AmplitudeSelector()); menu.add(menuItem); menu.addSeparator(); - ArrayList colOptList = getSymbolChooser().getQuickMenuItems(clickControl.getGuiFrame(), this, "Colour by ", SymbolModType.EVERYTHING, true); + ArrayList colOptList = getSymbolChooser().getQuickMenuItems(clickControl.getGuiFrame(), this, "Colour by ", SymbolModType.EVERYTHING, false); if (colOptList != null) { for (JMenuItem menuIt : colOptList) { menu.add(menuIt); } - menu.addSeparator(); } + menuItem = new JMenuItem("More symbol options ..."); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showDataSymbolOptions(1); + } + }); + menu.add(menuItem); + menu.addSeparator(); // menuItem = new JCheckBoxMenuItem("Colour by species id", // btDisplayParameters.colourScheme == BTDisplayParameters.COLOUR_BY_SPECIES); @@ -2470,7 +2488,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett return menu; } - + /** * Looks through the current modules and finds if there is a target motion or static localiser */ @@ -2771,7 +2789,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett BTDisplayParameters newParameters = ClickDisplayDialog.showDialog(clickControl, - clickControl.getGuiFrame(), btDisplayParameters); + clickControl.getGuiFrame(), btDisplayParameters, getDataSelector().getClickAlarmParameters()); if (newParameters != null){ btDisplayParameters = newParameters.clone(); if (getVScaleManager() != null) { @@ -2788,6 +2806,15 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett } } + + + /** + * Get a data selector specific to this display. + * @return click data selector specific to this display. + */ + public ClickDataSelector getDataSelector() { + return (ClickDataSelector) clickControl.getClickDataBlock().getDataSelector(getUnitName(), false); + } class AmplitudeSelector implements ActionListener { @Override @@ -2795,6 +2822,13 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett showAmplitudeSelector(); } } + + class DataSelectorAction implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + showDataSelector(); + } + } private void showAmplitudeSelector() { @@ -2814,6 +2848,38 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett // } } + /** + * Show a dialog with both data and symbol options, but go to the correct tab. + * @param selectedTab + * @return + */ + private boolean showDataSymbolOptions(int selectedTab) { + Window javaFrame = clickControl.getGuiFrame(); + DataSelectDialog dataSelectDialog = new DataSelectDialog(javaFrame, clickControl.getClickDataBlock(), getDataSelector(), symbolChooser); + if (javaFrame == null) { + dataSelectDialog.moveToMouseLocation(); + } + dataSelectDialog.setTab(selectedTab); + boolean ok = dataSelectDialog.showDialog(); + if (ok) { + repaintBoth(); + if (clickControl.getOfflineToolbar() != null) { + clickControl.getOfflineToolbar().displayActivated(clickBTDisplay); + } + } + return ok; + } + + public void showDataSelector() { +// if (getDataSelector().showSelectDialog(clickControl.getGuiFrame())) { +// repaintBoth(); +// if (clickControl.getOfflineToolbar() != null) { +// clickControl.getOfflineToolbar().displayActivated(clickBTDisplay); +// } +// }; + showDataSymbolOptions(0); + } + private void checkBTAmplitudeSelectHisto() { if (btAmplitudeSelector == null) { return; @@ -3036,15 +3102,15 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett zoomer.paintShape(g, this, true); } - // long t1 = System.nanoTime(); - synchronized (clickData.getSynchLock()) { - // long t2 = System.nanoTime(); - // double ms = ((double) (t2-t1)) / 1000000.; - // if (btDisplayParameters.VScale == BTDisplayParameters.DISPLAY_ICI) { - // sortTempICIs(); - // } + ArrayList clickCopy = clickData.getDataCopy(displayStartMillis, displayStartMillis+displayLengthMillis, true, getDataSelector()); + if (clickCopy.size() == 0) { + return; + } + ListIterator clickIterator = clickCopy.listIterator(clickCopy.size()-1); - ListIterator clickIterator = clickData.getListIterator(PamDataBlock.ITERATOR_END); +// synchronized (clickData.getSynchLock()) { +// +// ListIterator clickIterator = clickData.getListIterator(PamDataBlock.ITERATOR_END); while (clickIterator.hasPrevious()) { click = clickIterator.previous(); if (shouldPlot(prevPlottedClick)){ @@ -3060,11 +3126,6 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett if (shouldPlot(prevPlottedClick)){ // and draw the last one ! drawClick(g, prevPlottedClick, clipRectangle); } - // g.drawString(String.format("Wait synch %3.3fms", ms), 0, 20); - } - // long t3 = System.nanoTime(); - // g.drawString(String.format("Last draw %3.3fms", lastPaintTime), 0, 20); - // lastPaintTime = ((double) (t3-t0)) / 1000000.; } @Override @@ -3342,7 +3403,9 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett else if (btDisplayParameters.colourScheme == BTDisplayParameters.COLOUR_BY_HYDROPHONE) { keyPanel.add(new TextKeyItem("Colour by hydrophone")); } - if (btDisplayParameters.getShowSpecies(0)) { + ClickAlarmParameters selectParams = getDataSelector().getParams(); +// if (btDisplayParameters.getShowSpecies(0)) { + if (selectParams.onlineAutoEvents | selectParams.onlineManualEvents) { keyPanel.add(symbolChooser.getDefaultSymbol(true).makeKeyItem("Unidentified species")); } @@ -3354,7 +3417,8 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett PamSymbol[] symbols = clickControl.getClickIdentifier().getSymbols(); if (speciesList != null) { for (int i = 0; i < speciesList.length; i++) { - if (btDisplayParameters.getShowSpecies(i+1)) { + if (selectParams.getUseSpecies(i+1)) { +// if (btDisplayParameters.getShowSpecies(i+1)) { if (btDisplayParameters.colourScheme != BTDisplayParameters.COLOUR_BY_TRAIN) { keyPanel.add(symbols[i].makeKeyItem(speciesList[i])); } @@ -3423,11 +3487,12 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett PamDataBlock clickData = clickControl.getClickDataBlock(); ClickDetection click; int n = 0; + double minAmpli = getDataSelector().getParams().minimumAmplitude; synchronized (clickData.getSynchLock()) { ListIterator clickIterator = clickData.getListIterator(0); while (clickIterator.hasNext()) { click = clickIterator.next(); - if (click.getAmplitudeDB() < btDisplayParameters.minAmplitude) { + if (click.getAmplitudeDB() < minAmpli) { n++; } } @@ -3448,29 +3513,30 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett */ synchronized boolean shouldPlot(ClickDetection click) { if (click == null) return false; - if (!clickInTimeWindow(click)) return false; - if (btDisplayParameters.showEchoes == false && click.isEcho()) { - return false; - } +// if (!clickInTimeWindow(click)) return false; +// if (btDisplayParameters.showEchoes == false && click.isEcho()) { +// return false; +// } if (btDisplayParameters.VScale == BTDisplayParameters.DISPLAY_ICI) { // if (btDisplayParameters.showUnassignedICI == false && click.getICI() < 0) return false; if (btDisplayParameters.showUnassignedICI == false && click.getSuperDetectionsCount() <= 0) return false; // otherwise may be ok, since will estimate all ici's on teh fly. } - if (btDisplayParameters.amplitudeSelect && click.getAmplitudeDB() < btDisplayParameters.minAmplitude) { - return false; - } +// if (btDisplayParameters.amplitudeSelect && click.getAmplitudeDB() < btDisplayParameters.minAmplitude) { +// return false; +// } if (btDisplayParameters.displayChannels > 0 && (btDisplayParameters.displayChannels & click.getChannelBitmap()) == 0) return false; - int speciesIndex = clickControl.getClickIdentifier().codeToListIndex(click.getClickType()); - boolean showSpecies = btDisplayParameters.getShowSpecies(speciesIndex+1); - boolean showEvents = (btDisplayParameters.showEventsOnly == false || click.getSuperDetectionsCount() > 0); - if (btDisplayParameters.showANDEvents) { - return showSpecies & showEvents; - } - else { - return showSpecies | showEvents; - } +// int speciesIndex = clickControl.getClickIdentifier().codeToListIndex(click.getClickType()); +// boolean showSpecies = btDisplayParameters.getShowSpecies(speciesIndex+1); +// boolean showEvents = (btDisplayParameters.showEventsOnly == false || click.getSuperDetectionsCount() > 0); +// if (btDisplayParameters.showANDEvents) { +// return showSpecies & showEvents; +// } +// else { +// return showSpecies | showEvents; +// } + return true; } /** @@ -4085,7 +4151,7 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett amplitudeSelectorLabel.setText(""); } else { - String txt = String.format(" Amplitude Selector showing clicks > %3.1fdB", btDisplayParameters.minAmplitude); + String txt = String.format(" Amplitude Selector showing clicks > %3.1fdB", getDataSelector().getParams().minimumAmplitude); amplitudeSelectorLabel.setText(txt); } } diff --git a/src/clickDetector/alarm/ClickAlarmParameters.java b/src/clickDetector/alarm/ClickAlarmParameters.java index 8bed53c6..d126f4c6 100644 --- a/src/clickDetector/alarm/ClickAlarmParameters.java +++ b/src/clickDetector/alarm/ClickAlarmParameters.java @@ -17,10 +17,12 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable, public static final long serialVersionUID = 1L; private boolean[] useSpeciesList; private double[] speciesWeightings; - public boolean useEchoes; - public boolean scoreByAmplitude; - public boolean onlineAutoEvents, onlineManualEvents; + public boolean useEchoes = true; + public boolean scoreByAmplitude; // alarm options, probably not used any more. + public double minimumAmplitude; + public boolean onlineAutoEvents = true, onlineManualEvents = true; public int minICIMillis; + private boolean clicksOREvents = false; /* * Which events to use ... */ @@ -165,5 +167,30 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable, return ps; } + /** + * @return the clicksOREvents + */ + public boolean isClicksOREvents() { + return clicksOREvents; + } + + /** + * @param clicksOREvents the clicksOREvents to set + */ + public void setClicksOREvents(boolean clicksOREvents) { + this.clicksOREvents = clicksOREvents; + } + /** + * @return the clicksANDEvents + */ + public boolean isClicksANDEvents() { + return !clicksOREvents; + } + + + public void setClicksANDEvents(boolean clicksANDEvents) { + this.clicksOREvents = !clicksANDEvents; + } + } diff --git a/src/clickDetector/dataSelector/ClickDataSelector.java b/src/clickDetector/dataSelector/ClickDataSelector.java index 5be77c2a..9f2248d3 100644 --- a/src/clickDetector/dataSelector/ClickDataSelector.java +++ b/src/clickDetector/dataSelector/ClickDataSelector.java @@ -38,9 +38,9 @@ public class ClickDataSelector extends DataSelector { @Override public PamDialogPanel getDialogPanel() { - if (clickSelectPanel == null) { +// if (clickSelectPanel == null) { clickSelectPanel = new ClickSelectPanel(this, allowScores, useEventTypes); - } +// } return clickSelectPanel; } @Override @@ -60,19 +60,25 @@ public class ClickDataSelector extends DataSelector { if (clickAlarmParameters.useEchoes == false && click.isEcho()) { return 0; } - /** - * First score based on whether the event panel is in use and - * criteria satisfied. - */ + + double score = scoreClick(click); if (useEventTypes) { - if (wantEventType(click) == false) { - return 0; + double eventScore = scoreEventType(click); + if (clickAlarmParameters.isClicksANDEvents()) { + score = Math.min(score, eventScore); + } + else { + score = Math.max(score, eventScore); } } + return score; - /* - * Now score based on whether or not it's individual click type is wanted. - */ + } + + private double scoreClick(ClickDetection click) { + if (click.getAmplitudeDB() < clickAlarmParameters.minimumAmplitude) { + return 0; + } ClickIdentifier clickIdentifier = clickControl.getClickIdentifier(); int code = click.getClickType(); if (code > 0 && clickIdentifier != null) { @@ -81,13 +87,13 @@ public class ClickDataSelector extends DataSelector { boolean enabled = clickAlarmParameters.getUseSpecies(code); if (enabled == false) { return 0; - } - if (isAllowScores()) { + }if (isAllowScores()) { return clickAlarmParameters.getSpeciesWeight(code); } else { return 1; } + } /** @@ -95,7 +101,7 @@ public class ClickDataSelector extends DataSelector { * @param click * @return */ - private boolean wantEventType(ClickDetection click) { + private double scoreEventType(ClickDetection click) { OfflineEventDataUnit oev = null; try { @@ -107,7 +113,7 @@ public class ClickDataSelector extends DataSelector { int eventId = click.getOfflineEventID(); if (oev == null) { - return clickAlarmParameters.unassignedEvents; + return clickAlarmParameters.unassignedEvents ? 1 : 0; } // see if there is a super detection and see if it's got a comment. @@ -118,10 +124,10 @@ public class ClickDataSelector extends DataSelector { isAutomatic = comment.startsWith("Automatic"); } if (isAutomatic && clickAlarmParameters.onlineAutoEvents) { - return true; + return 1; } else if (clickAlarmParameters.onlineManualEvents) { - return true; + return 1; } // if (clickAlarmParameters.onlineAutoEvents && comment.startsWith("Automatic")) { // return true; @@ -134,7 +140,7 @@ public class ClickDataSelector extends DataSelector { * list of event types and see if it's wanted. */ String evType = oev.getEventType(); - return clickAlarmParameters.isUseEventType(evType); + return clickAlarmParameters.isUseEventType(evType) ? 1 : 0; } @@ -188,7 +194,7 @@ public class ClickDataSelector extends DataSelector { * @see PamguardMVC.dataSelector.DataSelector#getParams() */ @Override - public DataSelectParams getParams() { + public ClickAlarmParameters getParams() { return clickAlarmParameters; } diff --git a/src/clickDetector/dataSelector/ClickSelectPanel.java b/src/clickDetector/dataSelector/ClickSelectPanel.java index 512e088d..60e1566a 100644 --- a/src/clickDetector/dataSelector/ClickSelectPanel.java +++ b/src/clickDetector/dataSelector/ClickSelectPanel.java @@ -4,6 +4,7 @@ import generalDatabase.lookupTables.LookUpTables; import generalDatabase.lookupTables.LookupList; import java.awt.BorderLayout; +import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -13,11 +14,13 @@ import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; +import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import PamController.PamController; @@ -42,6 +45,7 @@ public class ClickSelectPanel implements PamDialogPanel { private ClickDataSelector clickDataSelector; private JPanel mainPanel; private boolean isViewer; + private JComboBox andOrBox; public static final String mainTip = "You should select options in both the Click Type and the Event Type panels"; @@ -70,10 +74,12 @@ public class ClickSelectPanel implements PamDialogPanel { public void setParams() { eventTypePanel.setParams(); speciesPanel.setParams(); + andOrBox.setSelectedIndex(clickDataSelector.getParams().isClicksANDEvents() ? 0 : 1); } @Override public boolean getParams() { + clickDataSelector.getParams().setClicksANDEvents(andOrBox.getSelectedIndex() == 0); return (speciesPanel.getParams() & eventTypePanel.getParams()); } @@ -163,17 +169,26 @@ public class ClickSelectPanel implements PamDialogPanel { // JRadioButton andEvents, orEvents; // JRadioButton anyEvents, onlyEvents; private JCheckBox useEchoes; + private JTextField minAmplitude; private JCheckBox scoreByAmplitude; private JTextField minICI; SpeciesPanel () { super(); - setLayout(new BorderLayout()); +// setLayout(new BorderLayout()); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); northPanel = new JPanel(); northPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new PamGridBagContraints(); - c.gridwidth = 3; + c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; + northPanel.add(new JLabel("Minimum amplitude ", JLabel.RIGHT), c); + c.gridx++; + northPanel.add(minAmplitude = new JTextField(4), c); + c.gridx++; + northPanel.add(new JLabel(" dB")); + c.gridx = 0; + c.gridy++; northPanel.add(new PamAlignmentPanel(useEchoes = new JCheckBox("Use Echoes"), BorderLayout.WEST), c); c.gridwidth = 1; c.gridy++; @@ -185,35 +200,50 @@ public class ClickSelectPanel implements PamDialogPanel { // minICI.setToolTipText("Minimum ICI in milliseconds"); // c.gridx++; // northPanel.add(new JLabel(" ms", JLabel.LEFT), c); - c.gridwidth = 3; - c.gridy++; - c.gridx = 0; - northPanel.add(scoreByAmplitude = new JCheckBox("Score by amplitude"), c); - scoreByAmplitude.setVisible(allowScores); - scoreByAmplitude.addActionListener(new AllSpeciesListener()); + scoreByAmplitude = new JCheckBox("Score by amplitude"); + if (allowScores) { + c.gridwidth = 3; + c.gridy++; + c.gridx = 0; + northPanel.add(scoreByAmplitude, c); + scoreByAmplitude.setVisible(allowScores); + scoreByAmplitude.addActionListener(new AllSpeciesListener()); + } WestAlignedPanel walpn; - add(BorderLayout.NORTH, walpn = new WestAlignedPanel(northPanel)); - walpn.setBorder(new SeparatorBorder("Echoes")); + this.add(walpn = new WestAlignedPanel(northPanel)); + walpn.setBorder(new SeparatorBorder("Click Selection")); JPanel centralOuterPanel = new JPanel(new BorderLayout()); centralPanel.setLayout(new GridBagLayout()); - centralOuterPanel.setBorder(new SeparatorBorder("Click Type Selection")); + centralOuterPanel.setBorder(new SeparatorBorder("Click Types")); - add(BorderLayout.CENTER, centralOuterPanel); + this.add(centralOuterPanel); JScrollPane scrollPane = new DialogScrollPane(new PamAlignmentPanel(centralPanel, BorderLayout.WEST), 10); centralOuterPanel.add(BorderLayout.CENTER, scrollPane); centralEastPanel.setLayout(new GridBagLayout()); c = new PamGridBagContraints(); - centralEastPanel.add(selectAll = new JButton("Select All"), c); - c.gridx++; - centralEastPanel.add(clearAll = new JButton("Clear All"), c); + c.ipady = 0; + c.insets.bottom = c.insets.top = c.insets.left = c.insets.right = 0; + centralEastPanel.add(selectAll = new JButton("All"), c); + c.gridy++; + centralEastPanel.add(clearAll = new JButton("None"), c); + selectAll.setBorder(new EmptyBorder(3,3,2,3)); + clearAll.setBorder(new EmptyBorder(3,3,2,3)); selectAll.addActionListener(new AutoSelect(true)); clearAll.addActionListener(new AutoSelect(false)); - centralOuterPanel.add(BorderLayout.SOUTH, new PamAlignmentPanel(centralEastPanel, BorderLayout.WEST)); + centralOuterPanel.add(BorderLayout.EAST, new PamAlignmentPanel(centralEastPanel, BorderLayout.NORTH)); centralOuterPanel.setToolTipText(mainTip); + this.add(andOrBox = new JComboBox<>()); + andOrBox.setToolTipText("Select how to logically combine the click and event selections"); + andOrBox.addItem("AND"); + andOrBox.addItem("OR"); + JPanel emptyPanel = new JPanel(); + emptyPanel.setPreferredSize(new Dimension(10, 5)); + this.add(emptyPanel); + setToolTipText(mainTip); } @@ -254,6 +284,7 @@ public class ClickSelectPanel implements PamDialogPanel { } } useEchoes.setSelected(clickAlarmParameters.useEchoes); + minAmplitude.setText(String.format("%3.1f", clickAlarmParameters.minimumAmplitude)); minICI.setText(String.format("%d", clickAlarmParameters.minICIMillis)); scoreByAmplitude.setSelected(clickAlarmParameters.scoreByAmplitude); allWeight.setText(String.format("%3.1f", clickAlarmParameters.getSpeciesWeight(0))); @@ -279,6 +310,12 @@ public class ClickSelectPanel implements PamDialogPanel { ClickAlarmParameters clickAlarmParameters = clickDataSelector.getClickAlarmParameters().clone(); clickAlarmParameters.useEchoes = useEchoes.isSelected(); + try { + clickAlarmParameters.minimumAmplitude = Double.valueOf(minAmplitude.getText()); + } + catch (NumberFormatException e) { + return PamDialog.showWarning(null, "Minimum amplitude", "Invalid minimum amplitude value"); + } try { clickAlarmParameters.minICIMillis = Integer.valueOf(minICI.getText()); } diff --git a/src/clickDetector/dialogs/ClickDisplayDialog.java b/src/clickDetector/dialogs/ClickDisplayDialog.java index 0a049c30..5c08f7bd 100644 --- a/src/clickDetector/dialogs/ClickDisplayDialog.java +++ b/src/clickDetector/dialogs/ClickDisplayDialog.java @@ -31,6 +31,7 @@ import PamView.dialog.warn.WarnOnce; import clickDetector.BTDisplayParameters; import clickDetector.ClickControl; import clickDetector.ClickClassifiers.ClickIdentifier; +import clickDetector.alarm.ClickAlarmParameters; /** * Dialog for basic click display parameters @@ -57,6 +58,8 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener { private SizePanel sizePanel; private SpeciesPanel speciesPanel; private JComboBox angleTypes; + + private ClickAlarmParameters clickSelectParams; private ClickDisplayDialog(Window owner) { @@ -86,12 +89,13 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener { } - public static BTDisplayParameters showDialog(ClickControl clickControl, Window parentFrame, BTDisplayParameters btDisplayParameters) { + public static BTDisplayParameters showDialog(ClickControl clickControl, Window parentFrame, BTDisplayParameters btDisplayParameters, ClickAlarmParameters clickSelectParams) { if (singleInstance == null || singleInstance.getOwner() != parentFrame) { singleInstance = new ClickDisplayDialog(parentFrame); } singleInstance.clickControl = clickControl; singleInstance.btDisplayParameters = btDisplayParameters.clone(); + singleInstance.clickSelectParams = clickSelectParams; singleInstance.setParams(btDisplayParameters); singleInstance.setVisible(true); return singleInstance.btDisplayParameters; @@ -514,14 +518,16 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener { } } } - showEchoes.setSelected(btDisplayParameters.showEchoes); + showEchoes.setSelected(clickSelectParams.useEchoes); if (species == null) { showAll.setSelected(true); } else { - showAll.setSelected(btDisplayParameters.getShowSpecies(0)); +// showAll.setSelected(btDisplayParameters.getShowSpecies(0)); + showAll.setSelected(clickSelectParams.getUseSpecies(0)); for (int i = 0; i < species.length; i++) { - species[i].setSelected(btDisplayParameters.getShowSpecies(i+1)); + species[i].setSelected(clickSelectParams.getUseSpecies(i+1)); +// species[i].setSelected(btDisplayParameters.getShowSpecies(i+1)); } // if (btDisplayParameters.showSpeciesList != null) { // for (int i = 0; i < Math.min(species.length, btDisplayParameters.showSpeciesList.length);i++) { @@ -529,9 +535,10 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener { // } // } } - - clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly); - andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1); + clicksInAnEvent.setSelected(clickSelectParams.onlineAutoEvents | clickSelectParams.onlineAutoEvents); + +// clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly); +// andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1); // orEvents.setSelected(!btDisplayParameters.showANDEvents); // andEvents.setSelected(btDisplayParameters.showANDEvents); // anyEvents.setSelected(!btDisplayParameters.showEventsOnly); @@ -540,19 +547,17 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener { enableButtons(); } boolean getParams() { - btDisplayParameters.showEchoes = showEchoes.isSelected(); - btDisplayParameters.setShowSpecies(0, showAll.isSelected()); - if (species != null) { - for (int i = 0; i < species.length; i++) { - btDisplayParameters.setShowSpecies(i+1, species[i].isSelected()); - } - - } - - btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected(); - btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0); -// btDisplayParameters.showANDEvents = andEvents.isSelected(); -// btDisplayParameters.showEventsOnly = onlyEvents.isSelected(); +// clickSelectParams.useEchoes = showEchoes.isSelected(); +// btDisplayParameters.setShowSpecies(0, showAll.isSelected()); +// if (species != null) { +// for (int i = 0; i < species.length; i++) { +// btDisplayParameters.setShowSpecies(i+1, species[i].isSelected()); +// } +// +// } +// +// btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected(); +// btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0); return true; } class AllSpeciesListener implements ActionListener { diff --git a/src/clickDetector/offlineFuncs/OfflineToolbar.java b/src/clickDetector/offlineFuncs/OfflineToolbar.java index 9ff5ba5f..414bae2b 100644 --- a/src/clickDetector/offlineFuncs/OfflineToolbar.java +++ b/src/clickDetector/offlineFuncs/OfflineToolbar.java @@ -31,12 +31,15 @@ import clickDetector.ClickBTDisplay; import clickDetector.ClickControl; import clickDetector.ClickDisplay; import clickDetector.ClickClassifiers.ClickIdentifier; +import clickDetector.alarm.ClickAlarmParameters; +import clickDetector.dataSelector.ClickDataSelector; import PamView.PamToolBar; import PamView.component.PamSettingsIconButton; import PamView.dialog.PamCheckBox; import PamView.dialog.PamLabel; import PamView.dialog.PamRadioButton; import PamView.panel.PamPanel; +import PamguardMVC.dataSelector.DataSelectParams; public class OfflineToolbar { @@ -252,19 +255,29 @@ public class OfflineToolbar { return; } try { + ClickDataSelector clickDataSelector = currentBTDisplay.getDataSelector(); + ClickAlarmParameters selectParams = clickDataSelector.getParams(); BTDisplayParameters btDisplayParameters = currentBTDisplay.getBtDisplayParameters(); - btDisplayParameters.setShowSpecies(0, showNonSpecies.isSelected()); - btDisplayParameters.showEchoes = showEchoes.isSelected(); + + selectParams.setUseSpecies(0, showNonSpecies.isSelected()); +// btDisplayParameters.setShowSpecies(0, showNonSpecies.isSelected()); +// btDisplayParameters.showEchoes = showEchoes.isSelected(); + selectParams.useEchoes = showEchoes.isSelected(); + if (clicksInAnEvent != null) { - btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected(); +// btDisplayParameters.showEventsOnly = clicksInAnEvent.isSelected(); +// selectParams.onlineAutoEvents = selectParams.onlineManualEvents = true; + selectParams.unassignedEvents =clicksInAnEvent.isSelected() == false; } if (andOrSelection != null) { - btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0); + selectParams.setClicksANDEvents(andOrSelection.getSelectedIndex() == 0); +// btDisplayParameters.showANDEvents = (andOrSelection.getSelectedIndex() == 0); } if (speciesButtons != null) { int n = speciesButtons.length; for (int i = 0; i < n; i++) { - btDisplayParameters.setShowSpecies(i+1, speciesButtons[i].isSelected()); + selectParams.setUseSpecies(i+1, speciesButtons[i].isSelected()); +// btDisplayParameters.setShowSpecies(i+1, speciesButtons[i].isSelected()); } } currentBTDisplay.repaintTotal(); @@ -275,23 +288,35 @@ public class OfflineToolbar { } private void checkButtons(BTDisplayParameters btDisplayParameters) { - showEchoes.setSelected(btDisplayParameters.showEchoes); - showNonSpecies.setSelected(btDisplayParameters.getShowSpecies(0)); + ClickDataSelector clickDataSelector = currentBTDisplay.getDataSelector(); + ClickAlarmParameters selectParams = clickDataSelector.getParams(); + showEchoes.setSelected(selectParams.useEchoes); + showNonSpecies.setSelected(selectParams.getUseSpecies(0)); +// showNonSpecies.setSelected(btDisplayParameters.getShowSpecies(0)); + boolean anySel = false;; if (clicksInAnEvent != null) { - clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly); + clicksInAnEvent.setSelected(selectParams.unassignedEvents == false); + anySel |= clicksInAnEvent.isSelected(); +// clicksInAnEvent.setSelected(btDisplayParameters.showEventsOnly); } if (speciesButtons != null) { int n = speciesButtons.length; for (int i = 0; i < n; i++) { - speciesButtons[i].setSelected(btDisplayParameters.getShowSpecies(i+1)); + speciesButtons[i].setSelected(selectParams.getUseSpecies(i+1)); + anySel |= speciesButtons[i].isSelected(); +// speciesButtons[i].setSelected(btDisplayParameters.getShowSpecies(i+1)); } } // setting combo box fires actionlistener, so we have to make sure that all checkboxes have been properly set first // or else they will get cleared later if (andOrSelection != null) { - andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1); + andOrSelection.setSelectedIndex(selectParams.isClicksANDEvents() ? 0 : 1); +// andOrSelection.setSelectedIndex(btDisplayParameters.showANDEvents ? 0: 1); } firstSetup = true; + if (anySel) { + selectParams.setCombinationFlag(DataSelectParams.DATA_SELECT_AND); + } } } diff --git a/src/clickDetector/tdPlots/ClickPlotInfo.java b/src/clickDetector/tdPlots/ClickPlotInfo.java index 18cdfb7a..baa60626 100644 --- a/src/clickDetector/tdPlots/ClickPlotInfo.java +++ b/src/clickDetector/tdPlots/ClickPlotInfo.java @@ -9,6 +9,8 @@ import clickDetector.BTDisplayParameters; import clickDetector.ClickControl; import clickDetector.ClickDetection; import clickDetector.ClickDisplayManagerParameters; +import clickDetector.alarm.ClickAlarmParameters; +import clickDetector.dataSelector.ClickDataSelector; import clickDetector.dialogs.ClickDisplayDialog; import PamView.GeneralProjector.ParameterType; import PamView.GeneralProjector.ParameterUnits; @@ -52,6 +54,10 @@ public class ClickPlotInfo extends TDDataInfo { allScaleInfo[3] = slantScaleInfo; clickHidingDialog = new ClickHidingDialog(this); } + + ClickDataSelector getDataSelector() { + return (ClickDataSelector) clickControl.getClickDataBlock().getDataSelector("ClickTDPlots", false); + } @Override public Double getDataValue(PamDataUnit pamDataUnit) { @@ -110,7 +116,8 @@ public class ClickPlotInfo extends TDDataInfo { private synchronized boolean shouldPlot(ClickDetection click) { if (click == null) return false; - if (btDisplayParams.showEchoes == false && click.isEcho()) { + boolean showEchoes = getDataSelector().getClickAlarmParameters().useEchoes; + if (showEchoes == false && click.isEcho()) { return false; } @@ -170,7 +177,7 @@ public class ClickPlotInfo extends TDDataInfo { */ @Override public boolean editOptions(Window frame) { - BTDisplayParameters newParams = ClickDisplayDialog.showDialog(clickControl, frame, btDisplayParams); + BTDisplayParameters newParams = ClickDisplayDialog.showDialog(clickControl, frame, btDisplayParams, getDataSelector().getClickAlarmParameters()); if (newParams != null) { btDisplayParams = newParams.clone(); updateSettings();